Text-to-Speech dalam Respons Agen
API OpenAI TTS, ElevenLabs, dan Google TTS dalam pipeline agen.
Text-to-Speech dalam Respons Agen adalah pelajaran AI Agents gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Agents, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Agents mencakup 4 pelajaran total.
Mengapa Agen Membutuhkan TTS
Agen suara yang hanya mendengarkan tetapi merespons dalam bentuk teks bukanlah agen suara yang sesungguhnya. Text-to-Speech (TTS) mengubah respons teks agen menjadi audio ucapan sehingga melengkapi seluruh siklus suara.
Dua API utama: OpenAI TTS (cepat, terjangkau, 6 suara) dan ElevenLabs (suara yang sangat realistis, penstriman, dan kloning suara).
Dasar-Dasar OpenAI TTS
API TTS OpenAI mengubah teks menjadi ucapan dalam hitungan detik. Enam suara bawaan: alloy, echo, fable, onyx, nova, shimmer. Mendukung format keluaran MP3, opus, AAC, dan FLAC.
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def text_to_speech(text, voice='alloy', output_path='response.mp3'):
response = client.audio.speech.create(
model='tts-1', # tts-1 (fast) or tts-1-hd (higher quality)
voice=voice, # alloy, echo, fable, onyx, nova, shimmer
input=text,
response_format='mp3' # mp3, opus, aac, flac
)
with open(output_path, 'wb') as f:
f.write(response.content)
print(f'Audio saved to: {output_path}')
return output_path
# Available voices:
# alloy - neutral, balanced
# echo - warm, conversational
# fable - expressive
# onyx - deep, authoritative
# nova - friendly, upbeat
# shimmer - soft, clearTTS OpenAI melalui Penstriman
Untuk mengurangi latensi yang dirasakan, alirkan audio saat dibuat, alih-alih menunggu seluruh berkas selesai. Pemanggil dapat mulai memutar audio saat bagian lainnya masih disintesis.
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def stream_tts_to_file(text, output_path, voice='nova'):
with client.audio.speech.with_streaming_response.create(
model='tts-1',
voice=voice,
input=text
) as response:
response.stream_to_file(output_path)
return output_path
def stream_tts_to_bytes(text, voice='nova'):
audio_chunks = []
with client.audio.speech.with_streaming_response.create(
model='tts-1',
voice=voice,
input=text
) as response:
for chunk in response.iter_bytes(chunk_size=4096):
audio_chunks.append(chunk)
return b''.join(audio_chunks)Deepgram SDK: TTS Berkualitas Tinggi
ElevenLabs menghasilkan suara yang paling realistis. Layanan ini mendukung kloning suara, pengaturan nuansa emosional, dan penstriman.
Instal dengan pip install elevenlabs.
from elevenlabs import ElevenLabs, VoiceSettings
import os
client = ElevenLabs(api_key=os.getenv('ELEVENLABS_API_KEY'))
def elevenlabs_tts(text, voice_id='pNInz6obpgDQGcFmaJgB', output_path='response.mp3'):
# Common voice IDs:
# Rachel: 21m00Tcm4TlvDq8ikWAM
# Adam: pNInz6obpgDQGcFmaJgB
# Bella: EXAVITQu4vr4xnSDxMaL
audio = client.generate(
text=text,
voice=voice_id,
model='eleven_multilingual_v2', # supports 29 languages
voice_settings=VoiceSettings(
stability=0.5, # 0.0-1.0: lower = more expressive
similarity_boost=0.8, # 0.0-1.0: higher = closer to original voice
style=0.3 # 0.0-1.0: style exaggeration
)
)
with open(output_path, 'wb') as f:
for chunk in audio:
f.write(chunk)
return output_pathTTS ElevenLabs melalui Penstriman
ElevenLabs mendukung penstriman—menerima bagian-bagian audio sebelum seluruh teks selesai disintesis. Hal ini penting bagi agen suara yang memerlukan latensi rendah.
from elevenlabs import ElevenLabs
import os
client = ElevenLabs(api_key=os.getenv('ELEVENLABS_API_KEY'))
def streaming_tts(text, voice_id='pNInz6obpgDQGcFmaJgB'):
audio_stream = client.generate(
text=text,
voice=voice_id,
model='eleven_turbo_v2', # fastest model, optimized for streaming
stream=True
)
return audio_stream # yields audio chunks as they are generated
def stream_to_file(text, output_path, voice_id='pNInz6obpgDQGcFmaJgB'):
stream = streaming_tts(text, voice_id)
with open(output_path, 'wb') as f:
for chunk in stream:
if chunk:
f.write(chunk)
print(f'Streaming TTS complete: {output_path}')Memutar Audio dengan sounddevice
Setelah membuat audio TTS, putar audio tersebut di perangkat lokal. sounddevice bersama soundfile adalah pilihan lintas platform paling sederhana untuk agen yang berjalan di komputer lokal.
Instal dengan pip install sounddevice soundfile.
import sounddevice as sd
import soundfile as sf
import numpy as np
import tempfile
import os
def play_audio_file(audio_path):
data, sample_rate = sf.read(audio_path)
sd.play(data, sample_rate)
sd.wait() # block until playback finishes
def play_mp3_bytes(audio_bytes):
# Write to temp file then play (soundfile needs a file)
with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as f:
f.write(audio_bytes)
tmp_path = f.name
try:
play_audio_file(tmp_path)
finally:
os.unlink(tmp_path)
def say(text, voice='nova'):
audio_bytes = stream_tts_to_bytes(text, voice=voice)
play_mp3_bytes(audio_bytes)
# Usage
say('Hello! How can I help you today?')Memutar Audio dengan pygame
pygame memberikan kontrol yang lebih besar: Anda dapat memeriksa apakah audio masih diputar, menghentikannya lebih awal, dan memutar beberapa suara. Fitur ini berguna untuk penanganan interupsi pada agen suara.
Instal dengan pip install pygame.
import pygame
import io
import tempfile
import os
pygame.mixer.init(frequency=44100, size=-16, channels=1, buffer=512)
def play_audio_pygame(audio_bytes):
with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as f:
f.write(audio_bytes)
tmp_path = f.name
try:
pygame.mixer.music.load(tmp_path)
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
pygame.time.wait(50) # check every 50ms
finally:
pygame.mixer.music.stop()
os.unlink(tmp_path)
def stop_audio():
if pygame.mixer.music.get_busy():
pygame.mixer.music.stop()
print('Audio stopped (interrupt)')Menyimpan Respons TTS dalam Tembolok
Frasa umum seperti salam, pesan kesalahan, dan perintah menu berulang kali disintesis. Simpan berkas audio tersebut dalam tembolok agar Anda hanya membayar sintesis satu kali untuk setiap frasa.
import hashlib
import os
TTS_CACHE_DIR = '/tmp/tts_cache'
os.makedirs(TTS_CACHE_DIR, exist_ok=True)
def cached_tts(text, voice='nova'):
cache_key = hashlib.md5(f'{voice}:{text}'.encode()).hexdigest()
cache_path = os.path.join(TTS_CACHE_DIR, f'{cache_key}.mp3')
if os.path.exists(cache_path):
print('TTS cache hit')
return cache_path
# Generate and save
audio_bytes = stream_tts_to_bytes(text, voice=voice)
with open(cache_path, 'wb') as f:
f.write(audio_bytes)
print(f'TTS cached: {cache_path}')
return cache_path
# Pre-warm cache for common phrases on startup
COMMON_PHRASES = [
'Hello! How can I help you today?',
'I did not catch that. Could you repeat?',
'Let me look that up for you.',
'Thank you, goodbye!'
]
def prewarm_tts_cache():
for phrase in COMMON_PHRASES:
cached_tts(phrase)
print(f'Pre-warmed {len(COMMON_PHRASES)} phrases')TTS per Kalimat untuk Penstriman
Untuk respons LLM yang panjang, bagi teks menjadi beberapa kalimat, lalu sintesis dan putar setiap kalimat satu per satu. Pengguna dapat mendengar kalimat pertama dalam waktu sekitar 500ms sementara bagian lainnya masih dibuat.
import re
def split_into_sentences(text):
sentences = re.split(r'(?<=[.!?])\s+', text.strip())
return [s.strip() for s in sentences if s.strip()]
def stream_response_as_voice(llm_response_text, voice='nova'):
sentences = split_into_sentences(llm_response_text)
print(f'Speaking {len(sentences)} sentences')
for i, sentence in enumerate(sentences):
if not sentence:
continue
print(f'Speaking ({i+1}/{len(sentences)}): {sentence[:60]}')
cache_path = cached_tts(sentence, voice=voice)
play_audio_file(cache_path)
# Example
response = 'The weather today is sunny and 22 degrees. Perfect for outdoor activities. Bring sunscreen if you plan to be outside for more than an hour.'
stream_response_as_voice(response)Memilih Suara dan Model
Sesuaikan pilihan suara dengan persona agen. Gunakan suara yang lebih dalam (onyx, echo) untuk agen formal atau profesional, dan suara yang lebih hangat (nova, shimmer) untuk asisten yang bersahabat.
VOICE_PROFILES = {
'assistant': {'service': 'openai', 'voice': 'nova', 'model': 'tts-1'},
'professional': {'service': 'openai', 'voice': 'onyx', 'model': 'tts-1-hd'},
'narrator': {'service': 'openai', 'voice': 'fable', 'model': 'tts-1-hd'},
'premium': {'service': 'elevenlabs', 'voice_id': '21m00Tcm4TlvDq8ikWAM', 'model': 'eleven_multilingual_v2'}
}
def speak(text, persona='assistant'):
profile = VOICE_PROFILES.get(persona, VOICE_PROFILES['assistant'])
if profile['service'] == 'openai':
audio_bytes = stream_tts_to_bytes(text, voice=profile['voice'])
play_mp3_bytes(audio_bytes)
elif profile['service'] == 'elevenlabs':
output_path = elevenlabs_tts(text, voice_id=profile['voice_id'])
play_audio_file(output_path)
speak('Your meeting has been rescheduled.', persona='professional')Menyesuaikan Kecepatan Bicara dan Tinggi Nada
Konteks yang berbeda memerlukan karakteristik ucapan yang berbeda. Peringatan notifikasi sebaiknya sedikit lebih cepat, sedangkan penceritaan sebaiknya lebih lambat dan ekspresif. Proses audio TTS setelah sintesis untuk menyesuaikan kecepatan tanpa mengubah tinggi nada.
from pydub import AudioSegment
from pydub.effects import speedup
import os
def adjust_speech_speed(audio_path, speed_factor=1.0, output_path=None):
if speed_factor == 1.0:
return audio_path
audio = AudioSegment.from_file(audio_path)
if speed_factor > 1.0:
# Speed up without changing pitch
audio = speedup(audio, playback_speed=speed_factor)
else:
# Slow down: overlay with silence (simple method)
# For production: use ffmpeg with atempo filter
slow_factor = 1.0 / speed_factor
audio = audio._spawn(
audio.raw_data,
overrides={'frame_rate': int(audio.frame_rate / slow_factor)}
).set_frame_rate(audio.frame_rate)
if output_path is None:
base = os.path.splitext(audio_path)[0]
output_path = f'{base}_speed{speed_factor}.mp3'
audio.export(output_path, format='mp3')
return output_path
# Usage
path = text_to_speech('Your meeting starts in 5 minutes.')
fast_path = adjust_speech_speed(path, speed_factor=1.2) # 20% faster for alertsUji Pemahaman
Apa manfaat utama sintesis TTS per kalimat pada agen suara?
Rangkuman: Teks ke Ucapan dalam Respons Agen
OpenAI TTS (tts-1, tts-1-hd) menyediakan 6 suara dengan sintesis cepat dan dukungan penstriman—ideal untuk sebagian besar agen suara. ElevenLabs menawarkan suara realistis dengan kualitas lebih tinggi melalui eleven_turbo_v2 untuk penstriman berlatensi rendah.
Putar audio dengan sounddevice (sederhana) atau pygame (dapat diinterupsi). Simpan frasa umum dalam tembolok untuk menghilangkan biaya API berulang. Gunakan sintesis per kalimat untuk respons panjang guna meminimalkan latensi yang dirasakan. Penyimpanan TTS dalam tembolok dengan hash MD5 memastikan teks yang sama selalu disajikan dari tembolok.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Text-to-Speech dalam Respons Agen” gratis?
Ya — teks lengkap “Text-to-Speech dalam Respons Agen” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Agents, upgrade ke CoddyKit PRO. Kursus AI Agents mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Text-to-Speech dalam Respons Agen”?
API OpenAI TTS, ElevenLabs, dan Google TTS dalam pipeline agen. Kamu berlatih AI Agents dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai AI Agents?
Tidak diperlukan pengalaman sebelumnya. AI Agents di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Text-to-Speech dalam Respons Agen” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Agents ini?
Ya. Setiap pelajaran AI Agents menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Speech-to-Text dengan Whisper dan Deepgram
- Text-to-Speech dalam Respons Agen
- Membangun Putaran Percakapan Suara
- Optimasi Latensi untuk Agen Suara