LiveKit Agents から ThunderPhone を使用する
LiveKit ルーム、SIP、電話機能と組み合わせて、LiveKit Agents セッションのリアルタイム(音声対音声)モデルとして ThunderPhone 音声エージェントを実行します。
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このプラグインは、ThunderPhone の
Realtime WebSocket が同じプロトコルを使用するため、LiveKit の OpenAI Realtime モデルをラップします。
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 Agent から取得されます。
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 として届きます。
制限
- ターン検出はサーバー側で常に有効です。フレームワーク側のターン検出(
AgentSessionのturn_detection)は無視されます。 - 通話開始後に指示やツールを変更することはできません。
- 音声は双方向とも24 kHzの16ビットモノラルPCMです。
- 動画フレームは無視されます。