# Model API 协议调研：Chat Completions、Responses、Messages 与 Gemini Interactions

> **面向读者**：熟悉 LLM、Function Calling、SSE、Prompt Caching，准备自研或选型 coding-agent harness 的工程师。  
> **资料快照**：2026-10-25（Asia/Shanghai）。协议和 harness 版本变化很快，文中尽量标注日期与来源；落地前请按你锁定的版本复核。  
> **一句话结论**：Chat Completions 是兼容层，Responses / Messages / Interactions 是 agent 运行时。它们不是同一层东西；选型先问“谁持有状态、谁持有 reasoning、谁执行工具”，再问 API 长什么样。
>
> **HTML 版（排版更友好）**：[model-api-protocols-report.html](model-api-protocols-report.html)

---

## 0. TL;DR

1. **“三种协议”在今天有两种常见切法**：按厂商是 OpenAI / Anthropic / Google；按代际是 Chat Completions / Responses / Messages。本文用“3 + 1”覆盖：三个 agent-native 协议（Responses、Messages、Interactions）+ 一个兼容基线（Chat Completions）。这样无论你原本指哪三种，都不会漏。
2. **Chat Completions 仍是事实标准，但已不适合作为“推理模型 + 工具调用”的 agent 主协议**。OpenAI 文档明确：从 GPT-5.4 起，Chat Completions 在 `reasoning_effort != "none"` 时不支持工具调用；GPT-6 Astra / GPT-6.1 Sol 在 Chat Completions 上不支持 function calling。它更适合作为兼容层、简单聊天、自托管/开源模型的入口。
3. **三个 agent-native 协议已经收敛到同一组抽象**：类型化的 item/block/step、带 `call_id` 的工具调用、必须原样回传的“不透明 reasoning 状态”、语义化 SSE、可选 server-side state、内置工具。差异主要在 schema、状态归属、缓存控制、工具生态和版本策略。
4. **真正影响 agent 质量的是 reasoning round-trip，而不是消息数组长什么样**。Responses 用加密 reasoning item，Messages 用带签名的 thinking block，Interactions 用带签名的 thought step；三者都要求“原样回传、不要重排、不要编辑”。跨协议翻译最丢的正是这些，所以网关应优先 native passthrough。
5. **Harness 的默认协议由厂商绑定，形成两堵硬墙**：OpenAI Codex CLI 只接受 Responses（`wire_api="responses"` 是唯一支持值）；Claude Code / Claude Agent SDK 只接受 Anthropic Messages（以及 Bedrock/Vertex/Foundry 的 Anthropic 变体）。第三方多模型 harness 则大多“provider-native + OpenAI-compatible 兜底”，没有单一默认协议；**DeepSeek Harness（DSH）是第三种范式**：内部 provider-neutral，DeepSeek 官方 route 默认走 Messages（`/anthropic` + `/v1/messages`），其他 provider 经 pi-ai 按 catalog 原生接入，不做 Chat 归一化。
6. **选型优先级**：OpenAI 前沿模型 / Codex 风格 → Responses；Claude 生态 / thinking + 精细缓存 → Messages；Gemini / 托管 agent / 长时后台 → Interactions；多模型或自托管 → Chat Completions 作为兼容层，但接受能力上限；要同时支持多个前沿模型 → native adapters + 网关分流，不要强行统一到 Chat Completions。
7. **长时程 coding agent 还需要**：state 策略（server/client/hybrid）、compaction、prefix 稳定的缓存、SSE 代理、工具调用幂等、审批/权限。这些不是后期优化，而是协议选型的一部分。
8. **2026-10 的三个新鲜事实**：Anthropic API `2026-10-21` 移除了 `temperature/top_p/top_k`，SDK 默认改用 Bearer 认证（API 仍接受 `x-api-key`）；Gemini Interactions 于 2026-06 GA 并成为 Google 新项目推荐面；当前 Codex 版本不再支持 Chat Completions wire API。生态变化以周计，本文给的是判断框架，不是永久结论。

> **方法与证据**：以各家官方 API 文档、官方 SDK/CLI 文档、开源 harness 仓库源码、网关（LiteLLM/OpenRouter/vLLM/Ollama 等）文档为主，辅以版本发布记录；访问日期均为 2026-10-25。闭源 harness 的 wire protocol 不可直接观测，相关结论标注了证据边界。文中“默认协议”指不额外配置协议、仅提供厂商 key 时的行为。

---

## 1. 范围：到底哪“三种”？

“model-api 的三种协议”在中文技术语境里通常有两种所指：

- **按厂商**：OpenAI 的 Chat Completions、Anthropic 的 Messages、Google 的 Gemini `generateContent`。这是 2024–2025 年最常见的说法。
- **按代际**：OpenAI Chat Completions、OpenAI Responses、Anthropic Messages。这是 2025 年以后做 coding agent 的人更常说的“三种”，因为 Responses 和 Messages 才是 agent-native 的两大代表。

2026 年还多了一个不能忽略的变量：**Gemini Interactions**。Google 在 2026-06 将其 GA，并明确“所有新模型、多模态能力、工具和 agentic 特性优先在 Interactions 上线”，`generateContent` 转为 legacy 但仍完全支持。因此，只比较 Chat Completions / Responses / Messages 会把 Google 的当前默认面漏掉；只比较三家厂商又会把 OpenAI 的两代协议混为一谈。

本文因此比较 **四个 wire format**，并用“3 + 1”来读：

| 层次 | 协议 | 角色 |
|---|---|---|
| 兼容基线 | OpenAI Chat Completions | 事实标准、最大公约数、旧应用/自托管入口 |
| Agent-native | OpenAI Responses | OpenAI 当前推荐；Codex 的唯一协议 |
| Agent-native | Anthropic Messages | Claude 当前原生协议；Claude Code 的唯一协议 |
| Agent-native | Gemini Interactions | Google 当前推荐；`generateContent` 的继任者 |

> 如果你只想记“三种”，可以记：**Chat Completions（兼容层）+ Responses（OpenAI agent）+ Messages（Claude agent）**；把 Interactions 当作“Google 版的 Responses”，需要时再看第 3.4 节。

### 1.1 四个协议总览

| 维度 | Chat Completions | Responses | Messages | Interactions |
|---|---|---|---|---|
| 端点 | `POST /v1/chat/completions` | `POST /v1/responses` | `POST /v1/messages` | `POST /v1beta/interactions`（示例均用 v1beta；参考中另有 `/v1` 面） |
| 数据模型 | `messages[]` | 类型化 `input` Items | 类型化 content blocks | 类型化 `steps[]` |
| 工具调用 | assistant `tool_calls` → `role:"tool"` 消息 | `function_call` item → `function_call_output` item | `tool_use` block → `tool_result` block | `function_call` step → `function_result` step |
| 终止信号 | `finish_reason:"tool_calls"` | output 中出现 `function_call` | `stop_reason:"tool_use"` | `status:"requires_action"` |
| Reasoning | 无正式 round-trip | 加密 reasoning Items | `thinking` + `signature` | `thought` + `signature` |
| 状态 | 无状态、客户端持有 | 可选 server state（`previous_response_id` / Conversations） | 无状态、客户端持有（另有 beta compaction） | 默认 server state（`previous_interaction_id`） |
| 流式 | `chat.completion.chunk` delta | 语义化 `response.*` 事件 | 命名 SSE 事件（`message_start` 等） | step 事件（`step.start/delta/stop`） |
| 缓存 | 隐式自动 | 隐式 + 显式 breakpoint | `cache_control`（自动或显式） | 隐式（stateful 提高命中） |
| 内置工具 | 无 | 最丰富（search/file/code/computer/MCP/shell 等） | 丰富（web/code/bash/editor/computer 等） | Google 系工具 + 托管 agent |
| 生态 | 最广 | OpenAI/Codex 系 + 部分网关 | Claude 系 + 网关 + 自托管 | Google 系，第三方仍薄 |

> 说明：Chat Completions 的“无内置工具”指该 wire format 本身没有 hosted tools 的一等公民；部分厂商会在自己的兼容层里塞私有扩展，但不属于可移植协议。

---

## 2. 演进逻辑：为什么从 messages 走向 items / blocks / steps

如果把协议只看成“JSON 字段”，会觉得四家只是命名不同。真正驱动分叉的是四个工程需求：

1. **工具调用要可关联、可排序**。一次 assistant turn 可能包含多个并行工具调用，工具结果又要和调用一一对应。`messages[]` 把 tool call 塞进 assistant message、把结果塞进 `role:"tool"`，能用，但会把“模型动作”和“对话消息”混在一起。
2. **Reasoning 必须跨请求保持**。推理模型的思考 token 不可见，但又是后续工具调用和回答质量的一部分。Chat Completions 没有正式的“reasoning 状态”载体；Responses/Messages/Interactions 都把它做成一等公民，并要求原样回传。
3. **长时程 agent 需要状态、压缩和缓存**。多轮工具循环会让上下文迅速膨胀；服务端 state、compaction、prefix caching 成为协议能力，而不只是 SDK 的便利功能。
4. **内置工具把 agent loop 的一部分搬到服务端**。web search、code execution、file search、computer use、MCP 等 hosted tools 需要协议能表达“模型动作 → 服务端执行 → 结果 → 继续推理”的完整事件序列。

于是四家给出不同答案：

- **Chat Completions**：把一切压回 message，客户端负责 loop 和状态；简单、通用，但表达力最低。
- **Responses**：用 Item 联合类型表达“模型动作”，服务端可代跑内置工具，`store`/`previous_response_id` 持有状态；OpenAI 把它定位为 agent runtime。
- **Messages**：用 content block 表达“模型动作”，坚持客户端持有历史；用 `stop_reason` 驱动 loop，用 thinking signature 保证 reasoning 完整性，用 `cache_control` 给开发者精细控制。
- **Interactions**：用 step 表达“执行轨迹”，默认服务端持有历史；把模型和托管 agent 统一到同一个 `Interaction` 资源，支持 background 和长任务。

**共同收敛**：类型化单元、工具调用/结果的一等公民、不透明 reasoning 回传、语义化流式事件、hosted tools。  
**真正分歧**：状态归属、缓存控制方式、内置工具目录、版本/兼容策略、以及“谁是默认协议”。

---

## 3. 四个协议逐个拆解

### 3.1 Chat Completions：兼容层的极限

**端点与数据模型**

```jsonc
POST /v1/chat/completions
{
  "model": "gpt-6-astra",
  "messages": [
    {"role": "developer", "content": "You are a coding agent."},
    {"role": "user", "content": "Fix the failing test."},
    {"role": "assistant", "content": null,
     "tool_calls": [{"id": "call_1", "type": "function",
                     "function": {"name": "read_file", "arguments": "{\"path\":\"a.py\"}"}}]},
    {"role": "tool", "tool_call_id": "call_1", "content": "print(1)"}
  ],
  "tools": [{"type": "function", "function": {"name": "read_file", "parameters": {"type": "object"}}}],
  "tool_choice": "auto",
  "parallel_tool_calls": true,
  "reasoning_effort": "none",
  "stream": true,
  "stream_options": {"include_usage": true}
}
```

响应是 `object:"chat.completion"`，核心是 `choices[0].message`（`content`、`tool_calls`、`refusal`）和 `finish_reason`。流式时每个 SSE chunk 是 `object:"chat.completion.chunk"`，`delta.content` 或 `delta.tool_calls[]` 逐步到达，最后以 `finish_reason` 和 `data: [DONE]` 结束。

**工具循环**：客户端把 assistant 的 `tool_calls` 原样放回 messages，再为每个调用追加一条 `role:"tool"` 消息，`tool_call_id` 必须匹配；模型继续生成，直到 `finish_reason != "tool_calls"`。没有服务端内置工具，也没有正式的 reasoning 状态回传。

**状态与缓存**：完全无状态，每轮重发完整历史。自动 prefix caching 可用；GPT-5.6+ 还支持 `prompt_cache_key`、`prompt_cache_options` 和内容块级 `prompt_cache_breakpoint`（每个请求最多 4 个显式 breakpoint，TTL 目前 30m；12h 只在 Responses API 提供）。但它无法表达 thinking 状态，所以对长 agent 会话，缓存收益存在，reasoning 连续性没有。

**当前定位**：OpenAI 仍支持 Chat Completions，但明确建议新项目用 Responses。关键限制是：

- 从 GPT-5.4 起，Chat Completions 在 `reasoning_effort` 非 `none` 时不支持工具调用。
- GPT-6 Astra / GPT-6.1 Sol 在 Chat Completions 上不支持 function calling。

这意味着：**用 Chat Completions 接 OpenAI 的新一代推理模型做 coding agent，工具循环要么退化，要么根本不可用**。它仍然适合简单聊天、分类、RAG、旧应用，以及只暴露 Chat Completions 的第三方/自托管模型。

**优点**：schema 最简单、生态最广、代理/网关最好实现、对非推理模型足够。  
**缺点**：无 reasoning 连续性、无 hosted tools、无 server state、语义化流式缺失、版本演进基本冻结。  
**最大的坑**：把“OpenAI-compatible”当成“能跑 OpenAI agent”；两者不是一回事。

### 3.2 Responses：OpenAI 的 agent runtime

**数据模型**：`input` 是字符串或 Item 数组。Item 是联合类型，不只 message：

```jsonc
POST /v1/responses
{
  "model": "gpt-6-astra",
  "instructions": "You are a coding agent.",
  "input": [
    {"role": "user", "content": [{"type": "input_text", "text": "Fix the test."}]}
  ],
  "tools": [
    {"type": "function", "name": "read_file", "parameters": {"type": "object"}, "strict": true},
    {"type": "web_search"}
  ],
  "reasoning": {"effort": "medium", "summary": "auto", "context": "all_turns"},
  "text": {"format": {"type": "json_schema", "name": "patch", "schema": {"type": "object"}}},
  "store": true,
  "stream": true
}
```

核心输出是 `object:"response"` + `output: Item[]`，常见 Item 包括 `message`、`function_call`、`function_call_output`、`reasoning`、`compaction`，以及内置工具调用项（`web_search_call`、`file_search_call`、`code_interpreter_call`、`computer_call`、`mcp_call`、`shell_call` 等）。SDK 提供 `output_text` 聚合辅助，但底层必须按 Item 处理，不能假设 `output[0]` 是文本。

**工具循环**：客户端函数调用是 `function_call` item → 本地执行 → `function_call_output` item，二者用 `call_id` 关联；你可以用 `previous_response_id` 续接，也可以手工回放完整 Item 历史。三种状态模式：

1. **手工回放**：最可控，适合需要编辑/压缩历史的 harness。
2. **`previous_response_id`**：服务端持有上一条 response 的上下文，客户端只传新增输入。注意：上一轮的 `instructions` 不会自动继承，需要重发；链中所有 previous input tokens 仍按 input 计费；不能与 `conversation` 参数同时使用。
3. **Conversations API**：把对话作为持久对象管理，适合更长期的产品会话。

`store:true` 是默认行为；ZDR/隐私场景用 `store:false`，此时 reasoning item 会带 `encrypted_content`，仍可跨请求回放。**Reasoning 是 Responses 的核心差异点**：它是不可读的 opaque Item（可选的 `summary` 是可读的），官方强烈建议在工具调用时把 reasoning item 与 `function_call` 一起原样回传；`reasoning.context`（`current_turn`/`all_turns`）控制是否把历史 reasoning 渲染进下一次采样。丢弃 reasoning item 不会立刻报错，但会降低工具循环质量。

**流式**：语义化 SSE，每个事件有 `type` 和 `sequence_number`。典型事件包括 `response.created`、`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`、`response.completed/incomplete/failed`。客户端应分支处理事件，而不是只拼接文本 delta。

**长任务能力**：`background:true` 支持异步执行；WebSocket 模式支持长工具循环、多路复用和更低延迟；`context_management`/compaction 可在上下文将满时压缩。OpenAI 文档还给出“同一 prompt 下 Responses 比 Chat Completions 在 SWE-bench 上高约 3%、缓存利用率高 40%–80%”的内部评测数据；这是厂商自报，但方向与协议设计一致。

**优点**：目前最完整的 agent 原语；内置工具最多；reasoning 生命周期最完整；state/background/WebSocket 对长时程 coding agent 很实用。  
**缺点**：Item 类型多、解析复杂；OpenAI 绑定强；服务端 state 带来保留期/ZDR/数据驻留决策；部分能力按模型/账号灰度。  
**最大的坑**：把 `output` 当普通 message；回放时漏掉 reasoning item 或 assistant `phase`；用 `previous_response_id` 时又手工裁剪历史；忽略 `status:"incomplete"`。

### 3.3 Messages：Claude 的强类型、强约束协议

**数据模型**：`system` 是顶层字段；`messages` 默认是 user/assistant 交替，但也支持显式的 `role:"system"` 消息作为 mid-conversation 指令（这是 preserved thinking 下 append-only 追加指令、而不改写顶层 `system` 的机制）。`content` 是类型化 block 数组：

```jsonc
POST /v1/messages
{
  "model": "claude-opus-5-5",
  "max_tokens": 8192,
  "system": [{"type": "text", "text": "You are a coding agent.", "cache_control": {"type": "ephemeral"}}],
  "messages": [
    {"role": "user", "content": [{"type": "text", "text": "Fix the test."}]},
    {"role": "assistant", "content": [
      {"type": "thinking", "thinking": "", "signature": "EqQ..."},
      {"type": "tool_use", "id": "toolu_1", "name": "read_file", "input": {"path": "a.py"}}
    ]},
    {"role": "user", "content": [{"type": "tool_result", "tool_use_id": "toolu_1", "content": "print(1)"}]}
  ],
  "tools": [{"name": "read_file", "description": "...",
             "input_schema": {"type": "object", "properties": {"path": {"type": "string"}}}}],
  "thinking": {"type": "adaptive", "display": "summarized"},
  "stream": true
}
```

响应是 `type:"message"` + `content: Block[]` + `stop_reason`。关键 block：`text`、`image`、`document`、`tool_use`、`tool_result`、`thinking`、`redacted_thinking`、`server_tool_use` 及各种 server-tool 结果。`stop_reason` 是循环驱动信号：`tool_use` 表示要执行客户端工具，`end_turn` 表示结束，`pause_turn` 表示服务端工具循环暂停需续传，`max_tokens`/`refusal`/`model_context_window_exceeded` 各自处理。

**工具循环**：`stop_reason == "tool_use"` 时，执行每个 `tool_use`，把 assistant 的完整 content 原样放回，再追加一条 user 消息，内含每个调用的 `tool_result`（`tool_use_id` 匹配）。**在工具调用回合中，thinking block 必须完整、未修改地回传**；过滤掉 thinking 只留 tool_use 会破坏协议。服务端工具（web search、code execution 等）不同：`server_tool_use` 在 Anthropic 服务端 loop 内执行，结果直接出现在同一 assistant turn 中，客户端不需要构造 `tool_result`；如果 loop 达到上限，会返回 `pause_turn`，客户端把暂停内容原样带回继续。

**Thinking 与 preserved thinking**：Claude 5 代模型（如 Opus 5/Sonnet 5.5）默认开启 adaptive thinking；thinking block 带 `signature`，可以 `display:"summarized"` 或 `"omitted"`。规则比另外两家更严：

- 工具回合内，thinking block 的顺序和内容必须与模型生成时一致；修改会 400。
- 跨回合建议全部回传，API 会按模型策略过滤/保留。
- 2026-08-31 后创建的新账号默认启用 preserved-thinking 前缀校验：顶层 `system`、`tools` 或更早 messages 变化会使该 thinking block 及其后的 block 失效（400 或丢弃，取决于配置）。因此 **append-only 历史**是硬要求。
- thinking 配置和 effort 会参与 prompt 渲染，改动会破坏 prefix cache。

**缓存**：`cache_control` 是 Messages 最有辨识度的能力。可以顶层自动缓存（自动把 breakpoint 放到最后一个可缓存 block），也可以在每个 block 上显式标记，最多 4 个 breakpoint；顺序是 `tools → system → messages`，默认 5 分钟 TTL，可付费升到 1 小时。缓存命中要求前缀稳定，所以“追加而非改写”是使用 Messages 的第一原则。

**流式**：命名 SSE 事件：`message_start` → 每个 block 的 `content_block_start`/`content_block_delta`/`content_block_stop` → `message_delta` → `message_stop`，其间可能有 `ping`。delta 类型包括 `text_delta`、`input_json_delta`（tool input 的部分 JSON）、`thinking_delta`、`signature_delta`。HTTP 200 之后仍可能收到 `event: error`（如 `overloaded_error`），需要流内错误处理。

**版本与兼容**：`anthropic-beta` 是逗号分隔的 beta 开关，很多能力（MCP connector、compaction、context editing、preserved-thinking controls）仍在 beta。2026-10-21 版本做了破坏性变更：移除 `temperature/top_p/top_k`，SDK 默认改用 `Authorization: Bearer` 而不是 `x-api-key`。老版本 `2023-06-01` 仍可用，但新集成应锁定当前版本并升级 SDK 主版本。Anthropic 提供 OpenAI SDK 兼容层（base URL `https://api.anthropic.com/v1/`），但它是“测试/评估用”的 Chat Completions 翻译：prompt caching 不支持、thinking 不返回、`strict`/`response_format`/`logprobs` 等字段被忽略。

**优点**：类型最干净；reasoning 完整性最强；显式缓存控制最成熟；server tools + MCP 覆盖广；企业/ZDR 选项完整。  
**缺点**：客户端持有状态，回放代码自己写；preserved thinking 的 prefix 约束很硬；beta 多；新版破坏性变更需要跟进；没有 Responses 那种持久 Conversation 对象（compaction 仍是 beta）。  
**最大的坑**：改历史、改 tools/system、丢 thinking、把 server tool 当 client tool、在工具回合中途 toggle thinking。

### 3.4 Interactions：Google 的“模型 + 托管 agent”统一面

**数据模型**：一个 `Interaction` 表示一个完整 turn/task，包含 `steps[]`：

```jsonc
POST /v1beta/interactions
{
  "model": "gemini-3.8-flash",          // 或 "agent": "deep-research-..." / "antigravity-..."
  "input": "Fix the failing test.",
  "system_instruction": "You are a coding agent.",
  "tools": [
    {"type": "function", "name": "read_file", "parameters": {"type": "object"}},
    {"type": "google_search"},
    {"type": "code_execution"}
  ],
  "generation_config": {"thinking_level": "medium", "max_output_tokens": 65536},
  "previous_interaction_id": null,
  "store": true,
  "stream": true
}
```

响应是 `object:"interaction"` + `status` + `steps[]`。Step 类型包括 `user_input`、`thought`、`model_output`、`function_call`、`function_result`，以及 `google_search_call/result`、`url_context_call/result`、`code_execution_call/result`、`file_search_call/result`、`mcp_server_tool_call/result` 等服务端工具 step。`status:"requires_action"` 表示模型发出了需要客户端执行的 `function_call`。

**工具循环**：执行 `function_call` 后，发新请求，`input` 里放 `function_result` step（`call_id` 匹配），并带 `previous_interaction_id`；`tools`/`system_instruction`/`generation_config` 是 interaction-scoped，每轮都要重新指定，不会随 `previous_interaction_id` 继承。Stateless 模式（`store:false`）必须回放完整历史，包括所有 `thought`/`function_call` step 和签名；漏掉签名会报 `missing_thought_signature`。

**状态与后台**：默认 `store:true`；付费层保留约 55 天，免费层约 1 天（可在 AI Studio 配置更短保留）。`previous_interaction_id` 只保留历史，不保留 tools/config。`background:true` 用于长任务、Deep Research、长 decode，要求 `store:true`；返回 interaction id 后可轮询/重连/取消。托管 agent（Deep Research、Antigravity）和普通 Gemini 模型共用同一 API 面，这是 Interactions 相对另外两家的独特定位。

**Thinking**：`thought` step 带必填加密 `signature` 和可选 `summary`；`thinking_level` 控制力度。stateful 模式由服务端管理签名；stateless 模式必须原样回传所有 thought 和内置工具签名。`max_output_tokens` 包含 thinking token，撞上限会 `status:"incomplete"` 但仍计费，遇到这种情况优先降 `thinking_level` 而不是硬加 token。

**流式**：SSE 事件为 `interaction.created`、`interaction.status_update`、每个 step 的 `step.start/delta/stop`、`interaction.completed`、`error`。delta 类型包括 `text`、`image`、`audio`、`thought_summary`、`thought_signature`、`arguments_delta`。注意 `interaction.completed` 可能不包含完整 `steps`，客户端要么自行组装，要么 `GET` 回读；断线可用 `last_event_id` 续传。官方文档对生命周期事件命名仍有不一致，生产客户端应忽略未知 `event_type` 并以实际端点为准。

**与 generateContent 的关系**：`generateContent` 仍是完全支持的 legacy 面，适合 batch、已有集成和 Python 自动函数调用；explicit caching 仅对部分 Gemini 3/2.5 模型可用，Gemini 4 Argon 起不再支持（Interactions 也一律只有 implicit caching）。多数第三方 harness 目前仍只接 `generateContent`，这是 Gemini 生态当前最大的“协议代差”。

**优点**：模型/agent 统一；step 可观测性好；默认 server state 对多轮和缓存友好；background/长任务/多模态最强；Google grounding 工具原生。  
**缺点**：新、变化快（2026 年有过 schema breaking change）；第三方 harness 支持薄；默认存储带来数据保留决策；部分能力（batch、explicit caching）不在 Interactions；文档在 v1/v1beta、事件命名上仍有不一致。  
**最大的坑**：以为 `previous_interaction_id` 会继承 tools/system；stateless 回放漏 thought/signature；把 completed stream 当完整 steps；忽略 `status:"incomplete"`。

### 3.5 一页纸优缺点（含 Chat Completions）

| 协议 | 核心优势 | 主要代价 | 最适合 | 不建议 |
|---|---|---|---|---|
| **Chat Completions** | 最简单、生态最广、代理/网关最易实现、几乎所有模型都支持 | 无 reasoning round-trip、无 hosted tools、无 server state、新 OpenAI 推理模型工具调用受限 | 旧应用、简单聊天/分类/RAG、自托管/开源模型、兼容性入口 | 用 OpenAI 新推理模型做长时程工具循环 |
| **Responses** | 最完整的 agent runtime：Items、hosted tools、state、compaction、background/WebSocket | 复杂度高、OpenAI 绑定强、默认存储需处理 ZDR/保留期、按模型灰度 | OpenAI-first coding agent、长时程/多工具任务、需要 hosted search/code/MCP | 要求强可移植、或只用非 OpenAI 模型 |
| **Messages** | 类型干净、thinking 完整性最强、cache_control 精细、server tools/MCP 成熟 | 客户端持有状态、preserved-thinking 前缀约束硬、beta 多、新版有破坏性变更 | Claude-first coding agent、企业网关、长缓存会话、需要精细控制成本 | 频繁重写历史/工具列表、不能接受 400 约束的快速原型 |
| **Interactions** | 模型+托管 agent 统一、step 可观测、默认 state/缓存友好、background/多模态强 | 新、生态薄、默认存储、batch/explicit caching 缺失、文档仍在收敛 | Gemini-first coding agent、Deep Research/Antigravity、长时后台任务 | 需要成熟第三方 harness、或要求 explicit cache/batch 的场景 |

---

## 4. 横向对比：真正的差异在哪里

### 4.1 状态归属：server state 不是免费午餐

| 协议 | 默认状态 | 续接方式 | 历史可编辑性 | ZDR/数据驻留 | 跨 provider failover |
|---|---|---|---|---|---|
| Chat Completions | 客户端 | 重发全部 messages | 完全可控 | 最容易 | 最容易（但丢 reasoning） |
| Responses | 服务端（可 `store:false`） | `previous_response_id` / Conversations / 手工回放 | stateful 模式受限；stateless 可控 | 需显式 `store:false` + 加密 reasoning | 需回放 Item；reasoning 不可跨 provider |
| Messages | 客户端 | 重发全部 messages | 可控，但 preserved thinking 要求 append-only | 最容易 | 需处理 thinking 签名，跨 provider 不可用 |
| Interactions | 服务端（可 `store:false`） | `previous_interaction_id` | stateful 模式受限；stateless 可控 | 默认存储需配置保留期 | 需回放 steps；thought 签名不可跨 provider |

**判断规则**：

- 如果你的 harness 需要**压缩、分支、重写历史、删敏感内容**，客户端状态（Chat/Messages，或 Responses/Interactions 的 stateless 模式）更合适。
- 如果你更看重**缓存命中、reasoning 连续性、少写回放代码**，server state 更合适，但要把 retention、ZDR、数据驻留、provider failover 作为一等约束。
- **混合模式**是常见折中：本地保存完整 transcript 作为 source of truth，同时用 server state 加速；一旦需要编辑历史，就退回 stateless 回放。

### 4.2 Reasoning round-trip：协议选型的胜负手

| 协议 | Reasoning 载体 | 回传要求 | 典型失败 |
|---|---|---|---|
| Chat Completions | 无（仅 usage 里的 reasoning tokens） | 无 | 多轮后推理不连续；新模型工具调用受限 |
| Responses | `reasoning` Item，含 `encrypted_content` | 与 `function_call` 一起回传；不要漏、不要改 | 工具循环质量下降；`previous_response_id` 与手工回放混用造成上下文重复/浪费与重复计费 |
| Messages | `thinking` / `redacted_thinking` block + `signature` | 工具回合内必须完整原样回传；跨回合建议全部回传 | 修改/重排导致 400；prefix 变化导致 preserved thinking 失效 |
| Interactions | `thought` step + `signature` | stateful 自动；stateless 必须原样回放所有 thought | `missing_thought_signature`；静默丢 reasoning 导致质量下降 |

**结论**：reasoning 是 **provider-scoped、model-family-scoped 的不透明状态**。它不能被翻译成另一家的字段，也不能在 fallback 时复用。任何“统一协议”的网关，如果为了兼容而丢掉 reasoning，都会在短对话里看起来正常、在长工具循环里暴露质量差距。这是本调研最重要的工程结论。

### 4.3 工具循环：形状不同，语义可以对齐

| 协议 | 调用载体 | 结果载体 | 关联键 | 并行 | 服务端工具 |
|---|---|---|---|---|---|
| Chat Completions | assistant `tool_calls[]` | `role:"tool"` message | `tool_call_id` | `parallel_tool_calls` | 无 |
| Responses | `function_call` Item | `function_call_output` Item | `call_id` | 有；`max_tool_calls` 限制单次 response 内置工具调用总数，并行由 `parallel_tool_calls` 控制 | 有，内置工具在单次 response 内循环 |
| Messages | assistant `tool_use` block | user `tool_result` block | `tool_use_id` | 有 | 有，`server_tool_use` 在服务端 loop |
| Interactions | `function_call` step | `function_result` step | `call_id` | 有 | 有，Google 工具/托管 agent |

**实现建议**：内部统一成 `ToolCall { id, name, arguments }` / `ToolResult { id, output, isError }`，但**不要把 assistant turn 拆散**。在 Messages 中这意味着 assistant content 必须整块保留；在 Responses 中意味着 reasoning item 必须和 function_call 一起保留；在 Interactions 中意味着 thought step 必须保留。工具循环的难点不是字段映射，而是“调用与结果之间的模型状态不能被丢掉”。

### 4.4 流式：从“token delta”到“状态机事件”

| 协议 | 传输 | 事件模型 | 文本 | 工具参数 | Reasoning | 终止 |
|---|---|---|---|---|---|---|
| Chat Completions | SSE | 统一 chunk | `delta.content` | `delta.tool_calls[].function.arguments` 片段 | 无 | `finish_reason` + `[DONE]` |
| Responses | SSE | 语义事件 | `response.output_text.delta` | `response.function_call_arguments.delta` | `response.reasoning_summary_text.delta` | `response.completed/incomplete/failed` |
| Messages | SSE | 命名事件 + block index | `content_block_delta` 的 `text_delta` | `input_json_delta` | `thinking_delta` + `signature_delta` | `message_delta` + `message_stop` |
| Interactions | SSE | step 事件 | `step.delta` 的 `text` | `arguments_delta` | `thought_summary` / `thought_signature` | `interaction.completed` |

**取舍**：

- Chat Completions 的流最好写，但信息最少；工具参数要自己累积 partial JSON。
- Responses 的事件最丰富，适合做细粒度 UI/trace，但客户端要写事件状态机，且事件类型会增长。
- Messages 的 block 索引模型最稳定，适合“文本/thinking/tool 三线并流”的 UI；但要处理 `ping` 和流内 `error`。
- Interactions 的 step 模型天然适合展示“执行轨迹”，但生态和文档仍在收敛。

**代理层注意**：所有 SSE 都必须关闭 buffering/compression，保证 `text/event-stream`，转发 `ping`/keep-alive，读超时要大于最长 thinking 时间；否则 agent 会“看起来卡死”。

### 4.5 缓存：协议决定了你能不能稳定命中

| 协议 | 机制 | 控制粒度 | 典型 TTL | 前缀失效条件 |
|---|---|---|---|---|
| Chat Completions | 隐式自动；GPT-5.6+ 支持显式 breakpoint | `prompt_cache_key`、`prompt_cache_options`（新模型）；内容块级 `prompt_cache_breakpoint` | 30m（新模型）；旧模型 `in_memory`/24h | system/tools/历史变化 |
| Responses | 隐式 + 显式 breakpoint | `prompt_cache_key`、`prompt_cache_options` | 模型相关（新模型 30m/12h；旧模型最高 24h） | 指令、工具、reasoning 配置、历史变化 |
| Messages | 顶层自动或 block 级 `cache_control` | 最多 4 个显式 breakpoint | 5m/1h | `system`/`tools`/历史/thinking 配置变化 |
| Interactions | 隐式 | 无显式缓存控制（Interactions 暂不支持 explicit caching） | 平台管理 | 历史/工具/配置变化；stateful 更易命中 |

**工程含义**：

- 缓存不是“省钱技巧”，而是**历史不可变**的约束。你一旦决定用 Anthropic 显式缓存或 OpenAI 显式 breakpoint，就必须保证工具列表、system、thinking 配置稳定，历史 append-only。
- server state（Responses/Interactions）通常更容易获得高缓存命中，因为服务端持有规范历史；但这也意味着你放弃了部分历史编辑能力。
- Chat Completions 的自动缓存对简单应用足够；新模型的 key/breakpoint 也能做显式控制，但它仍无法解决 reasoning 状态丢失的问题。

### 4.6 内置工具、多模态、结构化输出

| 能力 | Chat Completions | Responses | Messages | Interactions |
|---|---|---|---|---|
| 内置 web/file/code/computer | 无 | 全面 | 全面 | Google 系工具 + 托管 agent |
| MCP | 无（靠客户端） | 有 remote MCP | MCP connector（beta） | 有 MCP server tool（支持范围有版本/模型限制） |
| 图片/PDF/音频/视频 | 图片/音频/文件 | 图片/文件（音频输入按模型/端点核实） | 图片/PDF/文档 | 图片/音频/视频/文档 |
| 结构化输出 | `response_format` | `text.format` | `output_config.format` | 顶层 `response_format` |
| 后台/长任务 | 无 | `background` + WebSocket | 无（流式 + pause_turn） | `background` + 长 decode |
| 服务端压缩 | 无 | compaction | beta compaction/context editing | 无内置 compaction；靠 server state + 客户端上下文管理 |

**判断**：如果你需要“开箱即用的 search/code/computer/MCP”，Responses 和 Messages 更成熟；如果你需要 Google Search/Maps/URL context 或托管 Deep Research/Antigravity，Interactions 更合适。Chat Completions 适合“工具由 harness 自己实现”的场景。

### 4.7 兼容层：翻译一定会丢东西

| 入口 → 目标 | 常见实现 | 会丢什么 |
|---|---|---|
| Chat → Responses | 网关翻译 | signed/encrypted reasoning、hosted tools、state、语义化事件；reasoning 文本可近似映射，签名/加密 reasoning 不可 |
| Responses → Chat | 网关/兼容层 | 内置工具、reasoning item、`previous_response_id`、compaction、事件语义 |
| Messages → Responses | LiteLLM 等 | thinking signature、cache_control、beta 字段；server tools 中 web_search 可映射，其余多丢失；thinking 可能被当普通文本 |
| Messages → Chat | 网关 | thinking、cache、server tools、`stop_reason` 语义、block 顺序 |
| Gemini Interactions → Chat | 网关 | thought step/signature、step 轨迹、background、托管 agent、Google 工具 |
| 任意 → Bedrock Converse / Vertex 归一化层 | 云厂商 | 请求侧额外参数走 `additionalModelRequestFields`，响应侧模型原生字段走 `additionalModelResponseFieldPaths` 回取；签名/缓存/thinking 的语义被归一化（如 Converse 的 reasoning signature 需全量回放，cachePoint 与 Anthropic `cache_control` 不等价）；Vertex 的 OpenAI-compat 层没有等价透传；Claude 在 Agent Platform 上仍可用原生 `rawPredict` 保真 |

**重要区分**：

- **OpenAI-compatible ≠ Responses-compatible**。绝大多数“OpenAI-compatible”端点只实现 `/v1/chat/completions`，不实现 `/v1/responses`。Codex 需要后者。
- **Anthropic OpenAI SDK compatibility** 是 Chat Completions 形状的翻译层，官方明确说明它主要用于测试/评估，不是生产首选；thinking、caching、strict schema 等都不完整。
- **Gemini OpenAI compatibility** 也是 Chat Completions 形状（`/v1beta/openai/`），不是 Interactions；它仍是 beta。
- **Bedrock/Vertex** 同时提供“原生格式”和“归一化格式”。Claude Code 走的是原生 Anthropic 格式（InvokeModel/rawPredict），不是 Converse。

### 4.8 常见失败模式

| 现象 | 根因 | 处理 |
|---|---|---|
| 400 “unexpected field” / beta 不生效 | header 与 body 字段未成对转发 | 网关原样透传 `anthropic-beta` + body；不要重写请求 |
| 400 thinking block 不能修改 / 前缀失效 | 编辑了历史、重排了 thinking、改了 system/tools | append-only；保留原始 assistant turn；必要时降级为无 thinking |
| 400 `previous_response_id` 不支持 | 目标是 stateless-only 网关（如 OpenRouter Responses） | 改用完整历史回放；或换支持 state 的上游 |
| 404 Codex 连不上 | 端点只有 Chat Completions | 网关补 `/v1/responses`；不要只做 Chat 翻译 |
| 流式卡住/超时 | SSE buffering、压缩、keep-alive 丢失、读超时太短 | 关闭 buffering；转发 ping；加大 idle timeout；测试生产代理 |
| 工具参数 JSON 解析失败 | 流式 partial JSON 未累积完 | 等 `content_block_stop`/`arguments.done` 再整体解析；容错重试 |
| 工具被重复执行 | 重试/重连重放 | 用 call id 做幂等/去重；副作用工具加审批/幂等键 |
| 缓存命中率低 | 动态 system/时间戳/工具列表变化 | 把稳定内容前置；append-only；固定 tools/system 版本 |
| 上下文超限 / 输出截断 | 未使用 compaction/truncation | 用 Responses compaction、Messages context editing、Interactions 的长上下文/客户端总结；`background` 只解决长时执行/连接超时，不解决输入 context 超限；处理 `incomplete` |

---

## 5. Coding-agent harness 的支持矩阵

### 5.1 怎么读这张表

- **默认协议**：不给特殊配置、只用厂商 key 时，harness 走哪条 wire format。
- **native**：harness 自己实现了该协议适配（能保留 reasoning/cache/hosted tools 等能力）。
- **via gateway/shim**：通过 LiteLLM、OpenAI-compatible 端点或翻译层接入，通常有损。
- **“OpenAI-compatible”默认指 Chat Completions**，不是 Responses。这是 2026 年最常见的误判。
- 本表是“代表性快照”，不是穷举；闭源 harness 的 wire protocol 经常不可观测，表里会标注证据限制。

### 5.2 厂商自有 harness：协议墙最硬

| Harness | 厂商 | 默认协议 | 支持范围 | 自定义端点 | 备注 |
|---|---|---|---|---|---|
| **OpenAI Codex CLI** | OpenAI | **Responses only** | Responses；**推断**内置 OpenAI/Ollama/LM Studio 也走 Responses 端点（Ollama/LM Studio 需提供 `/v1/responses`） | `~/.codex/config.toml` 的 `model_providers.<id>`；`wire_api` 仅接受 `"responses"` | `wire_api="chat"` 已不支持；只实现 Chat Completions 的网关无法服务 Codex |
| **Claude Code** | Anthropic | **Messages only** | Anthropic Messages；Bedrock InvokeModel；Vertex `rawPredict`；Foundry/Claude Platform on AWS | `ANTHROPIC_BASE_URL` + token；`CLAUDE_CODE_USE_BEDROCK`/`CLAUDE_CODE_USE_VERTEX` | 没有 OpenAI 格式模式；网关必须暴露 Messages/Bedrock/Vertex 三者之一 |
| **Claude Agent SDK** | Anthropic | **Messages** | 同 Claude Code | `ANTHROPIC_BASE_URL`；SDK options | 包装 Claude Code 运行时，协议墙相同 |
| **Gemini CLI** | Google | **generateContent** | Gemini API / Vertex / Code Assist；无 OpenAI 兼容、无 Interactions | `GEMINI_API_KEY`、Vertex 环境变量、Code Assist 登录 | 2026-06-18 起免费/Google One 层由 Antigravity CLI 接替；仍可作 legacy 参考 |
| **Antigravity CLI** | Google | Google 托管后端 | Gemini；**通过 Google 提供的 partner Claude**；SDK 可用 LiteRT/OpenAI-compatible 本地模型 | 无 BYOK base URL；`GEMINI_API_KEY` 直连 Gemini API；`modelProvider` 仅 `"gemini"` | Google 账号锁定；ToS 禁止第三方复用登录；确切 Gemini API 面未文档化（不确定） |
| **GitHub Copilot CLI** | GitHub | GitHub 托管后端 | 托管模型；BYOK：`openai`（默认，Chat Completions）、`azure`、`anthropic`（Messages）；有 `COPILOT_PROVIDER_WIRE_API` | `COPILOT_PROVIDER_BASE_URL/TYPE/API_KEY/WIRE_API` 等 | 托管后端不可观测；BYOK 明确要求原生 tool calling + streaming |
| **Cursor** | Anysphere | 内部后端 | 所有请求经 Cursor 服务器；BYOK 仅 provider key，不暴露 wire protocol；OpenAI BYOK 限“标准非推理 chat 模型” | Settings → API keys | 闭源，协议不可观测；“自定义 API key 只对 chat 模型生效” |
| **Amp** | Amp（Sourcegraph 系，闭源） | Amp 托管 + 连接路由 | API key（Anthropic/Google/OpenAI/xAI 等）、订阅、Bedrock/Vertex/Foundry、OpenAI/Anthropic-compatible 自定义 URL | Settings → Model Routing；CLI `amp config model-providers` | 具体 wire protocol 不公开；默认 Amp 托管 |
| **Warp** | Warp | Warp 托管 | BYOK OpenAI/Anthropic/Google；自定义 OpenAI-compatible（Chat Completions）；订阅 | `/api-keys`；自定义 inference endpoint | 闭源，provider 级协议不公开 |

**读法**：Codex 和 Claude Code 是两堵硬墙，分别只接受 Responses 和 Messages。想用一个网关同时服务它们，网关必须**原生**提供 `/v1/responses` 和 `/v1/messages` 两个入口，而不是只做 Chat Completions 翻译。

### 5.3 多模型 harness（以开源为主，含少数闭源 BYOK）

| Harness | 默认协议 | 支持范围 | 自定义/网关 | 备注 |
|---|---|---|---|---|
| **DeepSeek Harness (DSH)** | DeepSeek 官方 route 走 **Messages**；其他 provider 经 pi-ai 按 catalog native | DeepSeek `https://api.deepseek.com/anthropic` 的 `/v1/messages` + Files API；pi-ai：OpenAI Responses/Completions、Anthropic Messages、Google `google-generative-ai`；自定义 route 仅 `openai-completions` / `openai-responses` / `anthropic-messages`；**无 Gemini Interactions** | `$DSH_HOME/profiles/<profile>/cordis.patch.yml`；`deepseek-official` / `deepseek-account`；`dsh-llm-pi-ai` 的 `providers` | 内部 `dsh-llm` provider-neutral，adapter 拥有 wire；MIT、开发预览；当前安装 0.2.1-rc.2 |
| **Cline** | 按 provider：OpenAI→Responses；Anthropic→Messages；Google→generateContent | 另支持 OpenAI-compatible（Chat）、Bedrock/Vertex/Ollama、Codex/Claude 订阅 | 每 provider key + base URL；`openai-compatible` provider | 源码里 OpenAI 走 `provider.responses`，Anthropic 用 AI SDK Anthropic，Google 用 `createGoogleGenerativeAI` |
| **Kilo Code** | 未知端点默认 **Chat Completions** | 显式 Provider API：OpenAI Compatible（Chat，默认）、OpenAI Responses、Anthropic Messages；Gemini 走 Google AI | Provider 设置/自定义 base URL；`@ai-sdk/*` 每协议包 | 少数把“协议”做成显式选项的 harness |
| **OpenCode** | AI SDK + Models.dev；OpenAI 默认 Responses | OpenAI Responses/Chat、Anthropic Messages、Gemini generateContent、Google Interactions、各厂商 responses/messages 路由 | `provider.<id>.options.baseURL`；自定义 provider `npm: "@ai-sdk/openai-compatible"` | 75+ provider；OpenAI 主路由默认 `.responses()` |
| **Continue** | 多数 **Chat Completions** | OpenAI 的 Responses 只对 o-series/GPT-5+ 做“minimal draft”；Anthropic Messages；Gemini generateContent | `config.yaml` 的 provider/model/apiBase | 典型的“provider adapter + 兼容优先”实现 |
| **Goose** | provider-native：OpenAI Chat、Anthropic Messages、Gemini generateContent | ChatGPT/Codex 订阅走 Responses；Bedrock/Vertex/Azure/Databricks/LiteLLM/兼容端点 | `goose configure`；`OPENAI_HOST`/`ANTHROPIC_HOST`/`LITELLM_HOST` | Rust provider crates 按厂商实现 |
| **Crush** | provider 类型：`openai` / `openai-compat` / `anthropic` / `google` | OpenAI 路由可 Responses（ChatGPT OAuth 走 Responses）；`openai-compat` 是 Chat；Anthropic Messages；Google generateContent | `crushrc`；`provider add --type ... --base-url` | “openai”和“openai-compat”明确区分，值得借鉴 |
| **Zed Agent** | 按模型 `protocol`；自定义 provider 默认 `openai_chat` | 显式枚举：`anthropic`、`openai_responses`、`openai_chat`、`google` | `settings.json` 的 `language_models.*`：`api_url`、`protocol`、`capabilities` | 少数把四协议都做成 per-model 选项的编辑器 |
| **Aider** | **Chat Completions**（LiteLLM，harness 侧）；出站按 provider 原生 | 通过 LiteLLM 接 Anthropic Messages、Gemini、OpenRouter 等；自定义端点默认 Chat | `OPENAI_API_BASE`；`--model provider/model`；`--api-key provider=key` | 经典 LiteLLM 架构；Responses 支持是间接/版本相关 |
| **OpenHands** | **Chat Completions**（LiteLLM，harness 侧）；出站按 provider 原生 | LiteLLM 支持的 provider；Agent SDK 部分有 Responses stream 处理；ACP 可委派 Claude Code/Codex | model string + Base URL + key；LiteLLM proxy | “能接任何 LiteLLM 模型”；harness 入口是 Chat 形状，但上游可能是 Messages/generateContent |
| **SWE-agent** | **Chat Completions**（LiteLLM，harness 侧）；出站按 provider 原生 | LiteLLM 支持的 provider；研究/benchmark 导向 | YAML model config；`api_base` | 协议由 LiteLLM 中介，原生 reasoning/cache 能力受限 |
| **Factory Droid** | 按显式 provider 类型 | `anthropic`=Messages；`openai`=Responses；`generic-chat-completion-api`=Chat；`bedrock-converse`=Converse | `~/.factory/settings.json` 的 `customModels[]`：`baseUrl`、`provider`、`authMode` | 少数闭源 harness 公开“provider→API 格式”映射 |
| **Roo Code**（历史） | OpenAI Chat / Anthropic Messages / Gemini generateContent | OpenAI-compatible Chat；原生工具调用 | Provider 设置 | 2026-05-15 已停止维护、仓库归档；仅作历史参考 |

**读法**：

- **“支持某模型”≠“支持该模型的 native 协议”**。Aider/OpenHands/SWE-agent 通过 LiteLLM 可以“支持 Claude”，但 harness 入口是 Chat Completions，LiteLLM 出站才会转成 Messages/generateContent；thinking/cache 等能力是否保留取决于 LiteLLM 的翻译，而非 harness 自己。
- **同一 harness 对不同 provider 可能用不同协议**。Cline/OpenCode/Goose/Crush 都是典型：OpenAI 走 Responses，Anthropic 走 Messages，Google 走 generateContent。
- **显式协议开关很重要**。Kilo/Zed/Factory/Copilot CLI/Crush 允许你按端点选择协议；这对自建网关最友好。

### 5.3.1 DeepSeek Harness：provider-neutral + native adapter 的样本

DSH 值得单独看：它既不是“把所有 provider 归一化成 Chat Completions”，也不是简单包一层 SDK，而是 **provider-neutral LLM service + per-protocol adapter + replay envelope**。这恰好是本文推荐的架构方向。

> **常见误解**：`dsh-llm-pi-ai` 不是 Pi harness。Pi 是 Earendil Works 的独立 coding agent harness（`pi-coding-agent` / `pi-agent-core` / TUI）；`@earendil-works/pi-ai` 是它拆出来的多 provider LLM 库。DSH 只依赖这个库，并用自己的 agent loop/tools/session；`dsh-llm-pi-ai` 是把 pi-ai 的 provider/auth/catalog/stream 事件适配到 `dsh-llm` 的插件。两者共享模型层，但不是同一个 harness，也不是 fork。

- **内部抽象**：`@deepseek-ai/dsh-llm` 定义 canonical message / content block / stream chunk，adapter 只负责把自家 wire 翻译成这套词汇；模型可见输入必须能由 session log 重建（“model-visible ⟺ logged”），replay 状态只在同一个 adapter 实例内流转。DSH 没有“内部统一走 Chat Completions”这一层。
- **DeepSeek 官方 route**：`dsh-llm-deepseek` 是 **Messages transport**，默认 base URL 为 `https://api.deepseek.com/anthropic`，请求追加 `/v1/messages`、文件走 `/v1/files`；它把 thinking/tool calls/tool results 作为 content block 发送，reasoning effort 走 `output_config.effort`，图片走 Files 引用或 inline base64，并把 DeepSeek 的 cache-hit 指标映射到 harness usage。DeepSeek 自家 route 有 `deepseek-official`（API key）和 `deepseek-account`（账号登录）两种。
- **多 provider route**：`dsh-llm-pi-ai` 通过 pi-ai catalog 接 OpenAI、Anthropic、Google、DeepSeek 等；catalog 中各模型保留自己的 native protocol。**手写自定义 route 只支持** `openai-completions`、`openai-responses`、`anthropic-messages` 三种；Google 走 catalog 的 `google-generative-ai`（即 `generateContent`），**不支持 Gemini Interactions**。
- **为什么 DeepSeek 选 Messages**：DeepSeek API 自己同时提供三种表面——Chat Completions（`https://api.deepseek.com`）、Responses（`https://api.deepseek.com`，stateless）、Anthropic Messages（`https://api.deepseek.com/anthropic`）。DSH 的官方 route 选的是 Messages；从 wire 形状看，Messages 的 block 模型能表达 thinking、tool_use/tool_result 和图片 Files，比 Chat Completions 更接近 DSH 的内部 block 词汇。但这并不意味着 DeepSeek 的 Messages 兼容面是完整的 Anthropic：`cache_control`、MCP、`document`、`redacted_thinking` 等并不支持，`thinking.budget_tokens` 会被忽略，只有 `output_config.effort` 生效。
- **对使用者的含义**：用 DSH + DeepSeek 时，你实际在跑 Messages，不是 Chat Completions；要接 OpenAI/Anthropic/Google，走 pi-ai profile；要接一个 OpenAI-compatible 网关，自定义 route 用 `api: openai-completions`；要接 DeepSeek 的 Responses 面，自定义 route 用 `api: openai-responses`，但记住它是 stateless（不支持 `previous_response_id`/`store`/`background`）。要接 Gemini Interactions，当前 DSH 没有现成路径，需要新增 adapter/插件。

**代价**：adapter 数量多、每个 provider 的能力差异要单独维护；好处是 reasoning/cache/tool 语义不被 Chat 归一化截断。DSH 是这个取舍的一个清晰样本，而不是“又一个多模型 harness”。

> 另外，DeepSeek 在 2026-10-20 开源了 DeepInfer + deepseek-recipe；后者是官方 PE/协议层的参考实现，用 Rust 代码替代 Jinja 渲染 prompt，详见 [deepseek-recipe PE 代码调研](deepseek-recipe-pe-code-review.md)。

### 5.4 Agent SDK / 框架

| SDK/框架 | 默认协议 | 其他协议 | 说明 |
|---|---|---|---|
| **OpenAI Agents SDK** | Responses | Chat Completions（`OpenAIChatCompletionsModel` / `set_default_openai_api("chat_completions")`） | 推荐 Responses；Responses-only 工具特性在 Chat 路径会被拒绝或丢弃 |
| **Claude Agent SDK** | Messages | Bedrock/Vertex/Foundry 变体 | 包装 Claude Code 运行时；`ANTHROPIC_BASE_URL` 可接网关 |
| **Google ADK** | Gemini generateContent | Interactions（`use_interactions_api=True` 显式开启）；Claude/OpenAI/LiteLLM 连接器 | 默认仍是 generateContent，Interactions 是 opt-in |
| **Vercel AI SDK** | 按 provider：OpenAI Responses（v5+）、Anthropic Messages、Google generateContent | OpenAI Chat（`openai.chat`）、Google Interactions（`google.interactions`）、OpenAI-compatible（Chat） | 统一抽象做得好；但“默认协议”随 provider 和 SDK 大版本变化 |
| **LiteLLM** | 网关，不是 harness | 入口：Chat/Responses/Messages/Gemini/Interactions/Bedrock；出口：100+ provider | 能做协议翻译，但有损；重要流量应 native passthrough |

### 5.5 按协议反查：谁“必须”什么

**必须 Responses（硬要求）**

- OpenAI Codex CLI。`wire_api` 只接受 `"responses"`；只实现 Chat Completions 的端点会被拒绝。

**Responses 为默认（可切 Chat）**

- OpenAI Agents SDK、Vercel AI SDK 的 `@ai-sdk/openai`（v5+）、Cline 的 OpenAI provider、OpenCode 的 OpenAI 主路由。

**可显式选 Responses（非默认）**

- Kilo 的“OpenAI Responses”选项、Zed 的 `openai_responses`、Factory 的 `openai` 类型（需显式 provider 配置）；它们对未知/自定义端点的默认通常是 Chat Completions。

**必须 Messages（硬要求）**

- Claude Code、Claude Agent SDK。只有三种 wire format：Anthropic Messages / Bedrock InvokeModel / Vertex `rawPredict`；Foundry 与 Claude Platform on AWS 复用 Messages 格式，只是换 base URL 变量，不是第四种协议。没有 OpenAI 格式模式。

**Messages 为 provider-native**

- Cline、Continue、OpenCode、Goose、Kilo、Crush、Zed、Factory、Copilot CLI BYOK 等在给 Anthropic key 时基本都走 Messages；LiteLLM 系（Aider/OpenHands/SWE-agent）则由 LiteLLM 翻译到 Messages。**DeepSeek Harness 的 `deepseek-official` / `deepseek-account` route 默认也是 Messages**（DeepSeek 的 Anthropic 兼容面）。

**只能/主要 Chat Completions**

- 真正“只会 Chat”的 harness 很少。更准确地说：LiteLLM 系（Aider/OpenHands/SWE-agent）的 harness 入口是 Chat，LiteLLM 出站按 provider 原生；而**自定义/自托管端点**默认走 Chat 的包括 Continue 的 `apiBase`、Cline 的 `openai-compatible`、Kilo 的 OpenAI Compatible、Roo 的 OpenAI Compatible（历史）、OpenCode 的 `@ai-sdk/openai-compatible`、Crush 的 `openai-compat`、Zed 的自定义 provider（默认 `openai_chat`）、Copilot CLI 的 `openai` BYOK、Warp 的自定义端点、Amp 的 Custom URL、Goose 的 `OPENAI_HOST`。

**Gemini Interactions 支持**

- 明确支持：Vercel AI SDK（`google.interactions()`）、Google ADK（opt-in）、OpenCode 的 `google-interactions` 路由。
- 仍以 `generateContent` 为主：Gemini CLI、Cline、Kilo、Continue、Goose、Crush、LiteLLM 系、Cursor/Warp/Amp 的 Gemini BYOK 路径，以及 **DeepSeek Harness 的 `google` catalog route**（pi-ai 只有 `google-generative-ai`，没有 Interactions）。
- 这说明 Google 的“新默认”与 harness 生态的“实际默认”存在明显时间差。

### 5.6 为什么 harness 的默认协议差异这么大？

1. **厂商自有 harness 优先服务自家模型**：Codex 用 Responses、Claude Code 用 Messages、Gemini CLI 用 generateContent。这是最自然的“dogfooding”，也形成了协议墙。
2. **抽象层决定默认值**：基于 Vercel AI SDK 的 harness（Cline/OpenCode/Kilo）更容易跟上 Responses/Interactions；基于 LiteLLM 的 harness（Aider/OpenHands/SWE-agent）天然以 Chat Completions 为内部形状；DeepSeek Harness 则选择“provider-neutral 内部词汇 + native adapter”，因此它的 DeepSeek route 直接落在 Messages，而不是 Chat。
3. **订阅 OAuth 是隐形协议通道**：ChatGPT/Codex、Claude、Copilot 的订阅后端往往走 Responses/Messages 的私有变体；harness 为了“免 API key”会单独实现，因而出现“同一 harness 的 OpenAI key 走 Chat、ChatGPT 订阅走 Responses”的混合状态。
4. **“OpenAI-compatible”是最低成本的扩展方式**：接一个新 provider 只要支持 `/chat/completions` 即可，所以大量 harness 把它作为兜底；代价是 reasoning 状态回传、hosted tools、server state 受限或不可用。
5. **Gemini Interactions 太新**：2026-06 才 GA，且 Google 自家 Gemini CLI 仍停在 generateContent；第三方自然没有动力先接。AI SDK/ADK/OpenCode 是少数先行者。

---

## 6. 如何选型

### 6.1 决策树

```text
你要做什么？
│
├─ 只做聊天/分类/RAG/批处理，或要接最多供应商
│   └─ Chat Completions（简单、通用；接受能力上限）
│
├─ 自研/选型 OpenAI 系 coding agent
│   ├─ 用 Codex CLI / OpenAI Agents SDK → Responses
│   └─ 自研 harness
│       ├─ 需要 hosted tools / server state / 长任务 → Responses
│       └─ 只需要简单 tool loop + 多 provider → Chat Completions（但新一代 OpenAI 推理模型可能不可用）
│
├─ 自研/选型 Claude 系 coding agent
│   ├─ 用 Claude Code / Claude Agent SDK → Messages
│   └─ 自研 harness
│       ├─ 需要 thinking 连续性/精细缓存/企业网关 → Messages
│       └─ 只需要普通 function calling → Messages 仍然是最佳，Chat 会丢 thinking/cache
│
├─ 自研/选型 Gemini 系 coding agent
│   ├─ 需要托管 agent/background/Google grounding → Interactions
│   └─ 需要 batch/显式缓存/已有 SDK → generateContent
│
├─ 多模型统一接入
│   ├─ 能 native passthrough → 按上游协议分流（推荐：/v1/responses + /v1/messages + /v1/chat/completions）
│   └─ 只能一个入口
│       ├─ 只做非推理聊天 → Chat Completions
│       └─ 要做 agent → 自建 canonical event model + 各协议 codec；不要强行用 Chat 统一
│
└─ 合规/ZDR/数据驻留优先
    ├─ 要求历史可编辑/可删 → Chat Completions 或 Messages（stateless）
    └─ 可用 server state → Responses/Interactions 的 store:false + 加密 reasoning；或自托管网关
```

### 6.2 场景配方

**场景 A：从零写一个 OpenAI-first coding agent**

- 选 **Responses**。用 `input` Items、`function_call_output` 驱动 loop；用 `previous_response_id` 或手工回放；用 `reasoning.context` 管理历史 reasoning；长任务用 `background`，高吞吐用 WebSocket。
- 历史策略：本地 transcript 为 source of truth，server state 只做加速；需要压缩时用 `context_management`/`/responses/compact`，不要在 `previous_response_id` 模式下手工裁剪。
- 兼容策略：如果要接非 OpenAI 模型，单独写 Chat/Messages adapter，不要把 Responses 硬翻译成 Chat。

**场景 B：从零写一个 Claude-first coding agent**

- 选 **Messages**。用 `stop_reason` 驱动 loop；assistant content 整块回传；thinking block 原样保留；`cache_control` 放在稳定前缀的末尾（通常是 system/tools 之后、动态内容之前）。
- 历史策略：append-only；需要改 system/tools 时用 mid-conversation system messages 或 tool_addition/tool_removal 等 append-only 机制（视 beta 可用性），不要重写前缀。
- 成本策略：长 thinking 会话用 1h TTL；工具循环中缓存会随 assistant turn 自动扩展，尽量保持 tools/system 不变。
- 兼容策略：Claude Code 网关必须原生支持 Messages；不要用 Chat 翻译层接 Claude Code。

**场景 C：从零写一个 Gemini-first coding agent**

- 选 **Interactions**（新项目）；`store:true` + `previous_interaction_id`；长任务 `background:true`；thought step 原样回放；每轮重新指定 tools/system/generation_config。
- 如果需要 batch、已有集成、Python 自动函数调用，或受支持的 Gemini 3/2.5 模型上的 explicit caching，退回 **generateContent**；这两条线短期内会并存。
- 兼容策略：第三方 harness 大多只支持 generateContent；如果你要接现成 harness，先确认它是否支持 Interactions，否则按 generateContent 设计。

**场景 D：企业统一网关**

- 入口至少三套：`/v1/chat/completions`、`/v1/responses`、`/v1/messages`；Gemini 可加 `:generateContent`/`/v1beta/interactions`。
- 出口优先 **native passthrough**：OpenAI→Responses、Anthropic→Messages、Gemini→Interactions/generateContent；只有在目标不支持时才翻译。
- 关键约束：reasoning 状态按 provider 隔离；fallback 不能跨 provider 复用 reasoning；SSE 必须端到端不缓冲；beta header/body 原样透传；state 作为路由约束而不是透明转发。
- 可观测性：记录“入口协议、出口协议、是否翻译、reasoning 是否丢失、cache read/write、上游 request id”。

**场景 E：选现成 harness**

- 先看**协议墙**：要 Codex → 只能 Responses；要 Claude Code → 只能 Messages；要 Gemini 原生 → 只能 Gemini 系。
- 再看**多模型需求**：要接 3 家以上，优先选有显式协议开关的（Kilo/Zed/Factory/Crush/Copilot CLI/OpenCode）或 AI SDK 系（Cline/OpenCode）。
- 最后看**证据**：闭源 harness（Cursor/Amp/Warp）协议不可观测，BYOK 也常有限制；对协议保真度要求高时，选开源、可审计的 harness。

**场景 F：本地/开源模型**

- 默认 **Chat Completions**：vLLM、SGLang、Ollama、LM Studio、llama.cpp 都支持。
- 想跑 Codex：用支持 Responses 的本地服务（Ollama `/v1/responses`、LM Studio `/v1/responses`、vLLM `/v1/responses`、llama.cpp 的桥接实现），注意很多是 stateless，`previous_response_id` 不可用。
- 想跑 Claude Code：用支持 Anthropic Messages 的本地服务（vLLM/SGLang/Ollama/LM Studio/llama.cpp 都已提供 `/v1/messages`），但要接受 Anthropic 兼容子集的差异（cache_control、beta 等可能被忽略）。
- 想跑 Gemini/Interactions：目前多数本地服务不支持 Interactions；用 generateContent 或换托管。

**场景 G：只做聊天/分类/RAG/批处理**

- 选 **Chat Completions** 最划算：生态最广、代理最简单、成本最低。
- 如果要做批量/离线，Gemini `generateContent` 的 batch 仍然比 Interactions 成熟；OpenAI 侧则看 Batch API 的协议支持。
- 不要为了“未来 agent 化”提前引入 Responses/Messages 的复杂度；但要在架构上留出 adapter 层。

**场景 H：使用或扩展 DeepSeek Harness**

- **只用 DeepSeek 模型**：默认 `deepseek-official` / `deepseek-account` route 走 Messages（`https://api.deepseek.com/anthropic`），不要把它误认为 Chat Completions；thinking/tool blocks、Files API 都按 Messages 语义工作。
- **接 OpenAI / Anthropic / Google**：用 `dsh-llm-pi-ai` 的 catalog route。OpenAI 模型通常是 Responses，Anthropic 是 Messages，Google 是 `generateContent`；自定义 route 只能声明 `openai-completions` / `openai-responses` / `anthropic-messages` 三选一。
- **接 Gemini Interactions**：当前 DSH 没有现成路径（pi-ai 只到 `google-generative-ai`）；需要新增 adapter/插件，或改用 AI SDK/ADK/OpenCode 等支持 Interactions 的 harness。
- **接 DeepSeek Responses**：可以加一条 pi-ai 自定义 route：`api: openai-responses`、`baseURL: https://api.deepseek.com`、显式 `models`；但它是 stateless（`previous_response_id`/`store`/`background` 不支持），不要按 OpenAI Responses 的 state 语义设计。
- **扩展新协议**：在 `dsh-llm` 的 adapter 层实现，保留 replay envelope 和 provider-scoped opaque reasoning；不要把新协议先归一化成 Chat Completions 再转，否则会丢掉本文反复强调的 reasoning/cache 语义。

### 6.3 选型评分表（按场景加权）

| 维度 | 权重（agent） | 权重（多模型网关） | 权重（简单应用） | 说明 |
|---|---|---|---|---|
| Reasoning/tool-loop 保真 | 高 | 高 | 低 | 长时程 coding agent 的核心 |
| 协议可移植性 | 中 | 高 | 高 | 是否容易被网关/多 provider 支持 |
| 内置工具 | 高 | 中 | 低 | 能否省掉自研 search/code/computer |
| 状态/缓存 | 高 | 高 | 中 | 长上下文成本与连续性 |
| 实现复杂度 | 中 | 高 | 高 | Item/step 状态机比 chunk 复杂 |
| 合规/ZDR | 高 | 高 | 中 | server state 的保留期/驻留 |
| 生态/版本稳定性 | 中 | 高 | 高 | beta 多、破坏性变更频繁会拖累 |

**经验法则**：agent 场景下，“保真”权重高于“统一”；简单应用/网关场景下，“兼容”权重高于“特性”。

### 6.4 反模式

1. **把 Chat Completions 当“统一协议”接所有前沿模型**：短对话正常，长工具循环质量下降；OpenAI 新模型甚至无法工具调用。
2. **把“OpenAI-compatible”当“Responses-compatible”**：Codex 直接 404；很多 agent 框架的 hosted tools 也不可用。
3. **在工具循环中丢弃/重排 thinking/reasoning**：Messages 会 400，Responses 会降质，Interactions 会缺签名。
4. **网关“聪明地”重写 body/裁剪未知字段**：破坏 beta header/body 配对、thinking 签名、缓存前缀。正确做法是“能透传就透传”。
5. **用 server state 却忽略 retention/ZDR/数据驻留**：Responses/Interactions 默认存储；合规场景要显式 `store:false` 或自托管。
6. **SSE 代理开 buffering/compression 或超时太短**：agent 表现为卡死/截断；必须端到端测试。
7. **重试时不考虑工具副作用**：可能重复执行 shell/写文件/发请求；用 call id 幂等、审批、幂等键。
8. **把 MCP/ACP 当 model API 协议**：MCP 是工具/上下文协议，ACP 是 agent-to-harness 协议，不是模型 wire format。
9. **在 beta 上做长期架构且不做 capability detection**：beta 字段/行为随版本变；要做探测和降级。
10. **用“能跑通一次”代替协议回归测试**：需要 golden transcripts、流式/断线/重试/缓存命中的测试矩阵。

### 6.5 迁移清单

**Chat Completions → Responses**

- 端点 `/v1/chat/completions` → `/v1/responses`；`messages` 大多可作为 `input` 复用，但工具/多模态/结构化输出要改。
- `response_format` → `text.format`；`tools[].function` 扁平化为 `{type:"function", name, parameters, strict}`。
- 读取 `output: Item[]`，不要读 `choices[0].message`；用 `output_text` 聚合文本。
- 工具结果从 `role:"tool"` 改为 `function_call_output` Item；`tool_call_id` → `call_id`。
- 流式从 chunk delta 改为 `response.*` 语义事件；把“拼接文本”改成“事件状态机”。
- 决定 state 策略：手工回放 / `previous_response_id` / Conversations；如果 ZDR，使用 `store:false` 并保留 encrypted reasoning。
- 注意 reasoning item 和 assistant `phase` 必须保留；不要只回放 message 文本。

**新增第二个协议（如 Messages 或 Interactions）**

- 先定义内部 `AgentEvent`/`ToolCall`/`ToolResult`/`ReasoningState`，但保留原始 opaque payload（不要反序列化 thinking/reasoning）。
- 为每个协议写 adapter：`encodeRequest`、`decodeStreamEvent`、`stateMode`、`capabilities`。
- 保留原始 assistant turn 的字节/对象；历史只追加，不重排。
- 建立 golden transcript：同一任务在每个协议下回放，比较工具调用、reasoning、终止条件。
- 网关层做 capability detection：不支持 `previous_response_id` 就不要接受 stateful 请求；不支持 cache_control 就明确降级。

---

## 7. 工程实现清单

### 7.1 内部抽象建议

不要试图用一个“万能 message schema”抹平四家；更稳的做法是：

```ts
type Protocol = "chat" | "responses" | "messages" | "interactions";

interface ProtocolAdapter {
  protocol: Protocol;
  capabilities: {
    serverState: boolean;
    reasoningRoundTrip: "none" | "opaque" | "signed";
    hostedTools: boolean;
    cacheControl: "implicit" | "explicit" | "both";
    semanticStreaming: boolean;
  };
  encodeTurn(state: AgentState, tools: ToolSpec[]): unknown;
  decodeStream(event: unknown): AgentEvent; // 文本/thinking/tool/reasoning/终止
  makeToolResult(call: ToolCall, result: ToolResult): unknown;
}
```

关键点：

- **保留原始对象**：thinking/reasoning/thought 不要反序列化再重建；原样存、原样传。
- **统一事件，不统一语义**：内部可以有 `AgentEvent`，但 `reasoning` 事件要带 provider-scoped blob 和 `opaque: true`。
- **能力探测**：不要假设每个端点都支持 `cache_control`/`previous_response_id`/hosted tools；启动时探测或按配置声明。
- **状态策略可切换**：`client` / `server` / `hybrid`；切到 client 时能完整回放，切到 server 时能禁用历史编辑。

### 7.2 历史与缓存

- 追加而非重写；对 prefix 做 hash，监控 cache hit。
- 固定 system/tools 的版本；动态内容后置。
- 不要在每个请求里重排 tool 定义；工具增删用 append-only 机制（若协议支持）。
- 记录 `cached_tokens` / `cache_read_input_tokens` / `cache_creation_input_tokens`，否则无法判断协议收益。
- 客户端压缩/摘要会破坏 prefix；要么接受 cache miss，要么用协议提供的 compaction。

### 7.3 工具执行

- 用 `call_id` 做幂等键；重试/重连不重复执行副作用工具。
- 工具结果截断要有明确策略；错误用协议的 `is_error`/`function_call_output` 表达。
- 审批/权限在 harness 层，不在协议层；但 hosted tools 会把执行移到 provider，审批边界要重新设计。
- 并行工具调用要按协议的限制处理（`parallel_tool_calls`、`max_tool_calls`）。

### 7.4 流式与网络

- SSE：关闭 buffering/compression；确保 `text/event-stream`；转发 keep-alive/ping；读超时覆盖最长 thinking。
- 终止事件必须处理：Chat 的 `[DONE]`、Responses 的 `response.completed/incomplete/failed`（以及流内 `error`）、Messages 的 `message_stop`、Interactions 的 `interaction.completed`。
- 断线重连：能续传就续传（Interactions `last_event_id`、Responses WebSocket/response id），不能就重启并做幂等。
- 代理层不要合并两个流；重试要作为新 attempt 暴露给客户端。

### 7.5 可观测性与测试

- 记录：协议、模型、上游 request id、入口/出口协议、是否翻译、reasoning 是否丢失、cache read/write、tool 调用耗时、终止原因。
- 测试矩阵：每个协议 × 流式/非流式 × 工具调用/无工具 × thinking/无 thinking × 断线/重试 × 缓存命中/未命中。
- Golden transcripts：固定 prompt、工具、模型版本，比较输出结构、tool call id、终止事件；不要只比较最终文本。
- 版本 pin：SDK 主版本、`anthropic-version`、Model API 版本、网关版本、harness 版本；升级前跑 fidelity 测试。

---

## 8. 2026-10 生态快照与风险

### 8.1 近期变化（会影响选型）

- **Anthropic API `2026-10-21`**：移除 `temperature/top_p/top_k`，SDK 默认改用 Bearer 认证（API 仍接受 `x-api-key`；Foundry SDK 仍发 `x-api-key`）；这是破坏性变更，老版本 `2023-06-01` 仍可用。Claude Code / Agent SDK 的版本兼容要跟着升。
- **Gemini Interactions GA（2026-06）**：Google 明确新能力优先在 Interactions 上线；`generateContent` 转 legacy 但继续支持。Gemini CLI 免费/Google One 层于 2026-06-18 由 Antigravity CLI 接替。
- **当前 Codex 版本不再支持 Chat wire API**：`wire_api` 只接受 `"responses"`；这使“Chat-only 网关”无法服务 Codex。具体移除时间官方未文档化。
- **DeepSeek Harness（DSH）0.2.x**：MIT、开发预览；内部 `dsh-llm` 是 provider-neutral，DeepSeek 官方 route 走 Messages（`https://api.deepseek.com/anthropic`），多 provider 经 pi-ai；自定义 route 只支持 Chat Completions / Responses / Messages 三种协议；当前不接入 Gemini Interactions。DeepSeek API 同时提供 Chat/Responses/Messages 三种表面，但 DSH 默认选 Messages。
- **第三方 harness 洗牌**：Roo Code 2026-05-15 停止维护；Aider 更新放缓；Gemini Interactions 支持仍集中在 AI SDK/ADK/OpenCode。
- **Chat Completions 继续存在**：它仍是最大公约数，但 OpenAI 的新模型/新 agent 能力优先 Responses；其他厂商也继续提供 Chat 兼容面（Gemini 的 `/v1beta/openai/`、Anthropic 的 OpenAI SDK compat）。
- **“OpenAI-compatible”泛滥**：大量端点只实现 Chat Completions，不支持 Responses；买网关/选 provider 时要问清楚“是 Chat 兼容还是 Responses 兼容”。

### 8.2 风险与不确定性

- **闭源 harness 的 wire protocol 不可观测**：Cursor/Amp/Warp/Copilot 托管后端可能随时换协议；BYOK 也只覆盖部分模型/能力。
- **Gemini Interactions 版本面**：文档同时出现 `/v1` 和 `/v1beta`，事件命名在 streaming/breaking-changes 文档间不完全一致；落地要以实际端点为准。
- **模型级 gating**：Responses 的 WebSocket/compaction/`pro` mode、Messages 的 thinking/preserved thinking、Interactions 的 background/长 decode 都按模型/账号灰度；不能假设“协议支持=所有模型支持”。
- **beta 依赖**：Messages 的 MCP connector、compaction、context editing、preserved-thinking controls 仍在 beta；生产使用要准备降级路径。
- **协议版本与 SDK 版本不同步**：Anthropic 新版 API 与旧 SDK/harness 可能不兼容；Codex/Claude Code 的版本升级也可能改变默认行为。锁定版本、做回归测试比“追新”重要。

### 8.3 建议持续跟踪的清单

1. OpenAI：Responses 的 Item 类型、built-in tools、compaction/WebSocket 的模型支持；Chat Completions 的 reasoning/tool 限制是否扩大。
2. Anthropic：`anthropic-version` 变更、preserved thinking 规则、cache_control 自动缓存、server tools/MCP connector 的 GA。
3. Google：Interactions 的 v1/v1beta 稳定性、batch/explicit caching 是否补齐、Gemini CLI/Antigravity 的协议面。
4. Harness：Codex `wire_api`、Claude Code gateway 要求、Cline/OpenCode/Kilo/Zed/Factory 的协议开关、AI SDK 的默认协议变化。
5. 网关：LiteLLM/OpenRouter/vLLM/Ollama/LM Studio 对 Responses/Messages/Interactions 的 native passthrough 与 fidelity。

---

## 9. 参考资料

### OpenAI

- [Migrate to the Responses API](https://developers.openai.com/api/docs/guides/migrate-to-responses)
- [Chat Completions reference](https://developers.openai.com/api/reference/resources/chat)
- [Responses reference](https://developers.openai.com/api/reference/resources/responses)
- [Function calling](https://developers.openai.com/api/docs/guides/function-calling)
- [Reasoning](https://developers.openai.com/api/docs/guides/reasoning)
- [Streaming responses](https://developers.openai.com/api/docs/guides/streaming-responses)
- [Conversation state](https://developers.openai.com/api/docs/guides/conversation-state)
- [Prompt caching](https://developers.openai.com/api/docs/guides/prompt-caching)
- [WebSocket mode](https://developers.openai.com/api/docs/guides/websocket-mode)
- [Codex config reference](https://developers.openai.com/codex/config-file/config-reference)

### Anthropic

- [Messages API](https://platform.claude.com/docs/en/api/messages)
- [Migrating to API version 2026-10-21](https://platform.claude.com/docs/en/api/migration-2026-10-21)
- [Thinking](https://platform.claude.com/docs/en/build-with-claude/thinking)
- [Prompt caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching)
- [Streaming Messages](https://platform.claude.com/docs/en/build-with-claude/streaming)
- [How tool use works](https://platform.claude.com/docs/en/agents-and-tools/tool-use/how-tool-use-works)
- [OpenAI SDK compatibility](https://platform.claude.com/docs/en/cli-sdks-libraries/libraries/openai-sdk)
- [Claude Code gateway compatibility](https://code.claude.com/docs/en/llm-gateway-protocol)
- [Claude Code model configuration](https://code.claude.com/docs/en/model-config)

### Google / Gemini

- [Interactions API overview](https://ai.google.dev/gemini-api/docs/interactions-overview)
- [Migrate from generateContent](https://ai.google.dev/gemini-api/docs/migrate-to-interactions)
- [Interactions breaking changes](https://ai.google.dev/gemini-api/docs/interactions-breaking-changes-may-2026)
- [Function calling](https://ai.google.dev/gemini-api/docs/function-calling)
- [Thinking](https://ai.google.dev/gemini-api/docs/thinking)
- [Streaming](https://ai.google.dev/gemini-api/docs/streaming)
- [OpenAI compatibility](https://ai.google.dev/gemini-api/docs/openai)
- [generateContent (legacy)](https://ai.google.dev/gemini-api/docs/generate-content/text-generation)
- [Gemini CLI](https://github.com/google-gemini/gemini-cli)
- [Antigravity models](https://antigravity.google/docs/models)

### Harness / SDK

- [Cline](https://github.com/cline/cline) · [Cline provider docs](https://docs.cline.bot/provider-config/openai)
- [Kilo Code](https://github.com/Kilo-Org/kilocode) · [Kilo AI providers](https://kilocode.ai/docs/ai-providers)
- [OpenCode](https://opencode.ai/docs/providers)
- [Continue](https://docs.continue.dev/customize/model-providers/overview)
- [Goose](https://goose-docs.ai/docs/getting-started/providers)
- [Crush](https://github.com/charmbracelet/crush)
- [Zed API access](https://zed.dev/docs/ai/use-api-access)
- [Aider LLM docs](https://aider.chat/docs/llms.html)
- [OpenHands LLM docs](https://docs.openhands.dev/openhands/usage/llms/llms)
- [SWE-agent models](https://github.com/SWE-agent/SWE-agent/blob/main/docs/config/models.md)
- [Factory Droid BYOK](https://docs.factory.com/model-independence/byok)
- [GitHub Copilot CLI BYOK](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/use-byok-models)
- [Cursor BYOK](https://cursor.com/docs/settings/api-keys)
- [Amp model routing](https://ampcode.com/docs/markdown/customize/model-routing)
- [OpenAI Agents SDK models](https://openai.github.io/openai-agents-python/models/)
- [Google ADK models](https://adk.dev/agents/models/)
- [Vercel AI SDK OpenAI provider](https://ai-sdk.dev/providers/ai-sdk-providers/openai)
- [Vercel AI SDK Google provider](https://ai-sdk.dev/providers/ai-sdk-providers/google)

### DeepSeek / DeepSeek Harness

- [DeepSeek Harness 仓库](https://github.com/deepseek-ai/deepseek-harness)（MIT；当前安装 `@deepseek-ai/dsh` 0.2.1-rc.2）
- [DSH LLM service](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm/README.md)（provider-neutral 内部协议）
- [DSH DeepSeek Messages adapter](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm-deepseek/README.md)（`https://api.deepseek.com/anthropic` + `/v1/messages`）
- [DSH pi-ai multi-provider adapter](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm-pi-ai/README.md)（catalog + 三种自定义协议）
- [DeepSeek: Using the Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api/)
- [DeepSeek: Using the Responses API](https://api-docs.deepseek.com/guides/responses_api/)（stateless）
- [DeepSeek API 首页](https://api-docs.deepseek.com/)（Chat Completions）

### 网关 / 自托管

- [LiteLLM](https://docs.litellm.ai/)
- [OpenRouter Responses](https://openrouter.ai/docs/api_reference/responses/overview)
- [vLLM OpenAI-compatible server](https://docs.vllm.ai/en/latest/serving/openai_compatible_server/)
- [Ollama OpenAI compatibility](https://docs.ollama.com/api/openai-compatibility)
- [LM Studio OpenAI compatibility](https://lmstudio.ai/docs/developer/openai-compat)
- [llama.cpp server](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md)

---

## 附录 A：三种常见切法对照

| 你原本说的“三种” | 本文对应 |
|---|---|
| OpenAI / Anthropic / Google 三家 | Chat Completions（OpenAI 兼容面）+ Messages + Interactions（或 generateContent） |
| Chat Completions / Responses / Messages | 三个都在正文；Interactions 作为 Google 的对应物补充 |
| 三种“agent 协议” | Responses / Messages / Interactions；Chat Completions 作为兼容基线 |

## 附录 B：Chat Completions ↔ Responses 快速映射

| Chat Completions | Responses |
|---|---|
| `messages[]` | `input`（string/Item[]）；message 仍可作为 Item |
| `system` message | `instructions` 或 `developer`/`system` message |
| `tools[].function` | `{type:"function", name, parameters, strict}` |
| assistant `tool_calls[]` | `function_call` Item |
| `role:"tool"` + `tool_call_id` | `function_call_output` Item + `call_id` |
| `response_format` | `text.format` |
| `choices[0].message.content` | `output` 中的 `message` Item / `output_text` |
| `finish_reason` | `status` + `incomplete_details` + `output` 内容 |
| `stream` chunk delta | `response.*` 语义事件 |
| 无状态 | `store`/`previous_response_id`/Conversations |

## 附录 C：术语表

- **Wire protocol**：模型 API 的 HTTP/JSON/SSE 形状；本文比较的对象。
- **Harness**：驱动模型、执行工具、管理上下文的 agent 运行时（CLI/IDE/SDK）。
- **Gateway**：统一入口、路由、鉴权、翻译、观测的代理层（LiteLLM/OpenRouter/自建）。
- **Hosted tools**：由模型厂商在服务端执行的内置工具（web search、code execution 等）。
- **Opaque reasoning**：加密/签名的 reasoning 状态；客户端不可读，但必须原样回传。
- **Native passthrough**：网关不翻译，直接把客户端协议转发到同协议上游。
- **Fidelity**：翻译后能力保留程度；reasoning、cache、hosted tools、state 是最容易丢的四类。
- **MCP**：Model Context Protocol，工具/上下文接入协议，不是模型 API 协议。
- **ACP**：Agent Client Protocol，agent 与编辑器/harness 之间的协议，不是模型 API 协议。

---

*本文基于 2026-10-25 的官方文档、开源仓库与网关文档整理；协议和 harness 版本变化很快，生产落地请锁定版本并建立自己的 fidelity 测试矩阵。*
