【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的典型会话启动流程如下:

  1. 运行 pwd 查看工作目录
  2. 读取 git log 和进度文件,了解最近的工作
  3. 读取 feature list 文件,选择最高优先级的未完成功能
  4. 启动开发服务器,运行基础端到端测试
  5. 确认基本功能正常后,开始新功能开发

关键发现:使用 JSON 格式追踪 feature 状态比 Markdown 更有效,因为 Agent 不太可能不恰当地修改或覆盖结构化数据。

支柱四:结构化执行(Structured Execution)

核心原则:将思考与执行分离。研究和规划在受控阶段进行,执行基于验证过的计划,验证号通过自动化反馈(测试、Linter、CI)和人类审查完毕。

结构化执行四步:

  1. 理解:探索代码库,分析需求背景,只读访问
  2. 规划:分解任务结构,指定执行计划,人类审查计划
  3. 执行:基于验证过的计划,增量实现功能,限定范围写入
  4. 验证:自动化测试反馈,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
2
3
4
5
6
7
8
Agent 反复用错 API
Agent 走错目录
Agent 把热更代码写到 Main
Agent 忘记释放资源
Agent 使用同步加载
Agent 不知道某个模块的正确入口
Agent 误跑了危险命令
Agent 总是忽略某个构建步骤

简单的错误(Agent运行了错误的命令、找到了错误的API)通过更新AGENTS.md解决。复杂的问题需要构建工具层面的解决方案。

不要维护一个巨大的 AGENTS.md,如果AGENTS.md 太长,Agent反而抓不住重点。更好的结构是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# AGENTS.md

请使用中文写提案和回答
这个文件为 Codex (Codex.ai/code) 提供指导,用于处理此代码库中的代码。
TEngine 基于 HybridCLR + YooAsset + UniTask + Luban 构建。

## 核心原则

- 异步优先:资源和 IO 使用 UniTask
- 模块访问:业务代码通过 GameModule.XXX
- 资源释放:LoadAssetAsync 对应 UnloadAsset
- 热更边界:Main 不热更,HotFix 热更
- 事件解耦:模块间用 GameEvent

## 详细文档

- 架构说明:UnityProject/repowiki/zh/content/...
- 资源管理:UnityProject/repowiki/zh/content/API参考/资源管理API.md
- UI 开发:UnityProject/repowiki/zh/content/UI系统/...

也就是AGENTS.md放最高优先级规则,细节连接放到更深的文档。

采用Tier 1/2/3 渐进式披露

Tier 1: AGENTS.md放最核心、最高频、最容易犯错的规则

Tier 2: 任务类型文档:当Agent要做具体类型的任务时再读,AGENTS.md只放链接。UnityProject\.claude\skills\tengine-dev\references\event-system.md

Tier 3: 实事源/深层文档/示例:这一层放更完整、更细、更低频的信息。UnityProject/repowiki/zh/content/API参考/资源管理API.md

由 Agent 为 Agent 维护文档:后台Agent定期做这些事情

1
2
3
4
5
检查 AGENTS.md 里的链接是否失效
检查文档里的 API 名是否和代码一致
发现旧路径、旧类名、旧规范
提交一个文档修复 PR
把最近反复出现的问题整理进 AGENTS.md

这就形成了反馈循环:

1
2
3
4
5
Agent 犯错
→ 人或工具发现
→ 更新 AGENTS.md / 文档 / Linter
→ 下次 Agent 更少犯错
→ 新问题继续沉淀

一句话总结:AGENTS.md 是 Agent 的项目驾驶手册;真正厉害的用法不是写得很长,而是让它随着错误持续变准,并把复杂规则升级成自动检查工具。

架构约束与自动化执行

分层架构依赖方向强制执行:

1
Types → Config → Repo → Service → Runtime → UI

任何违反这一方向的代码都被自定义 Linter 自动检测和阻止。在人类优先的工作流中,这些规则可能感觉过于严苛;对 Agent 来说,它们是乘数效应:一旦编码,便处处适用。

Linter错误消息即修复指令:

不仅要告诉AI错乱,还要告诉他如何修复,怎样是正确的。

结构测试:

结构测试不是测试业务功能对不对,而是测试代码结构有没有违反架构规则。比如

1
2
3
4
5
GameLogic 有没有反向污染 TEngine.Runtime?
Main 有没有引用 HotFix?
Repo 层有没有引用 UI 层?
业务代码有没有绕过 GameModule 直接访问 ModuleSystem?
资源加载有没有使用同步 API?

对 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:

  • 扫描文档不一致
  • 检测架构约束违规
  • 清理冗余或低质量代码
  • 确保“清理吞吐量”与“代码生成吞吐量”成比例

实践总结

行动清单

  1. 创建并维护AGENTS.md:不是一次性任务,而是每当Agent犯错时都更新的活文档。
  2. 在创库中建立单一实事源:所有团队知识作为版本控制的制品存放在代码仓库中,不放在Slack、Wiki或Google Docs。
  3. 构建自定义 Linter 并在错误消息中嵌入修复指令:工具在Agent工作时同时“教会”它。
  4. 为Agent提供端到端测试工具:浏览器自动化(如Puppeter MCP)显著提升验证质量。
  5. 实施增量执行策略:每次会话只处理一个功能,完成后提交git和进度更新。
  6. 分层管理上下文:避免将所有信息堆叠在单个文件中,使用Tier 1/2/3 渐进式披露。
  7. 上下文利用率保持在40%以下:更多token不代表更好的结构。
  8. 建立定期“垃圾回收”机制:自动化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 名。

共识二:文档必须是活的反馈循环,不是静态制品。

共识三:思考与执行必须分离。

共识四:上下文不是越多越好。

共识五:约束必须机械化执行,不能靠文档记录。

共识六:工程师角色正在从”写代码“转向”设计环境 + 管理工作“。