4.4 KiB
OpenAI Responses scheme の新設
背景
現状の crates/llm-worker/src/llm_client/scheme/openai は OpenAI Chat Completions (/v1/chat/completions) wire format のみ実装。OpenAI の Responses API (/v1/responses) はリクエスト body・SSE イベント構造ともに Chat Completions と別物で、同じ scheme には乗らない。
Codex CLI (github.com/openai/codex) の実装を確認したところ、ChatGPT OAuth 経路でも OpenAI API Key 経路でもすべて /v1/responses を叩いており、Chat Completions は使っていない。Codex 流用(別チケット llm-auth-codex-oauth)を実現する前提として、この scheme が必要。
また OpenAI 本家の最新モデル(GPT-5 系・o シリーズの reasoning)は Responses API 経由が主要な経路であり、長期的にも Chat Completions の地位は低下していく。
要件
-
scheme/openai_responsesを新設し、HttpTransport<S: Scheme>に差し込めるようにする -
リクエスト body は
/v1/responsesの item-based 形式:model,instructions(system prompt 相当),input: [ResponseItem],tools,tool_choice,parallel_tool_callsreasoning: { effort?, summary? }store,stream: true,include: [String]service_tier?,prompt_cache_key?,text?: { verbosity?, format? }previous_response_idは 使わない(stateless で運用、履歴は insomnia 側管理)
-
SSE event パース:
response.created/response.completed/response.failed/response.incompleteresponse.output_item.added/response.output_item.doneresponse.output_text.deltaresponse.custom_tool_call_input.delta(ToolCall 引数の partial JSON)response.reasoning_text.delta/response.reasoning_summary_text.delta
-
BlockType / DeltaContent との対応:
response.output_text.delta→DeltaContent::Textresponse.reasoning_text.delta/response.reasoning_summary_text.delta→DeltaContent::Thinkingresponse.custom_tool_call_input.delta→DeltaContent::InputJsonresponse.output_item.done(tool_use) →BlockMetadata::ToolUse { id, name }のBlockStart生成
-
reasoning の item 構造対応:
summary[]/encrypted_contentを持つ reasoning item の送受信をロスなく扱える- 送信時は
BlockMetadata::Thinkingからinput[]に再構築 - 受信時は
BlockType::Thinkingのブロックとしてストリームに流す
- 送信時は
-
認証は
AuthRef::ApiKeyのみ対応:Authorization: Bearer <api_key>ヘッダ。base_urlデフォルトはhttps://api.openai.com、パスは/v1/responses。ChatGPT OAuth 経路(CodexOAuth)は別チケット(llm-auth-codex-oauth)で追加 -
Usage の正規化:
response.completedのusage: { input_tokens, output_tokens, total_tokens }をUsageEventに変換。Chat Completions のprompt_tokens等との表記揺れを scheme 側で吸収 -
完了時の動作: OpenAI API key (
OPENAI_API_KEY) + モデルgpt-5等でModelConfig { scheme: OpenAIResponses, base_url: https://api.openai.com, model_id: "gpt-5", auth: ApiKey }を宣言すると、reasoning + tool call を含む会話が動作する
設計課題
1. reasoning item の encrypted_content
reasoning item の encrypted_content はサーバ側で暗号化された状態で返されることがあり、再送時にそのまま添える必要がある(ZDR 組織や store=false 運用時)。insomnia の Item enum に透過的に保持する仕組みが要る。
2. include[] と store のデフォルト
include: ["reasoning.encrypted_content"]を常に付けるか、capability / config で制御するかstore=falseをデフォルトにするかtrueにするか(ZDR 既定なら false)
3. Responses 非対応パラメータ
service_tier / prompt_cache_key / text.verbosity は当面不要かもしれないが、将来対応時に scheme 拡張で入れられる構造にしておく。
Scope 外
- ChatGPT OAuth 認証(
llm-auth-codex-oauth) previous_response_idを使う stateful 運用- 高次ツール(
web_search/code_interpreter/computer_use)— insomnia では採用しない方針
依存
tickets/llm-model-config.md(HttpTransport<S>構造とAuthRefが前提)