第 6 章 第二部分:核心引擎

System Prompt 工程

prompts.ts 的动态构建机制——静态/动态边界分离、Feature Flag 条件加载、环境信息注入,Context Engineering 的教科书级实现

Claude Code System Prompt Context Engineering Prompt Caching Feature Flags

6.1 为什么这是全书最重要的一章

如果你只读一章,读这一章。

Claude Code 的 System Prompt 不是一个静态文本文件。它是一个动态构建系统——根据运行模式、Feature Flag、用户配置、环境信息、工具列表、MCP 客户端等数十个变量,在每次对话开始时实时组装。prompts.ts 是这个系统的核心,它包含 41 个实体(11 个常量 + 30 个函数),统筹着”模型应该知道什么”这个关键问题。

这就是 AI Agent 工程三代演进中”Context Engineering”阶段的标杆实践:

代际时间核心关切典型操作
Prompt Engineering2022-2024优化单条指令的措辞Few-shot、Chain-of-Thought
Context Engineering2025 上半年管理送入模型的完整信息环境本章所述的动态 System Prompt 构建
Harness Engineering2025 下半年-2026构建 Agent 可靠运行的完整系统权限 + 工具 + 上下文 + 安全 + 恢复

Andrej Karpathy 在 2025 年提出”Context Engineering > Prompt Engineering”的判断被 230 万次浏览,而 2026 年的行业共识进一步演进——Claude Code 整体(权限系统 + 工具编排 + 上下文管理 + 安全边界 + 错误恢复)是 Harness Engineering 的标杆实现,本章聚焦的是 Harness 中最精密的一个组件:Context 的动态构建与缓存优化。

公式:Agent = Model + Harness,Harness = Context + Tools + Permissions + Safety + Recovery。

范式共识固化。2026 年上半年,“Context Engineering”从学术讨论正式进入工业实践共识。Tessa Karo(Shopify)的”Prompt Engineering is Dead, Long Live Context Engineering”文章引发广泛讨论,Google I/O 2026 专题演讲正式使用该术语。三层范式——Prompt Engineering → Context Engineering → Harness Engineering——不再只是 Karpathy 的个人判断,而是整个行业对 Agent 工程方法论演进的共识性描述。本章作为 Context Engineering 的深度案例,其价值不在于”如何写好一条指令”,而在于”如何管理一个动态信息环境的完整生命周期”。

Anthropic 2026 量化支撑。Anthropic 在 2026 Agentic Coding Trends Report 中给出了这一定位的硬数据:掌握 Context Engineering 的团队完成任务快 55%、错误少 40%。同期调研显示,82% 的工程领导认为单靠 Prompt Engineering 不足以扩展 AI 系统。这一数据印证了 Harness Engineering 范式的工业价值——Context 不是”优化项”,而是决定 Agent 是否能稳定上规模的核心变量。

Loop Engineering:Harness 之上的第四层。2026 年 Addy Osmani 正式提出 Loop Engineering 概念(Loop vs Prompt vs Context Engineering 2026 Map),在三层范式之上补充第四个工程层——它解决”工作如何跨回合继续”的问题:调度、验证、分支、重试、预算与停止条件。

范式时间关注点典型操作
Prompt Engineering2022-2024单条指令的措辞Few-shot、CoT
Context Engineering2025 上半年送入模型的完整信息环境动态 System Prompt
Harness Engineering2025 下半年-2026Agent 可靠运行的完整系统权限+工具+上下文+安全+恢复
Loop Engineering2026跨回合控制流调度/验证/分支/预算/停止条件

Loop Engineering 与 Harness Engineering 互不替代而是互补视角:Harness 关注”系统完整性”(权限/工具/上下文/安全/恢复),Loop 关注”控制流”(一个回合结束后下一个回合如何开始、何时停止、如何重试)。Claude Code 既是 Harness Engineering 的标杆(参见第 7-9 章),也天然是 Loop Engineering 的实现(Agent Loop、Hook 机制、SubAgent 重试、子任务调度都是 Loop 视角的具体落地)。两者的结合让 Claude Code 既”系统可证”又”行为可控”。

2026 年 7 月 3 日,Claude Code 负责人 Boris Cherny 在 X 上公开声明:“I don’t prompt Claude anymore. I have loops running that prompt Claude and figuring out what to do. My job is to write loops.”——这标志着 Loop Engineering 从外部概念变为 Claude Code 团队自身的工程哲学。同期,Anthropic 官方发布 “Getting Started with Loops” 指南(Delba Oliveira,2026-06-30),系统定义了四种循环类型——/goal(终点线循环)、/loop(定时器循环)、/schedule(日程循环)、Dynamic Workflows(并行循环)——并给出了验证条件设计和停止边界设定的工程原则。核心原则:“不要只修 Prompt,要修系统。“

6.1.0 Claude 5 时代的范式反转:从最大约束到最小约束

2026 年 7 月 24 日,Anthropic 技术团队成员 Thariq Shihipar 发布《The new rules of context engineering for Claude 5 generation models》,宣告了一个根本性的方向转变:为 Claude Opus 5/Fable 5,Anthropic 删除了 Claude Code 超过 80% 的系统提示词——编码评估无任何可衡量的下降。核心理由:旧规则是为弱模型写的 guardrails,Claude 5 不再需要这些约束;过度约束反而迫使模型消耗额外思考时间处理冲突指令。

这一发现不挑战本章四层范式(Prompt→Context→Harness→Loop)的架构正确性——Context/Harness/Loop Engineering 仍然成立。但它对 Context Engineering 的内部填充策略提出了 180° 校正:从”构建更精细、更全面的系统提示词”变为”删除系统提示词,信任模型的原生判断力”。

Six Shifts:Anthropic 新上下文工程法则

Anthropic 提出了六条 Claude 5 时代的上下文工程新法则:

#新法则旧做法对本章教学的影响
1Rules→Judgement给硬性规则(always/never)给原则性指导
2Examples→Interface Design堆示例引导行为设计自解释的工具接口
3Everything Upfront→Progressive Disclosure全量预置按需加载
4Repetition→Simple Tool DescriptionsSystem Prompt 与工具描述重复消除重复
5Memory in CLAUDE.md→Auto-memory手动维护文件依赖自动记忆
6Simple specs→Rich references文字描述规格HTML artifacts/测试集作规格

关键边界判断:Six Shifts 并不否定本章的教学价值。四层范式的演进(Prompt→Context→Harness→Loop)是 Agent 工程方法论的共识,每个范式内部的具体实践会随着模型能力提升而演变。Context Engineering 依然是 Harness Engineering 的核心组件——但现在它要回答的问题从”如何给模型最完整的上下文”变成了”如何给模型最精简的上下文”。用 Addy Osmani 的总结:“Claude 5 不再需要 guardrails,但你需要更好的 Loop。”

Harness Engineering 本身有多难:第一个外部度量(Doc2Harness,arXiv:2610.20344)。 上表把 Harness Engineering 立为一种范式,但全书此前的论据都是”Claude Code 做对了什么”——缺少一个外部可比的度量,读者无从判断”照着 Claude Code 抄一遍”的难度。2026-10-14 的 Doc2Harness 是第一个把构建 harness 本身作为评测对象的基准:

  • 两阶段设计:Stage 1 让 build model 在一个固定的 builder harness 里,仅凭一份接口-only 的契约骨架和一份汇总了 12 个前沿 harness 行为的开发文档,在隔离容器中构造出完整候选 harness;Stage 2 把冻结后的候选 harness 放到与构造环境分离的容器里逐测试用例运行,由一个脚本化的 mock model 端到端驱动——这样测的是 harness,不是驱动它的模型。
  • 评分通道:发给模型的请求、磁盘上的文件、进程退出码、命令输出,四条可观测通道;并设正向对照排除空过得分。
  • 结果:19 个前沿模型,每个做 3 次独立构建、328 个测试用例,最佳(GPT-6 Astra)53.05%,最差 27.44%,差距约 26 个百分点。最强的模型仍有接近一半的测试用例失败,且失败集中在跨模块的横切功能如何拆分。

对本章的教学含义有两条。其一,Harness Engineering 是一条有实测难度的工程路线,不是”把 Claude Code 的清单抄一遍”就能复制——最强模型在这个基准上也做不到 55%。其二,失败集中在横切关注点的模块划分上,这与本章的静态/动态边界、MCP/工具分层是同一类问题:边界划在哪里是 Agent 工程里最难被模型自动解决的部分。

⚠️ 边界:arXiv 元数据未给出 citation_author_institution,本书不标注机构;53.05% / 27.44% 为该论文摘要自报数字,未见独立复现。

中文社区将这一转变类比为”从管教小学生到信任成年人”——核心建议是审计 CLAUDE.md 中所有 always/never 类硬性规则,将其替换为原则性指导。这一讨论已是广泛关注的行业话题,非孤立的 Anthropic 内部实验。

源码引用:System Prompt 管理模块定义于 prompts.ts,辅助模块 systemPrompt.ts。

6.2 静态/动态边界分离

System Prompt 的第一个精妙设计是用 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 常量将内容分为两部分:

┌─────────────────────────────────┐
│ 静态部分(Static Segment)       │  ← 跨对话不变
│   - 角色定义                     │
│   - 工具使用指南                 │
│   - 安全规则                     │
│   - 输出格式规范                 │
│                                 │
│ ══ SYSTEM_PROMPT_DYNAMIC_BOUNDARY ══ │
│                                 │
│ 动态部分(Dynamic Segment)       │  ← 每次对话都可能变化
│   - 环境信息(OS、Shell、CWD)    │
│   - Git 状态                     │
│   - 工作目录列表                 │
│   - Feature Flag 条件内容        │
│   - MCP 工具描述                 │
│   - 用户自定义提示词             │
└─────────────────────────────────┘

这个边界分离的目的是什么?Prompt Caching。

Anthropic API 支持 Prompt Caching——如果两次 API 调用的 System Prompt 前缀相同,只需要为不同的部分付费。通过把不变的内容放在前面、变化的内容放在后面,Claude Code 可以最大化缓存命中率,静态部分只计费一次。

这是一个看似微小但在规模化使用中意义重大的优化。假设静态部分占 System Prompt 的 70%,那么每次对话可以节省 70% 的 prompt token 费用。

缓存可观测性:从”理论上能省”到”能测出省了多少”。上面 70% 这个数字是假设,不是度量。在 v2.1.251 之前,读者没有任何官方手段验证自己实际省了多少——/cost 只给总花费,缓存命中与否是个黑箱。两个版本改变了这件事:

  • v2.1.251(2026-08-28):/cost 新增每会话提示缓存行——命中率(hit ratio)、未命中数(misses)、重新缓存 tokens(tokens re-cached)、warm/cold 状态;并向状态行脚本暴露一个 prompt_cache 对象,可以把这些数字常驻在终端状态栏里。
  • v2.1.260(2026-09-03):/cost 与状态行的 prompt_cache 字段新增未命中的「可能原因」(likely cause)。官方给出的典型归因原文是:“tool definitions or the system prompt changed, or the session sat idle past the TTL”(工具定义或系统提示词发生变化,或会话空闲超过了 TTL)。

第二条的教学价值比第一条更大:它把本节抽象的 L1–L4 分层映射成了可定位的故障点。看到未命中时,按归因反查即可定位到具体层:

官方给出的未命中原因对应本节的层该查什么
system prompt changedL1 / L3Feature Flag 是否翻转、/model 是否切换、自定义提示词是否被改动
tool definitions changedL2工具集是否变化(MCP 服务器启停、--tools 调整、权限模式变更)
session sat idle past the TTL与分层无关(时间维度)会话空闲时长 vs 缓存 TTL 设置(见下)

换句话说,缓存命中率不再是一个只能靠”尽量别改 System Prompt”来祈祷的指标,而是一个能给出归因、能落到具体层的诊断信号。这也是本节二分法从”设计原则”升级为”可运维对象”的分界线。

第三条:可观测性从成本侧扩到内容侧(v2.1.300,2026-10-14)。 前两条量的是”省了多少”与”为什么没省”,都是成本侧。v2.1.300 把系统提示本身变成了可导出的工件:

Changed local session transcripts to also record each API request’s system prompt, tools and parameters, so a transcript you choose to share can reproduce a request exactly

两层教学价值。第一层是验证路径:6.9 那张占比表此前只能靠源码分析与社区逆向去估计(12,000–18,000 tokens),现在有一条官方路径拿到每个请求的真实 system prompt、tools 与 parameters——“静态段到底占多少”第一次可以被实测而非估计。第二层是分享边界变了:官方原文明确这份 transcript 是 “a transcript you choose to share”,即一份被分享出去的 transcript 现在包含完整的系统提示与工具定义。这与 6.8 Undercover Mode 的伦理讨论直接相连——“不想被别人看到的指令”现在会以可精确复现的形式离开本机;分享前要审的不再只是对话内容。

四层缓存模型

二分法是 Claude Code 的实现机制,但从概念层面看,System Prompt 的内容实际上有四层不同的缓存特性:

层级内容变化频率缓存命中率
L1:System Instructions角色定义、安全规则、输出格式几乎不变极高
L2:Tool Definitions42+ 工具的描述和 Schema工具集变化时才失效高
L3:Feature Flag / MCP 内容条件加载的模块、MCP 工具描述会话级别变化中
L4:环境信息 + 用户自定义OS、CWD、Git 状态、自定义 Prompt每次对话都可能不同低

Claude Code 的 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 将 L1-L2 划入静态段,L3-L4 划入动态段——这是实用的简化。理论上 L2 和 L3 之间还有进一步分离的空间(工具描述比 MCP 配置更稳定),但二分法已经捕获了大部分缓存收益。

“system prompt 被快照复用”有一个可直接引用的证据(v2.1.267)。 上面所有的缓存讨论都建立在”前缀逐字不变才命中”这一前提上,而这个前提此前是从原理推出来的。官方给的开关把它变成了可观测事实:

Added --system-prompt-snapshot off to render the system prompt fresh on every request instead of reusing the conversation’s recorded prompt (for iterating on prompt text)

既然有一个选项是”关掉快照、每请求重新渲染”,那么默认就是快照并复用会话里记录的那一份——这正是缓存前缀能保持稳定的实现前提。同一版本还把这条原则推广到了子代理与 --system-prompt / --append-system-prompt 启动的会话:

Improved prompt-cache stability: subagents and sessions started with --system-prompt or --append-system-prompt now record the system prompt and tool definitions once instead of re-rendering them

所以”改一个字就丢缓存”不是修辞。迭代 prompt 文本时要么接受每请求重渲染带来的缓存全丢,要么在改完之后另开会话,没有第三条路。

TTL:四层模型缺失的第二个维度。上表描述的是”内容按什么分层”,但缓存还有一个与之正交的维度——这条缓存能活多久。v2.1.243(2026-08-25)把这个隐含值变成了显式配置:

设置作用对象官方取值
promptCacheTtl主对话最长 1 小时
subagentPromptCacheTtl子代理5 分钟
experimental.cacheTtl(v2.1.248,代理 frontmatter)单个代理"5m" 或 "1h",在未配置上述子代理 TTL 设置时作为回退

(注:官方表述限定为 API-key 与云 provider 用户,订阅制用户的行为以官方当前文档为准。)

两点值得注意:

  1. TTL 不映射到 L1–L4。一条 L1 的静态指令和一个 L4 的环境信息片段,在同一个执行单元里共享同一个 TTL 生命周期。所以”变化频率”和”存活时长”是两个独立旋钮——前者由静态/动态边界控制(放哪儿),后者由 TTL 设置控制(留多久)。这也是本节原表没有”TTL 列”可填的原因:填进去对每一行都是同一个值。
  2. 主/子代理分治不是随意的。子代理生命周期短、前缀复用窗口小,给它 1 小时 TTL 只会占着缓存槽位而不产生命中收益。这恰好印证了上一段”L2 和 L3 之间还有进一步分离空间”的判断——缓存策略正在从按内容分层进一步细化到按执行单元分层。

作用域:四层模型缺失的第三个维度。前两个维度回答的是”放哪儿”(L1–L4)与”留多久”(TTL),第三个维度回答的是”谁能命中”——是只有当前会话能命中,还是新会话也能命中。v2.1.302(2026-10-16)第一次给出了官方证据:

Changed where the Claude in Chrome instructions sit in the system prompt so that new conversations can read them from the shared prompt cache

三个细节要写准。其一,被改动的是指令在系统提示中的位置,不是指令内容——为了让缓存能被共享,连注入位置都要调整。其二,目标是让新的会话(new conversations)能读到它,即缓存的受益者超出了产生它的那个会话。其三,官方称之为 shared prompt cache。

⚠️ 不得外推:官方只明示了 Claude in Chrome 指令这一段。任何”系统提示静态段现在跨会话共享”的写法都属于过度推断——本节其他三层是否落在共享缓存里,官方未说。

把它放进 6.2.1 那张表读,能看出这条的性质与前十余条相反:那张表全是负向条目(改一个字就丢缓存),这是第一条正向条目——为了让缓存能被共享而主动调整注入位置。手法与 v2.1.257 把 /fork 的 worktree briefing 从系统提示改成一条消息同源,但方向相反:v2.1.257 是”把内容挪出前缀以保住会话内缓存”,v2.1.302 是”把内容挪到能被共享的位置以扩大缓存受众”。两者合起来说明注入位置是一个有收益函数的决策变量,不只是实现细节。

下一代方案:TokenPilot 双粒度缓存(浙江大学 ZJUNLP,arXiv:2606.17016)。朴素的静态/动态二分法虽然有效,但忽略了前缀稳定性对 KV 缓存命中的核心影响——现有文本剪枝导致前缀不匹配→KV 缓存失效。TokenPilot 提出了更精细的双粒度解法:

  • 全局 Ingestion-Aware Compaction:识别稳定的 prompt 前缀(系统提示、工具定义等),压缩开放世界噪声但保持前缀不变——这是 6.2 节二分法的精细化升级,不只是”分清静态/动态”,而是”如何组织才能让前缀不变”
  • 局部 Lifecycle-Aware Eviction:监控上下文段的残余效用,仅在过期时批量卸载(而非立即碎片化删除)

实测数据:PinchBench 成本降低 61%,Claw-Eval 成本降低 87%。这一工作印证了 6.2 节末尾的判断——“L2 和 L3 之间还有进一步分离空间”——TokenPilot 为这个方向提供了工程实现路径,也代表了 Context Engineering 从”分清边界”演进为”主动维护前缀稳定性”的下一代方法论。

6.2.1 前缀稳定性的真实失效案例

TokenPilot 的”主动维护前缀稳定性”在本书里曾是一个前瞻论断——论点成立,但没有实例。2026-08-25 至 2026-09-08 的 15 天里,Anthropic 自己在 Claude Code 官方变更日志中修复了十余条提示缓存失效缺陷。这批实录正好构成该论断的实证,而且更有教学价值:它们全部不是”静态/动态分错了”。

按扰动来源归类:

扰动来源官方修复(版本)机制
工具定义被重新渲染v2.1.248长会话中约每小时一次的缓存未命中(并丢失 extended-thinking 上下文),根因是 OAuth token 刷新后工具定义被重新渲染
v2.1.248当账户进入用量超限(overage)时,ScheduleWakeup 的工具定义在会话与其 --resume 之间发生变化,导致恢复会话首轮整条缓存全丢
v2.1.257Remote Control 在会话中途连接时重新发送 Bash 工具定义
公告/上下文被重发或移出前缀v2.1.261in-process agent-team 队友在第二轮重发首轮的工具与技能公告,改变了请求前缀
v2.1.265agent 队友与恢复的子代理在后续轮次把 SubagentStart hook 上下文和预加载技能移出了提示词前缀
身份/环境切换改变前缀v2.1.265恢复前台派生的子代理时更改了其工具列表与系统提示词前缀
v2.1.257/fork 的 worktree briefing 原本以系统提示词更改的形式注入,改为作为一条消息到达,以在新后台会话保留原对话缓存
后台请求形成独立前缀v2.1.257设置了 advisor model 的会话在后台请求(压缩、/recap、提示建议)上丢失缓存,每次都把完整对话未缓存地重发一遍
副作用型失效v2.1.259遥测禁用的会话中,OAuth token 刷新导致缓存失效
v2.1.259阻塞型 Stop hooks 导致被 block 之后的轮次丢失该轮模型推理,并在部分模型上未命中缓存
v2.1.257截图密集的长会话中,一旦图片超过单请求体积上限,每一轮都未命中缓存

三个观察:

  1. 没有一条是分层错误。工具定义仍然在静态段、环境信息仍然在动态段,静态/动态边界划得完全正确——缓存一样全丢。因为真正决定命中的不是”内容属于哪一层”,而是请求前缀在字节层面是否逐字相同。二分法解决的是”放哪儿”,前缀稳定性解决的是”什么时候会变”,两者是不同层次的问题。
  2. 扰动源高度集中在”隐形重写”。OAuth token 刷新、账户用量超限、Remote Control 中途连接、Stop hook 阻塞、图片超体积——这些都不是用户主动改动了配置,而是系统内部状态变化顺带把前缀重写了一遍。这类缺陷最难自查,正是 v2.1.260 那条”可能原因”(见上)存在的意义。
  3. 修复手法本身也印证了二分法的价值。v2.1.257 把 /fork 的 worktree briefing 从”系统提示词更改”改成”一条消息”——这是在用动态段(消息)承载原本落在静态段的内容,代价是语义等价性,收益是保住原会话缓存。当缓存收益足够大时,连注入位置都要为它让路。

补充四条(v2.1.269–281):扰动源不只在会话内部。 上表的十一条全部发生在会话内部——工具定义、公告、环境切换、后台请求。官方随后修的四条把范围扩到了连接层、宿主层与输出侧:

扰动来源官方修复(版本)机制
MCP 连接层v2.1.281MCP 服务器在会话中断连,或恢复后仍在连接中,且 tool search 关闭时(如在 proxy/gateway 后)→ 丢缓存
宿主层v2.1.280宿主应用(Claude Desktop、VS Code、SDK)在 Claude 工作中切换模型 → 下一 prompt 缓存未命中
恢复路径v2.1.280恢复的 fork subagent 重建工具列表而非重发首次使用的那份 → 破坏该 agent 的缓存
输出侧事件v2.1.269响应在 output-token limit 被截断并自动恢复后,下一轮缓存部分失效

最后一条的分类和上表完全不同:它既不是工具定义变了,也不是环境变了,而是模型输出侧的一个事件反作用于下一轮的缓存状态。把它单列出来的意义是修正一个默认假设——排查缓存未命中时习惯去问”谁改了 prompt”,但截断恢复、后台请求、图片超体积这类输出侧与执行侧事件同样会污染前缀。

可观测性自身也会出错:v2.1.257 还修复了一个反向缺陷——把会话回退(rewind)到空之后,/model 与 /effort 会误报提示缓存告警。读到缓存告警时,先确认它是不是真的。

6.3 构建流程

getSystemPrompt 是主入口函数,它的构建流程如下:

getSystemPrompt()
  ├── 基础角色定义
  │     └── "You are Claude, an AI assistant by Anthropic..."
  │
  ├── 工具使用指南
  │     ├── 通用工具使用规范
  │     ├── 42+ 工具的 description(按工具列表动态生成)
  │     └── MCP 工具描述(如果有 MCP 客户端连接)
  │
  ├── Feature Flag 条件加载
  │     ├── PROACTIVE → 主动性模块(条件导入)
  │     ├── KAIROS → 日记模式模块
  │     ├── COORDINATOR_MODE → 协调器模式提示词
  │     ├── VERIFICATION_AGENT → 验证代理提示词
  │     └── ... 其他 20+ 条件分支
  │
  ├── 安全与隐私规则
  │
  ├── ═══ SYSTEM_PROMPT_DYNAMIC_BOUNDARY ═══
  │
  ├── enhanceSystemPromptWithEnvDetails()
  │     ├── 操作系统类型
  │     ├── Shell 环境
  │     ├── 当前工作目录
  │     ├── Git 状态
  │     └── 附加工作目录列表
  │
  ├── 用户自定义提示词(customSystemPrompt / appendSystemPrompt)
  │
  └── Memory Mechanics 提示词(SDK + KAIROS 路径覆盖时)

6.3.1 Advisor Strategy:架构反转对 System Prompt 的影响

2026 年 5 月,Anthropic 在 GitHub 开源了生产级 Agent 提示词(research_lead_agent.md 和 research_subagent.md),揭示了一个重要架构模式——Advisor Strategy。

传统多 Agent 系统采用”Orchestrator-Worker”模式:主 Agent 做所有决策,子 Agent 只负责执行。Advisor Strategy 颠覆了这一模式——子 Agent 同时做执行和决策,主 Agent 仅作为 Advisor/Reviewer。

这对 System Prompt 设计的影响是深刻的:

维度Orchestrator-WorkerAdvisor Strategy
主 Agent 角色决策者 + 分配者Advisor + Reviewer
子 Agent System Prompt简短指令(做什么)完整决策上下文(做什么+为什么+怎么做)
信息流向主→子(单向)双向(子自主决策,主审查)
System Prompt 体积主大子小主小子大
容错性主 Agent 单点故障子 Agent 可独立运作

在 Claude Code 的实践中,ForkSubagent 和 Agent Teams 已经体现了部分 Advisor Strategy 思想——子进程拥有独立的完整 System Prompt,而非仅仅接收主 Agent 的简化指令。这种”让执行者拥有完整上下文”的设计,是 Advisor Strategy 的核心教益。

“主小子大”的可观察边界。上表”System Prompt 体积:主小子大”是一个架构判断,v2.1.261(2026-09-04)给它提供了一个可以直接观察到的证据:官方新增标志 --append-subagent-system-prompt-file,用途是从文件读取子代理系统提示词,解决提示词过大而无法在命令行传递的问题(原文:“read the subagent system prompt from a file, for prompts too large to pass on the command line”)。

一个命令行工具需要为某一段提示词专门提供一个”改成从文件读”的开关,说明这段内容已经大到突破命令行参数长度限制。这比任何体积估计都更直观地印证了 Advisor Strategy 的体积反转:子代理的 System Prompt 不再是”一句话任务描述”,而是一个需要独立文件承载的决策上下文。

6.4 Feature Flag 条件加载

Claude Code 有 50+ 个 Feature Flag(32 编译时 Flag + 22+ GrowthBook 运行时门控),其中约 22+ 对外部用户隐藏。这些 Flag 不只控制功能开关,还直接影响 System Prompt 的内容:

// prompts.ts 中的条件导入模式(概念性)
const proactiveModule = feature('PROACTIVE')
  ? require('../proactive/prompts')
  : null;

const kairosModule = feature('KAIROS')
  ? require('../kairos/prompts')
  : null;

function getSystemPrompt() {
  const segments = [basePrompt];

  if (proactiveModule) {
    segments.push(proactiveModule.getProactivePrompt());
  }

  if (kairosModule) {
    segments.push(kairosModule.getKairosPrompt());
  }

  // ... 更多条件分支(v2.1.94 新增 `keepCodingInstructions` frontmatter 和 `hookSpecificOutput` 钩子类型)
}

这种设计的巧妙之处在于:Feature Flag 不是在运行时判断的——它们在构建时就被 Bun 打包工具处理了。如果某个 Flag 为 false,对应的模块代码根本不会出现在最终的 cli.js 中(Tree Shaking)。这既减少了包体积,也让反向工程变得更困难——你在泄露的代码中看到的 Feature Flag 分支,可能在实际发布版本中已经被完全移除了。

社区级验证:Karpathy Skills File。Andrej Karpathy 发布的 skills/dotfiles 仓库突破 104k stars,采用”system prompt as code”实践——将 Agent 指令以 Markdown 文件形式版本化管理。这与 Claude Code 的 CLAUDE.md + Feature Flag 体系形成有趣的对照:Karpathy 的方案更轻量(纯 Markdown + Git),适合个人开发者;Claude Code 的方案更工业(Feature Flag 编译时优化 + Prompt Caching),适合规模化部署。两者共享的核心洞察是:Agent 指令应该是版本化的、可审计的代码资产,而非写死在脚本中的字符串常量。

被遗漏的一种前缀扰动:切换模型。本节讨论的 Feature Flag 是构建时分支,但有另一类 System Prompt 变化发生在运行时且由用户主动触发——/model 切换。不同模型对应不同的指令段与工具使用指南,切换即意味着前缀变化,从而击穿提示缓存。v2.1.251(2026-08-28)为这件事补上了专门的检查点:

官方原文:“Added PreModelSwitch and PostModelSwitch hook events (block, confirm, or annotate a model switch); SessionStart resume hooks now receive session staleness and the estimated re-cache cost”

两个教学点:

  1. 换模型也是一种前缀变化,v2.1.251 给了它一个专门的 hook 事件。此前全书讨论的前缀扰动都是系统内部的(token 刷新、工具重渲染),而模型切换是第一个用户可见、可被拦截的扰动源——它可以直接被 hook 阻止(block)、要求确认(confirm)或附加说明(annotate)。这是 6.2.1 那批”隐形重写”缺陷的另一面:把不可控的失效变成可控的开关。
  2. 重新缓存成本被显式估算,并作为参数传给 hook。SessionStart 的 resume hooks 现在会收到会话陈旧度(staleness)与估算的重新缓存成本(re-cache cost)。这不只是可观测性(v2.1.251 的 /cost 缓存行)的延伸——它把缓存成本从”月底账单上的一个数字”提升为可编程的一等输入:hook 脚本可以据此决定”这个会话太旧了,恢复它不划算,干脆开新会话”。

⚡ 状态标注:/model 切换的这一路扰动已在 v2.1.271 修复。 本节把 /model 切换列为现行扰动,读的时候要带版本号:

Fixed /model warning about losing the conversation cache when switching back to the model the conversation actually ran on

官方修的是”切换回会话实际使用的那个模型时仍告警丢缓存”这一支。⚠️ 官方 changelog 只给了这一句的措辞,未展开机制细节,本章只标”已修复 + 版本号”,不据此推断工具定义是否重发。给这类条目加状态标注的必要性在于:读者若按已失效的行为去做规避(例如为了保缓存而不敢切模型),就是在为一个不存在的问题付出成本。

切换模型的第二重后果:它会触发一次压缩,而执行压缩的不是新模型(v2.1.301,2026-10-15)。 上面把 /model 切换列为一种前缀扰动——这是它的第一重后果。官方随后改进了同一操作的另一个侧面:

Improved switching to a model with a smaller context window: a conversation too long for the new model is now summarized by the previous model first

这条与前缀变化并列且独立:它不改变”换模型会击穿缓存”这个判断,而是补上了同一动作在系统侧的第二条分支——当新模型的上下文窗口更小、装不下当前对话时,先由切换前的那个模型把对话总结一遍。

两点值得单列。其一,一次用户视角的单个操作(换模型),在系统侧同时落在三条线上:前缀变化(6.4 本节)、缓存成本(v2.1.251 的 re-cache cost)、上下文压缩(第 9 章的五层压缩管线)。这是”用户操作”与”系统行为”多对多映射的一个干净样本。其二,执行压缩的模型不是新模型——摘要是由旧模型做的,而不是由窗口更小的目标模型做的。

⚠️ 不得推断:官方未说明这次摘要是否走 PreCompact hook、是否留下 compact_boundary 标记、是否计入 /cost 的压缩开销。本章只写”由切换前的模型执行”,不补充机制细节。

6.5 环境信息注入

enhanceSystemPromptWithEnvDetails 负责在动态段注入运行时环境信息:

// 注入的环境信息(概念性)
function enhanceSystemPromptWithEnvDetails() {
  return `
<env>
  OS: ${process.platform} (${os.release()})
  Shell: ${process.env.SHELL}
  CWD: ${getCwd()}
  Git Branch: ${getCurrentBranch()}
  Working Directories: ${getAdditionalWorkingDirectories().join(', ')}
  Date: ${new Date().toISOString()}
</env>
  `;
}

为什么要注入这些信息?因为模型需要知道它在什么环境下操作。比如:

  • OS 信息决定了模型应该生成什么样的 Shell 命令(bash vs PowerShell)
  • CWD 决定了文件路径的解析基准
  • Git 状态让模型知道当前在什么分支、有没有未提交的修改
  • 日期让模型不会产生时间上的幻觉

时间戳的呈现格式本身也是可配置项。v2.1.257(2026-09-01)新增 timeFormat 与 timeZone 两个设置:可选 12 小时制、24 小时制、24 小时 UTC,或自定义 strftime 模式。

⚠️ 口径更正:官方原文限定这两个设置的用途是 “the turn-end clock and transcript-view timestamps”——即轮次结束时钟与 transcript 视图的时间戳,两者都是面向用户的显示层,官方未表述其会改变注入 <env> 给模型看的日期。若按”时区设置会影响模型对’刚刚/很久以前’的判断”来使用,属于未经官方确认的推论,本节不予采纳。可以确认的只是:同一份上下文里,时间戳存在”给模型看”与”给用户看”两套呈现,而后者现在可配置。这两套是否应当统一(例如统一为 UTC 以避免跨时区协作的误读),值得在自己的场景里实测。

6.6 System Prompt 的优先级机制

当多个 System Prompt 来源冲突时,buildEffectiveSystemPrompt 函数定义了优先级:

优先级来源说明
1(最高)customSystemPromptSDK 调用方提供的自定义 System Prompt
2Coordinator Mode协调器模式的专用提示词
3Agent System Prompt子代理的专用提示词
4(默认)Default System PromptgetSystemPrompt() 构建的完整提示词

当 SDK 调用方提供了 customSystemPrompt 时,默认的 System Prompt 会被完全替换——但 appendSystemPrompt 会被追加到自定义提示词后面。这给了 SDK 调用方完全的控制权,还能通过 append 机制注入额外指令。

上表只描述了”谁覆盖谁”,没有涉及”内容从哪儿进来”。除 customSystemPrompt / appendSystemPrompt 这两个 SDK 级入口外,第 3 级 Agent System Prompt 在 v2.1.261(2026-09-04)新增了第三条注入路径:--append-subagent-system-prompt-file——从文件读取子代理系统提示词(见 6.3.1 节)。它作用在第 3 级之上、以追加而非替换的方式生效,解决的问题很具体:提示词大到命令行参数放不下。

同一入口的两种内容形式可以并用,且顺序是定的(v2.1.283,2026-09-25)。 上表只回答”谁覆盖谁”,没写”同一入口的多种内容形式怎么拼”。v2.1.283 给了 SDK 级两个入口的规则:

Changed --system-prompt and --append-system-prompt to accept their text and -file forms together; the file’s text comes first

即 --system-prompt / --append-system-prompt 的文本形式与对应的 -file 形式(如 --system-prompt-file)可以同时给出,文件内容排在前、命令行文本排在后。顺序决定了最终拼进 System Prompt 的次序——对有”最后一条指令权重最高”习惯的写法来说,这是一个需要显式确认的细节。

项目指令文件出现了第二种形态:AGENTS.md(v2.1.277)。 除 SDK 级入口外,System Prompt 还有一路内容来自项目里的指令文件。此前这条路径只有 CLAUDE.md 一种形态,v2.1.277 起多了一个回退分支:

Added AGENTS.md support: in a project with no CLAUDE.md, Claude Code reads AGENTS.md instead; change it under “Project instructions” in /config

两个细节要写准:触发条件是项目里没有 CLAUDE.md(有了就仍读 CLAUDE.md,不是合并);可在 /config 的 “Project instructions” 项下修改。v2.1.281 又把这个支持扩展到此前不覆盖的环境:

Changed AGENTS.md support to also work on Amazon Bedrock, Google Vertex AI, Microsoft Foundry, LLM gateways, and sessions with telemetry disabled

含义:项目指令的组装逻辑从”读不读得到 CLAUDE.md”变成”先找 CLAUDE.md,没有则退到 AGENTS.md,且这个回退在哪些环境下可用还分阶段放开”。跨工具协作的仓库(同一份 AGENTS.md 给多个 Agent 用)就不必再维护一份内容重复的 CLAUDE.md。

源码引用:优先级逻辑参见 systemPrompt.ts 中的 buildEffectiveSystemPrompt 函数。

6.7 内部用户 vs 外部用户

System Prompt 的另一个分化维度是用户类型。通过 process.env.USER_TYPE === 'ant' 判断,Anthropic 内部用户(“Ant”用户)和外部用户看到的 System Prompt 有显著差异:

维度内部用户外部用户
工具集可能包含 Tmux、内部工具标准工具集
Feature Flag更多实验性功能开启稳定功能
权限模板内部权限模板外部权限模板
采样率性能监控 100% 采样0.5% 采样

这个区分不是在配置文件里做的,而是直接编译进代码里——内部构建(Ant-native build)和外部构建走的是不同的编译路径。

6.8 Undercover Mode:当 Context Engineering 碰上伦理

泄露源码中引发最广泛讨论的发现之一是 Undercover Mode(隐身模式)。它是 System Prompt 的一个条件加载段,通过 Feature Flag 控制,启用时注入一组指令:

// 概念性重构(非原始提示词)
当启用 Undercover Mode 时,System Prompt 包含:
- 不要提及你是 Claude Code
- 不要列出你的内部工具名称
- 不要讨论你的系统架构
- 如果被问到你的身份,用通用方式回答

讽刺的是,Anthropic 精心设计的隐身模式,恰恰因为一个构建配置疏忽(source map 默认开启)而暴露在全世界面前。

技术本质

从实现上看,Undercover Mode 是纯粹的 Context Engineering——没有额外的代码逻辑,只有提示词。这意味着三件事:

  1. 它是建议性的,不是强制性的。模型可能在某些情况下仍然暴露身份——比如模型的安全训练可能与隐身指令冲突
  2. 它不影响功能。隐不隐身,工具能力和安全行为完全一样
  3. 它可以被 SDK 调用方覆盖。自定义 System Prompt 可以完全替换默认行为

最可能的启用场景是:Claude Code 作为其他产品的后端(通过 SDK 或 MCP)集成时,终端用户不应该知道他们在和 Claude Code 交互。

伦理争议

社区讨论集中在两个层面:

支持者认为这是标准的白标(White-label)商业实践——B2B 产品通常不暴露底层技术栈,用户不需要知道后端是 Claude Code,就像不需要知道网站用的是什么数据库。

反对者认为 AI 透明性是基本原则。“不承认自己是 AI”和”不暴露技术细节”是两回事,前者涉及欺骗。而 Anthropic 自己的负责任 AI 准则恰恰强调了透明性。

对 Agent 产品的启示

Undercover Mode 的争议提醒我们一个必须显式决策的问题:AI 应该在多大程度上暴露自己的身份和能力?这个问题没有通用答案,但不能默认忽略。它也说明 Anthropic 非常认真地对待 Claude Code 作为 B2B 基础设施的定位——它不只是一个面向开发者的 CLI 工具,还是一个可以被嵌入其他产品的 Agent 引擎。

6.9 最终组装后有多大

一个自然的问题:组装完的 System Prompt 到底有多长?

根据源码分析和社区逆向工程的估计,一次标准 CLI 会话的 System Prompt 大约 12,000-18,000 tokens(取决于工具数量和 MCP 配置)。其中:

Claude 5 视角:上述估算基于 Claude 4 时代的 System Prompt。Anthropic 已于 7 月 24 日宣布为 Claude Opus 5/Fable 5 删除 80%+ 系统提示词,实际 Claude 5 环境下 System Prompt 体积可能降至 2,000-4,000 tokens。两个数字都应保留——Claude 4 用户仍在使用旧版的 System Prompt 体系。由于 Claude 5 Prompt Caching 定价不同 + 体积骤降,Claude 5 环境下每会话成本可能下降 90%+ 而非此前估计的缓存后 $0.02-0.05。

反直觉提醒:体积变小 ≠ 缓存命中。上面”成本下降 90%+“的推论有一个隐含前提——减小后的前缀确实被缓存覆盖了。v2.1.260(2026-09-03)修复了 Claude Fable 5.1 上的一个缺陷,恰好说明这个前提可以单独失效:

官方原文:“Fixed prompt caching on Claude Fable 5.1 not covering the context attached after tool results, so it was re-sent as uncached input on every tool-call turn”

即:提示缓存没有覆盖”工具结果之后附加的上下文”,导致这段内容在每个工具调用轮次都被当作未缓存输入重发一遍。同版本还改进了 /effort:在 Fable 5.1 上,会话中途更改 effort 不再使提示缓存失效。

教学点有两层:

  1. System Prompt 变小只省了”前缀”那一段。在 Agent 场景里,真正被反复重发的是工具结果之后、下一轮输入之前的动态附加段——这是 6.2 静态/动态二分法没有覆盖的第三区域:它不属于静态段(每次工具调用都不同),也不落在动态段末尾(它在会话中间反复出现,而非一次性注入)。
  2. “删除 80% 系统提示词”的收益上限取决于缓存边界画在哪儿。前缀从 12,000 降到 2,000 tokens 是确定的;但缓存边界是否覆盖工具结果之后的段落,是另一个独立变量。这也再次说明 6.2 节新增的缓存可观测性(/cost 的命中率与未命中归因)为什么重要——只有测了才知道省下来的是不是你以为的那一段。
组成估计占比说明
角色定义 + 安全规则~15%静态段核心
工具描述(内置工具)~25-30%MCP Tool Search 推出后,MCP 工具不再全量加载,占比从 ~45% 下降;此数据为 v2.1.88 之前版本估计
Feature Flag 条件内容~10%因用户类型而异
MCP 工具描述~10-15%MCP Tool Search 按需加载后,仅少量常用 MCP 工具描述常驻
环境信息 + 用户自定义~15%动态段
预留/缓存优化~15-20%MCP Tool Search 节省的空间用于更多上下文容量

工具描述占比因 MCP Tool Search 的推出而显著下降——从 v2.1.88 之前版本的 ~45% 降至 ~25-30%(仅内置工具描述常驻,MCP 工具按需搜索加载)。节省的空间可用于更多上下文容量,这就是为什么工具延迟加载和 MCP Tool Search 对成本控制如此重要。

自动化维护:v2.1.205 引入的 /checkup(别名 /doctor)命令将 System Prompt 的上下文管理从”人工维护”升级为”自动化诊断”——自动识别未使用的 MCP 服务器(减少 St3 段的加载体积)、拆分臃肿的 CLAUDE.md(减少 L4 段的自定义注入)、关闭慢速 hooks、预批只读命令。这是 Context Engineering 从”设计时优化”走向”运行时自动管理”的标志——一个 12,000-18,000 tokens 的 System Prompt 不再依靠人工逐个审视,而是由 Agent 自身的工具链进行周期性巡检和修复。

Claude 5 迁移新定位:Opus Research 分析师 Amy Stapleton(2026-07-31)指出,/doctor 的定位正从”诊断上下文臃肿”升级为”识别旧模型时代的过时约束模式”。当团队从 Claude 4 迁移到 Claude 5 时,/doctor 可以标记那些为弱模型写的冗余 guardrails——这与 6.1.0 节讨论的”从最大约束到最小约束”范式反转直接呼应。

/skill-doctor:第三个测量点。v2.1.261(2026-09-04)新增 /skill-doctor——显示哪些已加载技能未被使用、以及它们各自占了多少上下文,便于清理(原文:“show which loaded skills go unused and what they cost in context, so you can prune them”)。

把它和 6.1.0 的 Six Shifts 放在一起读,能看出一条清晰的线:

Six Shifts 条目改变了什么对应的测量工具
第 3 条 Progressive Disclosure(全量预置 → 按需加载)技能/工具从常驻变为按需/skill-doctor(技能层)、/doctor(MCP 层)
第 5 条 Memory in CLAUDE.md → Auto-memory记忆从手写文件变为自动维护/doctor(CLAUDE.md 臃肿度)

第一个数量上限:子代理最多预加载 32 个技能(v2.1.295,2026-10-08)。 上表与 /skill-doctor、prompt-audit 测的都是体积——谁占了多少上下文。官方另给了一个性质不同的量:

Changed subagents to preload at most 32 skills from the skills field, each once; a subagent with the Skill tool can still invoke the rest

三个限定要写准:上限作用于子代理(subagents)、来源是 skills 字段、每个技能只预加载一次;持有 Skill 工具的子代理仍可调用超出部分,即 32 不是能力上限而是预加载上限。

这条给 Six Shifts 第 3 条(Everything Upfront → Progressive Disclosure)补了一个此前缺失的限定:按需加载不是无界的,预加载有 32 的硬顶,超出部分必须走运行时取用。于是”按需加载”从一种风格偏好变成一个有界机制——写子代理时若 skills 字段列了 60 个,实际只有 32 个会进入前缀,剩下 28 个要靠 Skill 工具现取,而这 28 个的取用本身又会改变请求前缀(参见 6.2.1 的”公告被移出前缀”一类扰动)。体积(占比表)与数量(32)因此是两个必须并列看的约束。

/doctor prompt-audit:继 /doctor 与 /skill-doctor 之后的第三个诊断入口(v2.1.283)。 前两个测的都是体积——哪些 MCP 没用、哪些技能白占上下文、CLAUDE.md 是不是太臃肿。prompt-audit 测的是内容质量:

Added /doctor prompt-audit (also /checkup prompt-audit) to audit your CLAUDE.md files, skills, agents and commands for prompting patterns written for older models

审计对象是 CLAUDE.md、skills、agents、commands 中为旧模型写的 prompting 模式。v2.1.283 同期还改进了报告排序:

Improved prompt-audit on Claude Code configuration: stale paths, stale commands and contradicting instruction files now lead the report, and thinking keywords that Claude Code documents are kept

过期路径、过期命令、互相矛盾的指令文件排在前面——这三类恰好是”规则越多越坏事”最容易堆积的地方。

它的定位值得单独说一句:这是官方给出的第一个直接面向 System Prompt 内容质量的测量点,把 prompt 工程从”写作技艺”变成了”可被工具诊断的对象”。它还呼应 6.1.0 的 Six Shifts 第 1 条(Rules → Judgement)——为旧模型写的硬性规则式 prompting 现在被官方视为需要清理的债,而不只是风格偏好。

也就是说,Six Shifts 告诉你上下文”应该怎么组织”,/doctor + /skill-doctor + prompt-audit 告诉你”这次转变到底省下没有、以及有没有留下过时的写法”。Anthropic 连续给出了 MCP、CLAUDE.md、技能、prompt 内容四个测量点——这本身就是一个信号:上下文成本可度量正在从”高级技巧”变成”常态能力”。对 6.10 设计启示第 5 条”量化你的 Prompt 预算”而言,这意味着”量化”这件事的门槛已经从”自己写脚本数 token”降到了”敲一条命令”。

缓存边界正在从内部实现外溢成调用方可声明的接口。 静态/动态分离此前只是 Claude Code 的内部实现(本节 6.2 的 SYSTEM_PROMPT_DYNAMIC_BOUNDARY),读者只能通过”尽量别改前缀”去迎合它。两个版本把它交到了调用方手上,而且是两个不同的入口:

入口版本声明方式粒度
自定义系统提示v2.1.275(2026-09-17)在 --system-prompt 里放一行仅含 __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ 的文本一刀切成两段
mods 的 $.model.completev2.1.292(2026-10-06)prompt 与 system 接受文本块,块上置 cache: true逐块声明缓存点

两条官方原文分别是:

Improved prompt caching for a --system-prompt that contains a __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ line: the text above it is now cached globally, as the SDK’s array form already is

Added prompt caching to $.model.complete for mods: prompt and system take blocks of text, and cache: true on a block caches the request up to it

三点读法。其一,v2.1.275 的官方措辞是 cached globally——标记线以上的文本按”全局”缓存,这与 6.2 新增的”作用域”维度是同一件事的不同侧面:调用方也能影响缓存的作用域。其二,v2.1.292 的粒度更细:cache: true 缓存的是到该块为止的请求,多个块可声明多个缓存点,比”一刀切成两段”更贴近 6.2 末尾”L2 与 L3 之间还有进一步分离空间”的判断。其三,第二条属于 Claude Mods(v2.1.287,见第 2 章),即声明缓存点的能力是随第四种扩展机制一起到来的。

这与 6.10 第 8 条”Context Engineering 工程化生态正在形成”是同一个趋势,但性质不同:第 8 条说的是第三方工具链在做上下文工程,这里是官方自己把接口交出来——“静态/动态分界”从一处只能遵守的实现约束,变成了一个可以声明的参数。

6.10 设计启示

从 prompts.ts 中可以提炼的不只是技术细节,而是一套方法论:

  1. 静态/动态分离是必须的。只要你的 AI 产品使用 Prompt Caching,就应该把不变的内容放前面。这个简单的优化可以节省大量成本。

  2. Feature Flag 不只是功能开关。它们控制着模型看到什么信息、拥有什么能力。这让同一个代码库可以服务于不同的用户群体和场景。

  3. 环境信息是上下文的一部分。模型不知道自己在哪台机器上运行——你必须告诉它。操作系统、Shell、工作目录、时间——这些都是”上下文工程”的组成部分。

  4. System Prompt 是一个动态系统,不是一个静态文件。如果你的 AI 产品的 System Prompt 是一个写死的字符串,你可能低估了这个环节的复杂度和重要性。

  5. 量化你的 Prompt 预算。12,000-18,000 tokens 的 System Prompt 在 Opus 模型上每次对话的成本约 $0.18-0.27(无缓存)。Prompt Caching 可以将这个数字降到 $0.02-0.05。这个差距足以决定产品的商业可行性。

⚡ 做这类测算的输入值已变(v2.1.280)。 上一段的单价是 Claude 4 / Opus 5 时代口径。官方在 v2.1.280 换了默认 Opus:

Added Claude Opus 5.5 (claude-opus-5-5), now the default Opus model — 1M context, 4/4/20 per Mtok with $0.20/Mtok cache reads

三个可直接用于重算的数字:上下文 1M、输入/输出 $4/$20 每 Mtok、cache reads $0.20/Mtok。其中 cache read 价是算”缓存到底值不值”的关键输入——把系统提示词命中缓存的部分按 $0.20/Mtok 计,未命中的按 $4/Mtok 计,两者的比值决定了 6.2 节那套前缀稳定化工作的实际回收周期。上一段的 $0.18-0.27 / $0.02-0.05 保留作为旧口径对照,不要直接混用。

  1. Anthropic 官方方法论的三策略框架。Anthropic Cookbook 发布的 Context Engineering 实战指南提炼了三种核心策略:Memory(结构化笔记持久化关键信息)、Compaction(压缩旧消息释放窗口空间)、Tool Clearing(清理冗余工具结果)。Claude Code 的 System Prompt 工程不是孤立设计,而是这套方法论在生产环境中的实例化——Memory 对应 CLAUDE.md / Memory Mechanics,Compaction 对应第 4 章的五层压缩管线,Tool Clearing 对应工具结果截断和 readFileState 缓存。

  2. 1M 上下文窗口改变了 Prompt 预算的经济学。v2.1.89+ 支持的 1M 上下文窗口让 System Prompt 的占比从 6-9%(基于 200K 窗口)降到约 1.2-1.8%。“Prompt 太长”不再是核心瓶颈,但静态/动态分离的缓存价值不变——绝对节省的 Token 数量相同,缓存对成本控制仍然至关重要。

⚡ 口径限定:1M 不是”装了就有”,同一个模型名在不同通道下窗口可能不同。 上面那组占比数字(6-9% → 1.2-1.8%)必须带上”在 1M 通道下”这个前提,否则在网关场景下会算错一个数量级。两个版本把 1M 的覆盖面推出了 Anthropic 直连:

  • v2.1.287(2026-10-01):Opus 4.7+ 与 Fable 在 Bedrock / Vertex / Foundry / Claude apps gateway 上默认使用 1M 窗口,且不再需要 [1m] 后缀(CLAUDE_CODE_DISABLE_1M_CONTEXT=1 保持 200K)。
  • v2.1.285(2026-09-29):使用自定义 ANTHROPIC_BASE_URL 的会话同样取模型的 1M 窗口(Opus 4.7+、Sonnet 5+、Fable);若网关只到 200K,官方建议跑 /autocompact 200k。

由此产生一个此前不存在的口径陷阱:同一个模型名,直连时是 1M、经某个网关时可能只有 200K。做 Prompt 预算测算前先确认窗口档位,不要按模型名默认。(同一事实在 ch00 阅读提醒第 8 条与 §上下文(v2.1.247)的 967K 阈值处亦有标注,三处口径一致。)

延伸:当硬限制不再是问题时,Prompt 的信息密度(而非长度)成为更关键的设计维度。Claude Code 的静态/动态分离策略从”节省 Token 费用”演进为”最大化有效信息比”——静态段的缓存价值仍存在,但动态段的质量和相关性更加关键。

  1. Context Engineering 工程化生态正在形成。Claude Code 的 System Prompt 工程不是孤例,而是更大趋势的标杆实践。2026 年三个关键工具标志着 Context Engineering 从概念走向工程化:(1) shadcn/skills(2026.03)将技能定义为可安装的上下文单元,与 Claude Code 的 Plugin 系统理念一致;(2) PromptArch v2(2026.04)推出 Context Engineering Studio,提供可视化上下文编排环境;(3) GSD Build 开源元提示系统,以 meta-prompting + context engineering + spec-driven development 三支柱构建 Agent 上下文。Claude Code 的 prompts.ts 动态构建系统本质上是一个手工实现的 Context Engineering Studio——随着生态成熟,类似的动态组装能力可能被更通用的工具链替代。