0Pricing
AI Agents · Leçon

Text-to-Speech dans les réponses des agents

API TTS d’OpenAI, ElevenLabs et Google TTS dans les pipelines d’agents.

Text-to-Speech dans les réponses des agents est une leçon AI Agents gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Agents, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Agents comprend 4 leçons au total.

Pourquoi les agents ont besoin de la TTS

Un agent vocal qui écoute mais répond uniquement par écrit n’est pas un véritable agent vocal. La synthèse vocale (TTS) convertit les réponses textuelles de l’agent en audio parlé, ce qui complète la boucle vocale.

Deux API de premier plan : OpenAI TTS (rapide, abordable, 6 voix) et ElevenLabs (voix ultra-réalistes, diffusion en continu et clonage vocal).

Principes de base d’OpenAI TTS

L’API TTS d’OpenAI convertit du texte en parole en quelques secondes. Six voix intégrées : alloy, echo, fable, onyx, nova, shimmer. Elle prend en charge les formats de sortie MP3, opus, AAC et 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, clear

Diffusion TTS en continu avec OpenAI

Pour réduire la latence perçue, diffusez l’audio au fur et à mesure de sa génération au lieu d’attendre le fichier complet. L’appelant peut commencer à lire l’audio pendant que le reste est encore synthétisé.

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)

SDK ElevenLabs : TTS haute qualité

ElevenLabs produit les voix les plus réalistes disponibles. Il prend en charge le clonage vocal, le contrôle du ton émotionnel et la diffusion en continu.

Installez-le avec 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_path

Diffusion TTS en continu avec ElevenLabs

ElevenLabs prend en charge la diffusion en continu : recevez des segments audio avant que le texte complet soit synthétisé. Cela est essentiel pour les agents vocaux lorsque la latence est 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}')

Lire l’audio avec sounddevice

Après avoir généré l’audio TTS, lisez-le sur l’appareil local. sounddevice associé à soundfile constitue l’option multiplateforme la plus simple pour un agent exécuté sur une machine locale.

Installez-les avec 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?')

Lire l’audio avec pygame

pygame offre davantage de contrôle : vous pouvez vérifier si l’audio est toujours en cours de lecture, l’arrêter prématurément et lire plusieurs sons. C’est utile pour gérer les interruptions dans les agents vocaux.

Installez-le avec 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)')

Mise en cache des réponses TTS

Les phrases courantes comme les salutations, les messages d’erreur et les invites de menu sont synthétisées à plusieurs reprises. Mettez leurs fichiers audio en cache afin de ne payer la synthèse qu’une seule fois par phrase.

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 phrase par phrase pour la diffusion en continu

Pour les longues réponses du LLM, divisez le texte en phrases, puis synthétisez-les et lisez-les une par une. L’utilisateur entend la première phrase en environ 500 ms, tandis que le reste est encore en cours de génération.

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)

Choisir la voix et le modèle

Adaptez le choix de la voix à la personnalité de l’agent. Utilisez des voix plus graves (onyx, echo) pour les agents formels ou professionnels, et des voix plus chaleureuses (nova, shimmer) pour les assistants sympathiques.

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')

Régler le débit et la hauteur de la parole

Des contextes différents nécessitent des caractéristiques vocales différentes. Les alertes de notification doivent être légèrement plus rapides ; la narration doit être plus lente et plus expressive. Post-traitez l’audio TTS pour ajuster la vitesse sans modifier la hauteur.

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 alerts

Vérification des connaissances

Quel est le principal avantage de la synthèse TTS phrase par phrase dans un agent vocal ?

Récapitulatif : synthèse vocale dans les réponses de l’agent

OpenAI TTS (tts-1, tts-1-hd) fournit 6 voix, une synthèse rapide et la prise en charge de la diffusion en continu : c’est l’option idéale pour la plupart des agents vocaux. ElevenLabs offre des voix réalistes de meilleure qualité avec eleven_turbo_v2 pour une diffusion en continu à faible latence.

Lisez l’audio avec sounddevice (simple) ou pygame (permettant les interruptions). Mettez les phrases courantes en cache pour éliminer les coûts d’API répétitifs. Utilisez la synthèse phrase par phrase pour les longues réponses afin de réduire la latence perçue. La mise en cache TTS avec des hachages MD5 garantit qu’un texte identique est toujours fourni depuis le cache.

Questions Fréquemment Posées

La leçon « Text-to-Speech dans les réponses des agents » est-elle gratuite ?

Oui — le texte complet de « Text-to-Speech dans les réponses des agents » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Agents, passe à CoddyKit PRO. Le cours AI Agents comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Text-to-Speech dans les réponses des agents » ?

API TTS d’OpenAI, ElevenLabs et Google TTS dans les pipelines d’agents. Tu pratiques AI Agents avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Agents ?

Aucune expérience préalable n'est requise. AI Agents sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Text-to-Speech dans les réponses des agents » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Agents ?

Oui. Chaque leçon AI Agents inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Speech-to-Text avec Whisper et Deepgram
  2. Text-to-Speech dans les réponses des agents
  3. Créer une boucle de conversation vocale
  4. Optimiser la latence des agents vocaux
← Retour à AI Agents