【AI】AI学习笔记--Harness
文章原地址:Harness Engineering 深度解析:AI Agent 时代的工程范式革命
前言
在学习本篇文章前进牢记————————————你这篇文章是教你如何完全使用AI不写代码从零开发一个完整的项目,而不是简单的Vibecoding
什么是Vibeconding
Vibeconding = Vibe(氛围、感觉) + Coding(编程)。
简单说,就是跟着直觉走的编程方式:
- 想到什么就写什么,不纠结完美的架构
- 够用就好,不追求 100% 的测试覆盖
- 快速迭代,边做边改
- 保持编程的乐趣,而不是被流程和规范束缚
这听起来像是”随便写”?不完全是。
Vibecoding 的核心不是不负责任,而是在速度和质量之间找到适合当下场景的平衡点。它承认一个事实:并不是所有代码都需要完美的工程实践。
适合场景:
- 原型开发和概念验证:你有一个想法,但不确定行不行得通,这时候需要的是快速验证,而不是完美实现,使用vibecoding可以显著缩短开发周期。
- 个人项目和玩具项目:写着玩的项目,或者给朋友做的小工具,没必要搞得像企业级应用。享受编程的乐趣,想到什么写什么,这才是个人项目该有的样子。
- 早期创业阶段:创业初期的主要风险之一不是代码质量,而是做错了方向。当你连用户是谁、需求是什么都不确定的时候,过度关注技术完美性就是本末倒置。与其花三个月打磨一个没人用的完美产品,不如快速迭代,根据用户反馈调整方向。等找到 Product-Market Fit 了,再回头优化也不迟。
- 一次性脚本和工具。
不适合场景
- 关键业务系统:支付系统、数据安全、用户隐私。这些领域容错率极地,不能“差不多就行”。
- 多人协作的大项目:没有规范,团队会陷入混乱。
- 长期维护的代码库:维护成本会指数级增长。(题外话:如果不是vibecoding,而是完全使用ai开发,可以让ai定期重构代码来优化)
- 生成环境的核心功能:用户直接使用的功能,稳定性是第一位的,不能拿用户体验做实验。
Harness Engineering
Harness Engineering四大支柱
支柱一:上下文架构(Context Architecture)
核心原则:Agent应当恰好获得当前任务所需的上下文——不多不少
| 层级 | 加载时机 | 内容示例 | 上下文占用 |
|---|---|---|---|
| Tier 1:会话常驻 | 每次会话自动加载 | AGENTS.md / CLAUDE.md,项目结构概览 | 最小 |
| Tier 2:按需加载 | 特定子 Agent 或技能被调用时 | 专业化 Agent 的上下文、领域知识 | 中等 |
| Tier 3:持久化知识库 | Agent 主动查询时 | 研究文档、规格说明、历史会话 | 按需 |
支柱二:Agent 专业化(Agent Specialization)
核心原则:专注于特定领域、拥有受限工具的Agent优于拥有全部权限的通用Agent。
| Agent 角色 | 职责范围 | 工具权限 |
|---|---|---|
| 研究 Agent | 探索代码库、分析实现细节 | 只读(Read, Grep, Glob) |
| 规划 Agent | 将需求分解为结构化任务 | 只读,无写入权限 |
| 执行 Agent | 实现单个具体任务 | 限定范围的读写权限 |
| 审查 Agent | 审计完成的工作,标记问题 | 只读 + 标记权限 |
| 调试 Agent | 修复审查发现的问题 | 限定范围的修复权限 |
| 清理 Agent | 对抗熵积累,清理低质量代码 | 读写权限 |
支柱三:持久化记忆(Persistent Memory)
核心原则:进度持久化在文件系统上,而非上下文窗口中。每次新Agent会话从零开始,通过文件系统制品重建上下文。
Agent的金典失败模式:
**失败模式一:试图一步到位。**Agent倾向于一次昨晚所有事情,结果在实现进行到一半时上下文窗口耗尽。下一个会话启动时看到的是半成品、没有文档的代码,只能话大量时间猜测之前发生了什么病试图恢复工作状态。
**失败模式二:过早宣布胜利。**在项目后期,当部分功能已经完成后,Agent会环顾四周,看到已有进展就直接宣布任务完成————即使还有大量功能为实现。
**失败模式三:过早标记功能完成。**在没有明确提升的情况下,Agent写完代码就标记为“完成”,缺没有做端到端测试。单元测试或curl命令通过了不代表功能真正可用。
**失败模式四:环境启动困难。**每次新会话启动时,Agent需要花费大量token弄清楚如何运行应用、如何启动开发服务器,而不是把时间花在实际开发上。
初始化Agent: 首次会话使用专门的prompt,要求模型建立初始环境——init.sh脚本、claude-progress.txt进度文件和初始git提交
编码Agent:后续每次会话要求模型在做出增量进展的同时,留下结构化更新。
每个编码Agent的典型会话启动流程如下:
- 运行 pwd 查看工作目录
- 读取 git log 和进度文件,了解最近的工作
- 读取 feature list 文件,选择最高优先级的未完成功能
- 启动开发服务器,运行基础端到端测试
- 确认基本功能正常后,开始新功能开发
关键发现:使用 JSON 格式追踪 feature 状态比 Markdown 更有效,因为 Agent 不太可能不恰当地修改或覆盖结构化数据。
支柱四:结构化执行(Structured Execution)
核心原则:将思考与执行分离。研究和规划在受控阶段进行,执行基于验证过的计划,验证号通过自动化反馈(测试、Linter、CI)和人类审查完毕。
结构化执行四步:
- 理解:探索代码库,分析需求背景,只读访问
- 规划:分解任务结构,指定执行计划,人类审查计划
- 执行:基于验证过的计划,增量实现功能,限定范围写入
- 验证:自动化测试反馈,Linter+CI检查,人类最终审查
人工检查点的价值:审查计划远比审查代码块。当规格正确时,实现自然可靠。当规格有误时,可以在500行代码生成之前及时纠正。
五大 Harness 原则
**原则1:设计环境,而非编写代码。**工程师的工作转向为Agent装备搞笑运行的环境。当Agent卡主时,不是“更加努力”,而是诊断“缺少什么能力”并让Agent自己构建该能力。
**原则2:机械化地执行架构约束。**不要指望 Agent “自觉遵守架构”。要把架构规则做成自动检测系统,让 Agent 一偏离就被工具拉回来。
比如你规定代码的依赖方向为
Types → Config → Repo → Service → Runtime → UI,UI可以调用Runtime、Types,但是Service不能调用UI。这对AI很重要,因为AI写代码时很容易“就近解决问题”,短期看能跑,但长期会让架构变乱。原则2指的是你将这个规则记录到wiki文档中是不够的,AI不一定每次都记得,人也不一定每次都能遵守,可以使用asmdef、写一个轻量扫描器、等规则稳定后,在迁移到Roslyn Analyzer,每条规则都写“为什么错 + 怎么修 + 正确实例”。文档像交通规则,Linter/Analyzer 像护栏和测速仪。AI Agent 写得再快,只要护栏够清楚,它就不容易把车开进架构田里。
原则3:将代码仓库作为唯一实事源。所有团队知识都作为版本控制的制品放置在仓库中。
原则4:将可观测性连接到Agent。 “把AI Agent 从“只会读代码和猜结果”,升级成“能观察真实运行状态、用数据判断自己有没有修好”的工程助手。比如可以让ai查询日志和指标,检测程序的启动时长是否降低,让其做的事情变成可度量的目标。
**原则5:对抗熵。**AI 生成代码很快,但也会持续制造“杂质”;团队必须把清理机制也自动化,否则项目会越来越乱。AI写代码越多,清理工作也必须自动变多。
Harness的核心组件详解
AGENTS.md——Agent的活文档
它不是一次写完就放在哪里吃灰,而是信息项目和Agent协作过程中不断更新的文件。
什么时候该更新
1 | Agent 反复用错 API |
简单的错误(Agent运行了错误的命令、找到了错误的API)通过更新AGENTS.md解决。复杂的问题需要构建工具层面的解决方案。
不要维护一个巨大的 AGENTS.md,如果AGENTS.md 太长,Agent反而抓不住重点。更好的结构是:
1 | # AGENTS.md |
也就是AGENTS.md放最高优先级规则,细节连接放到更深的文档。
采用Tier 1/2/3 渐进式披露
Tier 1: AGENTS.md放最核心、最高频、最容易犯错的规则
Tier 2: 任务类型文档:当Agent要做具体类型的任务时再读,AGENTS.md只放链接。
UnityProject\.claude\skills\tengine-dev\references\event-system.mdTier 3: 实事源/深层文档/示例:这一层放更完整、更细、更低频的信息。
UnityProject/repowiki/zh/content/API参考/资源管理API.md。
由 Agent 为 Agent 维护文档:后台Agent定期做这些事情
1 | 检查 AGENTS.md 里的链接是否失效 |
这就形成了反馈循环:
1 | Agent 犯错 |
一句话总结:AGENTS.md 是 Agent 的项目驾驶手册;真正厉害的用法不是写得很长,而是让它随着错误持续变准,并把复杂规则升级成自动检查工具。
架构约束与自动化执行
分层架构依赖方向强制执行:
1 | Types → Config → Repo → Service → Runtime → UI |
任何违反这一方向的代码都被自定义 Linter 自动检测和阻止。在人类优先的工作流中,这些规则可能感觉过于严苛;对 Agent 来说,它们是乘数效应:一旦编码,便处处适用。
Linter错误消息即修复指令:
不仅要告诉AI错乱,还要告诉他如何修复,怎样是正确的。
结构测试:
结构测试不是测试业务功能对不对,而是测试代码结构有没有违反架构规则。比如
1 | GameLogic 有没有反向污染 TEngine.Runtime? |
对 AI Agent 特别重要,是因为 Agent 经常会为了“把功能做出来”选择最短路径。比如它可能直接在某个底层模块里引用 UI 类:
1 | LoginService -> LoginUI |
短期能解决问题,长期就破坏架构。结构测试就是防止这种“能跑但架构坏了”的代码混进来。
可观测性集成
“把AI Agent 从“只会读代码和猜结果”,升级成“能观察真实运行状态、用数据判断自己有没有修好”的工程助手。比如:
浏览器自动化:通过 Puppeter MCP 让 Agent 像人类用户一样进行端到端测试
Chrome DevTools 集成:Agent能捕获 DOM 快照和截图
查询日志和指标查询:使性能目标(如“启动时长低于800ms”)变得可度量
遥测驱动的 bug 修复:Agent利用日志、指标和Span来自主重现bug和验证修复
熵管理与“垃圾回收”
Agent生成的代码以不同于人类编写的方式积累“技术债”。OpenAI 的 Harness Engineering 报告称之为“熵”。
解决方案:定期运行的“垃圾回收” Agent:
- 扫描文档不一致
- 检测架构约束违规
- 清理冗余或低质量代码
- 确保“清理吞吐量”与“代码生成吞吐量”成比例
实践总结
行动清单
- 创建并维护AGENTS.md:不是一次性任务,而是每当Agent犯错时都更新的活文档。
- 在创库中建立单一实事源:所有团队知识作为版本控制的制品存放在代码仓库中,不放在Slack、Wiki或Google Docs。
- 构建自定义 Linter 并在错误消息中嵌入修复指令:工具在Agent工作时同时“教会”它。
- 为Agent提供端到端测试工具:浏览器自动化(如Puppeter MCP)显著提升验证质量。
- 实施增量执行策略:每次会话只处理一个功能,完成后提交git和进度更新。
- 分层管理上下文:避免将所有信息堆叠在单个文件中,使用Tier 1/2/3 渐进式披露。
- 上下文利用率保持在40%以下:更多token不代表更好的结构。
- 建立定期“垃圾回收”机制:自动化Agent定期清理技术债、检查文档一致性。
Harness成熟度评估模型
| 阶段 | 特征 | 工程师角色 |
|---|---|---|
| Level 0:无 Harness | 直接给 Agent prompt,无结构化约束 | 手动写代码+偶尔使用 AI |
| Level 1:基础约束 | AGENTS.md + 基础 Linter + 手动测试 | 主要写代码,AI 辅助 |
| Level 2:反馈回路 | CI/CD 集成 + 自动化测试 + 进度追踪 | 规划+审查为主,部分 AI 编码 |
| Level 3:专业化 Agent | 多 Agent 角色分工 + 分层上下文 + 持久化记忆 | 环境设计+管理为主 |
| Level 4:自治循环 | 无人值守并行化 + 自动化熵管理 + 自修复 | 架构师+质量把关者 |
关键Harness组件检查清单
| 组件 | 用途 | 优先级 |
|---|---|---|
| AGENTS.md / CLAUDE.md | 会话常驻上下文,动态反馈循环 | P0 |
| 自定义 Linter + 结构测试 | 机械化执行架构约束 | P0 |
| CI/CD 管道 | 自动化测试和验证反馈 | P0 |
| 进度文件 (progress.txt / JSON) | 跨会话的持久化记忆 | P1 |
| 功能列表文件 (feature_list.json) | 结构化完成标准 | P1 |
| 浏览器自动化 (Puppeteer MCP) | 端到端测试验证 | P1 |
| 可观测性集成 | Agent 可查询日志/指标 | P2 |
| 熵管理 Agent | 定期清理低质量代码 | P2 |
| 专业化子 Agent | 分工协作减少上下文污染 | P2 |
| MCP 工具集成 | 连接外部工具和数据 | P2 |
六大共识
共识一:瓶颈在基础设施,不在模型智能。这是整个领域最核心的共识。Can.ac 实验中仅改变 Harness 的工具格式就让 Grok Code Fast 1 从 6.7% 跳到 68.3%,LangChain 同一模型靠 Harness 改进从第 30 名跳到第 5 名。
共识二:文档必须是活的反馈循环,不是静态制品。
共识三:思考与执行必须分离。
共识四:上下文不是越多越好。
共识五:约束必须机械化执行,不能靠文档记录。
共识六:工程师角色正在从”写代码“转向”设计环境 + 管理工作“。