Techsy
お問い合わせ
始める
ブログ一覧へ戻る
ai-machine-learning

OpenAI Realtime APIで音声エージェントを構築:2026年版7ステップ実装ガイド

著者: Mert Batur Gürbüz
Jun 6, 2026
1 分
目次
OpenAI Realtime APIで音声エージェントを構築:2026年版7ステップ実装ガイド

OpenAI Realtime APIで音声エージェントを構築:2026年版7ステップ実装ガイド

私たちのテストエージェントは、発信者が話し終えてから1.1秒後に最初の言葉を発してTwilioの応答を行いました。これはgpt-realtime-2とsemantic_vadを使用し、40回の通話で測定したp50(中央値)の往復時間です。魔法ではありません。OpenAI Realtime APIは1つのソケット内で音声対音声(speech-to-speech)処理を行うため、STT → LLM → TTSというリレー処理をスキップでき、約600msのオーバーヘッドを削減できます。しかし、デフォルト設定だけでは1秒以内には到達しません。以下は、コードとレイテンシ表とともに私たちが本番環境で導入した7ステップの構築プロセスです。

これは概念解説ではなく、実践的な構築チュートリアルです。まず階層的な概要を知りたい場合は、AI音声エージェントとは何かを読んでから戻ってきてください。以下の内容はすべて、OpenAI APIキーとNode実行環境を持っていることを前提としています。

主なポイント:

  • gpt-realtime-2は1つのソケットで音声対音声処理を行い、STT/LLM/TTSのリレーが不要で約600msを節約。
  • **一時鍵(ephemeral keys)**はサーバー側で発行し、標準APIキーをブラウザに渡さないこと。
  • Twilioのメディアストリームは8kHz μ-lawなので、Realtime API用に24kHz PCM16へリサンプリングする。
  • 私たちの測定では、往復時間がp50で1.1秒 / p95で1.9秒。割り込み(barge-in)はresponse.cancelで処理。

7ステップで構築するもの

このチュートリアルでは、1.5秒以内に返信し、会話中に実際の関数を呼び出し、発信者による割り込みを許可するOpenAI Realtime API音声エージェントを構築します。フローはシンプルです。発信者が電話番号にかけると、音声がサーバーにストリーミングされ、サーバーは単一のソケット経由でそれをgpt-realtime-2にブリッジします。モデルは発話を行い、ツール呼び出しを実行でき、音声は再びストリーミングされて戻ります。

以下がその道筋です。ユースケースに合わせて任意のステップで止めることができます。

  1. 一時鍵を発行する(サーバールート)
  2. セッションを開き、設定する
  3. 関数呼び出しを追加する
  4. Twilioで電話番号にブリッジする
  5. 割り込み(barge-in)と中断を処理する
  6. レイテンシをサブ秒級に調整する
  7. デプロイと強化

オーディオを運ぶトランスポートは3種類あり、選択はオーディオのソースによって異なります。ブラウザが直接キャプチャする場合(WebRTC)、サーバーがすでに生ストリームを持っている場合(WebSocket)、または電話網が配信する場合(SIP)です。ここではTwilioブリッジにWebSocketを使用し、他のものが適合する箇所ではそれらについても言及します。

ステップ1:一時鍵を発行する(省略できないルート)

標準的なOpenAI APIキーをブラウザやクライアントデバイスに公開してはいけません。Realtime APIはまさにこのために短命な**一時鍵(ephemeral keys)**を発行します。サーバーは実際のキーを使用してPOST /v1/realtime/client_secretsを呼び出し、約1分で期限切れになるトークンをクライアントに渡し、クライアントはそのトークンを使用して接続します。

以下は、一時鍵を発行する最小限のExpressルートです。

javascript
// server.js
import express from "express";
const app = express();

app.get("/session", async (req, res) => {
  const r = await fetch("https://api.openai.com/v1/realtime/client_secrets", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      session: { type: "realtime", model: "gpt-realtime-2" },
    }),
  });
  const data = await r.json();
  res.json({ client_secret: data.value, expires_at: data.expires_at });
});

app.listen(3000);

ブラウザは/sessionを取得し、短命なシークレットを読み取り、それを使用してRealtime接続を開きます。エージェントがサーバー専用(ステップ4のTwilioの場合)である場合は、クライアントへの受け渡しをスキップし、バックエンドから標準キーを直接使用してソケットを開くことができます。一時鍵のフローは、信頼できないクライアントを保護するために存在します。

ステップ2:セッションを開き、gpt-realtime-2を設定する

接続を開き、モデル、オーディオ形式、音声、ターン検出を設定するsession.updateを送信します。OpenAIのドキュメントでは、ツールのロジックにより高い精度が必要でない限り、reasoning.effortをlowに設定して開始することを推奨しています。高いeffortはレイテンシのコストとなるためです。オーディオは双方向で24kHz PCM16として動作します。

javascript
ws.send(JSON.stringify({
  type: "session.update",
  session: {
    type: "realtime",
    model: "gpt-realtime-2",
    output_modalities: ["audio"],
    audio: {
      input:  { format: "pcm16", sample_rate: 24000 },
      output: { format: "pcm16", sample_rate: 24000, voice: "marin" },
    },
    instructions: "You are a reservations agent for a restaurant. Be brief.",
    reasoning: { effort: "low" },
    turn_detection: { type: "semantic_vad" },
  },
}));

そのソケットをどのトランスポートで包むかは、オーディオソースによって異なります。

トランスポート使用場面オーディオソース
WebRTCブラウザまたはモバイルアプリがマイクを直接キャプチャする場合クライアントデバイス
WebSocketサーバーがすでに生のオーディオストリームを保持している場合サーバーパイプライン
SIPOpenAIに電話回線の処理を行わせたい場合PSTN / 電話通信

完全なセッションフィールドリストとGA機能セットについては、OpenAI Realtime APIドキュメントが正典です。ステップ4でTwilioから生のオーディオを受け取るため、ここではWebSocketを使用します。

ステップ3:関数呼び出しを追加する(エージェントに実際に行動させるため)

行動できない音声エージェントは、単なるナレーションに過ぎません。関数呼び出しにより、gpt-realtime-2は会話の途中で一時停止し、コードに何かを実行させ、その結果を持って会話を続けることができます。セッションでツールを宣言し、モデルが必要としたときにfunction_call_arguments.doneイベントを発行します。あなたは作業を実行し、出力を送り返します。

ツールを宣言し、イベントを処理します。

javascript
// in session.update -> session.tools:
tools: [{
  type: "function",
  name: "book_reservation",
  description: "Book a table for a given party size and time.",
  parameters: {
    type: "object",
    properties: {
      party_size: { type: "integer" },
      time: { type: "string", description: "ISO 8601 datetime" },
    },
    required: ["party_size", "time"],
  },
}]

// handling the call:
if (event.type === "response.function_call_arguments.done") {
  const args = JSON.parse(event.arguments);
  const result = await bookTable(args);            // your real logic
  ws.send(JSON.stringify({
    type: "conversation.item.create",
    item: {
      type: "function_call_output",
      call_id: event.call_id,
      output: JSON.stringify(result),
    },
  }));
  ws.send(JSON.stringify({ type: "response.create" }));  // let it speak the result
}

ツールが暗黙的に決して発火しない最も一般的な理由:function_call_arguments.doneをリッスンしておらず、その後response.createを送信していないことです。モデルは呼び出しを生成しましたが、あなたが無視したため、発信者は無音状態を聞くことになります。

エージェントが多くのツールを扱う場合、OpenAI Agents SDKがこの部分の計算式を変えました。2026年4月15日の刷新により、Model Context Protocol (MCP) がファーストクラスとなり、サブエージェントへのハンドオフがランタイムプリミティブとなりました。そのため、すべてのツールを1つのプロンプトに詰め込むのではなく、ルーターエージェントが予約を予約サブエージェントに、請求に関する質問を別のエージェントに引き渡すことができます。Agents SDK音声クイックスタートは、同じRealtimeセッションをRealtimeAgentで包み、独自のオーケストレーションループを書かずにハンドオフを提供します。

ステップ4:電話番号にブリッジする(Twilio)

実際の通話に応答するには、電話通信プロバイダーをソケットにブリッジする必要があります。Twilioを使用する場合、着信をTwilioのTwiML <Connect><Stream>に向け、サーバーへのWebSocketを開き、TwilioとRealtime APIの間でオーディオフレームをリレーします。SIPは代替手段です。OpenAI RealtimeはSIPを直接受け入れるため、オーディオに触れる必要がない場合、メディアリレーを完全に削除できます。

ストリームを開始するTwiML:

xml
<Response>
  <Connect>
    <Stream url="wss://your-server.com/twilio-stream" />
  </Connect>
</Response>

ここで注意すべき落とし穴があります。これを逃すと1日無駄になります。Twilioのメディアストリームは8kHz μ-lawですが、Realtime APIは24kHz PCM16を要求します。双方向でリサンプリングしないと、音が歪んだり、チップマンクのような高音になったりします。

javascript
// inbound: Twilio (8kHz μ-law base64) -> Realtime (24kHz PCM16)
const pcm16 = upsample(muLawDecode(Buffer.from(msg.media.payload, "base64")), 8000, 24000);
realtime.send(JSON.stringify({
  type: "input_audio_buffer.append",
  audio: pcm16.toString("base64"),
}));

// outbound: Realtime (24kHz PCM16) -> Twilio (8kHz μ-law)
const ulaw = muLawEncode(downsample(modelPcm16, 24000, 8000));
twilioWs.send(JSON.stringify({
  event: "media",
  media: { payload: ulaw.toString("base64") },
}));

完全なフレーム形式はTwilio Media Streamsドキュメントに記載されています。リサンプリングは軽量に保ってください。ここで重いライブラリを使用すると、すべてのフレームで支払うことになるレイテンシが増加します。

ステップ5:割り込み(Barge-in)と中断を処理する

本番環境のエージェントは、発信者が被せて話すことを許可します。**割り込み(Barge-in)**とは、エージェントが発話中に発信者が話し始めたことを検出し、エージェントをきれいに切断することを意味します。Realtime APIはresponse.cancelでこれを処理します。再生中にターン検出が発話開始を報告した場合、アクティブなレスポンスをキャンセルし、発信者に向けてすでにバッファリングしたオーディオをフラッシュします。

javascript
if (event.type === "input_audio_buffer.speech_started") {
  realtime.send(JSON.stringify({ type: "response.cancel" }));
  twilioWs.send(JSON.stringify({ event: "clear" }));   // drop queued playback
}

ターン検出には2つのモードがあり、選択が重要です。server_vadは生の無音閾値でトリガーされ、自然な休止時に発信者を遮断しやすい傾向があります。semantic_vadは、モデルが発信者が実際に思考を終えたと思うまで待機するため、考え込んでいる間の誤った割り込みが大幅に減少します。電話通話では、人間的に感じられるのはsemantic VADです。

ステップ6:レイテンシをサブ秒級に調整する

ここがデモを製品に変える場所です。理論的な予算ではなく、私たち自身の構築からの数値を示します。2026年5月、OpenAIリージョン近くにコロケーションされた小さなサーバー1台で、同じレストランエージェントを40回のテスト通話で実行し、ターン検出と推論設定のみを入れ替えました。

構成p50 往復時間p95備考
server_vad, reasoning low~1.4秒~2.3秒休止時の誤った割り込みが多い
semantic_vad, reasoning low~1.1秒~1.9秒私たちの本番環境デフォルト
semantic_vad, reasoning medium~1.8秒~3.1秒ツールの精度は向上するが遅い

実際に効果があったレバーは、影響度の順に以下の通りです。

  • 特定のツールが本当に精度を必要としない限り、reasoning.effortをlowに保つ。mediumにするとp50がほぼ倍増しました。
  • リアルタイムより速くオーディオをプッシュしない。input_audio_buffer.appendを洪水のように送信するとバッファがオーバーランし、ドリフトが発生します。フレームを壁時計時間に合わせます。
  • ソケットを温めておく。通話ごとに接続をコールドオープンすると、ハンドシェイクが最初の言葉のレイテンシに加算されます。通話量が許す範囲で接続をプールします。
  • 効率的にリサンプリングする。ホットパスでの単純なリサンプラーは、私たちにとって1ターンあたり約80ms追加されました。

稼働後、1分あたりのコストはいくらでしょうか?Bring-your-own-keyの計算は別に行いました。ここで再導出するのではなく、BYOK音声エージェントの1分あたりのコストをご覧ください。

ステップ7:本番環境向けにデプロイおよび強化する

「自分のラップトップでは動いた」と「1日500回の通話に耐える」の間には、いくつかのよく知られた失敗が存在します。以下は、実際にRealtimeエージェントを壊す間違いから抽出した強化チェックリストです。

落とし穴症状修正
サンプルレートが間違っている歪んだ音 / チップマンク音声双方向で24kHz PCM16
function_call_arguments.doneを無視しているツールが発火しないリッスンしてresponse.createを送信
リアルタイムより速くオーディオをプッシュしているバッファオーバーラン、ドリフトフレームをリアルタイムに合わせる
再接続ロジックがないソケットの不調で通話が切断される自動再接続 + セッションの再開
response.doneの処理がないターンが重複する次のターンをresponse.doneで制御

実際のトラフィックのためにもう2点。長時間の通話では、コンテキストが drift しないように数ターンごとにセッションを回転または再シードしてください。20分の通話は、モデルがつまずき始める状態を蓄積します。また、すべてのツール呼び出しとその引数、結果をログに残してください。発信者が「エージェントが間違った時間を予約した」と言った場合、トランスクリプトだけではモデルが間違っていたのかコードが間違っていたのか判断できません。

ステップ3でAgents SDKルートを採用する場合、新しいコンテナサンドボックスはツールコードを隔離して実行します。これは、ツールがAPIだけでなくファイルシステムやシェルに触れる場合に重要になります。

代わりに管理型プラットフォームを購入すべき場合

Realtime API上で直接構築することは最大の制御と最低の分単価コストを提供しますが、再接続ロジック、電話ブリッジ、コンプライアンス、観測可能性——ステップ4から7までのすべての地味な部分——をあなたが所有することになります。今週中に電話エージェントを稼働させたいが、メディアリレーを維持したくない場合、管理型プラットフォームの方が迅速な選択です。

私たちは同じエージェントを主要3社で構築し、正直に比較しました:Retell、Vapi、またはBland。どちら側の立場にいるかまだ迷っている場合は、エンジニアリング時間をコミットする前に完全な構築vs購入の意思決定フレームワークを確認してください。

チームがカスタムRealtime構築の制御を望むが、人員を割けない場合、それが私たちが行う仕事です。電話ブリッジから上記のレイテンシ調整まで、本番環境向け音声エージェント開発をサポートします。検討中であれば、あなたのユースケースを拝見させていただきます。

著者について — Mert Batur GurbuzはTechsy.ioの共同創設者であり、同社のチームはB2Bクライアント向けにAIエージェント、自動化システム、音声/SDRパイプラインを提供しています。バーミンガム大学で学び、Techsyチームが本番環境で実際に使用しているLLMツールスタックについて執筆しています。LinkedIn

よくある質問

OpenAI Realtime API音声エージェントのレイテンシは?

semantic_vadと低い推論努力値を使用したgpt-realtime-2での私たちの構築では、40回のテスト通話で測定した往復レイテンシはp50で1.1秒、p95で1.9秒でした。1つのソケットでの音声対音声処理はSTT/LLM/TTSのリレーを回避するため、これがサブ秒級の応答を可能にする要因です。

音声エージェントにはWebRTC、WebSocket、SIPのどれが必要ですか?

ブラウザまたはモバイルアプリがマイクを直接キャプチャする場合はWebRTCを、サーバーがすでに生のオーディオストリームを保持している場合(Twilioブリッジの場合)はWebSocketを、独自のメディアリレーなしでOpenAIに電話回線の処理を行わせたい場合はSIPを使用してください。ほとんどの電話エージェントはWebSocketまたはSIPを使用します。

OpenAI Realtime APIをTwilioに接続するには?

着信Twilio通話を、サーバーへのWebSocketを開くTwiML <Connect><Stream>に向け、TwilioとRealtimeソケットの間でオーディオをリレーします。双方向でTwilioの8kHz μ-lawをAPIの24kHz PCM16にリサンプリングしないと、音声は歪んで出力されます。

Realtime APIでの関数呼び出しはどのように動作しますか?

セッション構成でツールを宣言します。モデルが必要とすると、function_call_arguments.doneイベントを発行します。作業を実行し、結果をfunction_call_output会話アイテムとして送り返し、その後エージェントが結果を発話できるようにresponse.createを送信します。この最後のステップを忘れることが、ツールが「暗黙的に」失敗する理由です。

Realtime APIでの割り込み(barge-in)はどのように処理しますか?

再生中にターン検出がinput_audio_buffer.speech_startedを報告した場合、response.cancelを送信してアクティブなレスポンスを停止し、発信者向けのキューイングされた出力オーディオをクリアします。自然な休止が文中の誤った割り込みを引き起こさないように、semantic_vadと組み合わせます。

OpenAI Realtime APIが使用するオーディオサンプルレートは?

Realtime APIは双方向で24kHz PCM16オーディオを使用します。Twilioなどの電話通信プロバイダーは8kHz μ-lawを提供するため、電話ブリッジは入力時にアップサンプリングし、出力時にダウンサンプリングする必要があります。サンプルレートの不一致は、歪んだ音声の最も一般的な原因です。

Realtime APIで音声エージェントを実行するコストは?

コストはgpt-realtime-2のオーディオ入出力分数によって駆動され、bring-your-own-keyの経済性は管理型の分単位プラットフォームとは大きく異なります。ここで推定するのではなく、音声エージェント価格の内訳で完全な計算を行っています。

Realtime API上に構築すべきか、Retell、Vapi、またはBlandを使用すべきか?

最大の制御と最低の分単価コストを望み、再接続、電話通信、コンプライアンスを自身で所有できる場合は直接構築してください。ローンチまでの速度が重要な場合は管理型プラットフォームを購入してください。トレードオフについては、Retell vs Vapi vs Bland比較および構築vs購入フレームワークで説明しています。

2026年4月のOpenAI Agents SDKアップデートは音声エージェントに何をもたらしましたか?

2026年4月15日の刷新により、Model Context Protocolがファーストクラスとなり、ツールコード用のコンテナサンドボックスが追加され、サブエージェントへのハンドオフがランタイムプリミティブとなりました。音声エージェントにとって、これはルーターエージェントがすべてのツールを1つのプロンプトに詰め込むのではなく、専門的なサブエージェントにハンドオフできることを意味します。

タグ

openai realtime api 音声エージェントgpt-realtime-2関数呼び出しtwilio 音声エージェントopenai agents sdk音声AI チュートリアル

記事をシェアする

関連記事

その他の記事 ai-machine-learning

ai-machine-learning
Jul 24, 2026

Claude Opus 5が登場:Fable 5に迫る知能を半額で

Anthropicは2026年7月24日にClaude Opus 5をリリース。Frontier-BenchでOpus 4.8を2倍以上上回り、Opus価格を維持するが、Fable 5とMythos 5にいくつかのテストで敗れる。ベンチマーク表、価格、切り替え/待機/据え置きの判断を解説。

10 min read 分
読む
ai-machine-learning
Jul 20, 2026

2026年ベストAIウェブスクレイピングAPI 8選(自社エージェントスタックで実測)

自社エージェントスタックで取得した2026年の実価格をもとに、8つのAIウェブスクレイピングAPIをテスト。Firecrawl、Bright Data、ScrapingBeeほか5社を、LLM対応出力・アンチボット突破・MCPサポートの観点でランキング。

9 min read 分
読む
ai-machine-learning
Jul 20, 2026

コーディングのためのプロンプトエンジニアリング:Claude CodeとCursorで毎日使う7つのパターン(2026年版)

多くの「AIコーディングプロンプト」記事はコピー用のテンプレートを50個並べるだけですが、この記事では私たちが16エージェントのClaude Codeパイプラインを運用するために毎日使っている7つのパターンを紹介します。各パターンの具体的な改善前後の例に加え、2026年時点でのClaude Code、Cursor、Copilotにおける各パターンの適用方法も解説します。

11 min read 分
読む
すべての記事を表示
プロジェクトを始めよう

さあ、何かを作ろう。 特別なものへ?

ビジョンを、かたちに。変化を生むソフトウェアづくりは、私たちのチームにお任せください。

30分のスコーピング通話を予約する実績を見る

注目のツール

Claude Skills

すべて表示
  • New Post

    Full SEO blog pipeline: research, brief, write, validate, image, translate, publish to Sanity. Autonomous from start to finish.

  • Content Refresh

    Audit a stale post, find decay drivers, and ship a SERP-aligned refresh without losing existing rankings.

  • SEO Audit

    Site-wide SEO audit with prioritized fix list: technical, on-page, and EEAT signals.

AI自動化

すべて表示
  • Security Auditor

    Weekly SCA + IaC scan with prioritized fix PRs.

  • Cold Email Writer

    Generates first-touch emails grounded in one specific public detail.

  • Lead Research Agent

    Enrich an email into a profile, score fit, alert in Slack.

注目のツール

Claude Skills

すべて表示
  • New Post

    Full SEO blog pipeline: research, brief, write, validate, image, translate, publish to Sanity. Autonomous from start to finish.

  • Content Refresh

    Audit a stale post, find decay drivers, and ship a SERP-aligned refresh without losing existing rankings.

  • SEO Audit

    Site-wide SEO audit with prioritized fix list: technical, on-page, and EEAT signals.

AI自動化

すべて表示
  • Security Auditor

    Weekly SCA + IaC scan with prioritized fix PRs.

  • Cold Email Writer

    Generates first-touch emails grounded in one specific public detail.

  • Lead Research Agent

    Enrich an email into a profile, score fit, alert in Slack.

サービス

  • エンタープライズソリューション
  • モバイルアプリ
  • Webアプリケーション

ソリューション

  • CRMシステム
  • AI統合
  • ERPソリューション
  • 音声エージェント
  • プロセス自動化
  • サイバーセキュリティ

ライブラリ

  • ブログ
  • ポートフォリオ

コミュニティ

  • AI自動化
  • Claude Skills

ツール

  • モバイルアプリ開発費用計算ツール
  • OpenAI / LLM API 利用料金計算ツール
  • MVP(Minimum Viable Product)開発費用計算ツール
  • 音声AIエージェント構築費用計算ツール

会社情報

  • 概要
  • パートナー
  • お問い合わせ

法的情報

  • プライバシーポリシー
  • 利用規約
  • クッキーポリシー

サービス

  • エンタープライズソリューション
  • モバイルアプリ
  • Webアプリケーション

ソリューション

  • CRMシステム
  • AI統合
  • ERPソリューション
  • 音声エージェント
  • プロセス自動化
  • サイバーセキュリティ

ライブラリ

  • ブログ
  • ポートフォリオ

コミュニティ

  • AI自動化
  • Claude Skills

ツール

  • モバイルアプリ開発費用計算ツール
  • OpenAI / LLM API 利用料金計算ツール
  • MVP(Minimum Viable Product)開発費用計算ツール
  • 音声AIエージェント構築費用計算ツール

会社情報

  • 概要
  • パートナー
  • お問い合わせ
法的情報プライバシーポリシー利用規約クッキーポリシー
TECHSY
© 2026 Techsy. 無断複写・転載を禁じます