阅读收获

读完本文,你将了解:

  • 从 Prompt Engineering 到 Context Engineering 的范式转变
  • 为什么 Agent 比普通 Chatbot 更需要 Prompt Caching
  • 什么操作会破坏 Cache(比你想象的多)
  • Prompt 布局与动态信息管理的最佳实践
  • 工具管理的三种 Cache-aware 方案对比

1. 先说结论:Cache Rules Everything

Prompt Cache 不只是一个省钱技巧,它是 Agent 系统架构设计的核心约束。

就像数据库的 schema 设计会影响整个应用架构一样,Prompt Cache 的前缀匹配约束深刻地影响了 Agent 的每一个设计决策:

  • prompt 怎么组织?→ 稳定内容放前面,变化内容放后面
  • 工具怎么管理?→ 工具列表固定,通过其他机制限制可用范围
  • 状态怎么切换?→ 不切换工具,用工具模拟状态转换(Claude Code Plan Mode 就是最好的例子)
  • context 怎么压缩?→ 压缩操作本身必须 cache-safe
  • 模型怎么选?→ 不在同一会话中切换,用子代理隔离

1.1 从 Prompt Engineering 到 Context Engineering

  • Prompt Engineering:关注”怎么写指令让模型表现更好”——内容层面的优化。
  • Context Engineering:关注”怎么组织整个上下文——指令、工具、历史、外部信息——让 Agent 系统整体高效运转”——系统架构层面的设计。

Manus 在 25 年底最新总结中提出了三个维度:Reduce(缩减)、Isolate(隔离)、Offload(卸载)。

1.2 三家方案的共同规律

不同公司、不同架构,但核心规律惊人地一致:

  • 前缀不变:system prompt、tools、早期历史永远不修改
  • 追加不修改:Append-only,永远不编辑历史消息
  • 工具定义稳定:tools 数组不变,通过其他机制控制可用范围
  • 动态信息后置:时间戳、环境状态等放在后面的 user message 中
  • 压缩必须 cache-safe:压缩操作复用父对话的 cache prefix

2. 为什么 Agent 比 Chatbot 更需要 Prompt Cache?

2.1 Agent 的 I/O 比例严重失衡

Agent 每一步都需要发送完整的对话历史给模型,模型只输出一小段。Manus 披露过一个数据:input:output ≈ 100:1

如果没有 Prompt Cache → 每一步重新 Prefill 所有历史 token → 成本二次方增长

2.2 经济账

场景不缓存缓存后节约
Claude(正常 vs cached)$3/MTok$0.30/MTok90%
OpenAI GPT-5(正常 vs cached)$10/MTok$2.50/MTok75%
Claude Code 单任务(约 2M tokens)~$6.00~$1.1581%

Thariq(Claude Code 团队):“Coding agents would be cost prohibitive without prompt caching.”

OpenAI Codex:cache 命中后,采样开销从二次降为线性

2.3 延迟:TTFT 的大幅改善

  • Manus:KV cache hit rate 是 “the single most important metric”
  • Claude Code 团队:cache 命中率下降 → 当作线上事故(SEV)处理
  • OpenAI:150K+ tokens 时,cached 请求 TTFT 快 67%

3. 什么操作会破坏 Cache?

任何位置的任何改动 → 该位置之后的 cache 全部失效。

3.1 改动 System Prompt

在开头放时间戳——Manus 踩过的坑。时间戳每秒都变,第一个 token 就不同,整个 cache 废掉。

3.2 改动 Tool Definitions

Claude Code 团队经验中最常见的 cache 破坏方式。Tool definitions 在 prompt 前部,增删任何一个工具 → 后续所有 cache 失效。

具体场景:

  • 增删工具:动态加载不同工具集 → 每次变化 cache 全废
  • 工具顺序不确定:Codex 的 MCP 工具注册顺序不确定
  • 更新工具参数:如 allowed_subagents 列表变化

3.3 切换模型

Cache 是 model-specific 的。

一个反直觉推论:100K token 对话中,切换到更便宜的模型可能更贵—— Opus 的 100K cached token 只需 $1.50,换 Haiku 后全部重算。

3.4 修改历史消息

  • 编辑或删除之前的 action/observation → 破坏 cache
  • 非确定性序列化:JSON key 排序不一致(Manus 踩坑)→ 相同语义不同 token 序列

核心原则:序列化必须是确定性的。

4. Prompt 布局与动态信息管理

核心思路:把稳定的内容放前面,把变化的内容放后面。

4.1 Claude Code 的四层缓存架构

层级内容稳定性
Layer 1Static System Prompt & Tools全局不变
Layer 2CLAUDE.md 项目配置项目级不变
Layer 3Session Context(git status 等)会话级
Layer 4Conversation Messages每轮追加

每轮只有 Layer 4 增长,前 3 层稳定命中 cache。

4.2 OpenAI Codex 的 Prompt 构建

三层结构:instructions → tools → input

关键设计:旧提示是新提示的精确前缀

配置变更(沙盒权限、工作目录)→ 追加新消息而非 修改 旧消息。

4.3 Manus 的三条规则

  1. 稳定前缀
  2. Append-only
  3. 确定性序列化

4.4 动态信息怎么更新?

方案实现方式
Claude Code<system-reminder> 标签放在 user message 中
Codex追加新的 developer/user 消息

永远追加,永远不修改。

4.5 Cache Breakpoint 与 Auto-caching

  • Claude API:从手动 cache_control breakpoint → auto-caching 一个参数搞定
  • OpenAI APIprompt_cache_key 路由优化,自动缓存 ≥1024 token 前缀

反直觉:900 token prompt 永远不 cache hit,扩展到 1024+ token 反而更省钱。

5. 工具管理:三种方案,殊途同归

Agent 可能有 30 个工具,但不同阶段只需要一部分。如果按需加载 → 每次状态切换 cache 全废。

5.2 Claude Code:状态转换 + defer_loading

  • Plan ModeEnterPlanMode/ExitPlanMode 本身作为工具 → 工具列表永远不变
  • Tool Searchdefer_loading stub → ToolSearch 按需获取完整 schema
  • 模型可自主决定何时进入 Plan Mode

5.3 Manus:Logits Masking

  • 所有工具始终在 prompt 中
  • 工具命名约定:browser_xxxshell_xxx
  • Token logits masking 控制可用工具
  • 三种模式:Auto / Required / Specified

5.4 OpenAI:allowed_tools 参数

  • tools 数组完整不变
  • allowed_tools 限制当前可用子集
  • 注意:MCP 服务器可动态变更工具列表 → 需谨慎处理

5.5 对比总结

本质:工具定义不变(保 cache),通过其他机制限制可选范围。

方案实现方式优点限制
Claude Codetool 本身 + defer_loading灵活,模型自主决策需 API 支持
Manuslogits masking精细控制需 self-hosting
OpenAIallowed_tools 参数最简单仅粗粒度

参考

  • Thariq @trq212 - “Lessons from Building Claude Code: Prompt Caching Is Everything”
  • Lance Martin @RLanceMartin - “Prompt auto-caching with Claude”
  • Manus Blog - “Context Engineering for AI Agents”
  • “深入解析 Codex 智能体循环”
  • Anthropic - “Effective Context Engineering for AI Agents”