Использование ThunderPhone в LiveKit Agents
Запускайте голосового агента ThunderPhone как модель реального времени (речь-в-речь) в сеансе LiveKit Agents, используя комнаты LiveKit, SIP и телефонию.
LiveKit Agents — это фреймворк с открытым исходным кодом для голосовых агентов в реальном времени на базе комнат LiveKit. ThunderPhone подключается как модель реального времени: фреймворк отправляет аудио участника, ThunderPhone возвращает голос агента, расшифровки и вызовы функций, а комнаты LiveKit, SIP-транки и телефония передают аудио. Распознавание речи, языковая модель, голос, управление очередностью реплик, 47 языков и инструменты работают на ThunderPhone.
Звонки, совершаемые таким способом, отображаются в истории звонков и оплачиваются по поминутному тарифу вашего продукта, как и любые другие звонки в реальном времени. Для этого не требуется подписка или номер телефона ThunderPhone.
Установка
pip install livekit-plugins-thunderphone
export THUNDERPHONE_API_KEY=sk_live_... # a secret API keyПлагин оборачивает модель OpenAI Realtime из LiveKit, поскольку
Realtime WebSocket ThunderPhone использует тот же протокол. Для него требуется livekit-agents версии 1.8 или новее.
Запустите сохранённого агента
Всё, что делает агент (промпт, голос, движок, языки, инструменты, приветствие, проверки тишины), настраивается в ThunderPhone. Сеанс только передаёт аудио.
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))Сохранённый агент приветствует звонящего и использует собственные инструменты в ThunderPhone; инструкции и инструменты Agent из LiveKit не отправляются. Звонок завершается, когда агент ThunderPhone кладёт трубку, и вместе с ним закрывается сеанс.
Настройте сеанс прямо в коде
Без agent_id инструкции и инструменты поступают из Agent LiveKit,
так же, как для OpenAI. product выбирает движок, а voice — голос
ThunderPhone.
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 фиксирует инструкции и инструменты при начале звонка, поэтому
update_instructions, update_tools и передача разговора другому агенту, изменяющая их,
не поддерживаются во время звонка. Встроенные сеансы управляются клиентом: агент говорит,
когда вы вызываете generate_reply() или когда участник завершает реплику.
Параметры
| Аргумент | Значение |
|---|---|
api_key | Секретный ключ (sk_live_...). По умолчанию используется THUNDERPHONE_API_KEY. |
agent_id | Запускает сохранённого агента. Взаимоисключающий с product и voice. |
product | Движок для встроенных сессий: spark, bolt или storm. |
voice | Имя голоса ThunderPhone для встроенных сессий. |
language | Подсказка об основном языке для встроенных сессий, например es. |
from_number, to_number | Номера, которые нужно записать в вызове, когда комната обслуживает телефонную линию. |
live_transcripts | Передаёт фрагменты расшифровки речи звонящего во время реплики (оплачивается отдельно). |
base_url | Переопределение конечной точки; по умолчанию wss://api.thunderphone.com/v1/realtime. |
События
ThunderPhone добавляет события платформы поверх протокола реального времени. Сессия отправляет их:
@session.llm.session.on("thunderphone_call_ended") # or on the RealtimeSession you hold
def on_call_ended(event):
print("call ended:", event["reason"])RealtimeSession предоставляет call_id, когда сессия становится активной. Используйте его с
GET /v1/calls/{call_id}, чтобы получить запись,
расшифровку и оценку после вызова. Все остальные события call.* (перевод,
клавиатура, проигнорированная речь) поступают как thunderphone_call_event.
Ограничения
- Определение завершения реплики выполняется на стороне сервера и всегда включено; определение завершения реплики на стороне фреймворка
(
turn_detectionвAgentSession) игнорируется. - Инструкции и инструменты нельзя изменить после начала вызова.
- Аудио — 16-битный моно PCM с частотой 24 кГц в обоих направлениях.
- Видеокадры игнорируются.