Text-to-Speech nelle risposte degli agenti
API OpenAI TTS, ElevenLabs e Google TTS nelle pipeline degli agenti
Text-to-Speech nelle risposte degli agenti è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.
Perché gli agenti hanno bisogno del TTS
Un agente vocale che ascolta soltanto ma risponde con testo non è un vero agente vocale. Text-to-Speech (TTS) converte le risposte testuali dell'agente in audio parlato, completando l'intero ciclo vocale.
Due API principali: OpenAI TTS (veloce, conveniente, 6 voci) e ElevenLabs (voci ultra-realistiche, streaming e clonazione della voce).
Nozioni di base su OpenAI TTS
L'API TTS di OpenAI converte il testo in parlato in pochi secondi. Sei voci integrate: alloy, echo, fable, onyx, nova, shimmer. Supporta i formati di output MP3, opus, AAC e 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 in streaming con OpenAI
Per ridurre la latenza percepita, trasmetta l'audio in streaming man mano che viene generato invece di attendere il file completo. Chi effettua la chiamata può iniziare a riprodurre l'audio mentre il resto viene ancora sintetizzato.
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)ElevenLabs SDK: TTS di alta qualità
ElevenLabs produce alcune tra le voci più realistiche disponibili. Supporta la clonazione della voce, il controllo del tono emotivo e lo streaming.
Installi il pacchetto con 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 in streaming con ElevenLabs
ElevenLabs supporta lo streaming: riceva i blocchi audio prima che venga sintetizzato l'intero testo. Questo è fondamentale per gli agenti vocali, nei quali la latenza è importante.
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}')Riproduzione dell'audio con sounddevice
Dopo aver generato l'audio TTS, lo riproduca sul dispositivo locale. sounddevice insieme a soundfile è l'opzione multipiattaforma più semplice per un agente in esecuzione su una macchina locale.
Installi i pacchetti con 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?')Riproduzione dell'audio con pygame
pygame offre un controllo maggiore: è possibile verificare se l'audio è ancora in riproduzione, interromperlo in anticipo e riprodurre più suoni. È utile per gestire le interruzioni negli agenti vocali.
Installi il pacchetto con 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)')Memorizzazione nella cache delle risposte TTS
Frasi comuni come saluti, messaggi di errore e prompt dei menu vengono sintetizzate ripetutamente. Memorizzi i relativi file audio nella cache, così pagherà la sintesi una sola volta per frase.
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 frase per frase per lo streaming
Per le risposte LLM lunghe, suddivida il testo in frasi e le sintetizzi e riproduca una alla volta. L'utente ascolta la prima frase entro circa 500 ms, mentre il resto viene ancora generato.
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)Scelta della voce e del modello
Abbini la scelta della voce alla personalità dell'agente. Utilizzi voci più profonde (onyx, echo) per agenti formali o professionali e voci più calde (nova, shimmer) per assistenti amichevoli.
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')Regolazione della velocità e dell'intonazione
Contesti diversi richiedono caratteristiche vocali diverse. Gli avvisi di notifica dovrebbero essere leggermente più veloci, mentre la narrazione dovrebbe essere più lenta ed espressiva. Elabori l'audio TTS dopo la sintesi per regolare la velocità senza modificare l'intonazione.
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 alertsVerifica delle conoscenze
Qual è il principale vantaggio della sintesi TTS frase per frase in un agente vocale?
Riepilogo: Text-to-Speech nelle risposte dell'agente
OpenAI TTS (tts-1, tts-1-hd) offre 6 voci, sintesi rapida e supporto allo streaming: è ideale per la maggior parte degli agenti vocali. ElevenLabs offre voci realistiche di qualità superiore con eleven_turbo_v2 per lo streaming a bassa latenza.
Riproduca l'audio con sounddevice (semplice) o pygame (interrompibile). Memorizzi nella cache le frasi comuni per eliminare i costi ripetuti delle API. Utilizzi la sintesi frase per frase per le risposte lunghe, così da ridurre al minimo la latenza percepita. La memorizzazione nella cache del TTS con hash MD5 garantisce che lo stesso testo venga sempre fornito dalla cache.
Domande Frequenti
La lezione «Text-to-Speech nelle risposte degli agenti» è gratuita?
Sì — il testo completo di «Text-to-Speech nelle risposte degli agenti» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.
Cosa imparerò in «Text-to-Speech nelle risposte degli agenti»?
API OpenAI TTS, ElevenLabs e Google TTS nelle pipeline degli agenti Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Agents?
Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Text-to-Speech nelle risposte degli agenti»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Agents?
Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Speech-to-Text con Whisper e Deepgram
- Text-to-Speech nelle risposte degli agenti
- Creazione di un ciclo di conversazione vocale
- Ottimizzazione della latenza per gli agenti vocali