ThunderPhone 2.0 正式上线。全程自助,2 美分/分钟起。查看发布公告

Connect tools & data

从 LiveKit Agents 使用 ThunderPhone

将 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

该插件封装了 LiveKit 的 OpenAI Realtime 模型,因为 ThunderPhone 的 Realtime WebSocket 使用相同的协议。它 需要 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 上进行问候并运行自己的工具;LiveKit Agent 的指令和工具不会被发送。ThunderPhone 智能体挂断时, 通话结束,会话也随之关闭。

内联配置会话

如果不使用 agent_id,指令和工具将与 OpenAI 的方式相同,来自 LiveKit Agentproduct 用于选择引擎,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_instructionsupdate_tools 以及会更改它们的智能体交接。 内联会话由客户端驱动:当您调用 generate_reply() 或参与者完成一轮发言时, 智能体会进行回应。

选项

参数含义
api_key密钥(sk_live_...)。默认使用 THUNDERPHONE_API_KEY
agent_id运行已保存的智能体。与 productvoice 互斥。
product用于内联会话的引擎:sparkboltstorm
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 到达。

限制

  • 轮次检测在服务器端执行且始终启用;框架端的轮次检测 (AgentSession 上的 turn_detection)会被忽略。
  • 通话开始后,无法更改指令和工具。
  • 双向音频均为 24 kHz 的 16 位单声道 PCM。
  • 视频帧会被忽略。