AI Agent Hub
AI エージェント / プラグイン情報メディア
← 一覧へ
OpenAI Realtime Agents
CODEX

OpenAI Realtime Agents

OpenAI Realtime Agents

Realtime API + Agents SDK で構築する音声エージェントの公式リファレンス実装。チャットボット・カスタマーサポート・診断系などのテンプレートを収録。

原文: This is a simple demonstration of more advanced, agentic patterns built on top of the Realtime API.
#公式#Realtime#音声エージェント
REPO STATS

リポジトリ統計

⭐ Stars
6.8k
🍴 Forks
1.1k
⚠️ Open Issues
27
🌿 Language
TypeScript
📄 License
MIT
🕒 最終更新
2026.01.08 (3か月前)
📅 公開日
2025.01.16
🌿 Branch
main
README

ドキュメント

— AI による自動翻訳 (2026.05.07 更新)

リアルタイム API エージェント デモ

これは OpenAI Realtime API と OpenAI Agents SDK を使用した、音声エージェントのより高度なパターンのデモンストレーションです。

OpenAI Agents SDK について

このプロジェクトは OpenAI Agents SDK を使用しており、高度な AI エージェントの構築、管理、デプロイメントのためのツールキットです。SDK は以下を提供します:

  • エージェントの動作とツール統合を定義するための統一インターフェース。
  • エージェントオーケストレーション、状態管理、イベントハンドリングの組み込みサポート。
  • OpenAI Realtime API との簡単な統合により、低遅延でストリーミングなインタラクションが可能です。
  • マルチエージェント協業、ハンドオフ、ツール使用、ガードレールのための拡張可能なパターン。

完全なドキュメント、ガイド、API リファレンスについては、公式の OpenAI Agents SDK ドキュメント を参照してください。

注意: OpenAI Agents SDK を使用しないバージョンについては、without-agents-sdk ブランチ を参照してください。

以下の 2 つの主要なパターンが示されています:

  1. チャット-スーパーバイザー: リアルタイムベースのチャットエージェントはユーザーと対話し、ユーザーへのグリーティング、カジュアルな会話、情報収集などの基本的なタスクを処理します。より知的でテキストベースのスーパーバイザーモデル(例:gpt-4.1)がツールコールや、より複雑な応答を処理するために広く使用されます。このアプローチは簡単なオンランプと高品質な回答を提供し、わずかなレイテンシの増加があります。
  2. 連続的なハンドオフ: 特殊化されたエージェント(リアルタイム API で搭載)がユーザーを転送して、特定のユーザーインテント を処理します。これは、ユーザーのインテントが特定のドメインで優れた専門家モデルによって順序立てて処理できるカスタマーサービスに最適です。これは、すべての指示とツールを単一エージェントに含めることで、パフォーマンスが低下するのを避けるのに役立ちます。

セットアップ

  • これは Next.js TypeScript アプリです。npm i で依存関係をインストールしてください。
  • OPENAI_API_KEY を環境に追加してください。.bash_profile またはそれに相当するものに追加するか、.env.sample.env にコピーして追加してください。
  • npm run dev でサーバーを起動してください。
  • ブラウザを http://localhost:3000 で開いてください。デフォルトは chatSupervisor エージェント設定になります。
  • 右上の「Scenario」ドロップダウンで例を変更できます。

エージェントパターン 1: チャット-スーパーバイザー

これは chatSupervisor エージェント設定で示されています。チャットエージェントは Realtime モデルを使用してユーザーと会話し、ユーザーへのグリーティング、カジュアルな会話、情報収集などの基本的なタスクを処理します。より知的でテキストベースのスーパーバイザーモデル(例:gpt-4.1)がツールコールと、より複雑な応答を処理するために広く使用されます。決定境界を「オプトイン」することで、必要に応じて特定のタスクをチャットエージェントに処理させるように制御できます。

ビデオウォークスルー:https://x.com/noahmacca/status/1927014156152058075

チャット-スーパーバイザーフローのスクリーンショット このやり取りでは、電話番号を収集するための即座の応答と、ツールコールを処理して応答を作成するスーパーバイザーエージェントへの転送に注目してください。「give me a moment to check on that.」が話されるのが終わるのと、「Thanks for waiting. Your last bill...」が始まるのの間には約 2 秒です。

図解

sequenceDiagram
    participant User
    participant ChatAgent as Chat Agent<br/>(gpt-4o-realtime-mini)
    participant Supervisor as Supervisor Agent<br/>(gpt-4.1)
    participant Tool as Tool

    alt Basic chat or info collection
        User->>ChatAgent: User message
        ChatAgent->>User: Responds directly
    else Requires higher intelligence and/or tool call
        User->>ChatAgent: User message
        ChatAgent->>User: "Let me think"
        ChatAgent->>Supervisor: Forwards message/context
        alt Tool call needed
            Supervisor->>Tool: Calls tool
            Tool->>Supervisor: Returns result
        end
        Supervisor->>ChatAgent: Returns response
        ChatAgent->>User: Delivers response
    end
読み込み中

利点

  • オンボーディングの簡素化。 既に性能の良いテキストベースのチャットエージェントがあれば、同じプロンプトとツールセットをスーパーバイザーエージェントに提供し、チャットエージェントのプロンプトに若干の調整を加えるだけで、テキストエージェント同等のパフォーマンスを発揮する自然な音声エージェントを構築できます。
  • 完全なリアルタイムエージェントへのシンプルな段階的移行: エージェント全体をリアルタイム API に切り替えるのではなく、1 つずつタスクを移行でき、本番環境にデプロイする前に各タスクを検証して信頼を構築する時間が持てます。
  • 高い知能: gpt-4.1 のようなモデルの高い知能、優れたツール呼び出し能力、命令遵守能力の恩恵を音声エージェントで受けられます。
  • コストの削減: チャットエージェントが基本的なタスクにしか使用されていない場合、realtime-mini モデルを使用できます。これは gpt-4.1 と組み合わせても、完全な 4o-realtime モデルを使用するより安価です。
  • ユーザーエクスペリエンス: ユーザーが話し終わった後のレスポンスレイテンシーが 1.5 秒以上になることが多い複合モデルアーキテクチャよりも、より自然な会話体験です。このアーキテクチャでは、スーパーバイザーエージェントに頼ることになっても、モデルはユーザーに即座に応答します。
    • ただし、すぐに完全な応答をするのではなく、より多くのアシスタントレスポンスが「Let me think」で始まります。

独自のエージェント向けカスタマイズ

  1. supervisorAgent を更新します。
  • 既存のテキストエージェントのプロンプトとツールがあれば、それらを追加してください。これは音声エージェントロジックの「中核部分」を含む必要があり、何をするべき・すべきでないか、また正確にどのように応答すべきかについて非常に具体的である必要があります。この情報を ==== Domain-Specific Agent Instructions ==== の下に追加してください。
  • このプロンプトは音声に適したものに更新することをお勧めします。例えば、簡潔さを心がけ、長いリストの項目を避けるなどの指示を含めるとよいでしょう。
  1. chatAgent を更新します。
  • chatAgent の指示を自分のトーン、挨拶などでカスタマイズしてください。
  • chatAgentInstructions にツール定義を追加してください。モデルが混乱してツールを直接呼び出そうとしないよう、JSON ではなく簡潔な YAML 説明をお勧めします。
  • # Allow List of Permitted Actions セクションに新しい項目を追加することで、判定境界を変更できます。
  1. コストを削減するために、chatAgent に gpt-4o-mini-realtime を、スーパーバイザーモデルに gpt-4.1-mini を使用してみてください。特に難しいまたはハイリスクなタスクで知能を最大化するには、レイテンシーと引き換えにスーパーバイザープロンプトに連鎖思考を追加することを検討するか、o4-mini を使用する追加の推論モデルベースのスーパーバイザーを使用してください。

Agentic Pattern 2: 順序付きハンドオフ

このパターンは OpenAI Swarm に着想を得ており、ユーザーが専門化されたエージェント間で順序付きに受け渡されることを含みます。ハンドオフはモデルによって決定され、ツール呼び出しを通じて調整されます。可能なハンドオフはエージェントグラフで明示的に定義されます。ハンドオフは新しい指示とツールを含む session.update イベントをトリガーします。このパターンは、様々なユーザー意図を処理するのに効果的で、各エージェントは長い指示と多数のツールを持つ可能性があります。

ここに動作を示す ビデオウォークスルー があります。このリポジトリを使用して、20 分以内に独自のマルチエージェント リアルタイム音声アプリをプロトタイプ化できるはずです!

Screenshot of the Realtime API Agents Demo この簡潔な例では、ユーザーは greeter エージェントから haiku エージェントに転送されます。このフローの簡潔で完全な設定については以下を参照してください。

src/app/agentConfigs/simpleExample.ts での設定

import { RealtimeAgent } from '@openai/agents/realtime';

// Define agents using the OpenAI Agents SDK
export const haikuWriterAgent = new RealtimeAgent({
  name: 'haikuWriter',
  handoffDescription: 'Agent that writes haikus.', // Context for the agent_transfer tool
  instructions:
    'Ask the user for a topic, then reply with a haiku about that topic.',
  tools: [],
  handoffs: [],
});

export const greeterAgent = new RealtimeAgent({
  name: 'greeter',
  handoffDescription: 'Agent that greets the user.',
  instructions:
    "Please greet the user and ask them if they'd like a haiku. If yes, hand off to the 'haikuWriter' agent.",
  tools: [],
  handoffs: [haikuWriterAgent], // Define which agents this agent can hand off to
});

// An Agent Set is just an array of the agents that participate in the scenario
export default [greeterAgent, haikuWriterAgent];

CustomerServiceRetail Flow

これはより複雑で、代表的な実装で、以下の機能を備えた顧客サービスフローを示しています。

  • ユーザー認証、返品、販売、およびエスカレーション用のプレースホルダー人間エージェントを備えた、より複雑なエージェントグラフです。
  • 高リスク決定の例として、returns エージェントによる o4-mini へのエスカレーションで返品を検証および開始するもので、上記と同様のパターンを使用しています。
  • ユーザー認証のために、名前や電話番号などの情報を文字ごとに確認して正確に収集するなど、状態マシンに従うようモデルにプロンプトを指示しています。
    • このフローをテストするには、スノーボードを返したいと伝えて、必要なプロンプトを進めてください。

構成は src/app/agentConfigs/customerServiceRetail/index.ts にあります。

import authentication from "./authentication";
import returns from "./returns";
import sales from "./sales";
import simulatedHuman from "./simulatedHuman";
import { injectTransferTools } from "../utils";

authentication.downstreamAgents = [returns, sales, simulatedHuman];
returns.downstreamAgents = [authentication, sales, simulatedHuman];
sales.downstreamAgents = [authentication, returns, simulatedHuman];
simulatedHuman.downstreamAgents = [authentication, returns, sales];

const agents = injectTransferTools([
  authentication,
  returns,
  sales,
  simulatedHuman,
]);

export default agents;

スキーマティック図

このダイアグラムは、src/app/agentConfigs/customerServiceRetail/ で定義されたより高度なインタラクションフロー(詳細なイベントを含む)を示しています。

CustomerServiceRetail フロー図を表示
sequenceDiagram
    participant User
    participant WebClient as Next.js Client
    participant NextAPI as /api/session
    participant RealtimeAPI as OpenAI Realtime API
    participant AgentManager as Agents (authentication, returns, sales, simulatedHuman)
    participant o1mini as "o4-mini" (Escalation Model)

    Note over WebClient: User navigates to ?agentConfig=customerServiceRetail
    User->>WebClient: Open Page
    WebClient->>NextAPI: GET /api/session
    NextAPI->>RealtimeAPI: POST /v1/realtime/sessions
    RealtimeAPI->>NextAPI: Returns ephemeral session
    NextAPI->>WebClient: Returns ephemeral token (JSON)

    Note right of WebClient: Start RTC handshake
    WebClient->>RealtimeAPI: Offer SDP (WebRTC)
    RealtimeAPI->>WebClient: SDP answer
    WebClient->>WebClient: DataChannel "oai-events" established

    Note over AgentManager: Default agent is "authentication"
    User->>WebClient: "Hi, I'd like to return my snowboard."
    WebClient->>AgentManager: conversation.item.create (role=user)
    WebClient->>RealtimeAPI: {type: "conversation.item.create"}
    WebClient->>RealtimeAPI: {type: "response.create"}

    authentication->>AgentManager: Requests user info, calls authenticate_user_information()
    AgentManager-->>WebClient: function_call => name="authenticate_user_information"
    WebClient->>WebClient: handleFunctionCall => verifies details

    Note over AgentManager: After user is authenticated
    authentication->>AgentManager: transferAgents("returns")
    AgentManager-->>WebClient: function_call => name="transferAgents" args={ destination: "returns" }
    WebClient->>WebClient: setSelectedAgentName("returns")

    Note over returns: The user wants to process a return
    returns->>AgentManager: function_call => checkEligibilityAndPossiblyInitiateReturn
    AgentManager-->>WebClient: function_call => name="checkEligibilityAndPossiblyInitiateReturn"

    Note over WebClient: The WebClient calls /api/chat/completions with model="o4-mini"
    WebClient->>o1mini: "Is this item eligible for return?"
    o1mini->>WebClient: "Yes/No (plus notes)"

    Note right of returns: Returns uses the result from "o4-mini"
    returns->>AgentManager: "Return is approved" or "Return is denied"
    AgentManager->>WebClient: conversation.item.create (assistant role)
    WebClient->>User: Displays final verdict
">

— GitHub から取得した原文(一部省略の場合あり)

Realtime API Agents Demo

This is a demonstration of more advanced patterns for voice agents, using the OpenAI Realtime API and the OpenAI Agents SDK.

About the OpenAI Agents SDK

This project uses the OpenAI Agents SDK, a toolkit for building, managing, and deploying advanced AI agents. The SDK provides:

  • A unified interface for defining agent behaviors and tool integrations.
  • Built-in support for agent orchestration, state management, and event handling.
  • Easy integration with the OpenAI Realtime API for low-latency, streaming interactions.
  • Extensible patterns for multi-agent collaboration, handoffs, tool use, and guardrails.

For full documentation, guides, and API references, see the official OpenAI Agents SDK Documentation.

NOTE: For a version that does not use the OpenAI Agents SDK, see the branch without-agents-sdk.

There are two main patterns demonstrated:

  1. Chat-Supervisor: A realtime-based chat agent interacts with the user and handles basic tasks, while a more intelligent, text-based supervisor model (e.g., gpt-4.1) is used extensively for tool calls and more complex responses. This approach provides an easy onramp and high-quality answers, with a small increase in latency.
  2. Sequential Handoff: Specialized agents (powered by realtime api) transfer the user between them to handle specific user intents. This is great for customer service, where user intents can be handled sequentially by specialist models that excel in a specific domains. This helps avoid the model having all instructions and tools in a single agent, which can degrade performance.

Setup

  • This is a Next.js typescript app. Install dependencies with npm i.
  • Add your OPENAI_API_KEY to your env. Either add it to your .bash_profile or equivalent, or copy .env.sample to .env and add it there.
  • Start the server with npm run dev
  • Open your browser to http://localhost:3000. It should default to the chatSupervisor Agent Config.
  • You can change examples via the "Scenario" dropdown in the top right.

Agentic Pattern 1: Chat-Supervisor

This is demonstrated in the chatSupervisor Agent Config. The chat agent uses the realtime model to converse with the user and handle basic tasks, like greeting the user, casual conversation, and collecting information, and a more intelligent, text-based supervisor model (e.g. gpt-4.1) is used extensively to handle tool calls and more challenging responses. You can control the decision boundary by "opting in" specific tasks to the chat agent as desired.

Video walkthrough: https://x.com/noahmacca/status/1927014156152058075

Example

Screenshot of the Chat Supervisor Flow In this exchange, note the immediate response to collect the phone number, and the deferral to the supervisor agent to handle the tool call and formulate the response. There ~2s between the end of "give me a moment to check on that." being spoken aloud and the start of the "Thanks for waiting. Your last bill...".

Schematic

sequenceDiagram
    participant User
    participant ChatAgent as Chat Agent<br/>(gpt-4o-realtime-mini)
    participant Supervisor as Supervisor Agent<br/>(gpt-4.1)
    participant Tool as Tool

    alt Basic chat or info collection
        User->>ChatAgent: User message
        ChatAgent->>User: Responds directly
    else Requires higher intelligence and/or tool call
        User->>ChatAgent: User message
        ChatAgent->>User: "Let me think"
        ChatAgent->>Supervisor: Forwards message/context
        alt Tool call needed
            Supervisor->>Tool: Calls tool
            Tool->>Supervisor: Returns result
        end
        Supervisor->>ChatAgent: Returns response
        ChatAgent->>User: Delivers response
    end
Loading

Benefits

  • Simpler onboarding. If you already have a performant text-based chat agent, you can give that same prompt and set of tools to the supervisor agent, and make some tweaks to the chat agent prompt, you'll have a natural voice agent that will perform on par with your text agent.
  • Simple ramp to a full realtime agent: Rather than switching your whole agent to the realtime api, you can move one task at a time, taking time to validate and build trust for each before deploying to production.
  • High intelligence: You benefit from the high intelligence, excellent tool calling and instruction following of models like gpt-4.1 in your voice agents.
  • Lower cost: If your chat agent is only being used for basic tasks, you can use the realtime-mini model, which, even when combined with GPT-4.1, should be cheaper than using the full 4o-realtime model.
  • User experience: It's a more natural conversational experience than using a stitched model architecture, where response latency is often 1.5s or longer after a user has finished speaking. In this architecture, the model responds to the user right away, even if it has to lean on the supervisor agent.
    • However, more assistant responses will start with "Let me think", rather than responding immediately with the full response.

Modifying for your own agent

  1. Update supervisorAgent.
  • Add your existing text agent prompt and tools if you already have them. This should contain the "meat" of your voice agent logic and be very specific with what it should/shouldn't do and how exactly it should respond. Add this information below ==== Domain-Specific Agent Instructions ====.
  • You should likely update this prompt to be more appropriate for voice, for example with instructions to be concise and avoiding long lists of items.
  1. Update chatAgent.
  • Customize the chatAgent instructions with your own tone, greeting, etc.
  • Add your tool definitions to chatAgentInstructions. We recommend a brief yaml description rather than json to ensure the model doesn't get confused and try calling the tool directly.
  • You can modify the decision boundary by adding new items to the # Allow List of Permitted Actions section.
  1. To reduce cost, try using gpt-4o-mini-realtime for the chatAgent and/or gpt-4.1-mini for the supervisor model. To maximize intelligence on particularly difficult or high-stakes tasks, consider trading off latency and adding chain-of-thought to your supervisor prompt, or using an additional reasoning model-based supervisor that uses o4-mini.

Agentic Pattern 2: Sequential Handoffs

This pattern is inspired by OpenAI Swarm and involves the sequential handoff of a user between specialized agents. Handoffs are decided by the model and coordinated via tool calls, and possible handoffs are defined explicitly in an agent graph. A handoff triggers a session.update event with new instructions and tools. This pattern is effective for handling a variety of user intents with specialist agents, each of which might have long instructions and numerous tools.

Here's a video walkthrough showing how it works. You should be able to use this repo to prototype your own multi-agent realtime voice app in less than 20 minutes!

Screenshot of the Realtime API Agents Demo In this simple example, the user is transferred from a greeter agent to a haiku agent. See below for the simple, full configuration of this flow.

Configuration in src/app/agentConfigs/simpleExample.ts

import { RealtimeAgent } from '@openai/agents/realtime';

// Define agents using the OpenAI Agents SDK
export const haikuWriterAgent = new RealtimeAgent({
  name: 'haikuWriter',
  handoffDescription: 'Agent that writes haikus.', // Context for the agent_transfer tool
  instructions:
    'Ask the user for a topic, then reply with a haiku about that topic.',
  tools: [],
  handoffs: [],
});

export const greeterAgent = new RealtimeAgent({
  name: 'greeter',
  handoffDescription: 'Agent that greets the user.',
  instructions:
    "Please greet the user and ask them if they'd like a haiku. If yes, hand off to the 'haikuWriter' agent.",
  tools: [],
  handoffs: [haikuWriterAgent], // Define which agents this agent can hand off to
});

// An Agent Set is just an array of the agents that participate in the scenario
export default [greeterAgent, haikuWriterAgent];

CustomerServiceRetail Flow

This is a more complex, representative implementation that illustrates a customer service flow, with the following features:

  • A more complex agent graph with agents for user authentication, returns, sales, and a placeholder human agent for escalations.
  • An escalation by the returns agent to o4-mini to validate and initiate a return, as an example high-stakes decision, using a similar pattern to the above.
  • Prompting models to follow a state machine, for example to accurately collect things like names and phone numbers with confirmation character by character to authenticate a user.
    • To test this flow, say that you'd like to return your snowboard and go through the necessary prompts!

Configuration in src/app/agentConfigs/customerServiceRetail/index.ts.

import authentication from "./authentication";
import returns from "./returns";
import sales from "./sales";
import simulatedHuman from "./simulatedHuman";
import { injectTransferTools } from "../utils";

authentication.downstreamAgents = [returns, sales, simulatedHuman];
returns.downstreamAgents = [authentication, sales, simulatedHuman];
sales.downstreamAgents = [authentication, returns, simulatedHuman];
simulatedHuman.downstreamAgents = [authentication, returns, sales];

const agents = injectTransferTools([
  authentication,
  returns,
  sales,
  simulatedHuman,
]);

export default agents;

Schematic

This diagram illustrates a more advanced interaction flow defined in src/app/agentConfigs/customerServiceRetail/, including detailed events.

Show CustomerServiceRetail Flow Diagram
sequenceDiagram
    participant User
    participant WebClient as Next.js Client
    participant NextAPI as /api/session
    participant RealtimeAPI as OpenAI Realtime API
    participant AgentManager as Agents (authentication, returns, sales, simulatedHuman)
    participant o1mini as "o4-mini" (Escalation Model)

    Note over WebClient: User navigates to ?agentConfig=customerServiceRetail
    User->>WebClient: Open Page
    WebClient->>NextAPI: GET /api/session
    NextAPI->>RealtimeAPI: POST /v1/realtime/sessions
    RealtimeAPI->>NextAPI: Returns ephemeral session
    NextAPI->>WebClient: Returns ephemeral token (JSON)

    Note right of WebClient: Start RTC handshake
    WebClient->>RealtimeAPI: Offer SDP (WebRTC)
    RealtimeAPI->>WebClient: SDP answer
    WebClient->>WebClient: DataChannel "oai-events" established

    Note over AgentManager: Default agent is "authentication"
    User->>WebClient: "Hi, I'd like to return my snowboard."
    WebClient->>AgentManager: conversation.item.create (role=user)
    WebClient->>RealtimeAPI: {type: "conversation.item.create"}
    WebClient->>RealtimeAPI: {type: "response.create"}

    authentication->>AgentManager: Requests user info, calls authenticate_user_information()
    AgentManager-->>WebClient: function_call => name="authenticate_user_information"
    WebClient->>WebClient: handleFunctionCall => verifies details

    Note over AgentManager: After user is authenticated
    authentication->>AgentManager: transferAgents("returns")
    AgentManager-->>WebClient: function_call => name="transferAgents" args={ destination: "returns" }
    WebClient->>WebClient: setSelect
RELATED

同じカテゴリの他のツール