2-1 Harness Engineering:五层框架
先说清楚:Harness 是什么
Harness 是包裹在 agent 外面的工程结构,不是 prompt 里的一句话。
区别很关键:
- Prompt 是给模型的建议,模型可以忽略、可以误解、可以在长对话里"忘掉"
- Harness 是强制执行的机制,不经过模型判断,直接在系统层生效
一个成熟的 agent 系统,靠 prompt 控制行为的部分应该越来越少,靠 harness 控制的部分越来越多。
先用一个比喻建立直觉:
想象你刚入职一家公司,第一天 leader 跟你说:
"你不要动生产数据库,不要直接 push main,提交前记得跑测试。"
这就是 prompt——口头约束,靠你"记住并遵守"。
三个月后公司规模大了,这套规则变成:
- 生产数据库账号你根本没有(权限层)
- main 分支开了 branch protection,push 直接报错(hook 层)
- CI 不过测试,merge 按钮是灰的(验证层) 这就是 harness——系统约束,不依赖你"记住",违规在物理上就做不到。
五层框架
第一层:Memory(记忆)
模型本身没有持久记忆,每次 context window 清空就归零。
Memory 层的工程职责是决定哪些状态需要持久化、以什么形式存、下次怎么读回来。
实践上分三类:
- in-context:直接放进当前 window,最直接,但消耗 token
- 外部存储:文件、数据库、git commit——状态活在磁盘,不活在对话(Ralph 模式的核心)
- 摘要压缩:长 session 定期把历史压成摘要再续传,缓解 context rot
第二层:Tools(工具)
工具决定了 agent 能对世界做什么。读文件、写文件、跑命令、调 API——每一个工具都是一个能力边界的扩展,同时也是一个风险面的扩展。
工程上要想的不是"给它越多工具越好",而是:
- 这个工具的最坏情况是什么(删库?发邮件?推代码?)
- 最坏情况是否可逆
- 不可逆的操作是否加了确认门
第三层:Permissions(权限)
权限层控制的是 agent 被允许做什么,独立于它"想做什么"。
两种策略(2-3 会细讲):
- allow-list:只列出允许的操作,其余全拒——更安全,适合生产
- deny-list:只列出禁止的操作,其余全放——更灵活,适合开发调试
关键原则:权限边界应该比你预期的更窄。agent 能力越强,一次误操作的破坏半径越大。
第四层:Hooks(钩子)
Hooks 是 harness 里唯一能在工具调用发生前强制介入的机制。
在工具真正执行之前,hook 可以:
- 检查参数是否合法
- 记录操作日志
- 直接拦截并返回错误,阻止执行
这是整个 harness 里最有工程价值的一层,2-2 会专门深讲。
第五层:Observability(可观测性)
Agent 在跑,你怎么知道它在干什么?
这层解决的问题是:在不盯着它的前提下,能事后还原它做了什么、为什么这么做、哪一步出了问题。
最低要求:
- 每次工具调用都有日志(入参 + 出参 + 时间戳)
- 每次决策有 reasoning 记录(模型当时的判断依据)
- 异常和拦截有告警
没有 observability 的 loop 是盲跑,出了问题根本没法 debug。
五层的关系
Prompt / Context
← 纯引导,靠模型自律,随时可能失效
│
▼ 越往下,约束越强,越不依赖模型
┌─────────────────────────────┐
│ Memory │ 状态管理,控制模型"看到什么"
├─────────────────────────────┤
│ Tools │ 能力边界,没给工具就物理上做不到
├──────────┬──────────────────┤
│ Hooks │ Permissions │ 强制执行,不过模型,直接系统层拦截
└──────────┴──────────────────┘
Observability 横切所有层,不控制行为,控制可见性
越靠下的层越接近"强制",越靠上的层越接近"引导"。工程成熟度的标志之一,就是关键约束从上层下沉到下层。
- 最上面 Prompt:模型可以忘、可以误解、可以绕过
- 往下 Memory/Tools:缩小模型能接触的范围
- 最下面 Hooks/Permissions:不管模型想不想,系统直接挡住
本节核心一句话
Harness 是 agent 的骨架,Prompt 是建议,骨架不依赖模型的"理解"就能生效。