Agent Practice / 04

Auto Harness 实战:从失败轨迹迭代 Agent 运行骨架

Agent 能连续运行六小时、自动压缩历史、失败后自行重试,并不等于 Auto Harness。它可能只是同一套运行骨架跑得更久,或者在一次会话里临时改变上下文。

真正值得研究的问题是:当 Agent 反复暴露同一类缺陷时,系统能否把失败变成一个小而明确的 Harness 修改,并验证下一版确实更好。 这篇文章不讨论怎样增加更多管理流程,而是聚焦 H_t -> H_t+1 这一轮迭代怎样发生。

一、Auto Harness 迭代的到底是什么

可以把一个 Agent 写成:

Agent A = 固定模型 M + 运行骨架 H

这里的 H 是模型之外、决定 Agent 如何工作的全部非参数化机制:

  • System Prompt、上下文选择和压缩策略
  • 工具定义、参数 Schema、解析器和适配器
  • 规划、路由、重试、恢复和退出条件
  • 记忆、检索、验证器、权限与资源限制

Auto Harness 固定基础模型 M,根据运行证据修改 H。如果模型权重变了,那是训练;如果只更新当前会话摘要,那是 Context Adaptation;如果 Prompt、工具或控制流形成了可持久化的新版本,并通过新任务验证,才是 Harness 迭代。

场景 改变对象 是否产生新 Harness 判断
自动总结历史 当前会话上下文 Context Adaptation
人工修改 Skill 持久化规则 人工 Harness 迭代
Agent 提议并验证 Prompt Diff 持久化规则 Auto Harness 的基础形态
在线任意修改工具和权限 整套运行环境 风险过高,不适合作为起点

核心区别不在“是不是 Agent 写的”,而在于有没有形成一个可比较的新版本。

二、研究给出的共同主线

OpenAI 的 Harness Engineering 实践强调先把仓库知识、工具、测试和环境变得对 Agent 可读、可执行。它解决的是怎样得到一套可靠 Harness,是后续自动迭代的地基。

AutoHarness进一步把 Harness 当作代码搜索空间:模型根据游戏环境反馈迭代动作验证器或代码策略。它证明 Harness 不必停留在人工 Prompt,但实验集中在规则清楚、反馈可验证的 TextArena 游戏,不能直接外推到开放式软件工程。

Self-Harness把迭代压缩成三个动作:从多条轨迹挖掘重复弱点,围绕弱点提出小而多样的修改,再用未参与提议的任务做回归验证。这比“失败后再加一句 Prompt”更接近可复用改进。

HarnessBank继续补充了两个有用判断:新增机制必须在运行中真正触发,收益还要越过随机波动。与此同时,Harness 演化评测研究发现,匹配反馈和推理预算后,部分 Harness 演化并不稳定优于普通重试,跨任务泛化也有限。

这些工作虽然方法不同,但都绕不开同一条主线:

运行证据 -> 重复缺陷 -> 最小修改 -> 对照验证 -> 保留或拒绝

三、一轮 Harness 迭代怎样发生

flowchart TB
    A["稳定版本 H_t"] --> B["运行真实任务<br>收集失败轨迹"]
    B --> C["聚类重复缺陷<br>形成可证伪假设"]
    C --> D["只修改一个 Harness 表面<br>生成候选版本"]
    D --> E["目标任务修复验证<br>未见任务回归验证"]
    E --> F{"表现是否稳定提升"}
    F -->|"是"| G["保留为 H_t+1"]
    F -->|"否"| H["拒绝修改<br>保留负面经验"]
    G --> A
    H --> C

这不是一次“大升级”,而是一连串小实验。每轮只回答一个问题:某个明确的 Harness 缺口,是否能被一个最小修改稳定修复?

四、第一步:把失败变成可用证据

完整聊天记录通常太长,也混有大量无关内容。Harness 迭代真正需要的是一份紧凑的失败记录:

task_id: fix-api-timeout
harness_version: h-2026-08-01
outcome: failed
failure_stage: verification
last_valid_state: implementation_complete
tool: pytest
error_class: test_timeout
exit_reason: retry_budget_exhausted
cost_tokens: 18420
latency_seconds: 366

记录的目的不是归档一切,而是支持横向比较:同一版本是否在不同任务里反复停在验证阶段?某个工具是否经常参数错误?Agent 是否总在还有重试预算时提前结束?

先排除环境噪声。沙箱崩溃、依赖源不可用、验证器超时属于环境失败;一次随机推理错误也不足以修改共享 Harness。只有在多个独立任务上重复出现、并能定位到 Harness 行为的缺陷,才值得进入下一轮。

五、第二步:从失败簇提出最小修改

假设最近 30 次编码任务中,有 8 次在测试失败后直接结束。轨迹显示模型已经看到错误,但恢复流没有明确要求重新读取失败摘要。此时的候选不该是“重写整个 Coding Agent”,而应是一份很小的修改:

candidate_id: recovery-read-test-summary
parent: h-2026-08-01
hypothesis: 恢复流遗漏测试摘要导致 Agent 过早结束
changed_surface: workflows/recovery.yaml
expected_activation: test_failed and retry_budget_remaining
expected_effect: 降低可恢复测试失败造成的任务失败率
non_goals:
  - 不修改测试命令
  - 不增加重试预算
  - 不扩大工具权限

好的候选包含四件事:

  1. 失败机制:为什么当前 Harness 会失败。
  2. 最小 Diff:只改一个 Prompt、工具描述或控制条件。
  3. 触发条件:新机制应该在哪些轨迹中执行。
  4. 预期变化:什么指标会改善,什么行为必须保持不变。

这使候选可证伪。如果新恢复规则从未触发,即使平均分偶然提高,也不能把收益归因于它。

六、第三步:比较新旧版本,而不是证明候选能跑

验证至少回答两个问题:

  • 目标问题修好了吗? 在触发该缺陷的任务上比较 H_t 与候选版本。
  • 原有能力退化了吗? 在提议阶段未见的任务上检查回归。
固定条件 需要观察的变化
相同基础模型与推理参数 任务成功率、错误类型
相同任务与验证器 新机制是否触发
相同 Token 和重试预算 成本、时延、工具调用数
多次独立运行 均值、波动和失败分布

还要加入一个朴素基线:固定旧 Harness,只增加相同预算的并行采样或顺序重试。如果候选不比这个基线更好,所谓“迭代收益”可能只是多花了计算量。

通过验证后,候选成为 H_t+1,同时保留父版本和修改原因;失败候选也值得记录成负面经验,避免下一轮重复提出同一种无效规则。这里不需要复杂平台,Git Commit 加一份结构化评估结果就能起步。

七、应该先开放哪些可变表面

Auto Harness 的搜索空间越大,越难归因。建议按风险从低到高逐步开放:

可变表面 适合解决的问题 验证重点
Prompt / Skill 步骤遗漏、输出约束不清 指令冲突、长度膨胀
上下文策略 关键文件漏读、无关内容过多 召回率、Token 成本
工具描述 / Schema 工具选错、参数格式错误 契约兼容、非法调用
控制流 提前结束、无效重复、恢复失败 步数、退出原因、成本
记忆与检索 重复犯错、经验无法复用 污染、过期、隐私

第一版只优化 Prompt 或一个 Skill。等单组件迭代稳定后,再开放工具 Schema 或恢复策略。权限、安全策略和最终评估器不应由候选自动修改,否则系统会通过放宽约束来制造“提升”。

八、结合我们的工程实践看 Harness 怎样迭代

我们已经做过很多人工驱动的 Harness 迭代。它们的共同点不是增加项目管理,而是把重复失败变成更好的 Agent 运行条件:

观察到的重复问题 修改的 Harness 工件 迭代结果
Agent 进入错误仓库或遗漏项目约束 AGENTS.md 只提供地图,再按项目加载规则 初始上下文更小、更准确
多个任务在同一工作区互相污染 为独立任务使用隔离 Worktree Diff、测试和回滚互不干扰
同一类任务反复解释相同步骤 把稳定方法提炼为窄范围 Skill 后续运行直接复用已验证方法
外部 Push、PR 或评论容易越过人的判断 把外部动作设为明确授权点 Agent 可自主完成本地工作,外部影响仍可控
简单文章图也默认走 Draw.io,导出成本高 改为 Mermaid 默认,Draw.io 仅作例外 图表迭代直接留在 Markdown 中完成

最后一行就是本次真实迭代。我们先观察到默认 Draw.io 与实际写作偏好不一致,再定位到根 AGENTS.mdnew-article Skill 中两处旧规则,只修改这两个 Harness 工件,并在本篇文章中直接使用 Mermaid 验证新规则。

这仍然是人工 Harness 迭代:人发现问题、给出方向并决定是否保留。向 Auto Harness 再走一步,不是增加更多表单,而是让系统从已有运行证据中自动完成两件事:发现高频失效模式,生成可审查的最小 Diff。

九、最小可行的 Auto Harness 原型

第一版不需要让 Agent 自动改线上系统。它只需要离线生成候选和对比报告:

def iterate_harness(current, recent_runs, target_tasks, regression_tasks):
    failures = top_repeated_failures(recent_runs)

    for hypothesis in propose_hypotheses(failures):
        patch = propose_minimal_patch(current, hypothesis)
        if not patch.touches_only("prompts", "skills"):
            continue

        candidate = current.apply(patch)
        target = compare(current, candidate, target_tasks)
        regression = compare(current, candidate, regression_tasks)

        if target.improves and regression.no_degradation:
            return reviewable_candidate(patch, target, regression)

    return None

工程落地可以分三步:

  1. 人工迭代,统一证据:给 Harness 加版本号,保存紧凑轨迹,人工提出小 Diff。
  2. 自动提议,人工保留:Agent 聚类失败并生成候选,人 Review 后决定是否合入。
  3. 自动离线筛选:低风险候选在隔离任务集上自动比较,只把通过者交给人。

到第三步已经能显著减少 Harness 维护成本。在线自动修改、自动放宽权限或自动全量发布,并不是证明 Auto Harness 有价值的必要条件。

十、少量但必要的边界

边界的作用是保护迭代信号,不是增加流程:

  • 评估器不能和候选一起改,否则分数失去可比性。
  • 用于提议的任务与回归任务要分开,避免把记住测试集当成改进。
  • 随机模型要重复运行,不能用一次变绿证明收益。
  • 权限扩大和外部副作用继续由人决定。
  • 每个新版本保留父版本,出现退化可以立即回退。

十一、研究脉络:不同方法在迭代哪一层

工作 主要迭代对象 可以借鉴什么 边界
Harness Engineering 仓库、工具、规则和反馈环境 让 Agent 能读、能做、能验证 工程实践,不是自动搜索算法
ADAS Agentic System 代码结构 用 Meta Agent 搜索系统设计 搜索空间大、评估昂贵
GEPA 一个或多个 Prompt 从轨迹反思并演化规则 主要覆盖 Prompt 层
AutoHarness 动作验证器或代码策略 把 Harness 作为程序搜索 证据集中在规则明确的游戏
Self-Harness 模型特定 Harness 失败聚类、最小候选、回归验证 仍需更多生产验证
HarnessBank 多种 Harness 机制 激活检查、显著性筛选、保留多样候选 预印本结果需独立复现
Harness Evolution Evaluation 评测方法 匹配预算、加入简单基线、检查泛化 说明当前收益并不总是稳定

小结

  • Auto Harness 不是让 Agent 跑更久,而是让运行骨架形成新版本。
  • 一轮迭代从重复失败开始,以一个最小、可证伪的 Harness Diff 为单位。
  • 目标任务验证修复,未见任务保护原有能力,相同预算基线排除“多试几次”的收益。
  • 我们现有实践已经在人工迭代 Harness;下一步是自动发现失败簇并生成小 Diff,而不是增加管理流程。
  • 从 Prompt 和 Skill 开始,等单组件迭代稳定后再扩大搜索空间。

下一篇建议继续看: