收尾章。四种哲学的完整对照、Claude Code 独有的六个观察、前十四章 29 条可迁移判断的汇总、哪些不该抄,以及对本仓的具体启示。
同一道题:"给模型套一个外壳,让它能在真实代码库里干活"。四种答案。
| 组织原则 | 一句话 | 规模 | 最能代表它的一处设计 | |
|---|---|---|---|---|
| Pi | 减法 | 核心极简,缺的用扩展补 | 4 个包 | 明确不做 MCP / 子 agent / 权限弹窗 |
| dsh | 全插件化 | 一切能力都可替换 | 185 个包 | agent loop 本身是配置里的一行 |
| Codex | 工程完备 | 产品该有的全做出来塞进一个二进制 | 102 crate / 147 万行 | 四个操作系统四套沙箱 + 模型判官 |
| Claude Code | 上下文经济学 | 一切服从缓存前缀与上下文预算 | 1902 文件 / 51 万行 | 提示词里插一根字符串哨兵,把缓存边界写进数据 |
看一个系统不做什么,比看它做什么更能看清它的立场。
| 不做的事 | Pi | dsh | Codex | Claude Code |
|---|---|---|---|---|
| 沙箱 | 不做(明确) | seam + 多后端 | 自研四套 | 外包给独立包 |
| 子 agent | 不做(明确) | 三种机制 | 子进程 + 协作图 | fork + 6 个内建专家 + teammate |
| 权限弹窗 | 不做(明确) | seam | 审批 + Guardian | 6 种模式 + 8 来源规则 + 分类器 |
| 让扩展改内核 | 有限 | 允许 | 有限 | 不允许 |
| 时间线可考古 | 开源 | 开源 | 开源 | 闭源(只有 sourcemap 横截面) |
| 多种 wire 协议 | 支持多家 | provider 中立 | 只做一种(砍掉 Chat Completions) | 一家(自家 API + 三方云) |
最有意思的是"让扩展改内核"这一格:dsh 允许,Claude Code 明确不允许。
Claude Code 花最大力气优化的东西——缓存边界、五层压缩、附件预算、fork 前缀——恰恰是它不让扩展碰的。这不是保守,是产品承诺:如果扩展能改这些,"上下文永不受限"和"fork 很便宜"这两个承诺就守不住了。
前十四章数下来,为保护 prompt cache 前缀而做的设计至少有 12 处:
数据层的哨兵常量、DANGEROUS_ 前缀 + 不被读取的理由参数、agent 列表搬进附件、fork 的固定占位符、附件头部预计算、1h TTL 资格闩锁、只打一个消息级 cache_control、系统提示词 section 注册表的默认 memoize、时间触发的 microcompact、缓存编辑式 microcompact、fork 透传父进程渲染好的提示词字节、压缩走 forked agent 复用缓存。
它们散布在 12 个互不相干的子系统里,但是同一句话的 12 个变体。
而且有一整套配套设施:约定(哨兵)+ 类型(DANGEROUS_ 命名与强制理由)+ 观测(727 行的断裂检测,逐维度 hash + 逐工具 hash + 可读 diff)。
只做其中一样的团队很多,三样都做的极少。
这份源码里的注释反复出现同一种论证形式:
这些不是估算,是 BigQuery 查出来的。 注释里甚至带日期(BQ 2026-03-10、BQ 2026-03-22)。
一个系统能不能做这类优化,取决于它有没有机队级的可观测性。 第 9 章数过:工具执行链上每一道关都打点,而且带 queryChainId / queryDepth。没有那些埋点,上面每一条都无从谈起。
第 5 章那些 @[MODEL LAUNCH] 标记:
"虚假声明率 v8 是 29–30%,v4 是 16.7%" —— 这是一个被测量的模型行为指标,提示词是针对这个回归写的缓解措施,而且标了"等模型改好就删"。
第 6 章那个 smoosh 甚至为"消息数组的形状"做了 A/B(sai-20260310-161901, Arm B)。第 7 章那段"不许调工具"的压缩前言给了失败率数据(0.01% → 2.79%)。
提示词在这里不是文案,是有基线、有实验、有回滚计划的代码。
| 变体 | 位置 | 手法 |
|---|---|---|
| DANGEROUS_uncachedSystemPromptSection | 第 5 章 | 函数名带 DANGEROUS_ 前缀 |
| _reason 参数 | 第 5 章 | 强制传一个代码里根本不读的理由字符串 |
| AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS | 第 9 章 | 把安全声明编码进类型名(全仓大量使用) |
| SYSTEM_PROMPT_DYNAMIC_BOUNDARY + 缺失告警 | 第 4 章 | 把约束写进数据,并监控它被删 |
第二个最聪明:它把"解释清楚"从代码评审的社会规范变成了编译器要求。
第三个最实用:每一次赋值都要显式写出那个又长又刺眼的名字,作者不可能不注意到自己在声明什么。
第 13 章那个验证 agent 是本教程见到的最完整的例子:
两边的提示词互相引用、互相约束,形成闭环。
关键在最后一环:自律 + 他律。前四条是自律(模型要求自己诚实),最后一条是他律(调用方会抽查,而且被检查者知道)。只有自律的验证会随着任务变难而退化。
这个模式在书里出现了至少七次:
| 机制 | 告知模型 | 章节 |
|---|---|---|
| microcompact 会清老工具结果 | "重要信息抄到你的回复里" | 5、7 |
| 附件位置尽量放对 | "<system-reminder> 和它出现的位置无关" | 5、6 |
| Explore 禁用编辑工具 | "你没有编辑工具,试图编辑会失败" + 逐条堵死 Bash 写路径 | 13 |
| fork 的 sidechain 独立存储 | "不要偷看 output_file" | 12 |
| 上下文自动压缩 | "你的对话不受上下文窗口限制" | 5 |
| 权限模式与拒绝 | "被拒绝不要原样重试,想想为什么" | 5 |
| 延迟工具没有 schema | 参数校验失败时追加"先 ToolSearch 加载它" | 8 |
规律是:机制能挡住的用机制,机制挡不住的(模型的理解、模型的选择)用提示词。而且两边措辞要对得上。
前十四章标了 29 条。按主题重排,标 ★ 的是本教程认为优先级最高的 10 条。
| # | 判断 | 章 |
|---|---|---|
| ★① | 有前缀缓存时,把"这个改动会不会动到前缀"提升成固定的评审问题,并在类型/命名上留下痕迹(哨兵 + DANGEROUS_ + 强制理由) | 1 |
| ⑧ | 外部服务的内部行为显著影响成本时,值得搞清它的机制并写进注释 | 4 |
| ★⑨ | 不可见但成本关键的属性要建专门观测设施,且要能定位到"是谁改的" | 4 |
| ★⑫ | 每类注入上下文的东西设显式预算,按窗口百分比算不写死;双重上限;降级顺序显式且打点 | 6 |
| ⑬ | 找到"代价本来就要付"的时机,把有代价的维护操作挪过去 | 7 |
| ⑪ | 下游需要区分某类数据时,在汇合处统一补标记并保证幂等 | 6 |
| # | 判断 | 章 |
|---|---|---|
| ★② | 让"一次 agent 交互"的返回类型是流不是值 | 2 |
| ④ | 存在"随时间累积且累积有成本"的资源时,按时机分层比按职责分层更有解释力 | 2 |
| ⑤ | 用"缺少完成事件"当失败信号,比额外发失败事件更可靠 | 3 |
| ★⑦ | 结果不影响当前决策的辅助计算,藏进主路径的延迟窗口并轮询消费 | 3 |
| ⑥ | 上游流式、下游可并行时让下游边流边启动——但必须设计"整批作废"的路径 | 3 |
| ㉕ | 状态要跨越"数据会被重写"的边界时,放配置对象上;数据流里那份只当兜底 | 12 |
| ⑭ | "用 agent 解决 agent 的问题"要显式列递归守卫,按调用来源判断 | 7 |
| # | 判断 | 章 |
|---|---|---|
| ★⑮ | "给观察者看的数据"和"给执行用的数据"冲突时做两份,明确谁是权威 | 8 |
| ★⑯ | 错误消息要回答"该怎么办",不只是"哪里错了"——消费者是 LLM 时尤其关键 | 8 |
| ⑰ | 并发批次内的副作用攒到批后按确定顺序统一应用 | 8 |
| ⑱ | 投机执行可以,投机的 UI 反馈不行 | 9 |
| # | 判断 | 章 |
|---|---|---|
| ★⑲ | 扩展点对权限的影响必须不对称:收紧无条件生效,放宽必须再过中央策略——并把真值表写进文档 | 9 |
| ★⑳ | 把"我人工确认过某安全属性"编码进类型名 | 9 |
| ㉑ | "绕过所有检查"的模式必须有显式免疫清单,判据要能一句话说清 | 10 |
| ㉒ | 在代码里显式声明哪些机制不是安全边界 | 10 |
| ㉔ | 跨平台钩子命令不要硬编码可执行文件名;改成运行时解析 + 找不到就静默 no-op,但脚本自身失败仍要透传——"非阻塞失败"不等于"零成本失败",可"这台机器没装"也不该被记成失败 | 11 |
| ㉓ | 配置解析 schema 不要带 .transform()(回写时会静默丢数据) | 11 |
| # | 判断 | 章 |
|---|---|---|
| ★⑩ | 行为类提示词成对写:既禁过度也禁不足;给判据比给规则更能泛化 | 5 |
| ★㉗ | 让 LLM 认真验证需要五件事:命名失败模式、逐字反驳托词、规定证据格式、堵死逃生口、建立抽查机制并让它知道 | 13 |
| ㉖ | 异步委派的提示词必须显式禁止"预测结果",并演示"用户追问时怎么答" | 12 |
| ★㉙ | 扩展生态的价值取决于"模型对当前可用扩展的认知有多准确、多及时"——列表在上下文里 + 能增量更新 + 有强制执行语义 | 14 |
| ③ | "产物里不能有这段代码"成硬需求时,接受扭曲写法但把理由写进注释 | 2 |
| ㉘ | 间接层的理由不显而易见时,把被否决的替代方案连同理由一起写下来 | 14 |
Codex 教程第 15 章总结出的模式是"自由的策略 + 硬性的上限"。Claude Code 的对应物是一个三段式:
出现的地方:
| 资源 | 预算 | 降级 | 打点 |
|---|---|---|---|
| 技能清单 | 窗口 1% | 全量 → 非 bundled 截断 → 非 bundled 只留名字 | tengu_skill_descriptions_truncated(带 truncation_mode) |
| 工具 schema | 窗口 10% | 超了转延迟加载 | tengu_deferred_tool_schema_not_sent 等 |
| 记忆注入 | 5 文件 × 4KB | 按字节截断,保留开头 | —— |
| 单条工具结果 | maxResultSizeChars | 落盘 + 给预览和路径 | —— |
| 整个上下文 | 五层阈值 | snip → microcompact → collapse → autocompact → reactive | 每层都有事件 |
| 一轮 token | 用户设的预算 | 90% 停 / 边际收益递减停 | tengu_token_budget_completed |
第三段(打点)最容易被省掉,也最重要。 没有它你永远不知道有多少用户的技能列表其实是残缺的、有多少会话在静默地丢工具结果。
第 4 章那段"只打一个 cache_control 标记"的注释引用了推理服务的 KV page 淘汰算法。这种优化只有在你同时控制客户端和服务端、而且机队规模足够大时才有意义。
对绝大多数项目:做到"静态/动态分离"和"不要把会变的东西放进前缀"就够了,不需要去研究服务端的显存管理。
同理,第 6 章那个"预先计算'3 天前保存'这个字符串"——如果你的会话量不到百万级,这个优化的收益是零。
上面那张表里,⑧⑨⑬ 三条都隐含"你有机队级数据"这个前提。没有数据就照抄,会变成用直觉伪装成的工程决策——比抄之前更糟,因为它看起来有理有据。
判断方法:如果你抄的那条判断,在源码里的理由是一个数字(10.2%、77%、3400 万次/周),而你拿不出对应的数字,那就先别抄。
第 7 章那五层里,四层是 feature-gated 的实验。它们并存说明的不是"五层都必要",而是"他们还在试哪几层组合最好"。
对一般项目:一层摘要 + 一个"清老工具结果"的机制,加起来能覆盖绝大部分场景。 五层的复杂度需要五层的运维能力(断路器、递归守卫、跨层短路逻辑),而那些复杂度本身就是 bug 来源——第 7 章那三条事故注释都出在层间交互上。
第 9 章数过:工具执行链上十几个打点,每个带 queryChainId / queryDepth。
Claude Code 敢做这么复杂的系统,是因为它每一层都能被单独观测。 一个没有埋点的项目照抄这个复杂度,等于给自己造了一个无法调试的黑箱。
顺序应该反过来:先有可观测性,再有复杂度。
Claude Code 不让扩展碰缓存边界和压缩策略,是因为它对用户有"上下文不受限"和"fork 很便宜"的承诺。如果你没有这类承诺,那把内核锁死只是在给用户添堵。
dsh 的选择在很多场景下更合适。
本仓(VariFlightWork)是一个 Obsidian 知识库 + 35 个以上自定义技能 + 大量 CLAUDE.md 规则的重度 Claude Code 使用场景。前十四章有六条能直接落地。
[实测] 本机 48 个会话里 hook_non_blocking_error 附件 2249 条,占全部附件的 64%——来自四个把解释器写死成 powershell.exe 的 PowerShell 钩子(本机其实装了 pwsh,只是名字不叫 powershell.exe)。已于 2026-08-25 修复:命令改成运行时解析,找不到解释器就静默 no-op。
这条之前没被记录过。 本仓 CLAUDE.md 里那条 "Rule (Linux/macOS)" 处理的是功能缺失(目录级 CLAUDE.md 不会被注入),但没提到上下文开销这一面,而实测显示后者是更大的代价。
建议:把 inject-dir-claude-md.ps1 的注册从入库的 settings.json 挪到 Windows 侧的 settings.local.json,或者把它改写成跨平台脚本(Python,本仓有 .venv)。
自查脚本在第 6 章和第 11 章末尾。
本仓的技能大多只用了 name / description / allowed-tools / disable-model-invocation。第 14 章那 17 个字段里,至少四个对本仓有直接价值:
| 字段 | 适用场景 |
|---|---|
| context: 'fork' | axure-extractor(批量截图,输出巨大)、od-lowprice-batch(799 航线扫价)、ai-blog-fetcher(抓多篇文章)——这些技能的中间输出主线程一概不需要 |
| model: / effort: | 机械型技能(markdown-parser / table-parser / graph-parser)可以指定更便宜的模型 |
| paths: | 按路径触发——产品文档/ 下自动挂 PRD 相关技能,代码逻辑/ 下自动挂代码分析技能 |
| hooks: | 技能自带钩子,比往全局 settings.json 里堆更内聚 |
context: 'fork' 那条收益最直接:第 12 章讲过 fork 共享缓存、输出不进主上下文。本仓几个"跑一遍产出一堆中间数据"的技能正是它的目标场景。
[实测] 本会话的技能列表里有 40+ 个条目(本仓 35+ 个 + bundled 若干)。第 6 章那个预算是上下文窗口的 1%(默认 8000 字符),超了之后:
本仓的技能描述普遍很长(prd-to-tapd 的 description 有 500 多字,od-lowprice-batch 也有 400 多字),而单条硬上限是 MAX_LISTING_DESC_CHARS = 250。
这意味着本仓多数技能的描述在清单里已经被截断了。 而 skill-creator 那套"description 决定触发准确率"的方法论,前提是描述完整地出现在模型面前。
建议:把每个技能 description 的前 250 字符当成真正的触发文案来写——最关键的触发词放最前面,详细说明放后面(反正会被截)。
本仓 CLAUDE.md 用的模式是:
这和第 14 章那个"技能 token 只算 frontmatter,正文按需加载"是同一个模式,也和第 6 章那个"技能清单只放描述"一致。
继续保持。 而且可以更进一步:CLAUDE.md 本身是每轮都在上下文里的(userContext.claudeMd),它的每一行都在花常驻预算。第 12 章那个"只读 agent 砍掉 CLAUDE.md 每周省 50–150 亿 token"说明这个成本是真实的。
第 12 章那两条规则,在本仓的 130 远程协作流程里有直接对应:
已有的规则和 Claude Code 内部的 fork 协议是同构的。 这不是巧合——它们解决的是同一个问题:异步委派中,委派方对结果的无知必须被显式承认。
本仓有 remote-branch-review 技能(审核远程 Claude 提交的分支)。第 13 章那五条可以直接加进去:
第 5 条在本仓天然成立:用户本来就在看。把它写进技能里,让审核方知道自己会被抽查。
诚实地列一下边界。
因为 DCE 看不到的(第 2 章 §2.4):reactive compact、snip、context-collapse、cached microcompact 的实现;proactive/Kairos 那整条自主运行产品线;coordinator 模式;workflow 脚本;REPL 模式;DiscoverSkills;auto 模式分类器的提示词模板。
因为篇幅没展开的:TUI 层(components/ + ink/,485 个文件);sessionStorage.ts 的 5105 行(恢复、分叉、远程会话水合);LSP 集成;MCP 的 2465 行认证;遥测与 Perfetto 追踪;SessionMemory 子系统;teammate / 团队机制的完整形态。
因为没有 git 历史做不了的:时间线考古。Codex 教程能说"Guardian 2026-03-15 进的仓库",本教程说不了任何"什么时候加的"。
因为只有一个横截面做不了的:演进方向。快照停在 Opus 4.6 时代,本机跑的 2.1.241 已经不一样了(第 6 章那个 total_tokens_reminder、第 13 章那个 Explore 描述都对不上)。
读完四份 harness 教程,最大的收获不是任何一处具体设计,而是一个判断框架:
一个 harness 的架构,是它的约束条件的函数。
所以"该抄哪个"这个问题本身问错了。 该问的是:我的约束是什么?
如果你的 agent 一天跑十次,缓存优化毫无意义,Pi 的减法更合适。 如果你要给不同客户换不同的模型后端和存储,dsh 的接缝架构是对的。 如果你要跑在不可信的代码库上,Codex 的隔离优先是对的。 如果你的 agent 会话很长、上下文是主要成本、而且你能测量它——那 Claude Code 这 12 处缓存设计值得逐个抄。
最后引一句本教程读到的、最能概括这个系统的注释。它在讲那个只允许一个 cache_control 标记的地方:
With two markers the second-to-last position is protected and its locals survive an extra turn even though nothing will ever resume from there.
"哪怕不会有任何东西从那里恢复" —— 为了几个不会被用到的 KV page,写了 12 行注释和一处非直觉的实现。
这就是这个系统的性格。
本机侧: