Guide de démarrage Speech Engine

Ajoutez la voix à votre agent de chat avec le SDK ElevenLabs.

Ce guide vous accompagne dans la création d’un agent vocal avec Speech Engine. Configurez un serveur qui connecte votre LLM à ElevenLabs, puis reliez un client navigateur afin que les utilisateurs puissent converser vocalement avec votre agent.

Utilisez la compétence ElevenLabs Speech Engine pour ajouter la voix à votre agent de chat :

npx skills add elevenlabs/skills --skill speech-engine

Fonctionnement de Speech Engine

Speech Engine connecte votre LLM à ElevenLabs afin que les utilisateurs puissent parler à votre agent et entendre ses réponses. ElevenLabs gère la conversion de la parole en texte et du texte en parole ; votre serveur fournit la logique LLM.

Chaque connexion WebSocket représente une conversation. Lorsque l’utilisateur parle, ElevenLabs transcrit l’audio et envoie la transcription à votre serveur. Votre serveur la transmet à votre LLM, puis renvoie la réponse en continu. ElevenLabs convertit le texte en parole et le diffuse dans le navigateur. Le SDK gère les connexions, les tours de parole et la détection des interruptions.

Prérequis

Ce tutoriel utilise l’API d’OpenAI pour le LLM. Vous avez besoin d’une clé API OpenAI définie dans la variable d’environnement OPENAI_API_KEY.

Configuration du serveur

1

Créer une clé API

Créez une clé API dans le Dashboard ici, que vous utiliserez pour accéder à l’API de manière sécurisée.

Stockez la clé comme secret géré et transmettez-la aux SDK soit en tant que variable d’environnement via un fichier .env, soit directement dans la configuration de votre application, selon vos préférences.

.env
ELEVENLABS_API_KEY=<your_api_key_here>
2

Installer les dépendances

pip install elevenlabs openai python-dotenv
3

Exposer le serveur

Speech Engine requiert une URL accessible publiquement. Utilisez ngrok pour exposer votre serveur local. Le serveur n’est pas encore créé, mais ngrok doit d’abord être exécuté afin que vous disposiez de l’URL pour l’étape suivante.

ngrok http 3001

Copiez l’URL de transfert (par exemple, https://abc123.ngrok.io).

4

Créer une instance Speech Engine

Utilisez le SDK pour créer une instance Speech Engine, en transmettant votre URL ngrok avec le chemin /ws ajouté comme URL WebSocket.

import asyncio
from dotenv import load_dotenv
from elevenlabs import AsyncElevenLabs
load_dotenv()
elevenlabs = AsyncElevenLabs(
api_key=os.getenv("ELEVENLABS_API_KEY"),
)
async def main():
engine = await elevenlabs.speech_engine.create(
name="My Speech Engine",
speech_engine={
# Note we use the wss protocol instead of https
"ws_url": "wss://abc123.ngrok.io/ws",
},
)
print(f"Speech Engine ID: {engine.engine_id}")
if __name__ == "__main__":
asyncio.run(main())

Exécutez ce script et copiez l’ID Speech Engine (par exemple, seng_8k3m9xr4hjnfg983brhmhkd98n6) pour l’étape suivante.

5

Créer le serveur

Créez un fichier nommé server.py ou server.mts avec le contenu suivant. Il configure un serveur, associe Speech Engine au chemin /ws et utilise OpenAI pour générer des réponses.

import asyncio
import os
from dotenv import load_dotenv
from openai import AsyncOpenAI
from elevenlabs import AsyncElevenLabs
load_dotenv()
# Replace with your Speech Engine ID from step 4
SPEECH_ENGINE_ID = "seng_8k3m9xr4hjnfg983brhmhkd98n6"
openai = AsyncOpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
)
elevenlabs = AsyncElevenLabs(
api_key=os.getenv("ELEVENLABS_API_KEY"),
)
def on_init(conversation_id, session):
print(f"Session started: {conversation_id}")
async def on_transcript(transcript, session):
stream = await openai.responses.create(
model="gpt-4o",
instructions="You are a helpful voice assistant. Keep responses concise and conversational.",
input=[
{"role": "assistant" if m.role == "agent" else m.role, "content": m.content}
for m in transcript
],
stream=True,
)
await session.send_response(stream)
def on_close(session):
print(f"Session ended: {session.conversation_id}")
def on_error(err, session):
print(f"Error: {err}")
async def main():
engine = await elevenlabs.speech_engine.get(SPEECH_ENGINE_ID)
await engine.serve(
port=3001,
path="/ws",
debug=True,
on_init=on_init,
on_transcript=on_transcript,
on_close=on_close,
on_error=on_error,
)
if __name__ == "__main__":
asyncio.run(main())

Le callback onTranscript / on_transcript reçoit l’historique complet de la conversation et la session en cours. Le SDK TypeScript fournit également un AbortSignal qui se déclenche si l’utilisateur interrompt la réponse en cours. Transmettre signal à l’appel OpenAI annule automatiquement la requête LLM en cas d’interruption.

sendResponse() / send_response() accepte une chaîne, un itérable asynchrone ou un flux provenant d’OpenAI, Anthropic ou Google Gemini. Le SDK extrait automatiquement le contenu textuel.

Dans l’exemple ci-dessus, la transcription complète de l’utilisateur est transmise au LLM. En environnement de production, ajoutez des garde-fous pour prévenir toute tentative d’injection ou de manipulation de prompt.

6

Démarrer le serveur

python server.py

Configuration du client

1

Installer le SDK client

npm install @elevenlabs/react
2

Créer un endpoint de jeton

Ajoutez un endpoint côté serveur qui génère un jeton de conversation. Cela protège votre clé API dans le navigateur et utilise WebRTC pour une qualité audio optimale.

import os
from dotenv import load_dotenv
from flask import Flask, jsonify
from elevenlabs import ElevenLabs
load_dotenv()
app = Flask(__name__)
elevenlabs = ElevenLabs(
api_key=os.getenv("ELEVENLABS_API_KEY"),
)
@app.route("/api/token")
def get_token():
# Replace with your Speech Engine ID from step 4 of the server setup
speech_engine_id = "seng_8k3m9xr4hjnfg983brhmhkd98n6"
response = elevenlabs.conversational_ai.conversations.get_webrtc_token(
agent_id=speech_engine_id,
)
return jsonify(token=response.token)
if __name__ == "__main__":
app.run(port=3002)
3

Créer l'interface de conversation

Récupérez le jeton de conversation depuis votre serveur et utilisez-le pour démarrer une session.

App.tsx
import { useConversation } from "@elevenlabs/react";
import { useCallback } from "react";
async function getToken(): Promise<string> {
const response = await fetch("/api/token");
if (!response.ok) {
throw Error("Failed to get conversation token");
}
const data = await response.json();
return data.token;
}
export default function App() {
const conversation = useConversation({
onConnect: () => console.log("Connected"),
onDisconnect: () => console.log("Disconnected"),
onError: (error: Error) => console.error("Error:", error),
});
const startConversation = useCallback(async () => {
await navigator.mediaDevices.getUserMedia({ audio: true });
const token = await getToken();
await conversation.startSession({ conversationToken: token });
}, [conversation]);
const stopConversation = useCallback(async () => {
await conversation.endSession();
}, [conversation]);
return (
<div>
<p>Status: {conversation.status}</p>
<button onClick={startConversation} disabled={conversation.status === "connected"}>
Start conversation
</button>
<button onClick={stopConversation} disabled={conversation.status !== "connected"}>
End conversation
</button>
</div>
);
}
4

Tester

Vérifiez que trois processus sont en cours d’exécution :

  1. ngrok - transfert vers le port 3001
  2. Votre serveur Speech Engine - python server.py ou npx tsx server.mts
  3. Le serveur de jetons - npx tsx token-server.mts ou python token_server.py

Ouvrez votre application cliente dans le navigateur et cliquez sur Démarrer la conversation. Autorisez l’accès au microphone lorsque cela vous est demandé, puis parlez. Vous devriez entendre la réponse de l’agent dans vos haut-parleurs.

Si debug: true est activé sur le serveur, les transcriptions entrantes et les réponses sortantes s’affichent dans la console.

Événements de session

ÉvénementCallback TypeScriptCallback PythonDescription
user_transcriptonTranscripton_transcriptParole de l’utilisateur transcrite. Inclut l’historique complet de la conversation et un signal d’annulation.
initonIniton_initSession initialisée avec un ID de conversation.
closeonCloseon_closeDéconnexion propre d’ElevenLabs.
disconnectedonDisconnecton_disconnectWebSocket interrompu de manière inattendue.
erroronErroron_errorErreur de protocole ou WebSocket.

Configurer le premier message de l’agent

Par défaut, l’agent attend que l’utilisateur parle en premier. Pour que l’agent salue l’utilisateur au début de la conversation, définissez un premier message dans l’option overrides du client au démarrage de la session.

1

Pour permettre à l’agent de parler en premier, vous devez mettre à jour la ressource Speech Engine afin d’autoriser cette configuration depuis le client.

engine = await elevenlabs.speech_engine.update(
speech_engine_id="seng_8k3m9xr4hjnfg983brhmhkd98n6",
overrides={
"first_message": True,
},
)
2

Configurez ensuite le premier message dans le SDK client.

conversation.startSession({
conversationToken: token,
overrides: {
agent: {
firstMessage: "Hello! How can I help you today?",
},
},
});

Le premier message est prononcé par l’agent dès que la connexion est établie. Il ne déclenche pas le callback onTranscript sur votre serveur : il est entièrement géré côté ElevenLabs.

Prochaines étapes