Harness Engineering 技术原理(二):Feedforward、Feedback 与六层架构详解
约 14 分钟3977 字1 次阅读

Harness Engineering 技术原理(二):Feedforward、Feedback 与六层架构详解
引言
第一篇我们建立了核心认知:Agent = Model + Harness,模型决定上限,Harness 决定底线。
这一篇来深入技术原理——Harness 是如何通过**引导(Feedforward)和反馈(Feedback)**两大机制来控制 Agent 行为的?六层架构每层解决什么问题?ReAct 循环是怎么运转的?
一、Feedforward vs Feedback:控制论视角
1.1 核心概念
Martin Fowler 在深度分析中提出了一个关键框架——Harness 本质上是一个控制论调节器(cybernetic governor),通过引导和反馈两条路径将代码库调节到期望状态。
引导(Feedforward Controls):
事前约束——在 Agent 行动之前就设定好边界和方向,提升它第一次就做对的概率。
反馈(Feedback Controls):
事后检测——在 Agent 行动之后观察结果,帮助它自我修正。
两者的关键区别:
| 维度 | Feedforward(引导) | Feedback(反馈) |
|---|---|---|
| 时机 | 行动之前 | 行动之后 |
| 目的 | 预防问题 | 发现并修正问题 |
| 本质 | 塑造概率空间 | 提供验证信号 |
| 典型实现 | AGENTS.md、Skill、Linter 规则 | 测试、CI、浏览器自动化 |
为什么缺一不可?
- 只有 Feedback:Agent 会重复犯同样的错误
- 只有 Feedforward:Agent 编码了规则但从不知道效果好不好
1.2 Computational vs Inferential:执行方式的差异
引导和反馈各自有两种执行方式:
| 类型 | 特点 | 执行速度 | 可靠性 | 典型实现 |
|---|---|---|---|---|
| Computational(计算型) | 确定性强,CPU 执行 | 毫秒~秒级 | 高 | Linter、测试、类型检查、ArchUnit |
| Inferential(推理型) | 语义分析,GPU/NPU 执行 | 秒~分钟级 | 中等(概率性) | AI Code Review、LLM as Judge |
Computational 的价值:用确定性工具提升好结果出现的概率。速度快到可以每次变更都运行。
Inferential 的价值:处理需要语义判断的问题——同类语义重复代码检测、过度设计的解决方案识别等。但成本高、不确定,不能每次 commit 都跑。
二、六层架构详解
2.1 L1:信息边界层——Agent 该知道什么
核心问题:定义 Agent 该知道什么、不该知道什么,避免它对无关信息做出反应。
关键设计:
- 定义角色与目标:Agent 是代码审查员、前端开发者还是全栈工程师?
- 裁剪无关信息:不在上下文中塞无关文件
- 结构化组织任务状态:任务描述、进度、验收标准
典型实现:
# AGENTS.md(入口文件,约100行)
## 角色
你是一个专门处理 [具体系统] 的后端工程师。
## 关注范围
- 只修改 `src/services/` 和 `src/models/` 目录
- 不碰基础设施代码(CI、部署脚本)
## 当前任务状态
[见 progress.md]
2.2 L2:工具系统层——Agent 怎么跟外部世界交互
核心问题:Agent 需要用哪些工具?什么时候调用?结果怎么提炼?
工具分类:
| 工具类型 | 作用 | 例子 |
|---|---|---|
| Bash | 通用命令执行 | 运行测试、构建、脚本 |
| Filesystem | 安全文件操作 | 读、写、搜索,带路径验证 |
| State Management | 会话内任务追踪 | Todo list、进度文件 |
| Orchestration | 派生子 Agent | OpenCode task tool、Claude Code agent tool |
| MCP Servers | 外部系统集成 | GitHub、Slack、数据库 |
工具调用设计原则:
- 反馈优先:给 Agent 验证方式提升 2-3 倍质量(Boris Cherny, Claude Code 创始人)
- 限制探索 Agent 的写权限:防止意外修改
- 工具结果要 LLM 友好:自定义 Linter 报错带修复指令
2.3 L3:执行编排层——多步骤任务怎么串
核心问题:让模型像人一样走完"理解目标→判断信息→分析→生成→检查"的完整轨道。
ReAct 循环(Reasoning + Acting):
用户请求 → 模型接收当前状态
→ Reasoning(推理):思考下一步做什么
→ Acting(行动):通过工具执行
→ Observation(观察):获取结果
→ 循环直到满足停止条件
举例:用户让 Agent 修复一个失败的测试。
- 模型读测试输出,推理发现导入路径错误
- 通过 Edit 工具修改文件
- 重新运行测试,看到新的类型不匹配错误
- 再次修复,运行测试
- 测试通过,推理任务完成,停止
停止条件的设定至关重要:没有明确停止条件,Agent 会无限循环或过早退出。
2.4 L4:记忆与状态层——中间结果怎么管
核心问题:长任务中间结果怎么管?防止系统混乱。
三层记忆架构:
| 层级 | 存储 | 持久性 | 作用 |
|---|---|---|---|
| Filesystem | 磁盘 | 永久 | 进度文件、git 历史、session 记录 |
| RAM | 内存 | 会话内 | 对话历史、工具结果 |
| Context Window | 模型上下文 | 当前请求 | 模型实际看到的 |
状态持久化最佳实践(Anthropic):
- 初始化 Agent 创建 progress file(进度文件)和 feature list(功能列表)
- 编码 Agent 每轮从 git logs 和 progress files 读取
- 每轮结束时更新 progress file
- 没有数据库,没有向量存储,只有文件系统
2.5 L5:评估与观测层——怎么知道自己做对了
核心问题:Agent 怎么知道自己做对了?建立独立于生成过程的验证机制。
验证方式:
| 验证类型 | 例子 | 优点 |
|---|---|---|
| Computational | 单元测试、集成测试、架构测试(ArchUnit) | 快速、确定性强 |
| Inferential | AI Code Review、AI-generated tests | 能验证语义正确性 |
| Human-in-loop | 人工审查 | 最终保障 |
Boris Cherny 的洞察:给模型验证自己工作的方式,质量提升 2-3 倍。
2.6 L6:约束校验与恢复层——出错怎么办
核心问题:预设规则拦截错误,失败时提供重试或回滚机制。
约束类型:
| 类型 | 例子 |
|---|---|
| 架构约束 | 自定义 Linter 检查分层结构,违反报错 |
| 安全约束 | 白名单工具调用、文件系统路径限制 |
| 格式约束 | ESLint、Prettier 代码风格 |
| 恢复机制 | API 超时重试、上下文超限重启 |
OpenAI 的原则:"If it cannot be enforced mechanically, agents will deviate."——文档中记录约束是不够的,如果不能机械化地强制执行,Agent 就会偏离。
三、上下文管理与 40% 阈值
3.1 为什么上下文不是越多越好
Dex Horthy 的研究:168K token 上下文窗口,用到约 40%(~67K tokens)时,Agent 输出质量急剧下降。
| 区间 | 表现 |
|---|---|
| Smart Zone(0-40%) | 推理聚焦、工具调用准确、代码质量高 |
| Dumb Zone(>40%) | 幻觉增多、兜圈子、格式混乱 |
Anthropic 把这个问题叫"上下文焦虑"——Sonnet 4.5 快到上下文上限时变得犹豫,倾向于提前收工。
3.2 应对策略
策略一:压缩(Compaction)
将上下文中的冗长内容压缩为 LLM 摘要要点,保留关键信息的同时减少 token 占用。
策略二:上下文重置(Context Reset)(Anthropic 的选择)
不压缩,而是把当前任务状态、已完成工作、待办事项结构化提取出来,然后启动一个全新的干净 Agent,把交接文档交给它。
这就像程序碰到内存泄漏时的解法——不是手动释放每一个内存块,而是直接重启进程从检查点恢复。
策略三:渐进式披露(Progressive Disclosure)
不要把整个 AGENTS.md 塞进上下文。而是把 AGENTS.md 当目录用(约 100 行),指向深层文档,Agent 需要什么再加载什么。
3.3 生产环境建议
设置 40% 阈值告警——当 Agent 上下文占用超过 40% 时,触发上下文压缩或任务交接。等 Agent 已经变蠢了再处理就晚了。
四、Steering Loop:人机协作的核心
4.1 什么是 Steering Loop
Human's job is to steer the agent by iterating on the harness——每当 Agent 多次犯同一个错误,就要改进 Feedforward 和 Feedback 控制,让这个问题在未来更少发生甚至完全防止。
Agent 犯错 → 人类分析根因 → 改进 Harness(规则/工具/验证)→ Agent 不再犯
4.2 Harness 也是代码
Böckeler 提出的一个关键观点:Harness 是需要维护的软件。
- Skills、prompts、MCP 配置都是代码
- 应该版本化管理、在 PR 中审查
- 过时的 prompt 会像过时的测试一样腐烂
4.3 用 AI 改进 Harness
AI 也可以用来改进 Harness 本身:
- 帮助写结构测试
- 从观察到的模式生成规则草稿
- 搭建自定义 Linter
- 从代码库考古中创建操作指南
五、Timing:保持质量靠左
5.1 左移原则(Shift Left)
CI/CD 的成熟团队早就知道:检查越早发现错误,修复成本越低。
Harness Engineering 同样适用:
| 时机 | 应该做什么 |
|---|---|
| Commit 前(最左) | Linter、快速测试、基本代码审查 |
| Commit 后 | 慢速测试、mutation testing |
| 集成后 | 全面代码审查、端到端测试 |
5.2 持续监控
除了变更生命周期,还需要持续运行的监控:
- 死代码检测
- 测试覆盖率质量分析
- 依赖漏洞扫描
- 运行时 SLO 监控(让 Agent 关注性能退化)
总结
Harness 的技术原理可以浓缩为三个核心机制:
1. Feedforward + Feedback 双轨控制:事前引导 + 事后验证,缺一不可
2. 六层各司其职:L1 定义边界 → L2 装备工具 → L3 编排执行 → L4 管理记忆 → L5 验证结果 → L6 兜底恢复
3. 上下文是硬约束:40% 是红线,超过后质量断崖式下跌;重置优于压缩
下一期我们将从系统设计的角度,讲解生产级 Harness 的架构——记忆系统、工具设计、沙箱隔离、多 Agent 编排。
标签:#AI #Agent #HarnessEngineering #ReAct #Feedforward #Feedback #六层架构