Appearance
第21章 设计模式与架构决策
"Patterns are not invented — they are discovered." — Christopher Alexander
本章要点
- 从全书 20 章的实践中提炼 10 个核心设计模式
- 每个模式包括:问题场景、解决方案、真实案例、适用边界
- 这些模式是跨框架的——无论你用什么技术栈都能应用
模式 1:分层架构(Layered Architecture)
问题: Agent 系统涉及模型调用、工具执行、权限控制、上下文管理等多个关注点,混在一起难以维护。
解决方案: 将系统分为清晰的层次,每层职责单一。
┌─ 交互层 ─┐ 用户输入/输出、流式显示、UI
├─ 编排层 ─┤ Agent Loop、任务调度、多 Agent 协调
├─ 能力层 ─┤ 工具系统、Tool Registry、执行引擎
├─ 控制层 ─┤ 权限模型、沙箱、审计日志
├─ 模型层 ─┤ LLM 调用、Prompt 组装、响应解析
└─ 基础层 ─┘ 配置、存储、记忆、缓存案例: Claude Code 的架构严格分层——CLI 入口 → Query Engine → Tool System → Permission Model → LLM Client,每层通过接口通信。
适用边界: 所有 Agent 系统都应该分层。层数可以根据复杂度调整,但"关注点分离"的原则不可妥协。
模式 2:工具抽象(Tool Abstraction)
问题: Agent 的能力由工具决定,但工具的实现千差万别。
解决方案: 统一的工具接口——每个工具有 name、description、parameters schema、execute 方法。
typescript
interface Tool {
name: string
description: string
parameters: JSONSchema
execute(params: any, context: Context): Promise<ToolResult>
}核心价值: 模型不关心工具是怎么实现的(可能是本地函数、HTTP 调用、Shell 命令),它只看到统一的 name + description + schema。这让工具系统可以无限扩展——MCP 协议正是基于这个抽象。
模式 3:观察-思考-行动循环(Observe-Think-Act Loop)
问题: Agent 需要持续与环境交互,不是一次性生成答案。
解决方案: 循环结构——观察当前状态 → 思考下一步 → 执行动作 → 回到观察。
while (!done) {
observation = getToolResults() + getUserMessage()
thinking = llm.chat(observation) // 模型决策
if (thinking.hasToolCalls) {
results = executeTools(thinking.toolCalls) // 行动
} else {
done = true // 模型认为任务完成
}
}案例: 几乎所有 Agent 框架都实现了这个循环——Claude Code 的 query engine、LangGraph 的 Pregel engine、ReAct 模式。差异在于循环的控制逻辑(何时停止、如何处理错误、是否支持并行)。
模式 4:渐进式信任(Progressive Trust)
问题: Agent 有能力执行危险操作,但完全限制又使其无用。
解决方案: 从最严格的权限开始,随用户信任积累逐步放宽。
新用户 → 每个操作都需确认
↓ 使用一段时间后
普通用户 → 安全操作自动批准,危险操作确认
↓ 充分信任后
高级用户 → 大部分自动化,仅不可逆操作确认案例: Claude Code 的五级权限模式;GitHub Copilot 从建议到自动应用的演进。
关键原则: 信任升级应由用户主动选择,而非系统自动决定。
模式 5:纵深防御(Defense in Depth)
问题: 单一安全检查可能被绕过。
解决方案: 多层独立的安全机制叠加。
请求 → 权限检查 → 参数验证 → 命令过滤 → 路径验证 → OS 沙箱 → 执行每一层独立工作——即使某一层被攻破,后续层仍然提供保护。
案例: Claude Code 的 Bash 工具:权限模式检查 → 命令正则过滤 → 路径白名单 → Seatbelt 沙箱 → 超时限制。
模式 6:上下文即接口(Context as Interface)
问题: 模型无法直接调用 API 或读数据库——它只能通过文本"看"到信息。
解决方案: 把所有信息编码为模型能理解的上下文文本。
这不只是"把数据塞进 prompt"——而是精心设计模型看到的信息:
- 什么信息放在系统提示词(稳定的规则)
- 什么信息动态注入(当前环境状态)
- 什么信息按需获取(工具调用结果)
- 什么信息不需要(节省 token)
案例: Claude Code 在会话开始时注入 git status 而非让模型自己去查——因为这个信息几乎每次都需要。CLAUDE.md 的内容被注入上下文而非作为文件读取——因为它是"隐式的"项目规则。
模式 7:失败即信号(Failure as Signal)
问题: 工具调用可能失败,但失败不等于灾难。
解决方案: 将失败信息反馈给模型,让模型自适应调整策略。
typescript
try {
result = await tool.execute(params)
} catch (error) {
// 不是崩溃——而是给模型一个信号
result = {
error: true,
message: `Tool failed: ${error.message}`,
suggestion: 'Try a different approach or check the file path'
}
}
// 将错误结果送回模型,模型会调整策略模型天然具备从错误中学习的能力——测试失败了它会修复代码,文件不存在它会搜索正确路径。把模型当作错误处理器是 Harness Engineering 的核心洞察之一。
模式 8:记忆分层(Layered Memory)
问题: Agent 需要同时处理即时信息和长期知识。
解决方案: 三层记忆架构。
┌─ 工作记忆 ─┐ 当前上下文窗口中的信息
├─ 会话记忆 ─┤ 当前会话的历史(可压缩)
└─ 长期记忆 ─┘ 跨会话的持久化知识(文件/数据库)每一层有不同的容量、时效性和检索方式。
模式 9:预算约束(Budget Constraints)
问题: Agent 的资源消耗(token、时间、API 调用)可能失控。
解决方案: 在每个层面设置硬性上限。
typescript
const BUDGETS = {
maxTokensPerTask: 200_000,
maxToolCallsPerLoop: 50,
maxConcurrentAgents: 5,
maxWallTimeMs: 10 * 60 * 1000, // 10 分钟
maxCostPerTask: 5.00, // $5
}关键原则: 超过预算时必须硬停止而非"尽量控制"。没有硬上限的系统迟早会出事。
模式 10:人在回路(Human in the Loop)
问题: Agent 不可能 100% 正确,尤其在高风险场景。
解决方案: 在关键决策点暂停,等待人类审批。
设计好"何时中断"比"如何中断"更重要:
| 中断 | 不中断 |
|---|---|
| 不可逆操作 | 只读操作 |
| 影响共享状态 | 仅影响本地 |
| 模糊需求 | 明确需求 |
| 首次执行某类操作 | 已批准过的同类操作 |
十大模式的关联图
这 10 个模式不是孤立的——它们共同构成了 Harness 的完整骨架:
核心链路:分层架构 → OTA 循环 → 工具抽象 → 纵深防御 → 人在回路。这是从"系统骨架"到"安全兜底"的完整路径。
信息链路:上下文即接口 → 记忆分层 → 失败即信号。Agent 的决策质量完全取决于它能"看到"什么信息。
控制链路:渐进信任 → 预算约束。在"有用"和"安全"之间动态平衡。
架构决策总结
回顾全书,Harness Engineering 的核心架构决策可以归纳为:
决策 1:方法论优先于框架
框架会过时(LangChain v0.1 → v0.3 的 breaking changes),方法论不会。本书的每一个设计模式都可以在任何技术栈中实现。
决策 2:安全默认,能力可选
默认拒绝一切,然后有选择地开放。而不是默认允许一切,然后试图堵漏洞。
决策 3:可观测优先于可控制
你无法控制模型的内部推理过程,但你可以观测它的每一个外部行为。先做到看得见,再谈控得住。
决策 4:简单方案优先
能用单 Agent 解决的不用多 Agent,能用文件存储的不用向量数据库,能用正则过滤的不用训练分类器。复杂度是最大的敌人。
决策 5:为失败而设计
Agent 一定会犯错——工具会失败、模型会幻觉、用户会给出矛盾指令。好的 Harness 不是消除失败,而是让失败可恢复、可诊断、损害可控。
全书回顾
第一部分 · 认知框架
├── Ch 1 Harness ≠ Model: 工程层的价值
└── Ch 2 架构模式全景
第二部分 · 核心引擎
├── Ch 3 Agent Loop: 决策循环
└── Ch 4 上下文工程
第三部分 · 工具系统
├── Ch 5 工具设计
├── Ch 6 工具编排
└── Ch 7 错误恢复
第四部分 · 提示词架构
├── Ch 8 分层 Prompt 设计
├── Ch 9 指令优先级
└── Ch 10 动态提示策略
第五部分 · 记忆系统
├── Ch 11 短期记忆
├── Ch 12 长期记忆
└── Ch 13 会话状态机
第六部分 · 安全工程
├── Ch 14 权限模型
└── Ch 15 沙箱隔离
第七部分 · 协作系统
├── Ch 16 多 Agent 协调
└── Ch 17 Human-in-the-Loop
第八部分 · 生产化
├── Ch 18 评估与测试
├── Ch 19 可观测性
├── Ch 20 成本与性能
└── Ch 21 设计模式(本章)从理论框架到生产实践,从单一工具到多 Agent 系统,Harness Engineering 的核心信念始终如一:
模型是引擎,Harness 是缰绳。好的缰绳不限制马的力量,而是让力量指向正确的方向。
感谢你读完这本书。现在,去构建你自己的 Harness 吧。