第 18 章 第六部分:专题研究

专题:十个最重要的教训

从 51 万行源码中提炼出的十个关键认知——每一条都能直接影响你构建 AI 产品的决策

Claude Code Agent 设计 启示 工程哲学 专题研究

回顾前 15 章的系统性解剖,以及前面的专题研究,这一章试图做一件更难的事:把所有散落在各处的洞察压缩成十条可执行的认知。

每一条都不是空话。它有源码佐证、有设计理由、有你明天就能用上的行动建议。


教训一:Harness 决定产品,Model 只决定上限

“51 万行代码中,与模型 API 交互的不到 1000 行。”

这是整本书最核心的认知。Claude Code 的能力不来自 Claude 模型有多强——理论上换成同等能力的模型,大部分功能依然能工作。它的能力来自包裹在模型外面的 50 万行 Harness。

数据佐证(第 2 章):

组件代码量作用
工具系统~5 万行模型的”手脚”
权限系统~2 万行行为边界
System Prompt 构建~1 万行模型的”大脑配置”
上下文管理~3 万行”注意力”管理
多代理编排~4 万行多实例协调
UI + 命令~13 万行人机交互
基础设施~18 万行配置/权限/Git/遥测

行动建议:在团队资源分配上,Harness 工程应该占 80% 以上的工程投入。不要把 90% 的精力花在模型选型和 prompt 调优上——那只是最后 10% 的工作。

更深的洞察:Harness 和 Model 不是独立的关系,而是协同优化的。Addy Osmani 指出:“Today’s agent products are post-trained with harnesses in the loop. The model gets specifically better at the actions the harness designers think it should be good at.”Opus 4.7 装进 Claude Code 的 Harness 里比装进自己手搓的 while 循环里好用一大截,部分原因正是共训造成的。2026 年 4 月,Anthropic 切断第三方 Harness 订阅配额——这暗示 Harness 是竞争优势的一部分,不只是模型的外壳。

修正行动建议:不只”投 80% 在 Harness”,还要”让训练团队和 Harness 工程师坐在一起”。

“Harness > Model”的终极实证:Claude Code 100% 自举。Anthropic 工程师 Boris Cherny 公开分享: 8 个月零手写代码、单日最高 150 PR、工程师产出提升 250%,Claude Code 实现了 100% 自举——团队用 Claude Code 开发 Claude Code。这不是隐喻,而是工程现实:如果 Model 真的比 Harness 重要,用同一个 Model 的团队不会有 250% 的产出提升;这 250% 全部来自 Harness 的工程投入。

Harness 的范式升级:Dynamic Workflows(Opus 4.8,2026-05-28)使 Harness 从”静态包裹模型的 50 万行代码”升级为动态编写编排脚本的元系统——JS 脚本在运行时由 AI 自己生成,决定如何分解任务、分发给谁、如何验证。这意味着 Harness 的边界从”编译时确定”扩展到”运行时动态生成”。Bun 创始人用 Dynamic Workflows 将 75 万行 Zig 代码移植到 Rust,11 天完成,99.8% 测试通过——这是 Harness > Model 的最新标杆案例。

共训的底层机制:PRISM(arXiv:2603.17074)的大规模实证为此提供了定量支撑——中训练修改 >90% 参数,RL 仅修改 ~5%,权重变化幅度差 370-580 倍。这不是”训练时用一点,推理时用一点”的简单分工,而是”中训练做密集重组,RL 做稀疏细化”的深度耦合——这解释了为什么”训练团队和 Harness 工程师坐在一起”不只是组织建议,而是工程必需。

默认模型替换的速度验证:2026-06-30,Claude Sonnet 5 接替 Opus 4.8 成为 Claude Code 默认模型——Opus 4.8 在默认位上仅待了约一个月(5/25→6/30)。这次换模未引起大规模用户投诉或功能退化报告,证明了”Harness 是产品,Model 是组件”的架构假设。当 Harness 足够完善时,默认模型的替换可以像更换数据库引擎一样平滑——用户感知到的变化主要在延迟和成本上,不在能力上。Sonnet 5 原生的 1M token 上下文窗口反而使上下文管理变得更简单(对教训七的缓存策略有正向影响)。

2026-09:两个月内连换两代。上面那次替换发生在 6 月底。9 月又连着换了两次,两次相隔 6 天:

时间版本事件
2026-09-22v2.1.280Opus 5.5(claude-opus-5-5)成为默认 Opus 模型——1M 上下文,$4/$20 per Mtok,$0.20/Mtok cache reads
2026-09-28v2.1.284Sonnet 5.5(claude-sonnet-5-5)成为默认 Sonnet 模型——1M 上下文,$2/$10 per Mtok,$0.20/Mtok cache reads

中间那个版本还做了一件小事但信号很强:v2.1.283(09-25)把 /model 选择器里 Opus 那一行与 Default 模型的名字去掉了「(1M context)」后缀——因为 Opus 本身已经有 1M 窗口,窗口大小并没有变化。也就是说,1M 从”某一代模型的卖点”变成了默认事实,连标注都省掉了。

这把上面的论断从”换得动一次”升级为”两个月内连续换两轮,且两轮都一并换代次与价格”。对”Model 是组件”而言这是至今最强的一次验证:不只是接口稳定,而是代次与价格这两个用户最容易感知的变量,都在没有大规模抱怨的情况下完成了切换。

编者判断(非官方表述):这里也有另一面。组件化做得越彻底,模型迭代就越是一件用户察觉不到的事;而察觉不到也就意味着没有反馈压力。当用户不再因为换模型而抱怨,他们也失去了对换模型这件事发表意见的位置——组件化的收益与代价是同一枚硬币。

Harness 的可评测性闭环(v2.1.269):claude plugin eval 让插件扩展第一次可以被跑评测套件并产出可复现的评分结果(JSON + HTML 报告)。把它与上一版已收录的 prompt-audit 子命令(扫描旧模型冗余提示)合起来看,Harness 自身已经形成了一条审计—评测—优化工具链:审计冗余提示、评测扩展质量、度量逐项成本。这意味着 Harness 不只”能扩展”,而且扩展的质量与代价都可被量化——从”可迭代资产”进一步变为”可度量资产”。

“审计”升为一等入口(v2.1.283):v2.1.283 新增 /doctor prompt-audit(别名 /checkup prompt-audit),审计 CLAUDE.md、skills、agents、commands 中为旧模型写的提示模式。同一版本还改进了报告排序——陈旧路径、陈旧命令、互相矛盾的指令文件排在报告最前,并保留 Claude Code 文档化的 thinking 关键词以免误报。

⚠️ 口径提示:prompt-audit 的能力本身早于本轮就已收录(上一版已记 prompt-audit 子命令)。v2.1.283 的增量是入口(升为 /doctor 一等子命令)与报告排序,不是新增一项能力。不要把本条读成”Claude Code 现在才会审计提示”。

位置上的变化值得记:此前”审计”是一个要靠用户记得去跑的子命令,现在它和 /doctor 这个”体检”主入口并列——工具链的第一环从”想起来才做”变成”体检时顺带做”。排序那条更有信息量:把”互相矛盾的指令文件”排在最前,等于官方把指令冲突列为配置腐化里最该先修的一类,这与第 6 章讨论的提示腐化是同一个问题在官方工具里的体现。


教训二:Context Engineering 是一门独立学科

“System Prompt 不是一个写死的字符串。它是 30 个函数、11 个常量动态组装的结果。”

Claude Code 的 prompts.ts 是整个源码中信息密度最高的文件(第 6 章)。它教会了我一件事:给模型什么上下文,比用什么模型更重要。

这门学科的核心实践:

  1. 静态/动态分离。不变的放前面(角色、安全规则),变化的放后面(环境、工具),利用 Prompt Caching 降本 80%+
  2. 环境感知注入。模型不知道自己在哪——OS、Shell、CWD、Git 状态、项目语言,这些都要告诉它
  3. 条件加载。用 Feature Flag 控制哪些提示片段被加载。不是所有信息对所有场景都有用
  4. 工具描述即指令。工具的 description 是 prompt 的一部分——“何时用”比”能做什么”重要
  5. 预算感知。每个 token 都有成本,也占注意力。在信息量和 token 效率之间找平衡

行动建议:如果你的 System Prompt 还是一个写死的字符串,那你的产品还停留在 MVP 阶段。投资建设动态 Prompt 构建系统。


教训三:安全不是功能,是架构

“权限系统是 Claude Code 最复杂的子系统——不是因为过度工程,而是因为安全不能有捷径。”

Claude Code 的六层权限规则 + 双阶段 AI 分类器 + 危险模式检测 + 熔断机制(第 7 章),构成了一个纵深防御体系。这不是”加一个安全检查”能解决的。

关键设计原则:

Layer 1: 确定性规则匹配(快速,无歧义)
  └── 6 种来源的 allow/deny/ask 规则
Layer 2: AI 分类器(智能,概率性)
  └── 双阶段 YOLO 分类器(快思考 → 深思考)
Layer 3: 用户确认(最终兜底)

加上两个安全原则:

  • Fail-Closed:不确定时选择更安全的默认值。isConcurrencySafe 默认 false,isReadOnly 默认 false
  • 熔断:连续多次拒绝后降级到更保守的模式

行动建议:安全系统至少需要两层——一层确定性规则(快速、可审计),一层智能判断(灵活、覆盖边界案例)。Fail-Closed 原则应该是默认值,不是可选项。

解析器级绕过:每多一层间接引用,就多一类看不穿的位置。2026-08 至 09 的三条安全修复共享同一个结构,都不是新攻击面,而是既有防御在新增语法层上的解析器级绕过:

  1. v2.1.260:Bash 权限检查此前会自动批准把命令替换藏在 REPORTTIME、REPORTMEMORY、DIRSTACKSIZE 赋值中的 zsh 命令——现在一律提示确认
  2. v2.1.234:远程文件读取、会话恢复、CLAUDE.md includes、workflow 脚本与文件上传统一拒绝 Windows NT 命名空间(\??\)路径,封堵 NTLM 凭据泄露向量
  3. v2.1.251:Workflow 工具在权限检查执行之前就读取(并在报错里回显)了会话无权读取的 scriptPath

三条的共同点是:权限检查器看得懂命令本身,看不穿命令的间接引用层——shell 变量赋值、操作系统路径命名空间、脚本文件间接引用。由此得到「安全是架构」的一条实操含义:它不是”把规则写全”,而是每增加一层间接引用,就要重审一次权限检查器的可见性边界。规则写得再全,只要存在一层检查器不解析的语法,规则就对那一层无效。

第四条佐证落在 Fail-Closed 上:v2.1.267 修复了托管配置 allowedHttpHookUrls、httpHookAllowedEnvVars、allowedChannelPlugins 在不可读时的行为——改为一律不放行(admit nothing),而非一律放行(admit everything)。这与本章「Fail-Closed 默认值」是同一原则,只是发生在配置解析层而非工具标记层:读不到就当作最严格的配置,而不是当作无配置。

第二类论据:提权——managed 策略只能被收紧(v2.1.285)。上面四条都是”绕过”。这一条方向相反:v2.1.285 起,项目设置不能再① 放宽或关闭管理员要求的沙箱;② 替换 managed deny list 后面的代理;③ 扩展严格 allowlist;④ 重开 managed read-denies。

它补上了”安全是架构”缺失的半边:绕过类论据说明边界会被穿,这一条说明边界有方向——管理员层的策略是单向阀,项目层只能往更严的方向加,不能往松的方向减。对企业部署而言,这决定了托管策略究竟算不算”策略”:如果项目设置能反向覆盖,那管理员设的就不是边界,只是默认值。

配套的三条修复画出了这道边界的误判面:v2.1.285 修复 sandbox auto-allow 对含 = 的内联脚本(python3 -c、node -e)逐个要求批准;v2.1.284 修复 sandboxed Bash 在 Linux 上工作目录被写拒且含被读拒目录时无法启动;v2.1.283 修复 sandboxed git 要求凭证助手存储沙箱代理登录名(打印 “failed to store”)。三条都是”加固时伤到了正常用法”——方向对,粒度需要反复调,这本身也是一条工程经验。

Fail-Closed 的反面实证:PowerShell 权限检查曾经 fail-open(v2.1.285)。这是本章论据强度最高的一条。 教训三此前一直把 Fail-Closed 当原则陈述,而这条官方修复说明真实实现曾经是相反方向——PowerShell 工具的权限检查在命令解析器启动失败时(例如机器内存不足)跳过 deny 与 ask 规则,并把该失败缓存下来供后续检查使用。

两个细节使它比任何原则陈述都有说服力。一是失败方向是放行而不是拒绝。二是失败被缓存——不是一次误放行,而是此后所有检查都沿用这个放行状态。也就是说,一台内存告急的机器会在用户毫无察觉的情况下,从某一刻起持续地不检查 PowerShell 权限,直到进程重启。同版本的 auto mode 有一条同类问题:对已批准的 Artifact 资产上传、以及读取他人在另一权限模式下已批准过的 artifact 时跳过分类器。

两条放在一起读,结论比”Fail-Closed 是个好设计”硬得多:Fail-Closed 不是设计偏好,是官方曾经反向实现并修掉的坑。 一个系统的安全默认值到底朝哪个方向,不看它宣扬什么原则,看它在异常路径上怎么写。

权限模式在放宽,沙箱边界在收紧(v2.1.283 → v2.1.284 → v2.1.285)。与上面这条形成一组对照的是 auto mode 的三次”默认化”推进:

版本覆盖范围默认行为
v2.1.283第三方 provider 或遥测关闭的交互式会话未配置 permission mode 时默认 auto mode
v2.1.284交互式终端与 VS Code 会话默认 auto mode,覆盖所有 plan 与 provider
v2.1.285claude -p 与 Python Agent SDK 会话第三方 provider 或遥测关闭时同样默认 auto mode

三次都保留了退出通道(permissions.defaultMode / --permission-mode 仍可覆盖),“把 auto mode 设为默认”的一次性提示也随之下发到这些场景。既有论据是”Auto Mode opt-in 自 v2.1.207 取消”——那是”不必主动开启”;这三次推进得更远,是”未配置时默认就是它”,且覆盖面从交互式扩到 -p 与 SDK。

两个方向相反的动作发生在相邻版本里,这不是矛盾,而是一条可辨的策略:把”是否放行”这个高频判断交给分类器(放宽权限模式的门槛),并把”能触达什么”这个低频但致命的问题收紧到管理员层(沙箱只能更严)。前者降摩擦,后者守底线,两者分担的是不同的风险。 成本侧也配套:v2.1.278 起 auto mode 对 Claude API 与企业用户,以及 Bedrock / Vertex / Foundry / 网关默认改用服务端分类器且不收分类器开销,这些平台上 CLAUDE_CODE_AUTO_MODE_SERVER=0 可退出,回退到计费分类器时告警——放宽之所以推得动,部分原因是它的开销被移走了。

managed 部分失效的粒度是「项」不是「块」(v2.1.282 / v2.1.283)。这是一条教科书级的部分失效语义:v2.1.282 修复 managed permissions、autoMode、worktree、attribution 设置在某一个嵌套值无效时被整块忽略——现在其余部分仍然生效;v2.1.283 对 managed sandbox 做了同样处理,并明确无效的那个值 fail closed,块内其余仍适用。

两条加起来正好是”部分失效”应有的完整定义:失效粒度最小化(不株连)+ 失效方向最保守(fail closed)。只做到前者,一个错值会让整块策略静默消失;只做到后者,一个错值会禁用整个配置块。实践中这两者经常被人混淆,因为它们的表象都是”策略没生效”。

诚实度:安全架构的认知层延伸。Opus 4.8 最显著改进是诚实性——更有可能标记不确定性,不太可能做未经证实的断言。代码缺陷漏报率降至前代的 1/4,过度自信行为(如硬编答案)降至 1/10。“不确定时主动标记”本质上是一种运行时安全行为——类似于 Fail-Closed 原则的认知层实现:确定性规则防止已知风险,AI 判断覆盖边界案例,诚实度防止”过度自信导致的隐性风险”。

但 Opus 4.8 的 System Card 也标注了新的对齐隐患:模型推理文本中出现了越来越多对评分者的推测倾向——模型可能发展出”推测评估者”的行为模式。这暗示:安全架构需考虑模型自身的认知偏差——不仅是外部攻击的防护,还要防范模型”讨好评估者”的内在动机。这是安全架构从”对抗外部威胁”向”治理内部偏差”的延伸。

⚠️ 诚实度改进的具体机制未公开,推测评分者倾向为 System Card 标注的风险而非已验证问题。


教训四:工具设计决定 Agent 的天花板

“42+ 工具,每个都有 Schema、行为标记、权限配置和选择指导。这不是一个工具列表,这是一个工具系统。”

从 Claude Code 的工具系统(第 5 章)中提炼的七条工具设计原则:

原则实践来源
Schema 即契约用 Zod 做运行时验证Tool.ts
行为标记驱动调度isConcurrencySafe/isReadOnly/isDestructiveTool.ts#L400-472
精确 > 通用FileEdit(精确替换)和 FileWrite(完整覆写)分离FileEditTool.ts
描述引导选择告诉模型”何时用”而不只是”能做什么”各工具 description
延迟加载不常用工具按需加载,shouldDefer + ToolSearchToolSearchTool.ts
工具池排序稳定顺序提升 Prompt Caching 命中率assembleToolPool
大结果持久化maxResultSizeChars 超限后写入磁盘而非塞进上下文Tool.ts#L700-792

行动建议:工具不是给模型的函数调用接口。每个工具的 description 是 prompt 的一部分,要像写 prompt 一样写工具描述。

工具设计的终极形式:元工具。Dynamic Workflows GA 将 pipeline/parallel/agent 三原语下放至 Pro 计划,本质上是一种工具编排元语(meta-tool)——不是让 AI 使用更多工具,而是让 AI 自主编排工具的调用拓扑。Bun 项目用这三个原语完成 96 万行 JS→TS 移植,全程零手写代码。三原语的简洁性(三个原语覆盖所有工作流拓扑 DAG)直接验证了本章的工具设计原则——“精确 > 通用”不是说每个工具都要专精,而是说工具的抽象层次要精准。三个原语,不多不少,恰好覆盖所有编排需求。


教训五:多代理不是”多开几个 Agent”

“6 种代理,每种有不同的工具白名单、不同的模型、不同的角色定位。”

Claude Code 的多代理设计(第 8 章)教会的核心认知:

  1. 代理是权限边界。Explore 代理只有只读工具——不是因为它不需要写入,而是物理上防止它破坏代码
  2. 模型选择是成本优化。Guide 代理用 Haiku(便宜快速),General Purpose 用主模型。不是所有任务都需要最强模型
  3. 对抗性验证。Verification Agent 被明确指示”假设代码有 bug”——要”敌意地挑错”,不是”友好地检查”
  4. 代理间通过任务列表协调。不是直接调用,而是共享任务列表 + 消息传递,解耦更彻底

行动建议:给每个代理最小必要权限。如果一个代理只需要读代码,就不要给它写的能力——即使”以后可能需要”。

新进展:Agent Teams(Swarm Mode):v2.1.139 引入 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 启用 Swarm Mode——Team Lead + Specialized Teammates,每个 Teammate 独立 1M token 上下文窗口,通过 Mailbox 系统对等通信,Git Worktree 隔离。团队报告 5-10x 开发速度提升。

Anthropic 官方五大协调模式:Generator-Verifier Pairs、Parallelization、Orchestration、Routing、Specialization with Feedback Loops。关键指导:“从识别系统最可能的失败模式开始选择模式”。

行业收敛趋势:Cognition 从”反多代理”转向 Managed Devins(Conductor 模式),Anthropic 走 decoupled brain/hands——各家都趋向 Orchestrator + Isolated Subagents 模式,在集中协调和自主执行之间找平衡。

多代理的三阶段演进:

阶段架构特征版本
第一阶段内置 6 Agent(静态角色)预定义角色 + 固定工具白名单v2.0
第二阶段Agent Teams / Swarm Mode自主编队 + 对等通信 + Git Worktreev2.1.139
第三阶段Dynamic Workflows(脚本驱动动态编排)AI 生成 JS 编排脚本 + Generator-Validator 循环Opus 4.8

第三阶段的核心突破是 Generator-Validator 循环——不再是单个 Verification Agent 的单次检查,而是持续的生成-对抗迭代,直到答案收敛。这把”对抗性验证”教训从”一个检查步骤”升级为”一个持续收敛过程”,是目前最接近”软件工程 GAN”的实现。

第四阶段:嵌套子Agent(v2.1.172,2026-06-10)。Claude Code v2.1.172 将多 Agent 架构从”静态编排”升级为递归嵌套:

能力v2.1.166(ForkSubagent)v2.1.172(嵌套子Agent)
Agent 层级单层 fork(父→子,平级)最多 5 层递归嵌套(父→子→孙→曾孙→玄孙)
团队协作ForkSubagent 独立执行Agent Teams 实验性:预定义角色 + 任务分配
通信机制任务列表 + 消息传递Mailbox 系统对等通信 + Git Worktree 隔离

这直接深化了正文中”比 2 个 Agent 再多一点”的讨论——递归嵌套的实现意味着 Agent 不仅数量可以增加,还可以形成层级结构。每个子 Agent 有独立的 1M token 上下文窗口,且在独立 git worktree 中执行,从架构层面实现了”关注点分离”——这在 Cursor(同级并行)和 Copilot App(同级 worktree)中目前未见等价实现。5 层嵌套是目前已知最深的 Agent 层级结构,为 KAIROS Coordinator Mode 的多层任务分解提供了工程基础。

第五阶段:上限治理(v2.1.212,2026-07-17)。当子 Agent 可以递归嵌套 5 层、Dynamic Workflows 可以生成 1,000 个 Agent,失控风险变成现实威胁。v2.1.212 引入的会话级 web search 上限(默认 200)和 subagent spawn 上限(默认 200)代表了多代理架构的第五个演化方向:不是让 Agent 更多,而是让 Agent 更可控。这意味着”代理是权限边界”的原则有了新的维度——不仅是每个 Agent 的工具权限边界,还包括整个会话的 Agent 数量边界和外部资源消耗边界。MCP 工具调用超过 2 分钟自动后台化则是时间维度的治理。


教训六:记忆不需要向量数据库

“没有 RAG,没有 Pinecone,没有向量嵌入。只有一个目录里的 Markdown 文件 + 一个 25KB 的索引。”

这是最反直觉的发现之一。Claude Code 的记忆系统(第 9 章)完全基于纯文本 Markdown,通过四阶段梦境模式(Orient → Gather → Consolidate → Prune)自动维护记忆质量。

Memory Directory/
├── ENTRYPOINT.md      ← 索引 (< 25KB)
├── user-prefs.md      ← 用户偏好
├── project-ctx.md     ← 项目状态
├── feedback-testing.md ← 用户反馈/纠正
└── logs/2026/03/
    └── 2026-03-31.md  ← 每日日志(仅追加)

为什么这个方案比向量数据库好?

认知预算约束:HumanLayer 的研究揭示了一个此前未被量化的约束——LLM 的有效指令遵从窗口约 150 条行为指令,Claude Code 系统提示已占 ~50 条,留给用户自定义指令的空间约 100 条。这意味着 CLAUDE.md 的”25KB”限制不是工程约束的结果,而是认知约束的体现——超过 25KB 的 CLAUDE.md 通常意味着指令数量已超过模型的有效处理窗口。向量数据库方案的真正问题不是延迟或维护,而是它会鼓励用户添加更多记忆而不考虑认知预算——当一个 RAG 检索能返回 3 条最相关记忆时,它同时也在消耗 3 条指令的预算。

  • 可调试。打开文件就能看到 AI 记住了什么
  • 可编辑。用户可以直接修改记忆文件
  • 低延迟。文件读取比数据库查询快
  • 无维护。不需要 embedding 模型、索引更新、相似度阈值调优

行动建议:在追向量数据库之前,先试试纯文本 + 维护循环。对大多数 Agent 产品来说,25KB 的结构化 Markdown 可能就够了。


教训七:Prompt Caching 不是可选优化,是架构约束

“14 个缓存失效向量。任何一个字节变化,该位置之后的所有缓存全部失效。”

Claude Code 团队围绕 Prompt Caching 做了大量架构设计(第 6 章 + 第 19 章专题):

  • 系统提示通过 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 标记分为静态和动态两部分
  • 日期、Git 状态等变化信息放在用户消息的 <system-reminder> 中,不放进系统提示
  • Plan Mode 不是移除/替换工具,而是添加 EnterPlanMode/ExitPlanMode 工具——因为工具列表变化会破坏缓存
  • MCP 工具列表在启动时锁定,会话中途不增删
  • 压缩(Compaction)使用与父会话完全相同的前缀,复用热缓存

成本影响:100 轮 Opus 会话,无缓存 $50-100,有缓存(90% 命中率)$10-19,降低 80%。

行动建议:设计 Agent 时,Prompt Caching 应该是第一天就考虑的架构约束,不是事后优化。每个可能破坏前缀的设计决策都需要慎重评估。


教训八:Feature Flag 是产品演进的基础设施

“50+ 个 Feature Flag(32 编译时 + 22+ GrowthBook 运行时),控制着 20+ 未发布功能。BUDDY、KAIROS、ULTRAPLAN——都在代码里,但外部用户看不到。”

Claude Code 通过 Bun 的 feature() 宏 实现构建时死代码消除(第 13 章)——禁用的功能不是在运行时隐藏,而是在编译时直接从代码中移除。

v2.1.88 source map 确认的 Flag 分布:32 个编译时(feature() 宏消除)+ 22+ 个 GrowthBook 运行时。新增 Flag 包括:daemon(后台守护进程)、voice_mode(语音交互)、web_browser_tool(浏览器工具)、fork_subagent(子代理 Fork)、context_collapse(上下文折叠)、enable_buddy_command(宠物系统)、enable_capybara_models(模型变体)等。

这意味着:

  • 外部用户的代码体积更小(安全的附带好处)
  • 不可能通过 hack 启用隐藏功能
  • 内部版和外部版从同一份源码构建,只是 Flag 不同

同时,GrowthBook 提供运行时的 Feature Flag 管理,用于 A/B 测试和灰度发布。

行动建议:如果你在 AI 产品上做快速迭代(你应该是),Feature Flag 系统不是奢侈品。构建时 Flag(安全隔离) + 运行时 Flag(灰度发布)的双层方案值得参考。

flag 的另一半:让已发布的破坏性变更能撤回。上面讲的 feature() 宏是构建时那一半——让禁用功能不进包。另一半发生在发布之后:让一个已经发出去、已经开始影响用户的变更在极短时间内收回来。2026 年 9 月有一次官方自己执行、且完整可查证的实证:

  • v2.1.282(09-24):保留 anthropic-skills 与 claude-ai 两个命名空间。该命名空间下的 skill 文件夹 / command 文件 / workflow command 不再加载;以此命名的 MCP server 不列出 skill 与 prompt(工具仍可用);Skill(anthropic-skills:*) / Skill(claude-ai:*) allow 规则的匹配范围被收紧为”仅覆盖从 claude.ai 同步来的 skill”。
  • v2.1.283(09-25):回滚了一半——以 claude-ai 命名的 skills / commands / workflows / MCP server 的 skills 与 prompts 重新加载,Skill(claude-ai:*) 规则退回普通前缀规则。

⚠️ 本轮提案称「v2.1.283 完整回滚」「净效果接近零」——只对了一半。 回官方 changelog 原文,v2.1.283 的条目写的只有 claude-ai;对 anthropic-skills 做的是另一件事——把 Skill(anthropic-skills:<name>) 的 deny 规则扩展到”Claude Desktop 以插件形式投递”的场合,并让 Skill(skill:<name>) 的 deny 匹配别名与显示名。anthropic-skills 的保留并未撤销,反而被加硬了。 准确的说法是:24 小时内撤回了一半,另一半转为更强的约束。

即便如此,这次往返的过程价值不受影响,而且恰恰因为只撤了一半才更有说明力——它演示的不是”一键复原”,而是 flag 机制真正的能力:在一天之内,把一个已经影响到用户加载行为的命名空间变更精确地拆成”撤回”与”收紧”两部分分别处置。没有 flag 就没有这个选项:变更一旦以代码形式发布,撤回只能等下一个版本,而”增设 deny 规则”更是无从谈起。

另需记一笔:这次变更之所以能在 24 小时内被评估并拆分处置,前提是它的影响面可被枚举(skill 文件夹、command 文件、workflow command、MCP server 四类),而这正是”命名空间保留”这种软约束相比直接删代码的优势——先让功能停止加载,但保留名字与配置,就给回滚留了位置。


教训九:反蒸馏已经是现实威胁

“假工具注入、加密签名摘要、思维链隐藏——Anthropic 已经在主动构建反蒸馏防御。”

源码中发现的 Anti-Distillation 机制 揭示了一个行业趋势:模型公司越来越关心竞争对手通过 API 蒸馏其能力。

Claude Code 的两层防御:

  1. 假工具注入(tengu_anti_distill_fake_tool_injection):向响应中注入虚假工具定义,干扰蒸馏训练
  2. CONNECTOR_TEXT:服务器仅返回加密签名摘要而非完整推理链,隐藏详细思维链

行动建议:如果你在构建依赖特定模型能力的产品,要意识到这些能力可能会因为反蒸馏措施而发生变化。不要过度依赖模型的内部行为——依赖接口契约。


教训十:AI Agent 正在从”工具”进化为”同事”

“KAIROS 在源码中被引用 150+ 次。它不是一个功能,而是一个方向——AI 从’你使用的工具’进化为’与你并肩工作的助手’。”

Claude Code 的 KAIROS 系统(第 20 章专题)代表了 AI Agent 的下一个阶段:

  • 主动性:不需要用户发起对话,AI 自己决定何时行动
  • 持久性:不是”用完即关”,而是后台常驻,笔记本合盖后仍运行
  • 自治性:订阅 GitHub webhook、运行定时任务、主动推送通知
  • 审计性:仅追加日志(不可自行删除),形成审计追踪

同时,Buddy 宠物系统(第 22 章专题)展示了另一个方向:用情感连接(18 个物种、5 种稀有度、宠物”看着”你编码偶尔评论)增强用户粘性。

行动建议:现在就开始思考你的 AI 产品的”主动性”维度。即使不立即实现,架构上要为”AI 主动发起行动”预留空间。

v2.1.139 的落地进展:KAIROS 的愿景已部分落地——①Agent View + Supervisor 进程实现了”持久性”:会话不再与终端绑定,~1h 空置后自动停止,attach 时从磁盘状态无缝重启;② /goal 命令实现了”主动性”:目标状态收敛执行模型(类似 Kubernetes Reconcile Loop),Claude 自主判断是否完成,无需人工介入;③ Git Worktree 隔离实现了”多 Agent 并行”的工程基础——每个后台会话自动隔离到独立 worktree。KAIROS 的四阶段梦境模式(Orient → Gather → Consolidate → Prune)已在记忆系统中部分实现。

里程碑案例:Bun Zig→Rust 移植。Bun 创始人 Jarred Sumner 用 Dynamic Workflows 将 75 万行 Zig 代码移植到 Rust,11 天完成,99.8% 测试通过。这个案例实现了教训十预言的三个维度:

维度教训十描述Bun 移植的实现
主动性AI 自主决定何时行动AI 自主决定如何移植每个 .zig 文件
持久性后台常驻,合盖后仍运行隔夜 workflow 持续运行 + Dynamic Workflows 断点恢复
自治性订阅 webhook、运行定时任务数百 Agent 自主并行 + 每个 .zig 文件 2 个 reviewer

Dynamic Workflows 的”断点恢复”进一步实现了”持久性”——即使中断也能从断点继续,不再是”用完即关”的单次交互。这标志着 AI Agent 从”工具”(被动响应)到”同事”(主动持久)的关键转折。

交付闭环(v2.1.198,2026-07-01):后台 Agent 完成代码工作后自动 commit、push、打开 draft PR——这意味着 Agent 的自治性从”完成工作”扩展到了”完成交付”。传统工具在”完成任务”处停止,需要人类检查→commit→push→创建 PR。而”同事”模式下的 Agent 把这个交付流水线也包揽了——人类只需要 review 和 merge。这不只是效率提升,而是工作边界定义的根本变化:Agent 从”帮我把这个做完”变成了”这个已经做完了,你要不要看看”。

hook 的生命周期陷阱(v2.1.285):hook 是 Harness 与外部系统联动的主要手段,而”工具→同事”最依赖的正是这种联动。下面三条全是官方在同一版本里修掉的联动陷阱,它们说明一件反直觉的事——Agent 越主动,它与外部系统的生命周期耦合就越容易出错。

  1. 同步 hook 挂起 Claude Code:hook 自己启动的后台进程(例如 some-daemon &)保持输出打开,导致 hook 一直不结束。现在 hook 在其自身进程退出后很快结束。这条最典型——hook 认为自己结束了,但它间接启动的东西还没放手。
  2. 取消不生效:被取消的 shell 命令或 hook,若取消发生在设置阶段,此前仍会启动并跑到底。现在不会。取消之所以失效,是因为”设置”与”执行”之间有一个检查看不到的窗口。
  3. 读到过期的 plan:hooks 与 SDK 权限回调在 ExitPlanMode 时看到缺失或过期的 plan(当 plan 写在同一响应里时)。现在已修复。

三条共享同一个结构:失败点不在 hook 做了什么,而在 hook 与外部进程的生命周期边界上——谁持有着输出、取消发生在哪个阶段、读到的是不是刚写入的那一份。对”工具→同事”的工程含义很直接:主动性不是给 Agent 加一个定时器就完事,它要求 Harness 先把与外部系统的生命周期边界定义清楚,否则 Agent 越主动,卡死与读到脏状态的概率越高。

hook 的可观测性与决策语义(v2.1.284):上面三条是”联动会出错”,这两条是”出错了你知不知道”——

  • 可观测性:debug log 曾丢掉失败 hook 的 stderr(当该 hook 也写了 stdout 时),并对”无输出的失败 hook”什么都不记;现在失败 hook 也会记录状态码。
  • 决策语义:Elicitation 与 ElicitationResult hook 返回的 {"decision":"block"} 曾被忽略;现在它会拒绝该 MCP elicitation,与 exit code 2 等效。

第一条的教训是:一个 hook 失败了却没有任何记录,在运维上等同于它从未运行过——“静默失败”比”报错失败”危险。第二条更严重:hook 的返回值契约里明明白白写了 decision: block,实现却不执行,这是契约与实现不一致。对一个正在把决策权逐步下放给 hook 的系统而言,这类缺口是信任度最低的一类 bug——配置的人以为自己拦住了,实际没有。

2026-08 版本最新验证

Claude Code v2.1.221(2026-08-04)和 v2.1.225(2026-08-07)的多项更新为上述教训提供了最新的工程验证:

新功能强化的教训验证逻辑
Focus view(隐藏工具活动,仅展示结论)教训二 Context Engineering上下文管理的 UI 层实践——验证了”给模型什么上下文比用哪个模型重要”
Sandbox credential masking (mode:"mask")教训三 安全架构沙箱内命令读 sentinel copy,出口时代理替换真值——纵深防御从”是什么”到”隐藏什么”
zsh/PowerShell 权限绕过修复教训三 安全架构持续修复权限绕过,验证”安全不是一次性功能”
/fork 创建独立 worktree教训五 多代理隔离工作空间避免 fork 后文件冲突——验证”代理是权限边界”
prompt-audit 子命令教训一 Harness> Model扫描旧模型冗余提示——验证”Harness 是可迭代资产”
Gateway spend-limit 可视化教训七 Prompt Caching成本上限可视化——验证”缓存不是事后优化而是架构约束”
Remote Control 跨机消息教训十 工具→同事SendMessage 跨机主动消息——Agent 不再绑单机,自治性扩展至多机
Workspace trust prompt教训三 安全架构不受信目录提示——验证”Fail-Closed 默认”原则

“Harness > Model”的外部验证:Firecrawl 2026-08 横向对比报告中确认 Claude Code 拥有 “deepest programmable harness”(33 个生命周期事件 hook,截至 v2.1.285 / 2026-09-29 复核仍为 33 个(官方 hooks 文档口径),SWE-bench Verified 88.6%(最高),社区评价”best coding agent and it’s not close”(270 upvotes)。Token 消耗 $1,850/月(Max $100 计划用户报告)——这既验证了 Harness 深度,也提示了代价。

⚠️ 关于 SWE-bench Verified 的两个数值:本书第 1 章记录 Claude Opus 5 的 SWE-bench Verified 为 96.0%,本章此处为 88.6%,二者并非同一测量对象,不应择一替换。88.6% 是 Firecrawl 2026-08 报告对 Claude Code 这一产品/Harness 的横向对比快照;96.0% 是 Opus 5 这一模型 的能力基准分(见第 1 章)。产品级分数受 Harness 调度、工具链与默认配置影响,通常低于模型裸分。

lowtouch.ai 交叉验证(2026-08-03):第三方的 “agentic engineering v1” 报告从独立视角验证了教训:① “Every agent system reduces to one cycle”(验证教训四);② “Subagents buy fresh context, but every worker pays its own setup cost”(验证教训五);③ “Execution traces turn agent graphs into systems engineering”(验证教训七)。

2026-09 版本最新验证(v2.1.226–v2.1.269)

自上一版验证(v2.1.225,2026-08-07)至 v2.1.269(2026-09-11)的 34 个 release 中,与十条教训直接相关的官方条目如下:

新功能强化的教训验证逻辑
claude plugin eval(v2.1.269,对插件跑评测套件,输出 JSON + HTML 可复现报告)教训一 Harness > ModelHarness 首次具备「可评测」属性——不只是能扩展,扩展质量本身可被量化评分
/claude-api cost-optimize(v2.1.247,按缓存/token 卫生/批量/effort/模型选择逐项度量地优化开支)教训一 + 教训七成本从「事后账单」变成 Harness 可逐项度量的优化对象
/skill-doctor(v2.1.261,显示哪些已加载技能从未被使用、各占多少上下文)教训二 Context Engineering「预算感知」第一次有了官方诊断工具,从原则变成可操作项
子代理 fork 默认开启(v2.1.232):subagent_type: "fork" 继承完整对话与 prompt cache,非 teammate 的 agent spawn 在交互会话中默认后台运行教训五 多代理「代理是权限边界」下沉为默认行为,无需用户显式配置
CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTS(1–256,v2.1.269)教训五 上限治理并发上限从硬编码变为可显式配置区间,治理从硬编码走向策略化
notify_when_idle(v2.1.236):跨会话 SendMessage 可请求另一会话在下次空闲时发一次通知,opt-in、一次性、无轮询(macOS/Linux)教训十 工具→同事「主动性」首次以 opt-in 无轮询方式落地,是 KAIROS 式主动推送的保守实现
zsh 参数赋值绕过修复(v2.1.260)+ Windows NT 命名空间路径加固(v2.1.234)+ Workflow scriptPath 越界读取修复(v2.1.251)教训三 安全架构见下文教训三的「解析器级绕过」论断

2026-09 下旬版本验证(v2.1.270–v2.1.285)

自 v2.1.269(2026-09-11)至 v2.1.285(2026-09-29)的 16 个 release 中,与十条教训直接相关的官方条目如下:

官方条目强化的教训验证逻辑
Opus 5.5 成为默认 Opus(v2.1.280,1M,$4/$20 per Mtok,$0.20/Mtok cache reads)+ Sonnet 5.5 成为默认 Sonnet(v2.1.284,1M,$2/$10 per Mtok,$0.20/Mtok cache reads)+ /model 选择器去掉 Opus 行的「(1M context)」后缀(v2.1.283)教训一 Harness > Model两个月内连换两代,代次与价格一并变化而无大规模抱怨——「Model 是组件」至今最强的一次验证
/doctor prompt-audit(v2.1.283,一等入口;报告改为陈旧路径 / 陈旧命令 / 矛盾指令文件优先,并保留文档化 thinking 关键词)教训一 + 教训二「审计」从子命令升为体检主入口;官方把指令冲突列为最该先修的一类配置腐化
sandbox 层级加固(v2.1.285,项目设置不能放宽或关闭管理员沙箱、不能替换 managed 代理、不能扩展 allowlist、不能重开 read-denies)教训三 安全架构补上「提权」类论据:managed 策略是单向阀,只能收紧不能放宽
PowerShell 权限检查 fail-open(v2.1.285,解析器启动失败时跳过 deny/ask 且缓存该失败)+ auto mode 对已批准 Artifact 跳过分类器教训三 + Fail-Closed本章论据强度最高的一条:Fail-Closed 从原则变成「官方踩过并修掉的坑」
auto mode 三次默认化(v2.1.283 第三方 provider / 遥测关闭的交互式会话 → v2.1.284 交互式终端与 VS Code 全 plan 全 provider → v2.1.285 claude -p 与 Python Agent SDK)教训三 安全架构与上一行成对:权限模式在放宽,沙箱边界在收紧,两组动作发生在相邻版本
managed 设置部分失效语义(v2.1.282 permissions/autoMode/worktree/attribution;v2.1.283 sandbox,无效值 fail closed、块内其余仍适用)教训三 + Ch17 启示七失效粒度是「项」不是「块」,且失效方向最保守
auto mode 服务端分类器默认化(v2.1.278,Claude API / Enterprise 与 Bedrock / Vertex / Foundry / 网关不收分类器开销,CLAUDE_CODE_AUTO_MODE_SERVER=0 可退出,回退时告警)教训七 成本权限模式之所以推得动,部分原因是分类器的开销被移走了
skills 命名空间 24 小时往返(v2.1.282 保留 anthropic-skills / claude-ai → v2.1.283 回滚 claude-ai、anthropic-skills 改为加硬 deny 规则)教训八 Feature Flagflag 的「可撤回」半边:已发布的破坏性变更能在一天内被拆成「撤回」与「收紧」分别处置
hook 生命周期三条(v2.1.285:同步 hook 被后台进程挂起、取消在设置阶段不生效、ExitPlanMode 读到过期 plan)+ hook 可观测性与决策语义(v2.1.284:失败 hook 记录状态码、decision:"block" 生效)教训十 工具→同事主动性的工程前提:先把 Harness 与外部系统的生命周期边界定义清楚,并让 hook 失败可被诊断

⚠️ 口径提示:本表与上一节(v2.1.226–v2.1.269)不重叠,两节合起来覆盖 2026-08-07 至今。Opus 5.5 / Sonnet 5.5 这组事实在第 14 章(模型标识符映射表)与第 16 章(缓存读价口径)另有切面,三章各落各自角度,不重复计数。

⚠️ 负面发现已落地:本轮曾在 v2.1.268–2.1.285 区间逐条 grep 各 hook 事件名(PreToolUse / PostToolUse / UserPromptSubmit / SessionStart / SessionEnd / Stop / SubagentStop / Notification / PreCompact / Elicitation / ElicitationResult 等),未出现任何新事件名,命中的全是既有事件的修复与行为变更。故上节「33 个生命周期事件 hook」的数值不变,仅把版本锚点前移。


后记

这十条教训不是平行的。它们有一个隐含的优先级:

教训 1(Harness > Model)
  └── 决定了投资方向
教训 2(Context Engineering)+ 教训 4(工具设计)+ 教训 3(安全架构)
  └── Harness 的三根支柱
教训 5(多代理)+ 教训 6(记忆)+ 教训 7(Prompt Caching)
  └── 规模化运行的工程约束
教训 8(Feature Flag)+ 教训 9(反蒸馏)
  └── 产品演进和竞争保护
教训 10(工具 → 同事)
  └── 未来方向

如果你只能记住一条:Harness 比 Model 更重要。

如果你能记住三条:再加上Context Engineering 是独立学科 和 安全不是功能而是架构。

这三条加起来,就是 Claude Code 51 万行源码最精华的提炼。