第八章:设计模式全景
学习时间: 4 小时 | 难度: ⭐⭐⭐⭐ | 前置: 第三至七章
学习目标
完成本章后,学员将能够:
- 分类描述 Claude Code 中的 24 种设计模式
- 为每个模式提供定义、应用、代码示例和可移植性分析
- 评估模式在自己项目中的适用性
- 组合多个模式解决复杂架构问题
概述
Claude Code 的源码中蕴含了 24 种可识别的设计模式,分布在四个维度:
| 维度 | 模式数量 | 聚焦点 |
|---|---|---|
| 架构级 | 4 个 | 系统整体结构 |
| 工程级 | 8 个 | 具体实现技巧 |
| 数据管理 | 6 个 | 状态和缓存 |
| 扩展性 | 6 个 | 可扩展性设计 |
1. 架构级模式(4 个)
1.1 Fast-Path + DCE
| 属性 | 内容 |
|---|---|
| 定义 | 入口多路分发 + 构建时死代码消除 |
| 应用 | cli.tsx 13 条快速路径 |
| 核心思想 | 常见路径零开销,罕见路径延迟加载 |
代码示例:
// cli.tsx 快速路径
if (args.version) {
process.stdout.write(`${MACRO.VERSION}\n`)
return // 零模块加载
}
if (args.daemonWorker) {
// 跳过 analytics,直接进入守护进程模式
return runDaemonWorker(args)
}
// 默认路径:加载完整的 main.tsx
await import('./main.tsx')
可移植性: ⭐⭐⭐⭐⭐ — 任何 CLI 工具都可以应用
1.2 State Machine
| 属性 | 内容 |
|---|---|
| 定义 | 状态转换追踪 + 错误恢复 |
| 应用 | query.ts 7 种 Continue 类型 |
| 核心思想 | 每次循环记录状态转换原因,支持错误恢复 |
代码示例:
// query.ts 查询循环(概念还原)
async function query(messages: Message[]): Promise<ContinueType> {
const response = await streamAPI(messages)
switch (response.stopReason) {
case 'tool_use':
await executeTools(response.toolUseBlocks)
return 'tool_result'
case 'end_turn':
return 'end_turn'
case 'max_tokens':
if (recoveryAttempts < 3) {
recoveryAttempts++
return 'max_tokens_recovery'
}
return 'error'
case 'prompt_too_long':
return 'prompt_too_long_recovery'
}
}
可移植性: ⭐⭐⭐⭐⭐ — 任何需要多轮对话的 Agent 都应使用
1.3 Actor Model
| 属性 | 内容 |
|---|---|
| 定义 | 独立 Actor 通过消息总线通信 |
| 应用 | 后台任务系统 (7 种任务类型) |
| 核心思想 | 任务隔离、无共享状态、消息驱动 |
可移植性: ⭐⭐⭐⭐ — 适合需要后台任务的系统
1.4 Static/Dynamic Boundary
| 属性 | 内容 |
|---|---|
| 定义 | 分离可缓存和动态内容 |
| 应用 | System Prompt 构建 |
| 核心思想 | 静态内容缓存,动态内容实时生成 |
代码示例:
// prompts.ts 概念还原
function buildSystemPrompt(): string {
const staticPart = getStaticPrompt() // ~500行,不变
const dynamicPart = buildDynamicPrompt() // ~400行,每轮变化
return [
staticPart,
'__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__',
dynamicPart
].join('\n')
}
可移植性: ⭐⭐⭐⭐⭐ — 任何使用 LLM API 的系统都应考虑
2. 工程级模式(8 个)
2.1 Behavioral Metadata
| 属性 | 内容 |
|---|---|
| 定义 | 行为语义编码为元数据,编排层据此做调度决策 |
| 应用 | Tool 接口的 isConcurrencySafe、isReadOnly 等字段 |
| 核心思想 | 工具声明自己的行为特征,编排层自动决策 |
代码示例:
// Tool 接口的元数据字段
const grepTool: Tool = {
name: 'Grep',
inputSchema: z.object({ pattern: z.string(), path: z.string() }),
// 行为元数据
isConcurrencySafe: () => true, // 可以并行
isReadOnly: () => true, // 只读操作
isDestructive: () => false, // 不可逆操作
async call(input) { /* ... */ }
}
可移植性: ⭐⭐⭐⭐⭐ — 强烈推荐,这是最核心的模式
2.2 Fail-Closed Defaults
| 属性 | 内容 |
|---|---|
| 定义 | 默认值全部偏向安全侧 |
| 应用 | buildTool() 默认 isConcurrencySafe=false |
| 核心思想 | 安全第一,显式声明才放宽 |
可移植性: ⭐⭐⭐⭐⭐ — 安全关键系统的必选模式
2.3 Streaming Pipeline
| 属性 | 内容 |
|---|---|
| 定义 | 流式接收 + 边接收边执行 + 结果缓冲 |
| 应用 | StreamingToolExecutor |
| 核心思想 | 最大化并行度,减少等待时间 |
代码示例:
// StreamingToolExecutor 概念还原
class StreamingToolExecutor {
async processStream(stream: AsyncIterable<ToolUseBlock>) {
for await (const block of stream) {
// 边接收边执行
if (this.tool.isConcurrencySafe(block.input)) {
this.executeImmediately(block) // 不等待
} else {
await this.waitForAll()
await this.executeSerially(block)
}
}
return this.collectResults() // 按原始顺序输出
}
}
可移植性: ⭐⭐⭐⭐ — 需要流式处理的系统
2.4 Concurrency Partition
| 属性 | 内容 |
|---|---|
| 定义 | 按操作类型分区:读并行、写串行 |
| 应用 | 工具执行器 |
| 核心思想 | 读操作无副作用可以并行,写操作有冲突必须串行 |
可移植性: ⭐⭐⭐⭐⭐ — 并发控制的基础模式
2.5 Error Cascade
| 属性 | 内容 |
|---|---|
| 定义 | 一个失败,AbortController 取消所有兄弟 |
| 应用 | 工具执行器错误处理 |
| 核心思想 | 快速失败,避免无意义的继续执行 |
可移植性: ⭐⭐⭐ — 需要快速失败的并行任务
2.6 Multi-Stage Permission Pipeline
| 属性 | 内容 |
|---|---|
| 定义 | 7+ 步有序管道,每步可 short-circuit |
| 应用 | 4 层权限管道 |
| 核心思想 | 多层安全检查,优先级递增 |
可移植性: ⭐⭐⭐⭐ — 安全关键系统
2.7 Two-Stage Classifier
| 属性 | 内容 |
|---|---|
| 定义 | 快速分类 + 思维链复核 |
| 应用 | Auto Mode AI 分类器 |
| 核心思想 | 大多数请求快速处理,少数需要深入分析 |
可移植性: ⭐⭐⭐ — AI 分类场景
2.8 Denial Circuit Breaker
| 属性 | 内容 |
|---|---|
| 定义 | 连续拒绝追踪 + 阈值熔断 |
| 应用 | Auto Mode 拒绝熔断器 |
| 核心思想 | 防止 AI 误判导致系统僵死 |
可移植性: ⭐⭐⭐⭐ — 自动化决策系统
3. 数据管理模式(6 个)
3.1 Memoized Singleton
| 属性 | 内容 |
|---|---|
| 定义 | 函数级缓存,首次调用执行 I/O |
| 应用 | context.ts、MCP 连接 |
| 核心思想 | 避免重复 I/O,会话内只执行一次 |
代码示例:
// 伪代码:Memoized Singleton
const getGitStatus = memoize(async () => {
return await exec('git status --porcelain')
})
// 第一次调用:执行 git 命令
const status1 = await getGitStatus() // ~100ms
// 第二次调用:返回缓存
const status2 = await getGitStatus() // ~0ms
可移植性: ⭐⭐⭐⭐⭐ — 通用的性能优化模式
3.2 Layered Configuration with Merge
| 属性 | 内容 |
|---|---|
| 定义 | 多层配置叠加,后加载覆盖先加载 |
| 应用 | CLAUDE.md 4 层加载 |
| 核心思想 | 企业 → 用户 → 项目 → 本地,逐层覆盖 |
可移植性: ⭐⭐⭐⭐⭐ — 配置管理的标准模式
3.3 Checkpoint/Restore
| 属性 | 内容 |
|---|---|
| 定义 | 压缩前保存状态,压缩后恢复 |
| 应用 | compact.ts 上下文压缩 |
| 核心思想 | 不可逆操作前保存快照 |
可移植性: ⭐⭐⭐⭐ — 需要状态恢复的场景
3.4 Withhold-then-Recover
| 属性 | 内容 |
|---|---|
| 定义 | 错误先抑制,尝试多级恢复策略 |
| 应用 | query.ts prompt_too_long 处理 |
| 核心思想 | 用户不应看到可自动恢复的错误 |
代码示例:
// 伪代码:Withhold-then-Recover
async function handlePromptTooLong(error: Error) {
// 抑制错误,不 surface 给用户
// 策略 1: 截断最旧消息
for (let i = 0; i < 3; i++) {
try {
messages = truncateOldest(messages)
return await query(messages)
} catch (e) { continue }
}
// 策略 2: LLM 摘要压缩
try {
messages = await compactWithLLM(messages)
return await query(messages)
} catch (e) { /* 继续 */ }
// 策略 3: 升级 max_tokens
try {
maxTokens *= 2
return await query(messages)
} catch (e) { /* 继续 */ }
// 全部失败:surface 错误给用户
throw error
}
可移植性: ⭐⭐⭐⭐ — 用户体验关键的系统
3.5 Retry with Truncation
| 属性 | 内容 |
|---|---|
| 定义 | 逐步截断旧消息重试 |
| 应用 | PTL (Prompt Too Long) 重试策略 |
| 核心思想 | 每次重试减少上下文量 |
可移植性: ⭐⭐⭐ — LLM 上下文管理
3.6 Immutable State
| 属性 | 内容 |
|---|---|
| 定义 | 结构共享 + 引用相等跳过 |
| 应用 | AppState Store |
| 核心思想 | 不可变数据 + 结构共享 = 安全 + 高效 |
可移植性: ⭐⭐⭐⭐⭐ — 状态管理的最佳实践
4. 扩展性模式(6 个)
4.1 Template + Clone
| 属性 | 内容 |
|---|---|
| 定义 | 模板定义骨架,运行时克隆注入行为 |
| 应用 | MCPTool 创建 |
| 核心思想 | 复用模板,避免重复定义 |
可移植性: ⭐⭐⭐⭐ — 需要动态创建对象的场景
4.2 Strategy Pattern
| 属性 | 内容 |
|---|---|
| 定义 | 统一接口,多种实现 |
| 应用 | MCP 8 种传输协议 |
| 核心思想 | 运行时选择算法/实现 |
可移植性: ⭐⭐⭐⭐⭐ — 经典设计模式,通用性极强
4.3 Adapter Pattern
| 属性 | 内容 |
|---|---|
| 定义 | 协议/格式转换适配器 |
| 应用 | MCPTool、沙箱配置转换 |
| 核心思想 | 让不兼容的接口协同工作 |
可移植性: ⭐⭐⭐⭐⭐ — 经典设计模式
4.4 Event-Driven Middleware
| 属性 | 内容 |
|---|---|
| 定义 | 事件触发 + 中间件管道 |
| 应用 | Hook 系统 (PreToolUse → 执行 → PostToolUse) |
| 核心思想 | 请求经过一系列中间件处理 |
可移植性: ⭐⭐⭐⭐ — 需要可扩展处理管道的系统
4.5 Plugin Architecture
| 属性 | 内容 |
|---|---|
| 定义 | 标准化接口 + 版本化缓存 |
| 应用 | 插件系统 (marketplace + git) |
| 核心思想 | 第三方扩展通过标准接口集成 |
可移植性: ⭐⭐⭐ — 需要第三方扩展的系统
4.6 Partition Sort for Cache Stability
| 属性 | 内容 |
|---|---|
| 定义 | 内置在前,保证 prompt cache 前缀稳定 |
| 应用 | assembleToolPool() |
| 核心思想 | 稳定的前缀 = 更高的 cache 命中率 |
可移植性: ⭐⭐⭐ — 使用 LLM API 的系统
5. 模式关系图
┌─────────────────────┐
│ Behavioral Metadata │
│ (核心驱动模式) │
└──────────┬──────────┘
│
┌────────────────┼────────────────┐
│ │ │
┌─────────▼─────────┐ ┌───▼────────┐ ┌─────▼──────────┐
│ Concurrency │ │ Permission │ │ Streaming │
│ Partition │ │ Pipeline │ │ Pipeline │
└─────────┬─────────┘ └───┬────────┘ └─────┬──────────┘
│ │ │
┌─────────▼─────────┐ ┌───▼────────┐ ┌─────▼──────────┐
│ Error Cascade │ │ Two-Stage │ │ Fail-Closed │
│ │ │ Classifier │ │ Defaults │
└───────────────────┘ └───┬────────┘ └────────────────┘
│
┌─────────▼─────────┐
│ Denial Circuit │
│ Breaker │
└───────────────────┘
模式选择指南
| 场景 | 推荐模式 |
|---|---|
| CLI 工具启动优化 | Fast-Path + DCE |
| LLM 多轮对话 | State Machine + Withhold-then-Recover |
| 工具系统设计 | Behavioral Metadata + Fail-Closed Defaults |
| 并发控制 | Concurrency Partition + Error Cascade |
| 权限系统 | Multi-Stage Pipeline + Circuit Breaker |
| 上下文管理 | Static/Dynamic Boundary + Memoized Singleton |
| 状态管理 | Immutable State + Checkpoint/Restore |
| 可扩展性 | Strategy + Adapter + Event-Driven Middleware |
思考题
-
Behavioral Metadata 是 Claude Code 最核心的模式。如果只能选一个模式应用到自己的 Agent 系统,为什么选这个而不是 State Machine?
-
24 种模式中,哪些是「必须」的,哪些是「锦上添花」的? 如果要精简到 5 个核心模式,你会选哪些?
-
Withhold-then-Recover 和 Error Cascade 看起来矛盾——一个抑制错误,一个快速失败。它们在什么场景下分别适用?
-
Partition Sort for Cache Stability 依赖于「内置工具列表不变」的前提。在什么情况下这个前提会被打破?
-
如果让你设计一个新的 Agent 框架,你会组合哪些模式?画出你的模式关系图。