Telefonie-Integration (Twilio, etc.)
Auf dieser Seite
Aktualisiert am 3. November 2026 basierend auf der Realtime API-Dokumentation: Das G.711 μ-law-Format heißt
audio/pcmu(früher wurde im Textg711_ulawzitiert, was der Beta-Name war). Quelle: Realtime API.
Aktualisierung vom 2. November 2026 — Audio-Modelle. Mehrere Modelle in diesem Kurs sind veraltet:
tts-1,tts-1-hdundgpt-4o-mini-ttswerden am 6. Januar 2027 nicht mehr funktionieren (die angegebene Alternative istgpt-realtime-2.1-mini, die laut OpenAI-TTS-Leitfaden nicht über/v1/audio/speechunterstützt wird: Die Migration der Sprachsynthese muss über die Realtime API erfolgen);gpt-realtime,gpt-4o-realtimeund veraltete Audio-Modelle am 20. Januar 2027 (gpt-realtime-2.1,gpt-realtime-2.1-mini,gpt-audio-1.5);whisper-1,gpt-4o-transcribeund/v1/audio/translationsam 26. Februar 2027 (gpt-transcribe,gpt-live-transcribe,v1/realtime/translations). Für Voll-Duplex-Stimme ist GPT-Live 1 seit dem 10. September 2026 in der API verfügbar.
Telefonie-Integration (Twilio, etc.)
Ein Voice-Agent wird erst dann wirklich nützlich, wenn er über das Telefon erreichbar ist. Cloud-Telefonie-Plattformen wie Twilio, LiveKit und Daily ermöglichen es Ihnen, die Realtime API mit dem weltweiten Telefonnetz zu verbinden. Ein Nutzer wählt eine Nummer, und Ihr Agent antwortet in Echtzeit.
Telefonie-Architektur
Die Telefonie-Integration fügt eine Schicht zwischen dem Telefonnetz und der Realtime API ein:
Eingehender Anruf → Twilio
Der Nutzer wählt eine Telefonnummer. Twilio empfängt den Anruf und sendet ein Webhook an Ihren Server.
Ihr Server → Media Stream
Ihr Server antwortet mit TwiML-Anweisungen, die einen bidirektionalen Media-Stream-WebSocket öffnen.
Media Stream ↔ Realtime API
Ihr Server leitet Audio zwischen dem Twilio Media Stream und der OpenAI Realtime API weiter.
Stimmenantwort → Nutzer
Das Antwort-Audio von der Realtime API wird über Twilio zurück an das Telefon des Nutzers gesendet.
Implementierung mit Twilio
Webhook für eingehende Anrufe
Wenn ein Anruf eingeht, sendet Twilio eine HTTP-Anfrage an Ihren Server. Sie antworten mit TwiML, das einen Media Stream öffnet:
from fastapi import FastAPI, Request
from fastapi.responses import Response
app = FastAPI()
@app.post("/incoming-call")
async def incoming_call(request: Request):
"""Twilio-Webhook für eingehende Anrufe."""
twiml = """<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say language="en-US">
Willkommen bei Corsen AI. Wir verbinden Sie mit Ihrem Sprachassistenten.
</Say>
<Connect>
<Stream url="wss://your-server.com/media-stream">
<Parameter name="caller" value="{caller_number}" />
</Stream>
</Connect>
</Response>"""
form_data = await request.form()
caller = form_data.get("From", "unknown")
twiml = twiml.replace("{caller_number}", caller)
return Response(content=twiml, media_type="application/xml")
Die Brücke Media Stream ↔ Realtime API
Der WebSocket-Server empfängt Audio von Twilio und leitet es an die Realtime API weiter:
from fastapi import WebSocket
import websockets
import json
import base64
import audioop
import asyncio
OPENAI_API_KEY = "sk-..."
REALTIME_URL = "wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1"
@app.websocket("/media-stream")
async def media_stream(twilio_ws: WebSocket):
"""Brücke zwischen Twilio Media Stream und der Realtime API."""
await twilio_ws.accept()
# Verbindung zur Realtime API herstellen
headers = {
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
async with websockets.connect(REALTIME_URL, additional_headers=headers) as openai_ws:
await openai_ws.recv() # session.created
# Sitzung konfigurieren
await openai_ws.send(json.dumps({
"type": "session.update",
"session": {
"type": "realtime",
"output_modalities": ["audio"],
"instructions": "Sie sind ein Telefon-Assistent. "
"Antworten Sie auf Englisch, knapp.",
"audio": {
"input": {
"format": {"type": "audio/pcmu"},
"turn_detection": {
"type": "server_vad",
"threshold": 0.5,
"silence_duration_ms": 600
}
},
"output": {
"format": {"type": "audio/pcmu"},
"voice": "marin"
}
}
}
}))
await openai_ws.recv()
stream_sid = None
async def twilio_to_openai():
nonlocal stream_sid
async for message in twilio_ws.iter_text():
data = json.loads(message)
if data["event"] == "media":
audio_b64 = data["media"]["payload"]
await openai_ws.send(json.dumps({
"type": "input_audio_buffer.append",
"audio": audio_b64
}))
elif data["event"] == "start":
stream_sid = data["start"]["streamSid"]
async def openai_to_twilio():
async for message in openai_ws:
event = json.loads(message)
if event["type"] == "response.output_audio.delta":
await twilio_ws.send_json({
"event": "media",
"streamSid": stream_sid,
"media": {
"payload": event["delta"]
}
})
await asyncio.gather(twilio_to_openai(), openai_to_twilio())
G.711-Audioformat
Die Telefonie verwendet das G.711 μ-law-Format (8 kHz, ein Byte pro Sample). Die Realtime API unterstützt dies nativ unter dem Namen audio/pcmu, den Sie sowohl für die Eingabe als auch für die Ausgabe deklarieren (audio.input.format und audio.output.format, wie im obigen Code). Dies vermeidet jegliche serverseitige Konvertierung. Der Name g711_ulaw gehörte zur API-Beta; das äquivalente A-law-Format heißt audio/pcma.
Alternativen zu Twilio
| Plattform | Stärke | Integration mit Realtime API |
|---|---|---|
| Twilio | Komplettes Ökosystem, Nummern in über 100 Ländern | Native WebSocket Media Streams |
| LiveKit | Open Source, geringe Latenz, WebRTC | Offizielles OpenAI-Plugin |
| Daily | Einfach, gehostet, gut für Prototypen | Pipecat SDK mit Realtime-Connector |
Kernaussagen
- Twilio Media Streams ermöglichen die Verbindung eines Telefonanrufs mit einem bidirektionalen WebSocket.
- Ihr Server fungiert als Brücke zwischen dem Twilio Media Stream und der OpenAI Realtime API.
- Das G.711 μ-law-Format ist für die Telefonie nativ und wird direkt von der Realtime API unterstützt.
- LiveKit (Open Source, WebRTC) und Daily (gehostet) sind lebensfähige Alternativen zu Twilio.
- Die Architektur ist immer dieselbe: Telefonie → Ihr Server → Realtime API.