Przejdź do nawigacji

Szybki start Speech Engine

Dodaj głos do agenta czatowego za pomocą SDK ElevenLabs.

Ten przewodnik pokaże ci, jak zbudować agenta głosowego za pomocą Speech Engine. Skonfigurujesz serwer, który połączy twój LLM z ElevenLabs, a potem klienta w przeglądarce, aby użytkownicy mogli rozmawiać głosowo z twoim agentem.

Użyj umiejętności ElevenLabs Speech Engine, aby dodać głos do agenta czatowego:

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

Jak działa Speech Engine

Speech Engine łączy twój LLM z ElevenLabs, dzięki czemu użytkownicy mogą rozmawiać z agentem i słyszeć jego odpowiedzi. ElevenLabs obsługuje zamianę mowy na tekst i zamianę tekstu na mowę, a twój serwer zapewnia logikę LLM.

Każde połączenie WebSocket reprezentuje jedną rozmowę. Gdy użytkownik mówi, ElevenLabs transkrybuje audio i wysyła transkrypcję na twój serwer. Serwer przekazuje ją do LLM, a następnie przesyła odpowiedź strumieniowo. ElevenLabs zamienia tekst na mowę i odtwarza go w przeglądarce. SDK obsługuje zarządzanie połączeniami, kolejność wypowiedzi i wykrywanie przerwań.

Wymagania wstępne

Ten samouczek używa API OpenAI dla LLM. Potrzebujesz klucza API OpenAI ustawionego w zmiennej środowiskowej OPENAI_API_KEY.

Konfiguracja serwera

1

Utwórz klucz API

Utwórz klucz API w panelu tutaj, którego użyjesz, aby bezpiecznie uzyskać dostęp do API.

Przechowuj klucz jako zarządzany sekret i przekaż go do SDK jako zmienną środowiskową w pliku .env lub bezpośrednio w konfiguracji aplikacji — zależnie od preferencji.

.env
ELEVENLABS_API_KEY=<your_api_key_here>
2

Zainstaluj zależności

pip install elevenlabs openai python-dotenv
3

Udostępnij serwer

Speech Engine potrzebuje publicznie dostępnego adresu URL. Użyj ngrok, aby udostępnić lokalny serwer. Serwer nie jest jeszcze zbudowany, ale ngrok musi już działać, aby w kolejnym kroku użyć jego adresu URL.

ngrok http 3001

Skopiuj adres URL przekierowania (np. https://abc123.ngrok.io).

4

Utwórz instancję Speech Engine

Użyj SDK, aby utworzyć instancję Speech Engine, przekazując adres URL ngrok z dodaną ścieżką /ws jako adres 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())

Uruchom ten skrypt i skopiuj ID Speech Engine (np. seng_8k3m9xr4hjnfg983brhmhkd98n6) do następnego kroku.

5

Utwórz serwer

Utwórz plik o nazwie server.py lub server.mts z poniższą zawartością. Konfiguruje on serwer, podłącza Speech Engine pod ścieżką /ws i używa OpenAI do generowania odpowiedzi.

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

Callback onTranscript / on_transcript otrzymuje pełną historię rozmowy i bieżącą sesję. TypeScript SDK udostępnia też AbortSignal, który uruchamia się, gdy użytkownik przerwie odpowiedź. Przekazanie signal do wywołania OpenAI automatycznie anuluje żądanie LLM po przerwaniu.

sendResponse() / send_response() przyjmuje ciąg znaków, asynchroniczny iterowalny obiekt lub strumień z OpenAI, Anthropic albo Google Gemini. SDK automatycznie wyodrębnia treść tekstową.

W powyższym przykładzie pełna transkrypcja użytkownika jest przekazywana do LLM. W środowisku produkcyjnym dodaj zabezpieczenia przed próbami prompt injection lub manipulacji.

6

Uruchom serwer

python server.py

Konfiguracja klienta

1

Zainstaluj SDK klienta

npm install @elevenlabs/react
2

Utwórz endpoint tokenu

Dodaj endpoint po stronie serwera, który generuje token rozmowy. Dzięki temu klucz API nie trafia do przeglądarki, a do najlepszej jakości audio używany jest WebRTC.

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

Zbuduj interfejs rozmowy

Pobierz token rozmowy z serwera i użyj go, aby rozpocząć sesję.

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

Wypróbuj

Upewnij się, że działają trzy procesy:

  1. ngrok - przekierowuje do portu 3001
  2. Twój serwer Speech Engine - python server.py lub npx tsx server.mts
  3. Serwer tokenów - npx tsx token-server.mts lub python token_server.py

Otwórz aplikację kliencką w przeglądarce i kliknij Rozpocznij rozmowę. Gdy pojawi się prośba, zezwól na dostęp do mikrofonu, a potem zacznij mówić. Usłyszysz odpowiedź agenta przez głośniki.

Jeśli masz włączone debug: true na serwerze, w konsoli zobaczysz przychodzące transkrypcje i wychodzące odpowiedzi.

Zdarzenia sesji

ZdarzenieCallback TypeScriptCallback PythonOpis
user_transcriptonTranscripton_transcriptTranskrypcja mowy użytkownika. Zawiera pełną historię rozmowy i sygnał przerwania.
initonIniton_initSesja zainicjowana z ID rozmowy.
closeonCloseon_closePoprawne rozłączenie z ElevenLabs.
disconnectedonDisconnecton_disconnectPołączenie WebSocket niespodziewanie przerwane.
erroronErroron_errorBłąd protokołu lub WebSocket.

Konfigurowanie pierwszej wiadomości agenta

Domyślnie agent czeka, aż użytkownik odezwie się pierwszy. Aby agent przywitał użytkownika po rozpoczęciu rozmowy, ustaw pierwszą wiadomość w opcji overrides klienta podczas uruchamiania sesji.

1

Aby agent mógł odezwać się pierwszy, musimy zaktualizować zasób Speech Engine, aby zezwalał na ustawienie tego po stronie klienta.

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

Następnie konfigurujemy pierwszą wiadomość w SDK klienta.

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

Pierwsza wiadomość jest wypowiadana przez agenta, gdy tylko połączenie zostanie nawiązane. Nie uruchamia callbacku onTranscript na serwerze — jest obsługiwana w całości po stronie ElevenLabs.

Konfigurowanie maksymalnego czasu trwania rozmowy

Domyślnie rozmowa kończy się po 600 sekundach (10 minutach). Speech Engine obsługuje rozmowy do 7200 sekund (2 godzin). Aby zezwolić na dłuższe rozmowy, zaktualizuj zasób Speech Engine, ustawiając wyższą wartość max_duration_seconds:

engine = await elevenlabs.speech_engine.update(
speech_engine_id="seng_8k3m9xr4hjnfg983brhmhkd98n6",
conversation={
"max_duration_seconds": 7200,
},
)

Możesz też ustawić to w panelu: otwórz Speech Engine, przejdź do karty Zaawansowane i ustaw Maksymalny czas trwania rozmowy w sekcji Zachowanie rozmowy.

Kolejne kroki