PipecatからThunderPhoneを使用
独自のトランスポートと電話機能を使用するPipecatパイプライン内で、ThunderPhone音声エージェントを音声間サービスとして実行します。
Pipecat は、組み合わせ可能なサービスから音声エージェントを構築するためのオープンソースフレームワークです。ThunderPhone は 音声間LLMサービス として接続されます。Pipecat が発信者の音声を送信すると、ThunderPhone はエージェントの音声、文字起こし、関数呼び出しを返し、Pipecat のトランスポート(Daily、LiveKit、Twilio、WebRTC、ローカルマイク)が音声を伝送します。音声認識、言語モデル、音声、ターンテイキング、47言語、ツールはすべて ThunderPhone 上で実行されます。
この方法で行った通話は、他のリアルタイム通話と同様に通話履歴に表示され、製品の分単位料金で請求されます。サブスクリプションは不要で、ThunderPhone の電話番号も使用しません。
インストール
pip install pipecat-thunderphone
export THUNDERPHONE_API_KEY=sk_live_... # a secret API keyThunderPhone の Realtime WebSocket は同じプロトコルを使用するため、このパッケージは Pipecat の OpenAI Realtime サービスをラップしています。pipecat-ai 1.8 以降が必要です。
保存済みエージェントを実行する
エージェントが行うすべての処理(プロンプト、音声、エンジン、言語、ツール、あいさつ、無音時のチェックイン)は ThunderPhone で設定します。パイプラインは音声のみを転送します。
from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.worker import PipelineParams, PipelineWorker
from pipecat.processors.aggregators.llm_context import LLMContext
from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair
from pipecat_thunderphone import ThunderPhoneRealtimeLLMService
llm = ThunderPhoneRealtimeLLMService(agent_id=12)
context = LLMContext()
aggregators = LLMContextAggregatorPair(context)
pipeline = Pipeline([
transport.input(),
aggregators.user(),
llm,
aggregators.assistant(),
transport.output(),
])
worker = PipelineWorker(pipeline, params=PipelineParams(allow_interruptions=True))保存済みエージェントは独自のタイミングで通話を開始するため、サービスは Pipecat に開始応答を要求しません。それでも開始応答が必要な場合は、greet_on_connect=True を渡します。
セッションをインラインで設定する
agent_id を指定しない場合、指示とツールは OpenAI と同様に Pipecat コンテキストから取得されます。product でエンジンを選択し、voice で ThunderPhone の音声を選択します。
from pipecat.adapters.schemas.function_schema import FunctionSchema
from pipecat.adapters.schemas.tools_schema import ToolsSchema
from pipecat.services.llm_service import FunctionCallParams
llm = ThunderPhoneRealtimeLLMService(product="bolt", voice="olivia", language="es")
async def check_availability(params: FunctionCallParams):
slots = await calendar.free_slots(params.arguments["date"])
await params.result_callback({"slots": slots})
llm.register_function("check_availability", check_availability)
context = LLMContext(
messages=[{"role": "system", "content": "You are Acme Dental's receptionist."}],
tools=ToolsSchema(standard_tools=[
FunctionSchema(
name="check_availability",
description="Free appointment slots on a date",
properties={"date": {"type": "string"}},
required=["date"],
)
]),
)インラインセッションはクライアント主導です。コンテキスト到着時に Pipecat が応答を要求するため、エージェントが先に話し、メッセージを追加するか別の応答を要求しない限り、無音時は静かに待機します。
オプション
| 引数 | 意味 |
|---|---|
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 | 発話途中の発信者トランスクリプト断片をストリーミング(追加課金)。 |
greet_on_connect | セッションの準備完了後すぐに最初の応答をリクエスト。 |
end_task_on_call_ended | ThunderPhone が通話を終了したときに EndWorkerFrame をプッシュ(デフォルトで有効)。 |
イベント
ThunderPhone はリアルタイムプロトコルに加えてプラットフォームイベントを追加します。サービスはこれらをハンドラーに配信します。
@llm.event_handler("on_call_ended")
async def on_call_ended(service, event):
print("call ended:", event["reason"], "call id:", service.call_id)service.call_id はセッションが開始されると設定されます。通話後に録音、トランスクリプト、評価を取得するには、GET /v1/calls/{call_id} とともに使用します。
制限
- ターン検出はサーバー側で常に有効です。Pipecat 主導のターン(
turn_detection=False)はサポートされていません。 - サービスに登録した関数はインラインセッションでのみ実行されます。保存済みエージェントは ThunderPhone 上で独自のツールを実行します。
- 音声は双方向とも 24 kHz、16 ビット、モノラル PCM です。
- 動画フレームは無視されます。