Agent State and Model APIs

一句话解释

每次模型推理请求可以是无状态原子调用,但 Agent 通过显式重建或引用外部状态、对话历史、工具轨迹、推理项和压缩项,实现跨推理请求的状态连续性。

四层区分

层次 是否天然跨轮 核心对象 主要影响
Model inference Transformer forward pass、单次 KV cache 一次生成
Prompt cache 短期可复用 exact prompt prefix 的 K/V projection latency、cost
Conversation state messages、tool calls、tool outputs 任务事实
Reasoning state 条件性继承 opaque reasoning / compaction items 策略连续性

关键结论:stateless inference request != stateless agent。KV cache miss 主要导致重复 prefill,不会直接让模型变笨;换模型的质量风险来自 model-specific instructions、reasoning-state compatibility 和长期策略连续性损失。

Agent State

1
2
3
4
5
6
7
AgentState = {
external_state: repo, files, git diff, terminal, tests,
conversation_state: user, assistant, tool calls, tool outputs,
reasoning_state: compatible reasoning items,
compaction_state: opaque compressed prior context,
runtime_context: model-specific instructions, tools, schemas
}
1
2
3
4
5
6
7
8
Agent State
→ render request context
→ LLM inference
→ message / function call / reasoning item
→ tool or environment executes
→ append observation
→ update Agent State
→ loop or checkpoint

Codex 的例子说明这条链路:

  1. 每次 Responses API 调用是独立推理。
  2. Harness 回放旧消息、工具调用、工具结果和兼容推理项。
  3. store=true 可用服务端引用;store=false 必须客户端完整保存并回放。
  4. 长上下文压缩后产生 opaque compaction item。
  5. 中途换模型时,事实记录仍在,但另一个模型的 planning style、tool policy 和可继承推理状态不同。

“知道前一个模型做过什么”不等于“拥有它形成策略时的完整决策状态”。

OpenAI Responses API

Responses API 把输入输出建模为 typed items,而不是只有 role-based message。

常用字段:

1
2
3
4
5
6
7
8
9
{
"model": "gpt-5",
"input": [],
"tools": [],
"store": false,
"previous_response_id": null,
"include": ["reasoning.encrypted_content"],
"reasoning": { "effort": "medium" }
}

常用 item 类型:

Item 作用
message 用户或 assistant 可见消息
function_call 模型发起工具调用,含 call_idname、JSON 参数
function_call_output 客户端回传工具结果,通过同一 call_id 关联
reasoning opaque 推理项;stateless 模式默认携带 encrypted content
compaction opaque 压缩项,承载先前上下文的关键 latent understanding

两种连续性模式:

  • 服务端链式:允许存储时传 previous_response_id,由服务端展开历史。它只是省去重复上传历史的 convenience layer。
  • 客户端回放:设置 store=false 后保存所有相关 items,尤其是最近 user message 之后的 reasoning -> function_call -> function_call_output 序列。

注意:encrypted_content 不是人类可读 chain-of-thought;只有 compatible reasoning items 才会被后续模型利用。

OpenAI Chat Completions

Chat Completions 以 messages[] 为中心。

1
2
3
4
5
system message
→ user message
→ assistant.tool_calls
→ tool message(tool_call_id)
→ next assistant response

工具轮形状:

1
2
3
4
5
6
7
8
9
10
assistant:
tool_calls[{
id, type:"function",
function:{ name, arguments }
}]

tool:
role:"tool"
tool_call_id
content

特点:

  • 没有 Responses 式的 persisted reasoning / compaction item 抽象。
  • Agent 通常自己维护和追加完整 messages。
  • 多模态内容通过 content parts 表示。
  • Prompt cache 自动匹配稳定 exact prefix,缓存命中只减少成本延迟。

Anthropic Messages API

Anthropic Messages API 使用顶层 systemmessages[],并用 content blocks 表达工具交互。

工具轮形状:

1
2
3
4
5
6
7
8
9
10
11
12
user:
text block

assistant:
tool_use block {
id, name, input
}

user:
tool_result block {
tool_use_id, content
}

特点:

  • system 是顶层参数,不是普通 role:"system" message。
  • 工具定义使用 name 和 JSON Schema 风格的 input_schema
  • tool_use 在 assistant content 内,tool_result 作为后续 user content block 返回。
  • prompt caching 通过在稳定 prefix 的 content block 上加 cache_control 控制。

API 对比

维度 Responses API Chat Completions Anthropic Messages
主模型 typed input/output items messages[] messages[] + top-level system
工具请求 function_call item assistant tool_calls assistant tool_use block
工具结果 function_call_output item role:"tool" message user tool_result block
推理连续性 persisted/opaque reasoning item 无等价抽象 provider-specific thinking block
压缩状态 opaque compaction item 应用层自行 summary 应用层自行 summary 或编辑上下文
服务端续接 previous_response_id / conversations 一般客户端维护 messages 一般客户端维护 messages

常见误区

  • “API 无状态”不等于“Agent 无状态”。前者是单次 HTTP/model 边界,后者靠 harness 显式传递状态。
  • previous_response_id 不是魔法记忆;计费上仍可能把展开后的历史视为 input tokens。
  • Prompt caching 只复用计算,不等价于语义记忆或 reasoning continuity。
  • Chat Completions 的 messages 只是 Agent State 的一部分;文件系统、git、terminal 和 checkpoint 都在 API 外面。
  • 模型切换不是只换参数。model-specific base instructions 可能改变 prompt,compatible reasoning state 也可能无法无损继承。

尚未解决的问题

  • 不同 provider 对 thinking/reasoning item 的保留期、加密、可见性和模型兼容规则不同。
  • compaction 的质量损失难以离线预测,需要在长任务 benchmark 单独测。
  • Agent checkpoint 应该快照哪些环境副作用,取决于工具幂等性和任务恢复策略。

状态恢复不是历史回放

状态迁移时要区分“事实”与“决策过程”。文件、数据库行、工具 receipt 和用户约束属于可审计事实;messages 是把部分事实重新暴露给模型的表示;reasoning item 和 compaction item 则是 provider 可能识别、也可能无法识别的策略线索。恢复一个长任务时,最危险的做法是把一段看似完整的文本摘要当成全部状态:它可能保留结论,却漏掉尚未执行的副作用、权限变化或待确认动作。

1
2
3
4
5
checkpoint
├─ durable facts: files, DB, receipts, user constraints
├─ workflow cursor: current step, retries, deadlines, owner
├─ conversation projection: messages and tool results
└─ model-specific continuation: reasoning / compaction items

前三层可以设计成跨模型可迁移的系统状态,最后一层只能作为优化项,不能成为恢复正确性的唯一依据。也就是说,换模型后允许 planning style 变化,但不应重新扣款、丢失已批准范围或忘记任务已经完成的步骤。

三种连续性模式的代价

模式 省掉什么 仍要负责什么 典型风险
完整客户端回放 不依赖 provider 存储 token 成本、敏感数据、上下文裁剪 错序或漏回放 tool item
previous_response_id 链式续接 历史拼接和 item 关联 生命周期、费用、过期和模型兼容 误把引用当成永久记忆
durable state + 新请求摘要 大量历史 token 摘要正确性、任务游标和证据链接 摘要删除了约束或未完成动作

选择标准不是 API 长得更方便,而是任务能否在进程崩溃、模型切换和重复提交后恢复。可以做一个故障注入测试:在工具调用前、工具已执行但 output 未写入、compaction 后和模型切换后分别杀掉 worker,然后检查事实状态、重复副作用、约束召回率和人工接管原因。

跨 provider 的最小兼容层

应用若要切换模型,应把内部事件先规范化为 user_inputassistant_messagetool_calltool_resultcheckpoint 五类事件,并保留 provider 原始 payload 作为调试附件。规范化层只承诺事实和因果顺序,不承诺把某一家的 thinking block 翻译成另一家的等价推理状态。这样可以把“API 形状不兼容”和“策略连续性不可证明”分开处理。

验证时至少检查:工具调用与结果是否按 id 一一配对、历史中的拒绝/批准是否仍可见、模型切换后是否重复已完成动作,以及 compaction 前后的任务成功率是否只在允许误差内变化。相关的循环控制见 Agent Loop,评测分层见 Agent Evaluation