22个架构模式速查 + System Prompt全链路拆解
《Claude Code 架构解密》精读笔记 #19
覆盖章节:附录A(22个模式速查表,p.353-379)+ 附录C(System Prompt工程参考,p.399-417)
导语:从"深潜"回到"鸟瞰"
前18篇文章,我们用了超过50000字的篇幅,逐章拆解了Claude Code的13个核心章节------从CLI启动到远程架构,从权限模型到终端React。每一篇都在"深潜":钻进源码、追踪调用链、理解每一个设计决策的Trade-off。
但深潜久了,容易"只见树木不见森林"。
附录A和附录C,正是作者的"鸟瞰"设计:一个把22个模式压缩成30秒速查的参考表,一个把System Prompt从神秘黑箱变成可工程化蓝图。它们的价值不在于"新知识",而在于系统化收拢------把散落在13章中的设计模式串联成可迁移的工具箱,把Prompt工程从"玄学"变成有据可循的工程方法。
本篇是全系列倒数第二篇,我们的任务不是"再学新东西",而是退后一步,看见全局。
一、22个架构模式:按场景分类速查
附录A的核心价值不是"罗列",而是分类------22个模式不是22个孤岛,而是6个协作层。
1.1 六层分类总览
| 分类 | 模式数 | 包含模式 | 核心关切 |
|---|---|---|---|
| 多Agent协作 | 6 | Agent Type Registry、Async Agent Lifecycle、Context Inheritance with Cache Sharing、Coordinator-Worker、Fork-and-Delegate、Scoped Memory | 谁来做?怎么做?怎么共享? |
| 扩展架构(Hook/MCP) | 5 | Auth State Machine、Circuit-Breaker Connection Cache、Heterogeneous Transport Adapter、Layered Hook Event Bus、Polymorphic Hook Executor | 如何开放?如何安全?如何容错? |
| 状态管理 | 5 | Layered Persistence with Memory Buffer、Minimal Imperative Store、Multi-Agent View Routing、Selector-Driven Fine-Grained Subscription、State Change Side-Effect Gate | 状态归谁?怎么变?怎么持久化? |
| 上下文管理 | 2 | Background Agent-Driven Session Memory、Content Reference Separation | 记什么?存多少?怎么找回来? |
| 配置管理 | 1 | Layered Config Merge with Priority Arbitration | 谁优先?怎么去重?策略能否覆盖? |
| 工具编排 | 2 | Partitioned Batch Tool Orchestration、Tool Sandboxing | 能并发吗?安全吗? |
| Hook会话管理 | 1 | Session-Scoped Memory Hooks | 怎么隔离?怎么不泄漏? |
关键洞察 :这6层不是随机分组,而是架构分层。多Agent协作是顶层编排,扩展架构是中层接入,状态管理是底层支撑,配置管理和工具编排是横切关注点。
1.2 模式关联图:串起22颗珍珠
附录A最精彩的部分不是单个模式,而是模式关联图------展示模式之间的依赖和协作关系:
多Agent协作层
Fork-and-Delegate → Context Inheritance with Cache Sharing(缓存优化)
Coordinator-Worker → Agent Type Registry
Async Agent Lifecycle → Scoped Memory → Multi-Agent View Routing
状态管理层
Minimal Imperative Store → Selector-Driven Fine-Grained Subscription
→ State Change Side-Effect Gate → Layered Persistence with Memory Buffer
扩展架构层
Layered Hook Event Bus → Polymorphic Hook Executor → Session-Scoped Memory Hooks
→ Layered Config Merge → Heterogeneous Transport Adapter → Circuit-Breaker Connection Cache
→ Auth State Machine & Token Lifecycle
三种关联类型:
- 依赖链:Minimal Imperative Store是Selector-Driven的前提------没有Store,选择器无源可选
- 协作对:Fork-and-Delegate和Context Inheritance with Cache Sharing是天生一对------Fork创建子Agent,Cache Sharing让它们共享上下文不浪费Token
- 分层递进:Hook Event Bus定义"什么时候触发"→Polymorphic Executor定义"怎么执行"→Session Hooks定义"谁来执行"------一个完整的三层管线
1.3 按章节索引:模式在代码中的分布
| 章节 | 涉及模式 |
|---|---|
| 第2章:启动流程 | Minimal Imperative Store |
| 第3章:核心引擎 | Content Reference Separation |
| 第4章:工具系统 | Tool Sandboxing、Partitioned Batch Tool Orchestration |
| 第5章:权限模型 | Layered Config Merge with Priority Arbitration |
| 第6章:Agent编排 | Fork-and-Delegate、Agent Type Registry、Scoped Memory、Coordinator-Worker、Async Agent Lifecycle、Context Inheritance with Cache Sharing |
| 第7章:上下文管理 | Background Agent-Driven Session Memory、Content Reference Separation |
| 第9章:扩展架构 | Layered Hook Event Bus、Polymorphic Hook Executor、Session-Scoped Memory Hooks、Layered Config Merge、Heterogeneous Transport Adapter、Circuit-Breaker Connection Cache、Auth State Machine & Token Lifecycle |
| 第10章:状态管理 | Minimal Imperative Store、Selector-Driven Fine-Grained Subscription、State Change Side-Effect Gate、Layered Persistence with Memory Buffer、Multi-Agent View Routing |
反直觉发现:第6章和第9章是"模式密度最高"的章节。第6章(Agent编排)一个章节就贡献了6个模式,第9章(扩展架构)更是贡献了7个------这意味着**"协作"和"扩展"是最需要模式化思维的架构领域**。
1.4 每个模式的"30秒速查"精华
附录A的设计原则是"30秒定位"------每个模式的核心思想只有一句话。以下是22个模式的压缩版:
| # | 模式名 | 核心思想(一句话) |
|---|---|---|
| 1 | Agent Type Registry | 多源分层加载+Feature Flag+Markdown Frontmatter,后写覆盖实现优先级裁决 |
| 2 | Async Agent Lifecycle | 五阶段状态机+进度追踪+前台/后台双模式+确定性资源清理 |
| 3 | Auth State Machine | 认证建模为显式状态机,伪工具注入让用户在对话流中自然触发认证 |
| 4 | Background Agent-Driven Session Memory | Forked SubAgent后台提取9章节结构化笔记,双阈值控制频率,最小权限隔离 |
| 5 | Circuit-Breaker Connection Cache | 四层故障恢复(指数退避→认证熔断→终端错误→会话过期),memoize缓存复用 |
| 6 | Content Reference Separation | 基于大小阈值的内联/引用分离,SHA256哈希寻址自动去重 |
| 7 | Context Inheritance with Cache Sharing | 统一占位符+精确工具列表+模型继承→API请求前缀字节级一致→Provider Cache命中 |
| 8 | Coordinator-Worker | 主Agent纯编排(3个工具),Worker纯执行,XML通知协议报告结果 |
| 9 | Fork-and-Delegate | 克隆完整对话历史创建分叉,统一占位符保证Cache一致性,递归防护 |
| 10 | Heterogeneous Transport Adapter | 8种适配器统一收敛到MCP Client接口,memoize缓存复用连接 |
| 11 | Layered Config Merge | 明确优先级序列+去重键+策略级全局禁用短路 |
| 12 | Layered Hook Event Bus | 27种事件+模式匹配订阅+结构化结果聚合+事件缓冲100条FIFO |
| 13 | Layered Persistence with Memory Buffer | 三层架构:内存缓冲→异步刷盘(文件锁)→退出保障(registerCleanup) |
| 14 | Minimal Imperative Store | 30行代码:函数式updater+Object.is短路+onChange先于listeners |
| 15 | Multi-Agent View Routing | Discriminated Union路由+retain/evict生命周期+延迟驱逐宽限期 |
| 16 | Partitioned Batch Tool Orchestration | 按isConcurrencySafe分区+并发/串行混合+Hook的allow不绕过deny |
| 17 | Polymorphic Hook Executor | 统一入口+6种执行器(command/prompt/agent/http/callback/function)+每种独立安全约束 |
| 18 | Scoped Memory | 三级目录作用域(User/Project/Local)+路径安全防护+远程存储支持 |
| 19 | Selector-Driven Fine-Grained Subscription | useSyncExternalStore+selector返回稳定引用→只在关心的片段变化时重渲染 |
| 20 | Session-Scoped Memory Hooks | Map<sessionId,SessionStore>+可变写入引用短路+双轨类型(可序列化/仅内存) |
| 21 | State Change Side-Effect Gate | 单一onChange diff函数集中所有外部同步,消除N条路径遗漏 |
| 22 | Tool Sandboxing | 三层过滤+黑白名单混合+运行时沙箱+bare repo防护 |
1.5 模式的"适用/不适用"决策矩阵
附录A最有实践价值的部分是"适用条件"------每个模式都明确列出了什么时候不该用:
| 模式 | 适用场景 | ❌ 不适用场景 |
|---|---|---|
| Minimal Imperative Store | 中等复杂度(10-50状态字段) | 需要中间件/时间旅行调试的超大规模应用 |
| Selector-Driven Subscription | 状态更新频率高、UI组件多 | 无UI的后台Agent或简单CLI工具 |
| State Change Side-Effect Gate | 需3+种外部同步 | 副作用极少(<3个)的简单应用 |
| Layered Persistence | 高频写入+跨进程安全+崩溃恢复 | 需要事务级一致性的场景(用数据库) |
| Fork-and-Delegate | 并行独立任务,每个需完整父级上下文 | 任务间强依赖,或SDK/API非交互场景 |
| Coordinator-Worker | 多步骤并行任务+结果聚合 | 简单单步任务、Worker间需直接通信 |
| Layered Hook Event Bus | 10+个扩展点,多方定制 | 扩展点<5个,EventEmitter足够 |
| Polymorphic Hook Executor | 异构用户群,需AI推理参与 | 仅面向开发者的内部工具,Hook都是简单脚本 |
| Tool Sandboxing | 多角色Agent+最小权限 | 所有Agent权限完全相同 |
元洞察 :22个模式中有7个明确警告"简单系统不要用"------这是对过度设计的系统性防御。模式的门槛不在"能不能实现",而在"值不值得引入"。
二、附录B速览:技术数据表
附录B是纯参考性质的"参数字典",不需要逐页分析。以下是关键数据的压缩摘要:
2.1 系统级统计
| 维度 | 数量 | 说明 |
|---|---|---|
| 内置工具 | 30+ | tools.ts中心化注册 |
| 斜杠命令 | 50+ | commands.ts中心化注册 |
| Hook事件类型 | 27种 | 覆盖全生命周期 |
| Hook执行器类型 | 6种 | command/prompt/agent/http/callback/function |
| MCP传输协议 | 8种 | stdio/sse/http/ws/sse-ide/ws-ide/sdk/claudeai-proxy |
| 权限规则源 | 8层 | userSettings为入口 |
| 安全防御层 | 6+1层 | 权限+六层纵深防御 |
| 命令注入Validator | 23个 | 检测解析差异攻击/混淆/危险模式 |
| 秘密扫描规则 | 28+条 | 覆盖云厂商/AI API/版本控制/通信等 |
| 路径验证命令 | 30种 | 文件系统命令的路径参数安全检查 |
| 权限模式 | 6种 | default/acceptEdits/plan/auto/bypassPermissions/dontAsk |
| 扩展机制 | 3种 | MCP(进程级)+Plugin(模块级)+Skill(提示级) |
2.2 架构五层分层
| 层级 | 名称 | 核心组件 |
|---|---|---|
| Layer 5 | 入口与分发 | main.tsx / cli.tsx / init.ts / mcp.ts |
| Layer 4 | 交互与渲染 | REPL.tsx / components/ / ink/ / screens/ |
| Layer 3 | 编排层 | QueryEngine / query.ts / commands.ts / tools.ts |
| Layer 2 | 能力层 | tools/(30+工具) / commands/(50+命令) / skills/ |
| Layer 1 | 基础设施层 | services/ / state/ / utils/ / bridge/ / permissions/ |
2.3 工具安全默认值(Fail-Closed策略)
typescript
const TOOL_DEFAULTS = {
isEnabled: () => true,
isConcurrencySafe: () => false, // 默认不允许并发
isReadonly: () => false, // 默认视为写操作
isDestructive: () => false,
checkPermissions: allow,
toAutoclassifierInput: '', // 空串=不需要分类
}
设计原则 :新工具忘记声明并发安全性时默认串行执行,忘记声明只读性时默认需要权限检查。宁可多弹一次权限确认,不可漏放一次危险操作。
2.4 23个Validator执行链
按执行顺序排列,分为三个阶段:
早期放行/拦截:validateEmpty → validateIncompleteCommands → validateSafeCommandSubstitution → validateGitCommit
主检测:validateJqCommand → validateObfuscatedFlags → validateShellMetacharacters → validateDangerousVariables → validateCommentQuoteDesync → validateQuotedNewline → validateCarriageReturn → validateNewlines → validateIFSInjection → validateProcEnvironAccess → validateDangerousPatterns → validateRedirections → validateBackslashEscapedWhitespace → validateBackslashEscapedOperators → validateUnicodeWhitespace → validateMidwordHash → validateBraceExpansion → validateZshDangerousCommands → validateMalformedTokenInjection
关键机制 :标记为non-misparsing的Validator若先触发,结果暂存(deferredNonMisparsingResult),继续执行后续Validator。若后续有misparsing Validator也触发,优先返回misparsing结果------因为解析差异比危险模式更难被用户理解。
2.5 SSRF防护:被阻止的地址范围
| IPv4 CIDR | 说明 | 状态 |
|---|---|---|
| 127.0.0.0/8 | 回环地址 | ✅ 放行(本地开发需要) |
| 0.0.0.0/8 | 未指定/当前网络 | ❌ 阻止 |
| 10.0.0.0/8 | RFC1918私有 | ❌ 阻止 |
| 100.64.0.0/10 | CGNAT(含阿里云元数据100.100.100.200) | ❌ 阻止 |
| 169.254.0.0/16 | 链路本地(含AWS/Azure/GCP 169.254.169.254) | ❌ 阻止 |
| 172.16.0.0/12 | RFC1918私有 | ❌ 阻止 |
| 192.168.0.0/16 | RFC1918私有 | ❌ 阻止 |
注意 :当系统配置了HTTP代理时,SSRF Guard自动失效------因为代理代为DNS解析,Guard验证的是代理IP而非目标IP。这是一个已知的防御缺口。
三、System Prompt全链路拆解
附录C是全书最"实用主义"的部分------它不教你"怎么写Prompt"(那是Prompt Engineering的书做的事),而是教你怎么构建一个Prompt管线系统。
3.1 三层组装管线:缓存优化驱动的架构决策
Claude Code的系统Prompt不是静态字符串,而是动态拼装 的。核心驱动力只有一个:Anthropic API的Prompt Cache机制。
第1层:静态内容层(prompts.ts)
身份定义·行为准则·工具规范·安全约束
→ cacheScope: 'global',跨组织/跨用户可缓存
↓ SYSTEM_PROMPT_DYNAMIC_BOUNDARY
第2层:动态章节层(systemPromptSections.ts)
环境信息·MCP指令·技能列表·语言偏好·输出样式
→ 会话内缓存 / 每轮重算(DANGEROUS_uncached)
↓
第3层:用户指令层(claudemd.ts)
Managed · User · Project · Local 四级记忆文件
→ 按目录层级加载,就近覆盖
↓
buildEffectiveSystemPrompt() 汇总
↓ 发送至 Anthropic API
为什么是三层而非两层或单体?
| 方案 | 优点 | 缺点 |
|---|---|---|
| 单体Prompt | 实现简单 | 每次调用都全量传输,无法利用Prompt Cache |
| 两层(静态+动态) | 静态部分可缓存 | 用户指令变更频率与环境信息不同,混在一起浪费缓存 |
| 三层(当前方案) | 静态跨组织缓存、动态会话内缓存、用户指令按需加载 | 管线复杂度高,调试困难 |
核心洞察:变更频率决定分层边界。静态内容(行为准则、工具规范)对所有用户完全相同,可以获得全局缓存命中;动态内容每次会话可能不同但在会话内稳定;用户指令则完全个性化。三层分离使缓存利用率最大化。
3.2 第1层深度:静态内容的"宪法"设计
七大静态章节
| 序号 | 章节函数 | 内容概要 | 架构意图 |
|---|---|---|---|
| 1 | getSimpleIntroSection | 身份定义+网络安全指令 | 划定身份边界和安全底线 |
| 2 | getSimpleSystemSection | 工具执行、输出格式、自动压缩说明 | 告知模型自身运行环境的约束 |
| 3 | getSimpleDoingTasksSection | 编码风格、用户协助原则 | 控制代码质量和交互行为 |
| 4 | getActionsSection | 风险操作确认要求 | 安全架构的Prompt层防线 |
| 5 | getUsingYourToolsSection | 工具选择指导(优先使用专用工具) | 避免"Bash万能化"退化 |
| 6 | getSimpleToneAndStyleSection | 输出格式规范 | UX一致性 |
| 7 | getOutputEfficiencySection | 简洁性要求 | 降低Token消耗 |
章节排列顺序的设计哲学:
- 身份定义和安全指令排在最前面------利用LLM对Prompt开头内容的更高注意力权重
- 工具使用指导放在中段------模型在每次规划时都需要参考的操作手册
- 输出效率放在最后------它影响回复格式而非决策逻辑,优先级最低
Prompt层安全:软硬双层防御
第4章节(getActionsSection)揭示了Claude Code安全架构的关键设计哲学:
Prompt层(软性引导):让模型"不想"执行危险操作
→ 减少权限弹窗频率,改善用户体验
→ 在getActionsSection中列举: git reset --hard、rm -rf等
代码层(硬性约束):即使模型"想"执行也会被拦截
→ BashTool/bashSecurity.ts中的硬性黑名单
→ 权限系统、沙箱隔离
独特创新 :大多数Agent框架将安全完全放在工具执行层(拦截器、沙箱),而Claude Code通过Prompt层引导减少了模型尝试危险操作的概率,从而降低了安全弹窗的频率------这是安全性与用户体验的巧妙平衡。
静态分隔标记
typescript
export const SYSTEM_PROMPT_DYNAMIC_BOUNDARY = '...' // 分隔静态和动态内容的标记
这个标记被splitSysPromptPrefix使用,将Prompt分割为cacheable prefix和non-cacheable suffix,直接映射到Anthropic API的cache_control字段------一个简单的字符串标记,连接了Prompt工程和API优化两个原本独立的关注点。
3.3 第2层深度:动态章节的注册与缓存策略
注册表模式
typescript
type SystemPromptSection = {
name: string
compute: ComputeFn // () => string | null | Promise<string | null>
cacheBreak: boolean // 是否每轮重算
}
两个工厂函数体现了缓存策略的二元分类:
| 工厂函数 | cacheBreak | 用途 | 示例 |
|---|---|---|---|
| systemPromptSection(name, compute) | false | 会话内缓存 | 技能列表、MCP指令 |
| DANGEROUS_uncachedSystemPromptSection(name, compute, reason) | true | 每轮重算 | 当前时间 |
DANGEROUS_前缀:架构治理模式
这是一个在Claude Code中反复出现的治理哲学------通过API设计使"错误的事情难以做到":
DANGEROUS_前缀让代码审查者立即注意到缓存破坏------每一个使用此函数的地方都会在Code Review中被重点关注reason参数(虽然运行时不使用)强制开发者在代码中留下打破缓存的理由
核心思想:让性能开销可见化。如果创建每轮重算的章节和创建缓存章节一样简单,开发者就不会思考是否真的需要每轮重算。通过增加"使用成本"(需要解释原因、需要接受DANGEROUS前缀的审视),系统自然地保护了Prompt Cache的命中率。
并行解析流程
typescript
export async function resolveSystemPromptSections(
sections: SystemPromptSection[],
): Promise<(string | null)[]> {
const cache = getSystemPromptSectionCache()
return Promise.all(
sections.map(async s => {
if (!s.cacheBreak && cache.has(s.name)) {
return cache.get(s.name) ?? null // 缓存命中
}
const value = await s.compute() // 计算
setSystemPromptSectionCacheEntry(s.name, value) // 写入缓存
return value
}),
)
}
三个设计决策:
- Promise.all并行计算:各章节之间没有数据依赖,并行计算最大化启动速度
- 缓存粒度为章节级:不是整个动态层一起缓存,而是按章节独立缓存。只有一个章节变化时,其他章节仍可命中缓存
- null返回值的语义:当compute返回null时,该章节被跳过------这是条件性内容注入的机制。例如,没有启用MCP服务器时,MCP指令章节返回null
缓存清理触发点
| 触发场景 | 来源文件 | 原因 |
|---|---|---|
| /clear命令 | src/commands/clear/clear.ts | 用户主动重置会话状态 |
| /compact命令 | postCompactCleanup.ts | 压缩后上下文变化,Prompt需要重算 |
| 进入/退出Worktree | Enter(Exit)WorktreeTool | CWD变化导致环境信息过时 |
| 会话恢复 | sessionRestore.ts | 从持久化状态恢复时重建完整上下文 |
重要协同操作 :清理章节缓存时同步调用clearBetaHeaderLatches()------确保Feature Flags在新上下文中重新评估,避免Prompt内容和API Beta Header之间的不一致。这是缓存一致性原则的体现。
动态章节清单
| 章节名 | 缓存策略 | 内容说明 |
|---|---|---|
| 会话指导 | 缓存 | 按会话类型(REPL/MCP/SDK)的特定行为指导 |
| 记忆 | 缓存 | 从memdir加载的自动记忆文件 |
| 环境信息 | 缓存 | CWD、Git状态、平台、模型、Shell等运行时环境 |
| 语言 | 缓存 | 用户语言偏好 |
| 输出样式 | 缓存 | 输出风格配置 |
| MCP指令 | 缓存 | MCP服务器注入的自定义指令 |
| 暂存区 | 缓存 | 暂存目录使用说明 |
| Token预算 | 缓存 | Token预算说明(受Feature Gate控制) |
| 功能结果清理 | 缓存 | 微压缩清理说明(受Feature Gate控制) |
关键发现 :所有动态章节的缓存策略都是"缓存"而非"每轮重算"。DANGEROUS_uncachedSystemPromptSection的使用非常克制------绝大多数动态内容在会话内是稳定的,只有极少数(如精确到分钟的当前时间)才需要每轮重算。
3.4 第3层深度:四级记忆文件层级
加载层级(优先级从低到高)
/etc/claude-code/CLAUDE.md ← Managed(企业级)
~/.claude/CLAUDE.md ← User(个人全局)
<repo>/CLAUDE.md ← Project(项目级)
<repo>/.claude/CLAUDE.md ← Project(项目级,隐藏目录)
<repo>/.claude/rules/*.md ← Project Rules(条件规则)
<repo>/CLAUDE.local.md ← Local(本地私有,不入Git)
与CSS/Git/npm的类比 :这个设计与CSS的层叠规则、Git的.gitconfig层级、npm的.npmrc层级异曲同工------都是覆盖链(Override Chain)模式的实例。
| 层级 | 控制者 | 场景 | 是否入Git |
|---|---|---|---|
| Managed | 企业IT管理员 | 强制安全策略、合规约束 | N/A(系统级) |
| User | 个人开发者 | 个人编码风格、语言偏好 | 否(~/下) |
| Project | 项目负责人/团队 | 项目编码规范、技术栈约束 | 是 |
| Local | 当前开发者 | 实验性修改、个人覆盖 | 否(.local.md) |
条件规则(Conditional Rules)
yaml
# .claude/rules/frontend.md
paths:
- "src/components/**/*.tsx"
- "src/hooks/**/*.ts"
---
React组件必须使用函数组件,不使用class组件。
使用TypeScript严格模式,所有Props必须有类型定义。
为什么需要条件规则? 在大型monorepo中,前端代码和后端代码的规范完全不同:
- 上下文窗口浪费:无关规则占用宝贵的Token空间
- 模型遵循度下降:研究表明,Prompt中包含过多无关指令时,模型对相关指令的遵循度会降低
条件规则让Prompt只包含与当前任务相关的指令------这是**"最小权限原则"在Prompt工程中的应用**。
@include机制
markdown
# 项目级CLAUDE.md
@./coding-standards.md
@./api-guidelines.md
@~/personal-preferences.md
| 防御措施 | 实现方式 | 防护场景 |
|---|---|---|
| 循环引用防护 | processedPaths Set追踪已处理路径 | A→B→A的无限循环 |
| 深度限制 | MAX_INCLUDE_DEPTH = 5 | 过深的引用链消耗过多上下文 |
| 符号链接处理 | safeResolvePath解析,记录原始路径和解析后路径 | 符号链接指向同一文件的重复加载 |
内容处理管线
每个记忆文件在注入Prompt之前经过一条完整的处理管线:
读取文件
→ 检查文件扩展名白名单(TEXT_FILE_EXTENSIONS,100+种)
→ 解析YAML Frontmatter(提取paths条件)
→ 使用marked Lexer剥离HTML注释
→ 提取@include路径
→ 对AutoMem/TeamMem应用截断(MAX_MEMORY_CHARACTER_COUNT=40,000)
→ 递归处理@include引用
关键设计:
- HTML注释剥离 :用户在CLAUDE.md中使用
<!-- ... -->注释来组织内容或留给人类阅读的备注,这些内容不应该注入模型 - 40,000字符硬限制:自动记忆和团队记忆的内容可能随时间增长,截断防止吞噬过多上下文窗口
- 扩展名白名单:只处理已知的文本文件格式,防止意外加载二进制文件
3.5 优先级仲裁:buildEffectiveSystemPrompt
三层内容最终在buildEffectiveSystemPrompt中汇总,但这不是简单拼接------核心是一个六级优先级仲裁器:
| 级别 | 名称 | 场景 | 行为 | 设计意图 |
|---|---|---|---|---|
| 1 | Override | SDK嵌入/自动化 | 完全替换,忽略一切 | 用户需要完全控制模型行为 |
| 2 | Coordinator | 多Agent协调 | 使用协调器专用Prompt | 协调器需要不同于执行者的行为模式 |
| 3a | Agent (proactive) | 自主Agent模式 | 追加到默认Prompt | 保留安全约束,叠加Agent指令 |
| 3b | Agent (normal) | 普通Agent任务 | 替换默认Prompt | Agent完全定义自己的行为 |
| 4 | Custom | CLI --system-prompt | 替换默认Prompt | 开发者实验和调试 |
| 5 | Default | 正常交互 | 标准三层管线输出 | 日常使用 |
| 6 | Append | --append-system-prompt | 拼接到最终Prompt末尾 | 用户追加 |
关键Trade-off :Agent (proactive)和Agent (normal)的区别。Proactive模式下Agent Prompt是追加而非替换------这是一个安全决策。自主Agent可能执行更多操作(因为它是主动行动而非被动响应),保留默认Prompt中的安全约束(如风险操作确认要求)是必要的。
条件加载与死代码消除:
typescript
const proactiveModule =
feature('PROACTIVE') || feature('KAIROS')
? (require('../proactive/index.js') as typeof import('../proactive/index.js'))
: null
feature()在构建时由bun:bundle评估------如果条件为false,整个require()调用被消除,未启用功能的代码不会出现在最终bundle中。这同时解决了两个问题:减小bundle体积,以及避免未启用模块的潜在循环依赖。
3.6 上下文窗口约束:Prompt的物理边界
窗口大小决策链
环境变量覆盖(仅内部用户)
→ 模型名[1m]后缀检测 → 1,000,000 tokens
→ getModelCapability() 能力查询
→ Beta Header 检查
→ 实验分组检查
→ 内部模型解析(仅内部用户)
→ 默认值:200,000 tokens
自适应Token预算:先设小值,触达后重试
typescript
export const CAPPED_DEFAULT_MAX_TOKENS = 8_000 // 默认上限
export const ESCALATED_MAX_TOKENS = 64_000 // 达到上限后重试的值
精巧的策略:p99的输出长度约为4,911 tokens。如果默认将max_tokens设为32k/64k,会过度预留8-16倍容量------每次API调用都有大量Token被"预占"但从未使用。
解决方案:
- 默认max_tokens = 8,000------覆盖99%+的正常输出
- 如果模型实际输出触达上限(被截断),以max_tokens = 64,000重试
- 99%+的请求因此节省了大量Token预留空间
反直觉事实:静态Prompt在1M窗口下并不会变长。更长的Prompt不等于更好的行为------Claude Code的设计者明确选择了"精炼指令"而非"详尽指令"。额外的窗口空间留给了对话历史和工具结果------这才是Agent在长会话中真正需要的。
| 窗口大小 | 静态Prompt | 动态章节 | 用户指令 | 对话历史 |
|---|---|---|---|---|
| 200k | ~数千tokens | ~数千tokens | ~数千tokens | ~190k tokens |
| 1M | ~数千tokens(不变) | ~数千tokens | ~数千tokens | ~990k tokens |
3.7 与其他框架的对比
| 维度 | LangChain | AutoGPT/OpenHands | Claude Code |
|---|---|---|---|
| Prompt构建 | 模板+变量替换 | 平铺所有上下文 | 函数+条件组装 |
| 缓存策略 | 无原生支持 | 每轮重传 | 三级缓存(global/session/uncached) |
| 用户配置 | 环境变量/配置文件 | 配置文件 | 四级记忆文件覆盖链 |
| 安全约束 | 外部守护 | 外部守护 | Prompt层+代码层纵深防御 |
| 窗口优化 | 无 | 无 | 自适应Token预算 |
Claude Code的两个显著优势:
- 缓存效率:静态规则不随对话变化,跨请求复用------AutoGPT每轮都需要传输完整Prompt
- 关注点分离:行为规则(静态层)和环境状态(动态层)和用户指令(记忆层)各自独立演化------AutoGPT中这些内容混在一起,修改一处可能影响其他部分
3.8 六大可复用Prompt工程模式
附录C总结了6个可复用的设计模式:
| 模式 | 核心思想 | 适用场景 |
|---|---|---|
| 缓存感知Prompt分层 | 按变更频率分层,精确映射缓存策略 | 任何使用Prompt Cache的Agent系统 |
| DANGEROUS_API治理 | 通过命名约束强制开发者意识到操作成本 | 需要控制性能敏感操作的系统 |
| 覆盖链配置 | 多级配置文件,就近覆盖,企业策略兜底 | 需要企业/用户/项目多级配置的工具 |
| Prompt层纵深防御 | 安全指令同时存在于Prompt和代码中 | 需要降低安全弹窗频率的Agent |
| 条件性内容注入 | 基于路径模式决定是否注入规则 | 大型monorepo中的差异化规则 |
| 自适应Token预算 | 先设小值、触达后重试 | 需要优化API成本的高频调用场景 |
3.9 CLAUDE.md编写实践指南
附录C的最后给出了实用的编写建议:
推荐结构
markdown
# CLAUDE.md示例结构
## 项目概述
(简要描述项目的技术栈和核心架构,帮助模型建立上下文)
## 编码规范
(具体的编码风格要求,如命名规范、错误处理策略)
## 禁止事项
(明确列出不允许的操作,如"不要修改package.json")
## 工作流程
(描述期望的工作方式,如"修改前先运行测试")
五条最佳实践
- 具体优于抽象:"使用camelCase命名变量"优于"遵循良好的命名规范"
- 禁止优于建议:模型对明确的"不要做X"比模糊的"最好做Y"遵循度更高
- 善用.local.md:个人偏好写CLAUDE.local.md,不入Git
- 善用条件规则 :在monorepo中,为不同子目录创建
.claude/rules/frontend.md、.claude/rules/backend.md - 控制长度:聚焦于最重要的10-20条规则,而非试图覆盖所有场景
常见陷阱
| 问题 | 建议 |
|---|---|
| 指令过于冗长 | 精炼至核心规则,辅助内容放include文件 |
| 与默认行为冲突 | 理解默认行为后再决定是否需要覆盖 |
| 缺少.local.md | 个人偏好放CLAUDE.local.md(已在.gitignore中) |
| @include过深 | 保持引用层级在2-3层以内(MAX_INCLUDE_DEPTH=5) |
四、横向对比:模式速查 vs Prompt工程------两种"元知识"的互补
附录A和附录C,一个是架构模式 的速查,一个是Prompt管线的蓝图。表面上看它们是两个独立的附录,但实际上它们是同一种思维的两种表现:
| 维度 | 附录A:架构模式 | 附录C:Prompt工程 |
|---|---|---|
| 关注点 | 代码的组织方式 | Prompt的组织方式 |
| 核心矛盾 | 开放性 vs 安全性 | 缓存效率 vs 个性化 |
| 分层驱动力 | 关注点分离 | 变更频率差异 |
| 治理机制 | 优先级裁决 + 策略覆盖 | DANGEROUS_API + 覆盖链 |
| 最小权限 | Tool Sandboxing | 条件规则(路径模式限定) |
| 纵深防御 | 6+1层安全架构 | Prompt层 + 代码层双防线 |
深层联系 :附录A的"Layered Config Merge"模式,在附录C中变成了"四级覆盖链";附录A的"Polymorphic Hook Executor",在附录C中对应了"条件性内容注入"。架构模式和Prompt模式,都是对同一个设计问题的不同层面的解法。
五、实战启示:如何把这些模式用到自己的系统中
5.1 模式选择的决策树
你在构建什么?
├─ 单Agent CLI工具
│ └─ 只需要:Minimal Imperative Store + Tool Sandboxing
├─ 多Agent协作系统
│ └─ 还需要:Fork-and-Delegate + Context Cache Sharing + Async Agent Lifecycle
├─ 需要扩展的Agent平台
│ └─ 还需要:Layered Hook Event Bus + Polymorphic Executor + Layered Config Merge
└─ 企业级Agent服务
└─ 还需要:Circuit-Breaker + Auth State Machine + 覆盖链配置
5.2 Prompt管线的迁移清单
如果你的团队在构建自己的Agent系统,附录C的三层管线可以直接迁移:
- 第一层:把"不变的规则"提取成静态Prompt,标注全局缓存
- 第二层:把"会话级信息"做成动态章节,用注册表模式管理
- 第三层:实现CLAUDE.md的覆盖链------至少支持User和Project两级
- 加上自适应Token预算:8k默认 + 64k回退,这不需要任何框架改动就能省钱
5.3 附录A+C结合的"模式卡片"实践
建议每个团队为自己常用的模式创建"模式卡片"------一个包含五个字段的文档:
模式名:[中英文名]
问题场景:[30秒内说清楚什么时候需要]
核心思想:[一句话]
适用条件:[何时用 / 何时不该用]
参考实现:[Claude Code中的源码位置]
六、本篇核心收获
| 模块 | 关键洞察 |
|---|---|
| 22模式分类 | 6层架构分组+模式关联图+按章节索引------不是22个孤岛,而是一个协作网络 |
| 适用/不适用 | 7个模式明确警告"简单系统不要用"------对过度设计的系统性防御 |
| 三层Prompt管线 | 缓存优化驱动的分层决策:变更频率决定分层边界 |
| DANGEROUS_API | 让性能开销可见化------通过命名约束使"错误的事情难以做到" |
| 四级覆盖链 | Managed/User/Project/Local------与CSS/Git/npm异曲同工的Override Chain |
| 六级优先级仲裁 | Proactive追加vs Normal替换------安全约束的保留是一个刻意的设计决策 |
| 自适应Token预算 | 8k默认+64k回退------不追求理论最优,而是针对实际分布优化 |
| 条件规则 | Prompt工程中的"最小权限原则"------只注入与当前任务相关的指令 |
| 两层元知识 | 架构模式和Prompt模式,是对同一个设计问题的不同层面解法 |
下期预告
第20篇(系列收官):读完 Claude Code 架构,我学到了什么
417页、13个章节、3个附录、20篇精读笔记------这是全系列的最后一站。我们将跳出技术细节,从一个更宏观的视角回答三个问题:
- 全书5个最深刻的设计决策及其背后的工程哲学是什么?
- Agent架构 vs 传统分布式架构的本质差异在哪里?
- Claude Code的不足与未来------这本书没有告诉我们什么?
从"深潜"到"鸟瞰"再到"反思"------这20篇笔记的终点,不是"我读懂了",而是"我知道下一步该往哪走"。