ThunderPhone 2.0 уже доступен.Самостоятельное подключение — от 2 центов/мин.Читать анонс

Connect tools & data

Использование 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 first

ThunderPhone фиксирует инструкции и инструменты при начале звонка, поэтому 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 кГц в обоих направлениях.
  • Видеокадры игнорируются.