mcpField
O
open-responses

open-responses

github.com/openrouterteam開発309322 回インストール1 日前に更新
リポジトリ

open-responses について

Open Responses は、複数プロバイダーの LLM を扱う統一 HTTP プロトコルのオープンソース仕様です。プロトコル実装者やクライアント開発者向けに、メッセージ、ツール呼び出し、ストリーミング、マルチモーダル入力を標準化し、ステートレスを基本としています。

主な機能

  1. 01プロバイダー間のリクエスト・応答形式を統一
  2. 02メッセージ・ツール呼び出し・マルチモーダル内容を規定
  3. 03SSE ストリーミングイベントと状態遷移を定義
  4. 04previous_response_id による会話の連結
  5. 05ベンダー接頭辞付き拡張に対応

活用シーン

  1. 01仕様に準拠したモデルサービスの実装
  2. 02複数プロバイダー向けクライアントの開発
  3. 03ツール利用と複数ターンのエージェント処理
  4. 04ストリーミングイベントと応答状態のデバッグ

MCP 対応

仕様では MCP ツールを外部ホスト型ツールに分類し、プロトコルのツール呼び出しにおける位置付けを説明しています。MCP サーバーや SDK ではなく、汎用プロトコルを定めるものです。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/openrouterteam/skills --skill open-responses

インストール後、Claude Code で/open-responsesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

metadata.json
references/
extensions.md
protocol-and-items.md
state-machines-and-streaming.md

詳細

Open Responses

Open Responses は、複数プロバイダーとの LLM インタラクションを実現する、統一された HTTP プロトコルを定義するオープンソース仕様です。メッセージ、ツール呼び出し、ストリーミング、マルチモーダル入力、推論など、クライアントとサーバーの通信方法を標準化することで、あるプロバイダー向けに書かれたコードを、準拠するあらゆるプロバイダーで動作させます。

これはプロトコル標準そのものであり、特定の SDK ではありません。 Open Responses はプロバイダーに依存しません。あらゆる LLM プロバイダー(OpenAI、Anthropic、Gemini、Databricks、Hugging Face、Ollama など)が、準拠する API を実装できます。

デフォルトはステートレス、必要に応じてステートフルです。 コアプロトコルは、サーバー側でのセッション永続化を要求しません。複数ターンの会話は previous_response_id を通じて連結でき、これによりサーバーは以前のレスポンスからコンテキストを再構築します。ただし、プロバイダーは拡張機能としてステートフルな機能(例:サーバー側ストレージ、会話オブジェクト)を提供する場合があります。仕様では、アイテムの状態は「ディスクに永続化されたり、長期的に保存されたりするという意味で、必ずしもステートフルであるとは限らない」と記されています。

設計原則
  • 複数プロバイダーとの互換性 — 1 つのスキーマで、あらゆるプロバイダーに対応
  • ステートレス優先のプロトコル — previous_response_id を通じてコンテキストを再構築し、プロバイダーは任意で永続化を提供できます
  • ポリモーフィックなアイテム — すべてのモデル出力が、type で識別される共通のアイテム構造を共有します
  • セマンティックストリーミング — SSE イベントがステートマシンの遷移に直接対応します
  • 断片化を招かない拡張性 — ベンダー接頭辞付きの拡張により、名前空間の衝突を防ぎます

仕様: https://www.openresponses.org/specification


参照ファイル

詳細なスキーマ、JSON の例、イベントの完全なカタログについては、適切な参照ファイルを読み込んでください。

ファイル内容読み込むタイミング
references/protocol-and-items.mdHTTP プロトコル、アイテムの種類、コンテンツの種類、制御パラメーター、エラー処理リクエスト/レスポンス構造の実装またはデバッグ時
references/state-machines-and-streaming.mdステートマシン図、ストリーミングイベントのカタログ、テキストとツール使用時の完全な SSE シーケンスストリーミングや状態遷移の実装またはデバッグ時
references/extensions.mdカスタムアイテム、カスタムイベント、スキーマ拡張、ガバナンスの手順プロバイダー固有の機能で仕様を拡張する時

特定のトピックを参照ファイル内で検索するには、function_call、streaming、tool_choice、previous_response_id、vendor: などのキーワードで grep してください。


コアコンセプト

エンドポイントとトランスポート

すべてのリクエストは、Authorization: Bearer <token> と Content-Type: application/json を指定して POST /v1/responses に送信します。ストリーミングしないレスポンスは JSON を返します。ストリーミングレスポンスでは SSE(text/event-stream)を使用し、data: [DONE] で終了します。

アイテム

アイテムは、type で識別されるポリモーフィックな原子的単位です。出力アイテム(レスポンス内でモデルが出力するアイテム)には、id、type、status フィールドが必要です。コア出力タイプは、message、function_call、reasoning です。プロバイダーは、ベンダー接頭辞付きのタイプ(例:acme:web_search_call)で拡張できます。

入力アイテム(リクエスト内でクライアントが送信するアイテム)に必要な項目は、タイプごとに異なります。input_text、input_image、input_file などのコンテンツタイプには、id や status は含まれません。function_call_output アイテムには call_id と output が必要ですが、id と status は任意です。

メッセージのロール: user、assistant、system、developer。system ロールは instructions パラメーターとは異なり、入力配列内のインラインメッセージアイテムです。developer ロールは独立したロールであり、プロバイダーによっては system とは異なる扱いをする場合があります。

ステートマシンとイベントの発行

レスポンスとアイテムのライフサイクルは、どちらも有限状態マシンです。各状態によって、発行できるイベントが制約されます。

レスポンスのライフサイクル — 状態ごとに発行されるイベント
stateDiagram-v2
    [*] --> created : response.created
    created --> queued : response.queued
    queued --> in_progress : response.in_progress

    state in_progress {
        direction LR
        note right of in_progress
            Events emittable while in_progress:
            ─────────────────────────────────
            response.output_item.added
            response.content_part.added
            response.output_text.delta
            response.output_text.done
            response.function_call_arguments.delta
            response.function_call_arguments.done
            response.reasoning_summary_text.delta
            response.reasoning_summary_text.done
            response.content_part.done
            response.output_item.done
            vendor:custom_event

            All delta events carry: sequence_number,
            output_index, item_id
            Content-level events also carry: content_index
        end note
    }

    in_progress --> completed : response.completed
    in_progress --> incomplete : response.incomplete\n(item hit token budget)
    in_progress --> failed : response.failed
    completed --> [*]
    incomplete --> [*]
    failed --> [*]

注: アイテムが incomplete 状態で終了する場合、そのアイテムを含むレスポンスも必ず incomplete になります。

項目のライフサイクル — 状態ごとに発行されるイベント
stateDiagram-v2
    [*] --> in_progress : response.output_item.added

    state in_progress {
        direction LR
        note right of in_progress
            Events emittable while item is in_progress:
            ──────────────────────────────────────────
            Message items:
              response.content_part.added
              response.output_text.delta  (repeated)
              response.output_text.done
              response.content_part.done

            Function call items:
              response.function_call_arguments.delta  (repeated)
              response.function_call_arguments.done

            Reasoning items:
              response.reasoning_summary_text.delta  (repeated)
              response.reasoning_summary_text.done
        end note
    }

    in_progress --> completed : response.output_item.done
    in_progress --> incomplete : response.output_item.done
    completed --> [*]
    incomplete --> [*]

    note right of completed : Terminal — no further deltas
    note right of incomplete : Terminal — token budget exhausted
イベントの有効性の概要
レスポンスの状態有効なイベント
created(一時的 — レスポンスオブジェクトが作成された直後)
queued(モデルが利用可能になるのを待機中)
in_progressすべての差分イベント、すべてのカスタムイベント、項目のライフサイクルイベント
completed(終端 — [DONE] 以外のイベントはこれ以上発生しない)
incomplete(終端 — [DONE] 以外のイベントはこれ以上発生しない)
failed(終端 — [DONE] 以外のイベントはこれ以上発生しない)
項目の状態有効なイベント
in_progressコンテンツの差分(.delta)、コンテンツの完了(.done)、パートのライフサイクル
completed(終端 — この項目について、これ以上差分は発生しない)
incomplete(終端 — この項目について、これ以上差分は発生しない)

すべての差分イベントと項目イベントには、sequence_number(単調増加)、output_index(レスポンス出力配列内の位置)、item_id が含まれます。コンテンツレベルのイベント(テキスト、推論の要約)には、さらに content_index(コンテンツパート内の位置)が含まれます。サーバーは SSE の id フィールドを使用しないことが推奨されます。

ストリーミングイベント

SSE イベントには 2 つのカテゴリがあります。

  • 差分イベント — 増分コンテンツ:response.output_text.delta、response.function_call_arguments.delta、response.output_item.added、response.output_item.done など。
  • ライフサイクルイベント — 状態遷移:response.created、response.queued、response.in_progress、response.completed、response.incomplete、response.failed

ルール:SSE ヘッダーの event は、JSON 本文内の type フィールドと一致する必要があります。


ツール

Open Responses では、実行場所に基づいて 2 種類のツールを定義しています。

外部ホスト型ツール — 実装がプロバイダーのシステム外にあります。モデルは function_call 項目を通じて呼び出しを要求し、開発者は後続のリクエストで function_call_output 項目として結果を渡す必要があります。「外部ホスト型」が、必ずしも開発者がツールをローカルで実行することを意味するわけではありません。MCP ツールは外部ホスト型です(実装が外部サーバー上にあります)が、必ずしも先に制御が開発者へ戻るわけではありません。例:関数ツール、MCP サーバーのツール。

内部ホスト型ツール — 実装がプロバイダーのシステム内にあります。プロバイダーは制御を引き渡さずに実行し、同じレスポンス内でプロバイダー固有の項目タイプとして結果を返します。これらの項目は、後続のリクエストで損失なくラウンドトリップできる必要があります。例:ファイル検索、コードインタープリター、ウェブ検索。

ツールの定義
{
  "type": "function",
  "name": "get_weather",
  "description": "Get current weather for a location",
  "parameters": {
    "type": "object",
    "properties": {
      "location": {"type": "string", "description": "City name"},
      "units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
    },
    "required": ["location"]
  }
}
ツールの制御

tool_choice パラメーターは、モデルがツールを使用するかどうか、およびその使用方法を制御します。

tool_choice の値目的
"auto"ツールを呼び出すかどうかをモデルが決定します(デフォルト)
"required"モデルは少なくとも 1 つのツールを呼び出す必要があります
"none"ツール呼び出しは許可されません
{"type": "function", "name": "..."}特定のツールを強制します
{"type": "allowed_tools", "tools": [...]}モデルが呼び出せるツールを制限します

allowed_tools 形式は tool_choice の中にネストされており、独立したトップレベルのパラメーターではありません。

{
  "tool_choice": {
    "type": "allowed_tools",
    "tools": [
      {"type": "function", "name": "get_weather"}
    ]
  }
}

モデルは、ツール呼び出しを allowed_tools で指定されたサブセットに限定しなければなりません(MUST)。サーバーはこれを厳格な制約として適用しなければなりません(MUST)。ツール定義はモデルのコンテキストに残るため、プロンプトキャッシュが維持されます。


エージェントループのパターン

エージェントループは、複数ステップでツールを活用するワークフローの中核となるパターンです。

フロー
  Client                     Provider                    Model
    |                           |                          |
    |-- POST /v1/responses ---->|                          |
    |                           |--- prompt to model ----->|
    |                           |<-- output items ---------|
    |                           |                          |
    |            [external tool calls needing               |
    |             client-supplied results?]                 |
    |                           |                          |
    |              YES                                     |
    |<-- response with --------|                          |
    |   function_call items     |                          |
    |                           |                          |
    |   [client satisfies       |                          |
    |    tool calls]            |                          |
    |                           |                          |
    |-- POST /v1/responses ---->|                          |
    |   previous_response_id +  |                          |
    |   function_call_output    |--- prompt + context ---->|
    |   items in input          |<-- output items ---------|
    |                           |                          |
    |              NO: no client-satisfied calls remain     |
    |<-- completed response ----|                          |
    |   (may contain message,   |                          |
    |    reasoning, hosted-tool |                          |
    |    items, etc.)           |                          |
主要原則
  1. ステートレス優先の反復処理 — ループの各反復処理は、新しい HTTP リクエストです。サーバーは previous_response_id からコンテキストを再構築します。プロバイダーは任意で状態を保持できますが、プロトコルではそれを必須としていません。

  2. 外部ツールの実行は開発者が制御 — 外部ホスト型の関数ツールでは、実行するタイミング、返す結果、処理を続けるかどうかを開発者が決定します。MCP ツール(こちらも外部ホスト型)の場合は、開発者に制御を渡すことなく実行されることがあります。

  3. 並列ツール呼び出し — モデルは、1 回のレスポンスで複数の function_call アイテムを出力することがあります。それらをすべて実行し、後続の 1 回のリクエストですべての結果を返します。

  4. ループの終了 — レスポンスに、クライアント側で処理する外部ツール呼び出しが残っていない場合、ループは終了します。最終レスポンスには message アイテムだけでなく、reasoning アイテム、内部ホスト型ツールアイテム、その他のメッセージ以外の出力アイテムが含まれることもあります。

  5. 内部ツールはプロバイダーが処理 — 内部ホスト型ツールでは、プロバイダーが同じリクエスト内で実行し、プロバイダー固有のアイテムタイプを返します。開発者側でループを実行する必要はありません。

例:複数ツールを使うエージェント

ターン 1 — ツールを含むリクエスト:

{
  "model": "provider/model-name",
  "input": [{"type": "message", "role": "user", "content": "Compare the weather in Paris and Tokyo."}],
  "tools": [{"type": "function", "name": "get_weather", "description": "Get current weather for a city", "parameters": {"type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"]}}]
}

ターン 1 — モデルが 2 つの並列 function_call アイテムを出力:

{
  "id": "resp_100",
  "status": "completed",
  "output": [
    {"id": "item_101", "type": "function_call", "name": "get_weather", "call_id": "call_paris", "arguments": "{\"location\":\"Paris\"}", "status": "completed"},
    {"id": "item_102", "type": "function_call", "name": "get_weather", "call_id": "call_tokyo", "arguments": "{\"location\":\"Tokyo\"}", "status": "completed"}
  ]
}

ターン 2 — 開発者がツールの結果を返す:

{
  "model": "provider/model-name",
  "previous_response_id": "resp_100",
  "input": [
    {"type": "function_call_output", "call_id": "call_paris", "output": "{\"temperature\":18,\"condition\":\"partly cloudy\"}"},
    {"type": "function_call_output", "call_id": "call_tokyo", "output": "{\"temperature\":24,\"condition\":\"sunny\"}"}
  ],
  "tools": [...]
}

ターン 2 — モデルが最終回答を統合(function_call アイテムがないためループ終了):

{
  "id": "resp_101",
  "status": "completed",
  "output": [
    {"id": "item_200", "type": "message", "role": "assistant", "status": "completed", "content": [{"type": "output_text", "text": "Paris is currently 18°C and partly cloudy. Tokyo is warmer at 24°C with sunny skies."}]}
  ]
}
マルチターンの会話

マルチターンの会話では、previous_response_id を使ってコンテキストを連結します。サーバーはレスポンスチェーンをたどって会話全体を再構築します(プロバイダーは拡張機能としてサーバー側での永続化にも対応できます)。

Server loads: previous_response.input + previous_response.output + new_input
// Turn 1
{"model": "provider/model-name", "input": [{"type": "message", "role": "user", "content": "What is the population of France?"}]}
// Response: {"id": "resp_200", ...}

// Turn 2 — references Turn 1
{"model": "provider/model-name", "previous_response_id": "resp_200", "input": [{"type": "message", "role": "user", "content": "And what about Germany?"}]}

拡張機能

Open Responses は、名前の衝突を防ぐため、ベンダー接頭辞付きの名前を使う 4 つの拡張メカニズムをサポートしています。例を含む詳細については、references/extensions.md を読み込んでください。

メカニズム命名パターン必須フィールド制約
カスタムアイテムvendor:type_nameid、type、statusアイテムのステートマシンに従い、往復可能であること
カスタムイベントvendor:event_nametype、sequence_numberコアのセマンティクスやトークンの順序を変更しないこと
スキーマ拡張ベンダー接頭辞付きフィールドN/A(任意フィールド)不明なフィールドを無視するクライアントを破損させないこと
ガバナンスパスN/AN/A幅広い採用 → TSC への提案 → コア仕様

クライアントは、不明なアイテムタイプとイベントタイプを無視しなければなりません。これは前方互換性を保証するための契約です。


準拠性

API が仕様を直接実装しているか、適切な上位互換仕様であれば、Open Responses に準拠しています。公開されている受け入れテストスイートは https://www.openresponses.org/ で利用できます。

コア準拠テスト
テスト検証内容
基本的なテキストレスポンスResponseResource スキーマ、アイテム構造、使用量
ストリーミングレスポンスSSE イベント、正しい順序、最終構造
システムプロンプトinstructions パラメーター、システムロールの処理
ツール呼び出し関数ツールの定義、function_call 出力、往復処理
画像入力ユーザーコンテンツ内の画像 URL
マルチターンの会話メッセージ履歴、アシスタントとユーザーのターン
サーバー実装チェックリスト
  • Authorization ヘッダーを使用する POST /v1/responses エンドポイント
  • id、type、status を含む有効な出力アイテム。入力アイテムはそれぞれの型の要件を満たすこと
  • アイテムの状態遷移:in_progress -> completed / incomplete
  • レスポンスの状態遷移:created -> queued -> in_progress -> completed / incomplete / failed
  • 6 つすべてのライフサイクルイベントを送信:response.created、.queued、.in_progress、.completed、.incomplete、.failed
  • いずれかのアイテムが incomplete で終了した場合、レスポンスも incomplete
  • event と type が一致する非ストリーミング JSON とストリーミング SSE
  • 終端マーカー data: [DONE]
  • 関数ツール:function_call アイテム、function_call_output によるラウンドトリップ
  • 会話の継続に使用する previous_response_id
  • 正しい HTTP ステータスコードを伴うエラーオブジェクト:type、code、param、message
  • ベンダープレフィックス付き拡張(該当する場合)
クライアント実装チェックリスト
  • Authorization と Content-Type ヘッダーを送信
  • type フィールドに基づいて多相アイテムを解析
  • アイテムとレスポンスの状態遷移を追跡
  • SSE を処理:event: + data: 行を解析し、[DONE] を処理
  • 外部ホスト型ツール向けのエージェントループを実装
  • 未知のアイテム型とイベント型を無視
  • 複数ターンの会話で previous_response_id をサポート
  • 1 つのレスポンス内での並列ツール呼び出しに対応

クイックリファレンス

ストリーミングイベントの種類
イベントカテゴリ
response.createdライフサイクル
response.queuedライフサイクル
response.in_progressライフサイクル
response.completedライフサイクル
response.incompleteライフサイクル
response.failedライフサイクル
response.output_item.added / .doneデルタ
response.content_part.added / .doneデルタ
response.output_text.delta / .doneデルタ
response.function_call_arguments.delta / .doneデルタ
response.reasoning_summary_text.delta / .doneデルタ
vendor:custom_eventカスタム
アイテムの種類
種類カテゴリ
messageコア
function_callコア
function_call_outputコア
reasoningコア
vendor:custom_type拡張
状態の概要
オブジェクト状態終端状態
レスポンスcreated -> queued -> in_progress -> completed / incomplete / failedcompleted、incomplete、failed
アイテムin_progress -> completed / incompletecompleted、incomplete

いずれかのアイテムが incomplete で終了した場合、それを含むレスポンスも必ず incomplete でなければなりません。

エラーの種類
種類HTTP再試行
invalid_request400いいえ
not_found404いいえ
too_many_requests429はい
server_error500はい
model_error500場合による

コメント