# 24. 第三方白皮书全站审阅与增量补充
# 24.1 资料定位与证据边界
本章审阅了 Claude Code Architecture (opens new window) 在 2026-08-05 通过 llms.txt 公开的 62 个 Markdown 页面。该站对逆向源码、CCB 分支能力、实验 Feature 和产品实践做了较完整的主题化整理,适合作为线索库和知识覆盖检查表,但不作为高于本地源码的权威来源。
吸收规则如下:
- 先找增量:只补充当前手册缺失或解释不足的主题,不重复搬运已有章节。
- 再做验证:页面中的实现结论必须能在本地 Claude Code/Codex 快照中定位,才标记为源码事实。
- 区分产品与原理:CCB、Ant-only、隐藏 Feature 或特定服务部署只作为产品案例,不能推广成所有 Agent 的通用架构。
- Stub 不算能力:凡页面明确写有“待实现、需要补全、纯 Stub、N/A”,只进入排除/观察清单。
- 争议结论不转述为事实:安全事件、版本影响范围和厂商行为必须有官方公告或可复现实证,否则不进入面试结论。
证据优先级仍为:本地源码事实 > 官方协议/文档 > 可复现实验 > 第三方白皮书观点 > 架构推导。引用第三方页面的目的,是说明“为什么检查这个主题”,最终回答仍应落到源码位置、状态机、数据模型和工程取舍。
# 24.2 62 个页面的覆盖矩阵
矩阵的结论不是“62 个页面都要背”。其中直接提升 P0/P1 面试回答的,是 Worktree、Hooks、Loop 恢复、System Prompt 缓存、Deferred Tool、LSP/AST、Feature Gating 和外部依赖审计;其余页面用于确认边界、产品演进或低优先级扩展。
# 24.3 增量一:Multi-Agent 的工作区隔离
第 3 章已覆盖任务 DAG、Mailbox 和权限委托,但并发 Coding Agent 还需要区分三种隔离:
- 逻辑隔离:不同 Agent 有独立上下文、Task owner 和 call id,防止状态串扰。
- 文件隔离:每个写任务进入独立 Worktree 或 Patch Artifact,防止并发覆盖同一工作树。
- 安全隔离:沙箱、权限 Profile 和凭证边界限制真实副作用;Worktree 本身不是安全沙箱。
Claude Code 的 EnterWorktreeTool 创建 Session Worktree 后同时更新进程 cwd、运行时 cwd 和持久化状态:EnterWorktreeTool.ts:92、EnterWorktreeTool.ts:97。创建逻辑优先支持 Hook,从而能把 Git 替换为其他 VCS 隔离实现;无 Git 且无 Hook 时拒绝创建:worktree.ts:702、worktree.ts:715、worktree.ts:734。退出删除时只允许处理本 Session 创建的 Worktree;状态无法验证时 fail-closed,要求明确确认而不是猜测删除:ExitWorktreeTool.ts:176、ExitWorktreeTool.ts:190。
面试时应补充:Worktree 解决“并发写冲突”,权限和沙箱解决“能否访问”,任务锁解决“谁负责执行”,三者不可互相替代。合并阶段还需要基线哈希、冲突检测、验证器和集成责任人。
# 24.4 增量二:Hooks 是扩展协议,也是治理边界
Hook 不应被描述成简单回调。它位于模型决策与真实副作用之间,可以承担四类职责:
- 观察:采集 Session、模型、工具和通知事件,用于审计与外部自动化。
- 拦截:PreToolUse 在执行前拒绝、询问,或把工具调用限制到更小范围。
- 改写:在 Schema 允许范围内修改输入、MCP 输出或附加上下文。
- 控制流:阻止结束、唤醒下一 Step,或将异步 Hook 结果送入统一消息队列。
Claude Code 默认始终发出 SessionStart/Setup,其余事件受 Hook 配置控制:hookEvents.ts:18、hookEvents.ts:84。异步 Hook 通过 Registry 保存 pending 状态,完成后进入消息队列而不是阻塞工具主链:AsyncHookRegistry.ts:28、AsyncHookRegistry.ts:113。Pre/Post Tool Hook 分别有独立结构化输入,并支持 updatedMCPToolOutput 等有限改写:hooks.ts:3496、hooks.ts:3546、hooks.ts:2893。
生产设计必须补充 Hook 的超时、输出上限、来源信任、失败策略、去重和可观测性。安全 Hook 默认应 fail-closed;纯遥测 Hook 可 fail-open,但不能让遥测失败阻断用户任务。
# 24.5 增量三:Agent Loop 要有恢复矩阵
第 4 章的停止条件之外,还应明确错误是否“可恢复”以及恢复后从哪个状态继续。典型矩阵如下:
| 异常 | 局部恢复 | 不应做的事 |
|---|---|---|
| Prompt Too Long | 先清理大 Tool Result,再触发压缩并重建上下文 | 使用同一 Prompt 无限重试 |
| Max Output Tokens | 提升允许的输出槽位,或把已生成内容作为前缀继续 | 丢弃已有部分导致重复生成 |
| Tool transient error | 依据幂等性、退避和 retry budget 重试 | 对写操作无条件重放 |
| Stop Hook 阻塞 | 注入 Hook 原因并允许模型修正一次 | 忽略 Hook 直接完成 |
| Stream disconnect | 按 provider 能力续传,否则从已持久化边界恢复 | 把半个 ToolCall 当作完整 JSON 执行 |
| Model unavailable | 在能力与安全契约兼容时降级模型 | 静默换成不支持现有 Tool Schema 的模型 |
Claude Code 的 query.ts 把这些恢复显式编码为 collapse_drain_retry/reactive_compact_retry/max_output_tokens_escalate/max_output_tokens_recovery/stop_hook_blocking/token_budget_continuation 等 transition reason:query.ts:1095、query.ts:1165、query.ts:1220、query.ts:1305、query.ts:1341。这说明“重试”必须是带原因和状态迁移的恢复策略,而不是外围统一 retry(3)。
# 24.6 增量四:Prompt Cache 与 Tool Virtualization
System Prompt 应拆成稳定前缀和动态后缀。身份、长期规则、工具公共协议放在稳定前缀;cwd、Git 状态、计划、记忆、诊断和最近 Tool Result 放在动态区。更新动态事实时不要改写稳定前缀,否则每个 Step 都会破坏 Prompt Cache。
工具数量很大时,也不应把所有 Schema 永久塞入 Prompt。可采用 Tool Virtualization:
- 启动时只暴露核心工具和轻量目录;
- MCP/低频工具标记为 Deferred;
- 模型通过 Tool Search 召回少量相关 Schema;
- Tool Reference 必须受模型/provider 能力检测和权限过滤;
- MCP 上下线或 Schema 变化后使描述 Token 缓存失效。
Claude Code 的 Tool Search 会按 deferred 描述占上下文比例自动决定是否启用,并在 MCP 连接变化时失效 Token 计数缓存:toolSearch.ts:45、toolSearch.ts:120、toolSearch.ts:155。它还检查模型是否支持 tool_reference,并对不确定的第三方代理保守关闭:toolSearch.ts:227、toolSearch.ts:282。
这与 Skill 的渐进披露是同一类 Context Engineering:目录常驻,完整能力按需加载,加载后仍经过普通权限和沙箱。
# 24.7 增量五:结构化代码证据闭环
Coding Agent 不应只依赖文本搜索。更可靠的证据链是:文本检索定位候选 → AST/LSP 确认语义 → 编辑 → LSP/编译/测试验证。
- Tree-sitter Bash 解析命令结构,用于识别管道、重定向、命令替换和复合命令;解析失败时应保守降级,而不是当作安全。
- LSP 提供 definition、references、hover、symbols 和 diagnostics,适合做跨文件语义导航与编辑后快速反馈。
- LSP 是辅助证据,不是最终正确性证明;索引可能未完成,动态语言和生成代码可能不完整,最终仍需编译与测试。
Claude Code 的 Bash 权限链优先使用 Tree-sitter 分析,不可用时才进入 legacy 路径并记录降级:bashPermissions.ts:1672、bashPermissions.ts:1809。LSPTool 只有在 Server 连接后才可用,并限制单文件大小:LSPTool.ts:53、LSPTool.ts:127、LSPTool.ts:138。文件写入后会发送 didChange/didSave,异步诊断先进入 Registry,再在安全边界注入后续上下文:FileWriteTool.ts:307、LSPDiagnosticRegistry.ts:49。
# 24.8 增量六:Feature Gating 是 Harness 治理能力
生产 Harness 的能力发布至少有三层:
- 构建时门控:从产物中删除内部模块或实验依赖,解决“代码是否存在”。
- 运行时门控:按用户、组织、版本、平台和实验组灰度,解决“能力是否启用”。
- 身份/策略门控:按 principal、租户和组织 Policy 决定“主体是否有资格使用”。
Feature Flag 不是权限系统。运行时 Flag 即使返回 true,也必须继续经过工具权限、审批和沙箱;远程配置不可覆盖组织 Deny。安全相关 Flag 读取失败要有显式默认值,不能把“配置服务不可用”解释成无限放行。
function resolveFeatureAvailability(feature, runtime): // 计算某项 Agent 能力在当前运行环境是否真正可用
if !buildManifest.contains(feature): return UNAVAILABLE // 构建产物没有该能力时立即拒绝,运行时配置不能凭空恢复代码
rollout = remoteConfig.cachedValueOrSafeDefault(feature) // 从缓存读取灰度值,失败时采用预先定义的安全默认值
if !rollout.matches(runtime.subject, runtime.version): return HIDDEN // 用户、组织或版本未命中灰度条件时不向模型暴露能力
if !policy.allows(runtime.principal, feature): return DENIED // 身份和组织策略仍具有否决权,Feature Flag 不能充当授权
if !environment.canEnforce(feature.requirements): return UNSUPPORTED // 当前平台不能实施所需沙箱或依赖时禁止启用
return AVAILABLE_WITH_NORMAL_AUTHORIZATION // 能力可见后,每次具体调用仍走普通权限、审批和沙箱链
Claude Code 源码明确把 feature() 视为可 Tree-shake 的构建边界,而 Runtime 配置不包含这些构建时 Gate:query/config.ts:13。GrowthBook 的非阻塞读取优先内存、再回退磁盘缓存和默认值,并通过周期刷新保持更新:growthbook.ts:224、growthbook.ts:727、growthbook.ts:1012。面试重点不在背 Flag 名,而在解释发布、缓存、默认值、回滚、审计和权限边界。
# 24.9 增量七:外部依赖与远程 Runtime 审计
Agent Harness 的攻击面不只在模型和本机工具,还包括模型 Provider、OAuth、MCP Registry/Proxy、遥测、Feature Config、更新分发、语音/浏览器桥接和远程执行服务。建议维护机器可读的 egress inventory:
| 字段 | 说明 |
|---|---|
| owner / purpose | 谁负责、为什么必须访问 |
| domains / protocol | 允许的域名、端口、传输和重定向规则 |
| data classification | 发送 Token、Prompt、文件片段、Trace 还是匿名 Metric |
| credential audience | 凭证只能给哪个服务和哪个租户使用 |
| timeout / retry / circuit breaker | 故障是否会拖死 Agent Loop |
| offline behavior | 依赖不可用时禁用、降级还是阻塞 |
| retention / deletion | 服务端保留周期和删除机制 |
| observability | 成功率、延迟、出站字节和拒绝原因 |
远程或守护进程(Daemon)Runtime 还必须增加限时租约(lease)、定期心跳(heartbeat)、防止过期 Worker 提交结果的递增令牌(fencing token)和进程监管。连接断开不等于任务失败;控制端重连后应按事件游标恢复,旧 Worker 的租约过期后不能继续提交结果。自动更新同样属于供应链安全:需要签名与哈希校验、一次完成的版本切换、版本兼容、回滚和文件锁,不能只做“下载后覆盖”。
# 24.10 未吸收为事实的内容
以下页面虽已审阅,但不进入核心结论:
Context Collapse、Experimental Skill Search、Web Browser Tool、Ultraplan、Bash Classifier等标有待实现或需要补全的页面;只能用于讨论预期架构。Tier3 Stubs明确是低优先级占位集合,不应出现在“已实现能力”列表。Ant-only、Hidden Features、Buddy、Voice属于内部/实验/体验功能,不是 20 个岗位知识维度的必要组成。- 安全预警与具体受影响版本属于高风险事实,未获得官方来源或本地可复现实证前不采用。
- CCB 自托管、迁移和部署命令属于特定分支运维说明,不与 Claude Code/Codex 通用内核混写。
这一排除过程本身是面试能力:阅读逆向资料时要能判断“真实主路径、灰度实现、编译时删除、运行时关闭、Stub、产品设想”之间的差别,而不是看到文件名或 Feature 名就宣称系统已经支持。
# 24.11 新增面试检查题
问:为什么 Worktree 不能代替 Sandbox?
Worktree 只给并发任务独立文件视图,仍是同一用户权限下的普通进程;它不能阻止读取密钥、访问网络、启动子进程或写工作区外文件。Worktree 管冲突,Sandbox 管强制访问边界。
问:Feature Flag、权限与 Capability 的区别?
Feature Flag 决定功能是否发布或可见;权限策略判断主体是否可以请求某动作;Capability 是绑定主体、资源、受众和期限的可执行授权载体。Flag 为 true 不能跳过后二者。
问:为什么 Agent Runtime 需要 LSP,又不能只相信 LSP?
LSP 提供低成本语义定位和编辑后诊断,能比文本搜索更快发现类型与引用问题;但索引、新语言支持和生成代码可能不完整,因此它只是验证链的一环,必须与编译、测试和 Diff 证据组合。
问:如何设计一个不会拖垮主循环的 Hook?
为 Hook 定义结构化 Schema、超时、输出上限、幂等键和失败策略;安全拦截同步执行并默认拒绝,遥测类异步执行并允许失败;异步结果进入统一队列,在 Step 边界注入,不能并发修改正在执行的 ToolCall。
# 24.12 第三方结论到本地源码的验证清单
参考站点中的每条增量结论都应经历同一验证流程:先记录页面、原始主张和其标注的 Feature 状态;再在本地源码查找数据结构、调用端和配置/门控;随后确认是否有实际执行路径与测试;最后标记为 源码事实 / 架构推导 / 产品案例 / Stub或未证实。只有“定义 + 创建点 + 消费点”至少闭合,才可提升为源码事实。
| 检查项 | 通过标准 | 未通过时的处理 |
|---|---|---|
| 数据结构 | 找到真实字段、枚举或协议对象 | 只作为术语线索 |
| 可达调用链 | 从产品入口能走到实现,而非孤立函数 | 标为未启用或 Stub |
| Feature/配置 | 确认构建、运行时和身份门控 | 不宣称默认可用 |
| 失败与测试 | 找到错误分支、恢复或 conformance 证据 | 降级为架构推导 |
| 双源码对照 | 明确共同不变量及产品差异 | 不强行写成同一实现 |
例如参考站提到 Tool Search 后,必须继续核对延迟加载的工具描述占比、模型 tool_reference 能力检查和 MCP 变化后的缓存失效,才能得出“按需加载工具定义”的原理;若某页面同时写有 TODO 或源码只有空 Handler,则只保留期望架构。这份清单让第三方资料发挥覆盖检查价值,同时避免把逆向推测、实验分支和生产主链混为一谈。