Harness Engineering(三):让软件运行状态对 Agent 可读
Agent 能修改代码,不等于它能验证软件。要让它独立完成工程闭环,应用状态、浏览器、日志、指标和验收标准都必须可供它直接检查。
Jonathan
创始人
对编程 Agent 来说,最常见的完成标准是:代码已经修改,测试已经通过,Pull Request 已经创建。
但用户不会使用代码差异,他们使用的是运行中的软件。一个按钮可能通过了组件测试,却在真实页面上被其他元素遮挡;一个接口可能返回正确数据,却让关键用户路径慢了两秒;一次修复可能消除了原有异常,却破坏了相邻流程。
如果只能由人打开浏览器、查看日志和监控面板来确认结果,Agent 就只是完成了代码实现,并没有走完工程闭环。代码生成得越快,人工测试就越容易成为新的瓶颈。
OpenAI 的 Harness Engineering 实验展示了一种做法:每项代码变更都可以在独立 worktree 中启动应用;Codex 则通过 Chrome DevTools Protocol 获取 DOM 快照、截图并操作页面。同时,每个 worktree 都配有临时的可观测性环境,让 Agent 能够查询日志、指标和 trace。这样,Agent 不只会修改文件,还能复现问题、验证修复并检查性能目标。
Agent 能有多自主,取决于工作环境能为它提供多少可以直接验证的系统状态。
可运行不等于可观察
给 Agent 一条启动命令,只能回答“应用能否运行”。要判断应用运行得是否正确,它还需要三类证据。
第一类是界面状态。Agent 需要知道页面是否成功加载、元素是否出现、交互后 DOM 如何变化,以及视觉结果是否符合预期。
第二类是系统行为。一次点击触发了哪些请求?后台任务是否执行?数据库或缓存状态是否变化?错误来自哪个服务?
第三类是质量信号。启动耗时、接口延迟、关键路径的 trace、错误率和资源占用是否超出约定范围?
如果环境只能提供终端输出,Agent 就只能根据间接信号猜测结果。拥有结构化的页面状态、日志、指标和 trace 后,它才能依据证据作出判断。
这与人类工程师的工作没有本质区别。工程师会自然地打开浏览器、DevTools 和监控面板,而 Agent 只有在这些能力被明确接入 Harness 后才能使用它们。
每个任务都需要独立、用完即弃的验证环境
让多个 Agent 操作同一个开发环境会带来明显问题:任务之间相互污染,状态难以复现,日志混杂在一起,有风险的操作也无法有效隔离。
更稳妥的做法,是让每项代码变更都拥有独立、临时且可以重新创建的运行环境:
任务
↓
独立 worktree 或 sandbox
↓
应用实例 + 测试数据
↓
浏览器会话 + 日志 + 指标 + trace
↓
验证完成后整体销毁
这个环境不必一开始就复制完整生产系统。关键是四个性质:
- 隔离:一个 Agent 的操作不会影响其他任务。
- 可重建:环境状态由代码和明确配置生成,而不是依赖人工准备。
- 可定位:Agent 能确定自己应该访问哪个实例,以及查询哪一组日志和指标。
- 可清理:任务结束后,应用、数据和日志可以一起安全销毁。
有了这层隔离,Agent 才能安全地启动服务、修改状态、重放请求并执行端到端流程。
浏览器工具不仅要能操作,还要返回证据
为 Agent 提供 click、type 和 navigate 工具,只是浏览器自动化的起点。要验证产品行为,工具还必须帮助它回答“操作后究竟发生了什么”。
至少应考虑四类输出:
- DOM 或 accessibility tree:确认元素、文本和交互状态。
- 截图:发现布局、遮挡、颜色和响应式问题。
- Console 与网络请求:定位前端异常、请求失败和加载顺序问题。
- 可重放的操作步骤:重复执行同一路径,并比较修复前后的结果。
结构化信息和截图应该同时存在。DOM 更适合精确断言,截图更适合发现视觉偏差。只靠截图,Agent 很难稳定定位元素;只靠 DOM,又会错过布局和视觉层面的错误。
一个完整的 UI 修复任务可以要求 Agent 提供两组证据:修复前用于复现问题的操作步骤和截图,以及修复后重复同一路径得到的结果。OpenAI 的案例更进一步:Codex 会分别录制修复前后的演示视频。这样,Pull Request 不只包含代码,也包含能够证明问题已经解决的材料。
可观测性必须从人类仪表盘变成 Agent 可查询的接口
很多团队已经建立了日志、指标和 trace 系统,但它们通常只能通过面向人的仪表盘访问。Agent 即使知道某个监控平台存在,也未必能稳定查询,更无法把结果限定到自己正在处理的任务实例。
面向 Agent 的可观测性更强调可查询的接口:
- 日志是否结构化,能否按任务、服务和请求过滤。
- 指标是否有稳定名称,能否通过查询语言访问。
- trace 能否把用户操作与后端调用连接起来。
- 工具结果是否返回关键证据,而不是数万行原始输出。
- 每个临时环境产生的遥测数据是否与其他任务隔离。
在 OpenAI 的案例中,Codex 可以使用 LogQL 查询日志,使用 PromQL 查询指标。于是,“确保服务在 800ms 内启动”或“这四条关键用户路径中的任何 span 都不得超过两秒”,就不再只是写给人的要求,而成为 Agent 可以自行验证的任务条件。
有了这套环境,单次 Codex 运行经常可以围绕一个任务持续工作六小时以上,有时整段过程都发生在人类团队休息期间。真正重要的并不是运行时间本身,而是 Agent 在长时间执行中始终能够获取足够的系统证据,从而不断检查和修正自己的工作。
重点不在于使用哪种查询语言,而在于把质量目标连接到机器可读的信号。没有这种连接,验收标准只是一句话;建立连接之后,它才真正进入执行闭环。
验收标准必须对应可以观测的信号
Agent 能否自主验证,很大程度上取决于任务如何定义。
“优化登录体验”无法直接验证;“用户提交有效凭证后进入控制台,页面没有 Console 报错,关键请求的 P95 延迟低于 500ms”,则分别对应页面状态、Console、网络请求和性能指标。
可以使用一个简单结构编写 Agent 任务:
初始状态:使用什么数据和环境开始
执行动作:用户或系统完成哪些步骤
预期结果:页面和外部状态应该如何变化
质量边界:延迟、错误、安全或资源限制
验证证据:由哪些测试、查询、截图或 trace 证明
这种写法能让团队提前发现模糊需求。如果预期结果无法对应任何可观测信号,就很难让 Agent 端到端完成任务,也很难让人稳定验收。
先从一条关键用户路径建立验证能力
没有必要一次接入整套可观测性系统。可以先选择一条高频且边界清晰的用户路径,例如注册、登录、创建项目或完成支付测试流程,再逐步补齐以下能力:
- Agent 能启动属于当前变更的独立应用实例。
- 它能准备结果稳定、可以重复使用的测试数据。
- 它能通过浏览器执行完整操作。
- 它能读取 DOM、截图、Console 和网络请求结果。
- 它能查询这次操作对应的日志和 trace。
- 它能把验证证据附在任务结果或 Pull Request 中。
这条路径稳定后,再扩展到更多场景。每增加一条可以独立验证的路径,人工测试就能把更多注意力放在产品判断、边界情况和高风险变更上。
本文对 Console、网络请求和任务模板的建议,是在 OpenAI“提高应用可读性”思路上的实践延展。官方案例明确提到了 DOM 快照、截图、页面导航、日志、指标、trace 和修复前后的视频;这里进一步把这些能力整理成团队可以落地的验证清单。
Agent 可读性最终也是系统可测试性
让软件对 Agent 可读,并不是为某个模型添加特殊接口。结构化日志、稳定指标、可重建环境、明确验收标准和可以重放的用户路径,本来就是高质量工程系统需要的能力。
Agent 只是让这些缺口更早显现出来。人可以凭经验绕过不完整的文档,从混乱日志中寻找线索,也可以临时询问同事;Agent 则更依赖明确、可访问、可验证的系统事实。
因此,提高系统对 Agent 的可读性,往往也会改善新工程师上手、事故排查、自动测试和团队协作。Harness Engineering 不是简单地在代码库外面包上一层 AI,而是重新审视:软件是否清楚地提供了理解和验证自身所需的信息。
前三篇到这里形成了一个最小闭环:先重新定义工程工作的重心,再建立知识入口,最后让 Agent 能够观察并验证运行结果。后续文章将继续讨论可执行的架构约束、Agent 之间的代码审查,以及高速生成环境下的代码库熵治理。
本文整理自 OpenAI 的文章 Harness engineering: leveraging Codex in an agent-first world,核心观点来自原文。
Harness Engineering 系列
- (一)当工程师开始设计 Agent 的工作环境
- (二)给 Agent 一张代码库地图
- (三)让软件运行状态对 Agent 可读(本文)
- (四)把工程规则变成可执行约束
- (五)当 Agent 的产出超过人的注意力
- (六)Agent 也会复制技术债务
相关阅读
- 生产级 Agent 的评估与监控 —— 如何把运行轨迹、结果与评分器组织成持续改进系统。
- Agent 长任务的瓶颈,是上下文工程 —— Agent 在长任务中如何保持正确状态。