結論:OpenAI Agents SDK(Pythonライブラリ)には音声エージェントを構築する2経路があり、既存テキストエージェントを延長するVoicePipelineと、低遅延会話に特化したRealtimeRunnerを用途で選び分けることが成功の鍵です。
- 要点1:VoicePipelineはSTT→Agent→TTSを自動チェーン。
pip install 'openai-agents[voice]'の追加インストールだけで既存エージェントが音声対応になります。 - 要点2:RealtimeRunnerは
gpt-realtime-2モデルとの永続WebSocket接続でbarge-in(割り込み)・ツール承認・ハンドオフをリアルタイム制御できます。 - 要点3:SIP/電話系は
RealtimePlaybackTrackerで再生進捗を追跡し、電話回線の遅延に合わせた割り込みカットを実現できます。
対象読者:OpenAI Agents SDKを使って音声エージェントを構築したい開発者・プロダクトエンジニア
今日やること:pip install 'openai-agents[voice]'でインストールし、本記事のVoicePipeline最小コードをローカルで動かしてみましょう
動作環境でこんな失敗ログから話を始めます。
ImportError: No module named 'agents.voice'
OpenAI Agents SDKに音声サポートを追加しようとして最初に踏む落とし穴です。openai-agentsのベースインストールには音声ライブラリが含まれておらず、[voice]のオプショングループを明示しないとこのエラーが出ます。
このエラーを解消した後、次に迷うのが「VoicePipeline」か「RealtimeRunner」かの選択です。ドキュメントには両方が書かれていますが、どちらをいつ使うべきかは一読しただけでは分かりにくい。本記事では2経路の選定基準をコードで示し、割り込みハンドリング・ツール承認・SIP接続まで順を追って解説します。
なお、本記事のAPI名・クラス名はOpenAI公式ドキュメント(openai.github.io/openai-agents-python・developers.openai.com)の2026年6月時点の内容を基準にしています。本番環境で使用する前に、必ず最新の公式ドキュメントで動作確認してください。
インストールと2経路の全体像
まずセットアップから始めます。音声機能には専用の依存関係グループが必要です。
# 音声サポートつきでインストール
pip install 'openai-agents[voice]'
# sounddevice(マイク/スピーカー操作)が含まれる
# numpy も自動でインストールされる
インストール後、2つの音声経路を図で整理します。
| 経路 | クラス | 仕組み | 向いているケース |
|---|---|---|---|
| VoicePipeline | VoicePipeline |
STT→Agentワークフロー→TTSをチェーン | 既存テキストAgentを音声化・中間テキストを検査したい・シンプルな実装 |
| RealtimeRunner | RealtimeRunner |
Realtime APIとWebSocketで永続接続、音声to音声 | 自然な割り込み会話・低遅延・電話/SIP連携 |
どちらもエージェントを定義する部分のコードは共通です。違いは「テキストを中継するかどうか」と「割り込み処理の方法」です。
VoicePipeline:既存テキストエージェントを5分で音声化する
VoicePipelineの構造を理解するには「3ステップのチェーン」として見るのが一番分かりやすいです。
- STT(Speech-to-Text):音声をテキストに変換
- Agentワークフロー:テキストを処理してレスポンステキストを生成
- TTS(Text-to-Speech):レスポンステキストを音声に変換
まずシンプルな天気エージェントをVoicePipelineに通す最小コードを示します。
# 動作環境: Python 3.11+, openai-agents[voice]>=0.0.17
# pip install 'openai-agents[voice]' numpy sounddevice
import asyncio
import random
import numpy as np
import sounddevice as sd
from agents import Agent, function_tool
from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
from agents.voice import SingleAgentVoiceWorkflow, VoicePipeline, AudioInput
@function_tool
def get_weather(city: str) -> str:
"""指定した都市の天気を返す。"""
choices = ["晴れ", "曇り", "雨", "雪"]
return f"{city}の天気は{random.choice(choices)}です。"
# テキストエージェントをそのまま使える
agent = Agent(
name="音声アシスタント",
instructions=prompt_with_handoff_instructions(
"あなたは丁寧で簡潔な音声アシスタントです。"
),
model="gpt-4o-mini",
tools=[get_weather],
)
async def main():
# VoicePipelineは既存のAgentをラップするだけ
pipeline = VoicePipeline(
workflow=SingleAgentVoiceWorkflow(agent)
)
# AudioInput: 録音済み/push-to-talk向け(完全な音声バッファを渡す)
# ここでは無音バッファを代用(実際はマイク録音データを渡す)
buffer = np.zeros(24000 * 2, dtype=np.int16) # 2秒分の無音
audio_input = AudioInput(buffer=buffer)
result = await pipeline.run(audio_input)
# ストリームで音声チャンクを受け取る
player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16)
player.start()
async for event in result.stream():
if event.type == "voice_stream_event_audio":
player.write(event.data)
elif event.type == "voice_stream_event_lifecycle":
print(f"ライフサイクル: {event.event}") # turn_started / turn_ended
elif event.type == "voice_stream_event_error":
print(f"エラー: {event.error}")
player.stop()
player.close()
asyncio.run(main())
ポイントは3つです。SingleAgentVoiceWorkflowが既存のAgentをVoicePipeline対応にラップします。AudioInputは録音済みバッファやpush-to-talk用で、リアルタイムストリームには後述のStreamedAudioInputを使います。result.stream()のイベント型はvoice_stream_event_audio/voice_stream_event_lifecycle/voice_stream_event_errorの3種類です。
StreamedAudioInput:リアルタイムマイク入力と音声区間検出
プッシュtoトークではなく「常にマイクを開けておきたい」場合はStreamedAudioInputを使います。パイプラインが発話区間を自動検出してAgentワークフローを起動します。
# 動作環境: Python 3.11+, openai-agents[voice]>=0.0.17
import asyncio
import sounddevice as sd
import numpy as np
from agents.voice import StreamedAudioInput, VoicePipeline, SingleAgentVoiceWorkflow
async def main():
pipeline = VoicePipeline(workflow=SingleAgentVoiceWorkflow(agent))
# StreamedAudioInput: マイクから逐次チャンクを push していく
audio_input = StreamedAudioInput()
result_task = asyncio.create_task(pipeline.run(audio_input))
# sounddevice のコールバックで音声チャンクをキューに積む
async def mic_stream():
loop = asyncio.get_event_loop()
queue: asyncio.Queue = asyncio.Queue()
def callback(indata, frames, time, status):
loop.call_soon_threadsafe(
queue.put_nowait, indata.copy().flatten().astype(np.int16)
)
with sd.InputStream(samplerate=24000, channels=1,
dtype=np.int16, callback=callback):
while True:
chunk = await queue.get()
await audio_input.add_audio(chunk) # パイプラインに逐次送信
mic_task = asyncio.create_task(mic_stream())
result = await result_task
async for event in result.stream():
if event.type == "voice_stream_event_audio":
# 再生処理(省略)
pass
elif event.type == "voice_stream_event_lifecycle":
if event.event == "turn_started":
print("エージェントが応答中...")
elif event.event == "turn_ended":
print("応答終了")
mic_task.cancel()
asyncio.run(main())
注意点として、VoicePipelineには割り込み処理の組み込み機能がありません。turn_startedイベントをトリガーにマイクをミュートし、turn_endedで開放するという実装を自分で書く必要があります。自然なbarge-in(話し中への割り込み)が重要なユースケースでは、次のRealtimeRunnerが向いています。
RealtimeRunner:gpt-realtime-2で低遅延の直接音声会話を実現する
RealtimeRunnerはOpenAIのRealtime APIとWebSocketで永続接続を維持し、音声→音声の処理をモデル側で一括して行います。中間テキストを生成せず遅延が短く、サーバー側で割り込み検出(semantic VAD)まで処理します。
# 動作環境: Python 3.11+, openai-agents[voice]>=0.0.17
import asyncio
from agents import function_tool
from agents.realtime import RealtimeAgent, RealtimeRunner, realtime_handoff
@function_tool
def get_weather(city: str) -> str:
"""指定都市の天気を返す。"""
return f"{city}は晴れ、気温22度です。"
# RealtimeAgent: 通常のAgentより機能が絞られている
# 構造化出力は未サポート。モデル選択はセッションレベルで行う
assistant = RealtimeAgent(
name="音声アシスタント",
instructions="あなたは簡潔に答える音声アシスタントです。天気の質問に答えられます。",
tools=[get_weather],
)
async def main():
runner = RealtimeRunner(
starting_agent=assistant,
config={
"model_settings": {
"model_name": "gpt-realtime-2", # 2026年6月時点の推奨モデル
"audio": {
"input": {
"format": "pcm16",
"transcription": {"model": "gpt-4o-mini-transcribe"},
# semantic_vad: ユーザー発話の意味的完結を検出して自動割り込み
"turn_detection": {
"type": "semantic_vad",
"interrupt_response": True, # 応答中でも割り込みを許可
},
},
"output": {
"format": "pcm16",
"voice": "ash", # 利用可能なボイス: alloy, ash, ballad, coral, echo, sage, shimmer, verse
},
},
"tool_choice": "auto",
}
},
)
# セッションを取得して処理ループに入る
session = await runner.run()
async with session:
# テキストでも音声でも入力を送れる
await session.send_audio(b"...") # 実際にはPCM16バイト列
# または
await session.send_message("東京の天気を教えて")
async for event in session:
if event.type == "audio":
# 音声チャンクを再生キューに積む
print(f"音声データ: {len(event.data)} bytes")
elif event.type == "audio_interrupted":
print("ユーザーが割り込みました — 再生キューをクリア")
# 再生バッファを破棄する処理をここに書く
elif event.type == "agent_start":
print(f"エージェント '{event.agent.name}' が応答開始")
elif event.type == "tool_start":
print(f"ツール '{event.tool_name}' を呼び出し中...")
elif event.type == "error":
print(f"エラー: {event.error}")
break
asyncio.run(main())
設定のポイントです。semantic_vadは単純な無音検出より賢く、発話が意味的に完結したタイミングを検出します。interrupt_response: Trueを設定するとモデルの応答中にユーザーが話し始めても割り込めます。gpt-realtime-2はセッションレベルで指定するため、エージェント定義にモデルを書く必要はありません。
割り込み処理(barge-in)の実装パターン:VoicePipeline vs RealtimeRunner
割り込みの実装は2経路で大きく異なります。以下の比較表を参考にしてください。
| 項目 | VoicePipeline | RealtimeRunner |
|---|---|---|
| 割り込み検出 | なし(自前実装が必要) | semantic_vad でサーバー側自動検出 |
| 割り込みイベント | turn_started/turn_ended を流用 |
audio_interrupted が発行される |
| 再生バッファの破棄 | 自前で実装 | イベント受信後に自前で実装 |
| 電話回線対応 | 向かない | RealtimePlaybackTracker で対応可 |
| 遅延 | STT+LLM+TTS の合計(数秒) | 音声to音声で300ms〜1秒程度 |
電話回線や遅延が大きいネットワーク向けに、RealtimePlaybackTrackerを使った割り込み制御のコード例を示します。
# 動作環境: Python 3.11+, openai-agents[voice]>=0.0.17
from agents.realtime.model import RealtimePlaybackTracker
# 再生進捗トラッカーを作成
tracker = RealtimePlaybackTracker()
runner = RealtimeRunner(
starting_agent=assistant,
config={
"model_settings": {
"model_name": "gpt-realtime-2",
"audio": {
"input": {
"format": "pcm16",
"turn_detection": {"type": "semantic_vad", "interrupt_response": True},
},
"output": {"format": "pcm16", "voice": "ash"},
},
},
# 再生トラッカーをセッション設定に渡す
"playback_tracker": tracker,
},
)
session = await runner.run()
async with session:
async for event in session:
if event.type == "audio":
# 実際に音声を再生した量を tracker に報告
play_audio_bytes = event.data # 再生処理
tracker.on_play_bytes(len(play_audio_bytes)) # 再生バイト数を通知
elif event.type == "audio_interrupted":
# この時点で tracker が把握している「実際の再生位置」まででカット
print("実際の再生進捗に基づいて割り込みを適用")
ポイントはtracker.on_play_bytes()を呼ぶことです。電話回線では「生成した音声」と「実際に再生された音声」の間に数秒のバッファがあります。トラッカーなしでは割り込み時に実際には聞いていない部分まで削除してしまいます。
リアルタイム中のツール呼び出しとhuman-in-the-loop承認
RealtimeAgentはセッション中にツールをリアルタイムで呼び出せます。さらに、重要な操作(外部APIへの書き込み・決済・個人情報アクセスなど)にはツール実行前に人間の承認を挟むことができます。
# 動作環境: Python 3.11+, openai-agents[voice]>=0.0.17
from agents import function_tool
from agents.realtime import RealtimeAgent, RealtimeRunner
@function_tool
def book_appointment(date: str, time: str, service: str) -> str:
"""予約を確定する。実行前に承認が必要。"""
# 実際には外部カレンダーAPIを呼ぶ
return f"{date} {time}の{service}予約を確定しました。"
agent = RealtimeAgent(
name="予約アシスタント",
instructions="ユーザーの予約を受け付けてください。予約確定前に必ず確認を取ります。",
tools=[book_appointment],
)
runner = RealtimeRunner(
starting_agent=agent,
config={"model_settings": {"model_name": "gpt-realtime-2", "audio": {
"input": {"format": "pcm16", "turn_detection": {"type": "semantic_vad"}},
"output": {"format": "pcm16", "voice": "ash"},
}}},
)
session = await runner.run()
async with session:
async for event in session:
if event.type == "tool_approval_required":
# ツール実行前にここで一時停止する
print(f"ツール '{event.tool_name}' の承認リクエスト")
print(f"引数: {event.arguments}")
# 本番では管理画面やチャットUIで人間に確認を取る
# ここでは自動承認(実際は await asyncio.sleep() + 管理者からの入力待ちなど)
user_approved = True # UIからの入力で取得
if user_approved:
await session.approve_tool_call(event.call_id)
print("承認しました — ツールを実行します")
else:
await session.reject_tool_call(event.call_id)
print("拒否しました — ツール実行をキャンセル")
elif event.type == "tool_start":
print(f"ツール '{event.tool_name}' 実行中...")
elif event.type == "tool_end":
print(f"ツール完了: {event.output}")
elif event.type == "audio":
pass # 音声再生処理
承認フローの設計で注意すべき点があります。tool_approval_requiredイベントが来た時点でセッションは自動的にツール実行を一時停止します。approve_tool_call()/reject_tool_call()を呼ぶまでセッションは待機状態になります。UIやWebhook経由で管理者に通知し、入力を受け取った後に呼び出す設計が本番では現実的です。
Human-in-the-loopの設計パターンについては、AIエージェントのhuman-in-the-loop承認設計ガイドも参照してください。
マルチエージェントハンドオフ:専門エージェントへのリアルタイム転送
RealtimeAgentはセッション中に別のエージェントへシームレスに転送(ハンドオフ)できます。コールセンターのように「一次受付→専門担当」という流れを自然な会話の中で実現できます。
# 動作環境: Python 3.11+, openai-agents[voice]>=0.0.17
from agents.realtime import RealtimeAgent, RealtimeRunner, realtime_handoff
# 専門エージェント(請求担当)
billing_agent = RealtimeAgent(
name="請求サポート",
instructions="請求・支払いに関する問い合わせに対応します。丁寧に解決策を提示してください。",
)
# 専門エージェント(技術サポート担当)
tech_agent = RealtimeAgent(
name="テクニカルサポート",
instructions="技術的な問題のトラブルシューティングを担当します。",
)
# 一次受付エージェント
main_agent = RealtimeAgent(
name="カスタマーサービス",
instructions="""
あなたはカスタマーサービスの一次窓口です。
請求に関する問い合わせは請求サポートへ、
技術的な問題はテクニカルサポートへ転送してください。
""",
handoffs=[
realtime_handoff(billing_agent, tool_description="請求・支払い関連の問い合わせを請求サポートに転送"),
realtime_handoff(tech_agent, tool_description="技術的な問題をテクニカルサポートに転送"),
],
)
runner = RealtimeRunner(
starting_agent=main_agent,
config={"model_settings": {
"model_name": "gpt-realtime-2",
"audio": {
"input": {"format": "pcm16", "turn_detection": {"type": "semantic_vad", "interrupt_response": True}},
"output": {"format": "pcm16", "voice": "ash"},
},
}},
)
session = await runner.run()
async with session:
async for event in session:
if event.type == "handoff":
print(f"エージェントを '{event.to_agent.name}' に転送")
elif event.type == "agent_start":
print(f"現在の担当: {event.agent.name}")
elif event.type == "audio":
pass # 音声再生処理
注意点として、リアルタイムハンドオフは通常のハンドオフのinput_filterに対応していません。転送前に会話コンテキストを加工したい場合は別の方法が必要です。また、ハンドオフ先のエージェントは同じセッション内で動くため、モデル設定はセッションレベルのものが引き継がれます。
SIP・電話システム連携:Twilio経由でOpenAI音声エージェントに電話をかける
OpenAI Realtime APIはSIP(Session Initiation Protocol)をネイティブサポートしています。Twilioなどの電話プラットフォームのSIPトランクを経由して、一般の電話番号から音声エージェントに直接かけることができます。
アーキテクチャ概要
- TwilioのSIPトランクのOriginationURIをOpenAIのSIPエンドポイントに設定
- 着信時にOpenAIからWebhookが届く
- Webhookサーバーがコールを受け入れて音声処理を開始する
SIPトランク設定(Twilio管理コンソール)
Origination URI:
sip:[your-openai-project-id]@sip.api.openai.com;transport=tls
your-openai-project-id を実際のOpenAIプロジェクトIDに置き換える
Webhookサーバー(Python + FastAPI)
# 動作環境: Python 3.11+, fastapi>=0.100, httpx>=0.24, openai>=1.0
# pip install fastapi uvicorn httpx openai
import hmac, hashlib, os
import httpx
from fastapi import FastAPI, Request
app = FastAPI()
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
WEBHOOK_SECRET = os.environ["OPENAI_WEBHOOK_SECRET"]
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
"""Webhookの署名を検証する。"""
expected = hmac.new(
secret.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
@app.post("/webhook/calls")
async def handle_incoming_call(request: Request):
"""OpenAIからの着信Webhookを受け取る。"""
body = await request.body()
signature = request.headers.get("openai-signature", "")
# 注意: 本番環境では必ず署名検証を行うこと
if not verify_signature(body, signature, WEBHOOK_SECRET):
return {"error": "Invalid signature"}, 401
event = await request.json()
call_id = event["call_id"]
# コールを承認し、エージェントの設定を送信
async with httpx.AsyncClient() as client:
await client.post(
f"https://api.openai.com/v1/realtime/calls/{call_id}/accept",
headers={"Authorization": f"Bearer {OPENAI_API_KEY}"},
json={
"instructions": "あなたは丁寧な電話オペレーターです。お客様の問い合わせに対応してください。",
"voice": "ash",
"turn_detection": {
"type": "semantic_vad",
"interrupt_response": True,
},
# 注意: SIPセッションでは一部のturn_detectionフィールドが使えない
# 使えないフィールドを渡すとAPIがエラーを返す
},
)
return {"status": "accepted"}
# uvicorn で起動: uvicorn main:app --host 0.0.0.0 --port 8000
SIP実装時の注意点(RealtimePlaybackTrackerとの組み合わせ)
電話回線は遅延が大きいため、RealtimePlaybackTrackerによる再生進捗の追跡が特に重要です。また、SIPセッションではturn_detectionの一部フィールドがサポートされず、未対応フィールドを渡すとAPIがエラーを返します。実装前にOpenAI公式のRealtime SIPガイド(2026年6月時点)で最新の制限を確認してください。
【要注意】よくある失敗パターンと回避策
失敗1:VoiceパッケージなしでVoicePipelineをインポートしようとする
❌ pip install openai-agentsだけでインストールしてfrom agents.voice import VoicePipelineを試みる
⭕ pip install 'openai-agents[voice]'で音声オプショングループを必ず指定する
なぜ重要か:音声ライブラリは任意依存(Optional dependency)として分離されており、ベースインストールには含まれません。
失敗2:VoicePipelineにモデルを直接指定しようとする
❌ RealtimeAgent(name="...", model="gpt-realtime-2")とエージェントにモデルを書く
⭕ RealtimeRunnerのconfig["model_settings"]["model_name"]で指定する
なぜ重要か:RealtimeAgentはモデル選択をサポートしていません。モデルはセッションレベルの設定項目です。通常のAgentとは設計が異なります。
失敗3:SIPセッションで対応外のturn_detectionフィールドを送る
❌ WebSocketセッションと同じ設定をSIPセッションにそのままコピーする
⭕ SIPセッションがサポートするフィールドのみを/acceptエンドポイントに渡す
なぜ重要か:SIPはWebSocketと異なるサブセットの設定しかサポートしておらず、未対応フィールドを送るとAPIがエラーを返して通話が失敗します。
失敗4:電話連携でRealtimePlaybackTrackerを使わない
❌ tracker不使用でweb向けと同じ割り込み処理を電話回線に適用する
⭕ RealtimePlaybackTrackerをセッション設定に渡し、tracker.on_play_bytes()を音声再生ごとに呼ぶ
なぜ重要か:電話回線では生成完了から実際の再生まで数秒の差があります。trackerなしでは実際には聞いていない部分まで削除されて会話が不自然になります。
失敗5:tool_approval_requiredへの応答を忘れてセッションが止まる
❌ tool_approval_requiredイベントを受け取ったがapprove_tool_call()/reject_tool_call()を呼ばずにループを続ける
⭕ このイベントを必ずハンドルし、承認か拒否を必ず返す
なぜ重要か:SDK側はこのイベントに対する応答を待ち続けます。応答しないとセッションがデッドロック状態になります。
VoicePipeline vs RealtimeRunner:ユースケース別の選択ガイド
| ユースケース | 推奨経路 | 理由 |
|---|---|---|
| 既存テキストエージェントをそのまま音声化 | VoicePipeline | コード変更が最小。SingleAgentVoiceWorkflowでラップするだけ |
| 途中のテキスト(STT結果)をログや検査に使いたい | VoicePipeline | 中間テキストが明示的に生成される設計 |
| 自然な会話・割り込みが重要なチャットbot | RealtimeRunner | semantic_vadでサーバー側が自動割り込み検出 |
| コールセンター・IVR・電話AI | RealtimeRunner + SIP | SIPネイティブサポート + RealtimePlaybackTracker |
| ツール実行前に承認が必要な業務フロー | RealtimeRunner | tool_approval_required / approve_tool_callが使える |
| 最低遅延を求めるリアルタイム応答 | RealtimeRunner | 音声to音声で中間STT処理を省略、300ms〜 |
品質・テスト:音声エージェントの検証をどう設計するか
音声エージェントのテストは通常のテキストエージェントより難しいですが、いくつかの実践的なアプローチがあります。
まずテキスト層でのユニットテストから始めることを推奨します。VoicePipelineではSTT/TTSを切り離し、AgentワークフローをテキストでテストできるためTextモードで先に品質を担保します。
# 動作環境: Python 3.11+, openai-agents>=0.0.17, pytest-asyncio
# 音声を使わずにAgentロジックをテストする
import pytest
from agents import Agent, Runner, function_tool
@function_tool
def get_weather(city: str) -> str:
return f"{city}は晴れです。"
@pytest.mark.asyncio
async def test_weather_agent_text():
"""音声なしでAgentロジックをテスト。"""
agent = Agent(
name="テスト用エージェント",
instructions="天気を答える。",
tools=[get_weather],
)
result = await Runner.run(agent, input="東京の天気は?")
# 出力に「東京」と「晴れ」が含まれることを確認
assert "東京" in result.final_output
assert "晴れ" in result.final_output
音声エージェントのテスト戦略全般については、AIエージェントのテスト・品質保証完全ガイドも参照してください。LiveKitやPipecat等の他の音声フレームワークとの比較は、Pipecat完全ガイドをご覧ください。
参考・出典
- VoicePipeline — OpenAI Agents SDK公式ドキュメント(OpenAI、参照日: 2026-06-11)
- Realtime Guide — OpenAI Agents SDK公式ドキュメント(OpenAI、参照日: 2026-06-11)
- Voice Agents — OpenAI Developers(OpenAI、参照日: 2026-06-11)
- Connect the OpenAI Realtime SIP Connector with Twilio Elastic SIP Trunking(Twilio、参照日: 2026-06-11)
- Voice Quickstart — OpenAI Agents SDK(OpenAI、参照日: 2026-06-11)
まとめ:今日から始める3つのアクション
- 今日やること:
pip install 'openai-agents[voice]'でインストールし、本記事のVoicePipeline最小コードをローカルで実行する。APIキーはOPENAI_API_KEY環境変数に設定するだけでOKです。 - 今週中:既存のテキストエージェントがあればVoicePipelineに通す。次のステップとしてRealtimeRunnerのsemantic_vad設定を試してbarge-inの体験差を比較する。
- 今月中:SIP連携やtool_approval_requiredを使ったhuman-in-the-loopフローを構築し、電話やSlackと連携した本番ワークフローへ展開する。
あわせて読みたい:
- AIエージェントのhuman-in-the-loop承認設計ガイド — ツール承認フローのアーキテクチャパターン
- AIエージェントのテスト・品質保証完全ガイド — pytest/Deepevalを使った検証手法
- Pipecat完全ガイド|音声AIエージェント実装 — 別フレームワークとのアーキテクチャ比較
著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー10万人以上。
100社以上の企業向けAI研修・導入支援。著書『AIエージェント仕事術』。
ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。
