ThunderPhone mit LiveKit Agents verwenden
Führen Sie einen ThunderPhone-Sprachagenten als Echtzeitmodell (Speech-to-Speech) einer LiveKit-Agents-Sitzung aus, mit LiveKit-Räumen, SIP und Telefonie darum herum.
LiveKit Agents ist ein Open-Source-Framework für Echtzeit-Sprachagenten in LiveKit-Räumen. ThunderPhone wird als Echtzeitmodell integriert: Das Framework sendet das Audio des Teilnehmers, ThunderPhone liefert die Stimme des Agenten, Transkripte und Funktionsaufrufe zurück, und der LiveKit-Raum, SIP-Trunks und die Telefonie übertragen das Audio. Spracherkennung, das Sprachmodell, die Stimme, Sprecherwechsel, 47 Sprachen und Tools laufen vollständig auf ThunderPhone.
Auf diese Weise geführte Anrufe erscheinen im Anrufverlauf und werden wie jeder andere Echtzeitanruf zum minutenbasierten Tarif Ihres Produkts abgerechnet. Es gibt kein Abonnement und keine beteiligte ThunderPhone-Telefonnummer.
Installieren
pip install livekit-plugins-thunderphone
export THUNDERPHONE_API_KEY=sk_live_... # a secret API keyDas Plugin kapselt das OpenAI-Echtzeitmodell von LiveKit, da der
Realtime WebSocket von ThunderPhone dasselbe Protokoll verwendet. Es
erfordert livekit-agents 1.8 oder neuer.
Einen gespeicherten Agenten ausführen
Alles, was der Agent tut (Prompt, Stimme, Engine, Sprachen, Tools, Begrüßung, Rückfragen bei Stille), wird in ThunderPhone konfiguriert. Die Sitzung überträgt nur Audio.
from livekit.agents import Agent, AgentSession, JobContext, WorkerOptions, cli
from livekit.plugins import thunderphone
async def entrypoint(ctx: JobContext):
session = AgentSession(llm=thunderphone.RealtimeModel(agent_id=12))
await session.start(agent=Agent(instructions=""), room=ctx.room)
if __name__ == "__main__":
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))Ein gespeicherter Agent begrüßt Anrufer und führt seine eigenen Tools in ThunderPhone aus; die
Anweisungen und Tools des LiveKit-Agent werden nicht gesendet. Der Anruf endet, wenn der
ThunderPhone-Agent auflegt, und die Sitzung wird mit ihm geschlossen.
Die Sitzung inline konfigurieren
Ohne agent_id stammen Anweisungen und Tools vom LiveKit-Agent, genauso wie bei
OpenAI. product wählt die Engine und voice wählt die
ThunderPhone-Stimme.
from livekit.agents import Agent, AgentSession, RunContext, function_tool
from livekit.plugins import thunderphone
class Receptionist(Agent):
def __init__(self):
super().__init__(instructions="You are Acme Dental's receptionist. Be brief.")
@function_tool
async def check_availability(self, context: RunContext, date: str) -> dict:
"""Free appointment slots on a date."""
return {"slots": await calendar.free_slots(date)}
async def entrypoint(ctx: JobContext):
session = AgentSession(
llm=thunderphone.RealtimeModel(product="bolt", voice="olivia", language="es"),
)
await session.start(agent=Receptionist(), room=ctx.room)
await session.generate_reply() # the agent speaks firstThunderPhone friert Anweisungen und Tools beim Anrufstart ein. Daher werden
update_instructions, update_tools und Agentenübergaben, die diese ändern,
während eines Anrufs nicht unterstützt. Inline-Sitzungen werden vom Client gesteuert: Der Agent spricht,
wenn Sie generate_reply() aufrufen oder wenn der Teilnehmer einen Sprechzug beendet.
Optionen
| Argument | Bedeutung |
|---|---|
api_key | Geheimer Schlüssel (sk_live_...). Standardmäßig THUNDERPHONE_API_KEY. |
agent_id | Einen gespeicherten Agenten ausführen. Schließt sich gegenseitig mit product und voice aus. |
product | Engine für Inline-Sitzungen: spark, bolt oder storm. |
voice | ThunderPhone-Sprachname für Inline-Sitzungen. |
language | Hinweis auf die primäre Sprache für Inline-Sitzungen, z. B. es. |
from_number, to_number | Nummern, die beim Anruf aufgezeichnet werden, wenn der Raum einer Telefonleitung vorgeschaltet ist. |
live_transcripts | Transkriptfragmente des Anrufers während der Äußerung streamen (zusätzliche Abrechnung). |
base_url | Endpoint-Override, standardmäßig wss://api.thunderphone.com/v1/realtime. |
Ereignisse
ThunderPhone fügt zusätzlich zum Echtzeitprotokoll Plattformereignisse hinzu. Die Sitzung gibt diese aus:
@session.llm.session.on("thunderphone_call_ended") # or on the RealtimeSession you hold
def on_call_ended(event):
print("call ended:", event["reason"])Die RealtimeSession stellt call_id bereit, sobald die Sitzung aktiv ist. Verwenden Sie sie mit
GET /v1/calls/{call_id}, um nach dem Anruf die Aufzeichnung,
das Transkript und die Bewertung abzurufen. Jedes andere call.*-Ereignis (Weiterleitung,
Tastenfeld, Sprache ignoriert) wird als thunderphone_call_event übermittelt.
Einschränkungen
- Die Sprecherwechselerkennung erfolgt serverseitig und ist immer aktiv; die
frameworkseitige Sprecherwechselerkennung (
turn_detectionin derAgentSession) wird ignoriert. - Anweisungen und Tools können nach Beginn des Anrufs nicht mehr geändert werden.
- Audio ist bidirektional 16-Bit-Mono-PCM mit 24 kHz.
- Videoframes werden ignoriert.