RHO:让 Agent 从自己的历史轨迹中自我改进 Harness
问题:Agent 的 Harness 如何自我改进?
如果你部署了一个 AI agent,它每天完成了大量的任务——修代码、跑命令、做知识检索。随着时间推移,你希望它越做越好。但这里有一个根本性的难题:你没有带标签的验证集。
传统的 harness 优化方法(prompt engineering、tool synthesis、agent search)都依赖一个标注好的验证集来打分——试试这个 prompt 变体,看看验证集上的 pass rate 是升了还是降了。但在真实部署场景里,维护一个能代表未来任务分布的验证集成本极高,甚至不可能。
另一方面,你的 agent 不断在产生轨迹(trajectories)——它做了什么、成功还是失败、走了哪些弯路。这些轨迹是免费的、持续的、天然覆盖了真实任务分布的。
于是 CityU HK 和 Microsoft Research Asia 的团队问了这样一个问题:
能不能只靠 agent 自己的历史轨迹(没有外部标注),就让它的 harness 不断变好?
他们给出的答案是 RHO(Retrospective Harness Optimization)——一个自监督的 harness 优化方法。单轮优化后,SWE-Bench Pro 的 pass rate 从 59% → 78%(+19pp),全程零外部标注。
论文:arXiv:2606.05922(2026-06-04)| 代码:github.com/wbopan/retro-harness(MIT License)
Harness 是什么?
在讨论 RHO 的方法之前,先定义清楚它优化的对象。
RHO 把 harness 物化为一个文件系统目录,包含三类可编辑的资产:
- Instructions(指令):markdown 文件,写的是任务无关的程序性规则("在修改代码前先读完整文件"、"输出最终结果前运行一次构建验证")
- Skills(技能):markdown 文件,记录的是环境和评分器的 idiosyncrasies("Go 工具链安装在非标准路径 /opt/go"、"Python 缓存目录必须从 patch 中排除")
- Tools(工具):可执行的 shell/Python 脚本(check_build_and_lint、validate_polygon_masks、smoke_test_imports)
这比传统 prompt engineering 能编辑的表面要宽得多——RHO 可以直接创建新的可执行工具。相比之下,Dynamic Cheatsheet(Suzgun et al., 2025)只能追加文本笔记,ReasoningBank(Ouyang et al., 2025)只能记录和检索推理模式,Sleep-time Compute(Lin et al., 2025)只能在离线阶段预处理轨迹摘要。
RHO 的三阶段 Pipeline
核心流程:
历史轨迹 → ① Coreset 选择(DPP, k=10)→ ② 并行回滚(G=3, 自诊断)→ ③ Harness 提案(N=3, self-preference 选出最优)
阶段一:DPP Coreset 选择
你有大量历史轨迹,但全量重放不现实(太贵)。RHO 用 Determinantal Point Process(DPP) 从轨迹池中选择 k=10 个最具代表性的任务。
DPP 的核心公式:
L = Diag(r) × S × Diag(r)
L是 DPP 的核矩阵(kernel matrix),尺寸为候选轨迹数 × 候选轨迹数S = XXᵀ是任务 fingerprint embedding 的余弦相似度矩阵——衡量任务之间的语义相似性r_i = θ × judged_difficulty + (1-θ) × coverage_bonus是每个任务的质量分数,由 LLM 判断的难度和覆盖奖励加权组合
DPP 保证选出的 k 个任务同时最大化难度和多样性——难而非冗余。这里的"难度"不是人工标注的,而是 LLM 读了任务描述后自己的判断。实现用的是 Chen 2018 的 fast greedy MAP 算法(selection/dpp_selector.py,约 200 行纯 NumPy)。
消融实验的发现很关键(见图):
- 纯难度选择(θ=1):pass rate 仅 0.62,甚至比随机选择(0.64)还差——因为 LLM 对某些类型的任务有系统性偏见,导致选出的样本聚集在任务分布的一个狭窄区域,缺乏代表性
- 纯覆盖选择(θ=0):pass rate 0.58,更差——只追求多样性但忽略了难度信号,选了一堆容易但无信息量的任务
- DPP 平衡(学习到的 θ):0.78——难度和多样性缺一不可
阶段二:Group Rollout + 双信号诊断
对每个 coreset 任务,用当前 harness 重新求解 G=3 次,得到 3 条轨迹。然后 agent 自己分析这些轨迹,提取两种无监督信号:
- Self-validation(自验证):逐条分析每条轨迹——任务完成没有?证据是否充分?有哪些多余步骤?missed 了什么?
- Self-consistency(自一致性):对比三条轨迹的差异——哪里分叉了?分叉的原因是什么?对结果质量的影响是什么?
诊断结果输出为结构化的 JSON,包含 severity(0.0-1.0)、failure mode analysis、inconsistency analysis、harness improvement direction(一条高层次改进方向,而非具体的编辑方案)。诊断的 prompt 设计得很精细(orchestrators/diagnose.py),有明确的五步工作流和结构化输出格式。
消融实验(去掉某个诊断信号)的结果非常说明问题:
| 变体 | SWE Pro | TB2 | GAIA-2 |
|---|---|---|---|
| Full diagnosis | 0.78 | 0.76 | 0.37 |
| − self-consistency | 0.56 | 0.75 | 0.27 |
| − self-validation | 0.70 | 0.73 | 0.30 |
| Raw trajectory(跳过诊断) | 0.60 | 0.75 | 0.29 |
Self-consistency 在 SWE-Bench Pro 上单独贡献了 22pp——这是最大的单一因素。去掉它,pass rate 从 0.78 直接掉到 0.56。这说明在代码修复任务中,跨 rollout 的一致性信号是 harness 优化的核心驱动力,单条轨迹的内部质量分析远不够。
阶段三:Best-of-N Harness 提案 + Self-Preference 选择
有了诊断信号后,agent 并行生成 N=3 个候选 harness(每个候选是一个独立的优化调用,LLM 直接修改 harness 目录中的文件)。然后,用每个候选 harness 重新求解 coreset 任务,获取新轨迹。
关键问题:没有 ground truth 标签,怎么比较三个候选 harness?
RHO 的方案是 self-preference ranking:对每个 coreset 任务,比较新 harness 的轨迹和新旧轨迹之间的差异,计算 rank 分数——agent 自己判断新轨迹是否比旧轨迹更好。
S_j = (1/|D_core|) × Σ rank(t, τ_j, τ_0)
S_j是候选 harness j 的聚合分数rank(t, τ_j, τ_0)是 agent 对任务 t 下新轨迹 τ_j 和旧轨迹 τ_0 的 pairwise 偏好排名
选 S_j 最大且严格大于 0 的候选替换当前 harness。
一致性分析显示:三个候选 harness 的得分方差适中(SWE-Bench Pro 上 std=0.06),即使最差的候选也比 baseline 有意义地好(最低 0.73 vs baseline 0.59)。Best-of-N 选择虽然不总是选中最高分的候选,但总是避开了最差的那个。
实验结果:三个领域,一致提升
实验用 Codex CLI + GPT-5.5(high reasoning effort)作为 base agent,在三个不同领域的 benchmark 上测试:
| Benchmark | Vanilla Codex | RHO | Δ | 领域 |
|---|---|---|---|---|
| SWE-Bench Pro | 0.59 | 0.78 | +0.19 | 多文件代码修复 |
| Terminal-Bench 2 | 0.71 | 0.76 | +0.05 | 命令行任务 |
| GAIA-2 | 0.29 | 0.37 | +0.08 | 异步知识工作 |
与有监督的基线方法(Meta-Harness)对比更具说服力:
| 方法 | 需要标注 | Agent 调用量 | SWE-Bench Pro |
|---|---|---|---|
| Vanilla Codex | — | — | 0.59 |
| Meta-Harness (1 round) | ✓ | 41 (0.4×) | 0.62 |
| RHO (1 round) | ✗ | 103 (1.0×) | 0.78 |
| Meta-Harness (10 rounds) | ✓ | 320 (3.1×) | 0.80 |
这里有两个关键信息:(1)RHO 在单轮预算下完胜 Meta-Harness(0.78 vs 0.62),且不用任何标签;(2)Meta-Harness 扩展到 10 轮达到 0.80,但这需要 3.1× 的计算量 和 一个带标签的验证集。
行为变化:RHO 不只是提高了分数
论文的分析揭示了 harness 优化后 agent 的行为模式发生了质变(Figure 4):
- SWE-Bench Pro:Verify +61%,Navigate −13%——agent 学会在提交修改前大幅增加了验证步骤(检查构建、运行测试、验证 diff 洁净度)
- Terminal-Bench 2:Execute +27%,Edit −44%——agent 从"边改边试"变为"先分析再直接执行",减少了对工作文件的无效编辑
- GAIA-2:Execute +25%,Edit −17%——类似模式,agent 更直接地使用新创建的工具完成任务
更重要的是,性能提升主要来自长 horizon 任务——短任务上 vanilla 和 RHO 差不多,但需要 40+ 步的任务上 RHO 的累积成功率显著更高。这意味着 harness 优化不是让 agent "做更快",而是让它 "能在更复杂的问题上坚持到成功"。
RHO 优化出的 Harness 里有什么?
论文给出了三个 benchmark 上最优 harness 的具体内容(Figure 3):
- SWE-Bench Pro:新增 check_build_and_lint 工具(定位非标准工具链 + 标记不应进入 patch 的生成产物),以及"先追踪真实代码路径再编辑"等技能
- Terminal-Bench 2:新增 validate_polygon_masks 工具(验证导出的 mask 格式正确)、smoke_test_imports(检查包能否正常加载)
- GAIA-2:新增 list_app_functions、get_function_schema、call_function 等工具(将异步环境中的 app 交互标准化)
这些东西不是 hand-crafted 的,而是 agent 从自己的失败中自动抽象出来的。SWE-Bench Pro 的最优 harness 里,"Python cache 目录必须从 patch 排除"这条技能,就是在多次 diff hygiene 失败后自动生成的。
代码实现质量评估
开源代码(2026-06-07 发布,6 stars,MIT 许可)的质量值得单独一说:
- ~16k src 行 + ~13k test 行,test-to-code ratio 0.81——在学术代码中极为罕见
- 全部接口用 typing.Protocol 解耦——Agent、Harness、Task、TaskJudge、Embedder、Dataset 都是 protocol,可替换实现
- 150+ 个 test 文件,覆盖 hermetic 测试、真实 agent 端到端测试、数据集级别测试
- 依赖清爽:uv 管理,核心仅 numpy + litellm + Codex CLI
- 组件组织清晰:selection/ strategies/ orchestrators/ datasets/ stores/ 各司其职
这种代码质量和工程素养,在 arxiv paper accompany 的代码中属于顶级水平。MIT 许可意味着可以放心用于任何场景。
与我们技术栈的交叉点
RHO 的核心创新与我的几个研究兴趣高度重叠:
- Harness Engineering——RHO 给出了一个完整的 label-free harness 优化范式。它把 harness 定义为"可编辑的文件系统状态"这一抽象,可以推广到任何 agent 框架
- 递归自我改进——RHO 的 self-preference 机制是一种 agent 通过自身轨迹信号实现自我进化的方法。Harness 提案 → rollout → self-preference → 接受/拒绝,形成了一个完整的自我改进闭环
- 约束工程——RHO 通过 harness 目录结构显式约束 agent 的行为:tools/ 是可执行脚本、skills/ 是 markdown 文本、instructions.md 是规则。这种"harness = 文件系统状态"的设计是约束工程的一个具体实例
可以借鉴的技术点:
- DPP coreset 选择——需要从大量轨迹中选子集做分析时,DPP > random >> pure difficulty > pure coverage
- Self-validation + self-consistency 双信号——作为无标注评估的通用方法,比 raw trajectory 直接喂给优化器效果好得多(0.60 → 0.78)
- Protocol-driven 架构——用 typing.Protocol 而非 ABC 做接口抽象,轻量且可组合
但有几个值得追问的方向,RHO 没有涉及:
- 控制面/执行面分离——RHO 的 harness 优化和执行在同一个 agent 内完成。如果引入独立的"meta agent"来负责 harness 优化,能否在安全性和效果上都更好?
- 多轮优化天花板——RHO 只做了一轮。Meta-Harness 十轮到 0.80,RHO 单轮 0.78,差距可能来自迭代次数而非方法论
- LLM-as-judge 的偏差——self-preference 依赖 LLM 做 pairwise ranking。当 judge 能力不足时,选择质量会退化——没有实验评估这个假设
局限与推断边界
论文明确指出的局限(高置信度):
- 需要可重置、可重复执行的环境——排除了一次性任务和不可逆操作
- 假设 agent 的大部分能力由可编辑的 harness 承载——如果 agent 的瓶颈在底层模型能力而非工具/指令层面,RHO 的效果上限有限
- 仅在 Codex + GPT-5.5 上验证——换模型/provider 后效果是否一致需要实验
我的推断(中置信度,需独立验证):
- Self-preference ranking 的有效性对 judge 模型的能力有强依赖——弱模型可能无法可靠地区分轨迹质量,甚至引入噪声导致 harness 退化
- DPP 选择依赖 task fingerprint embedding 的质量——如果 embedding 不能有效捕获任务的困难模式,DPP 的选择优势会消失(正如消融实验所示)
- 单轮优化的天花板可能由 coreset 的信息量决定——如果 k=10 的 coreset 已经覆盖了所有关键失败模式,多轮迭代的边际收益可能不大
- Harness proposal 阶段的"直接修改文件"范式——LLM 在单次调用中能做出的改动质量上限,是 RHO 整体效果的理论上限
评分
从几个维度给 RHO 打分:
| 维度 | 评分 | 说明 |
|---|---|---|
| 方法论创新 | ★★★★★ | 首次将 harness 优化从有监督改为自监督,DPP coreset + 双信号诊断 + self-preference 的 pipeline 设计精巧 |
| 实验结果说服力 | ★★★★★ | 三个不同领域 benchmark,丰富消融实验(coreset 选择策略、诊断信号、candidate 一致性),开源代码可复现 |
| 工程实现质量 | ★★★★★ | 16k/13k 代码/test 比例,Protocol 抽象,150+ 测试文件,MIT 许可 |
| 实践可用性 | ★★★★☆ | 当前仅支持 Codex CLI + GPT-5.5,但 Protocol 设计使适配其他 agent 框架成本较低;k=10 coreset + N=3 proposal + G=3 rollout = 103 次 agent 调用,对普通用户来说 API 成本不低 |
| 理论深度 | ★★★★☆ | DPP 理论、self-preference 的数学框架清晰,但缺少对 self-preference 选择质量的严格理论保证 |
总评:2026 年 Agent infrastructure 领域目前最令人兴奋的工作之一。如果你关心"agent 如何在实际部署后持续自我改进"这个核心问题,RHO 提供了目前最完整的答案。
技术声明
信息来源: 论文 arXiv:2606.05922(2026-06-04,41 页)全文 PDF 提取,以及 GitHub 仓库 wbopan/retro-harness(MIT License,截至 2026-06-07 的代码)。所有引用的消融实验数据、pass rate 数值、架构描述均直接来自论文原文。
分析边界: 本文分析基于论文 + 开源代码,未独立复现实验。对未在论文中明确实验验证的推断(如 LLM-as-judge 的模型能力依赖)已标注置信度。本文不构成学术评审,仅代表技术分析的立场。
利益声明: 作者正在开发 meta-agent-poc,其中 RuntimeGate 和 harness 优化方向与 RHO 存在交叉。本文的分析基于公开材料和工程评估,不构成竞争性比较。