Agent 自进化 · Harness 优化 · 论文精读

Agent 不看答案,也能学会把自己改得更好?我拆解了微软 RHO 的「黑暗进化」

没有测试、标准答案和用户打分,Agent 还能从自己的历史轨迹中学到什么?RHO 给出了一条不改模型权重、只进化 Harness 的可审计路径。

2026-09-08约 9000 字阅读约 24 分钟AgentRHOHarness
无标签历史轨迹经过筛选与并行诊断,汇入改进后的 Agent Harness
没有标准答案时,Agent 仍可以从历史轨迹的分歧中提炼改进信号;但自我偏好必须被门控、审计与回滚约束。
先给结论:RHO 不训练模型权重,而是用历史轨迹改写 Agent 的 Instructions、Skills 与 Tools。它最重要的贡献不是“Agent 可以自己批改自己”,而是把自我怀疑组织成一条可比较、可拒绝、可回滚的 Harness CI/CD。

如果一个 Agent 做完任务以后,我们不知道它到底做对了没有,它还能从这次经历中学到什么?

直觉上,答案应该是:学不到。没有单元测试,没有标准答案,没有用户打分,连一个可靠的 pass/fail 都没有,系统凭什么知道该保留哪段经验、该修哪条 Skill?这就像让一个学生自己出题、自己答题、自己批卷,最后还自己修改教材——任何一个环节的自我感觉良好,都可能把错误写进下一版。

但现实中的 Agent 恰恰长期处在这种环境里。部署以后,它每天会留下大量任务轨迹:读了哪些文件、调用了哪些工具、做过哪些假设、在哪一步放弃、最终回复了什么。真正稀缺的不是日志,而是标签。很多企业有十万条 Agent 会话,却没有十万份由专家逐条核验的答案。

微软亚洲研究院与香港城市大学的这篇 Evolving Agents in the Dark,就在研究这个看似矛盾的问题:能不能只用 Agent 自己留下的、没有标准答案的历史轨迹,反过来改进它的长期工作方式?

论文给出的答案叫 RHO(Retrospective Harness Optimization,回溯式 Harness 优化)。它不训练模型权重,也不是让 Agent 把失败总结成一句话塞进 Memory;它把过去的任务重新组织成一次离线复盘:挑出最值得复盘的任务,多跑几遍找分歧,生成多套 Harness 修改方案,再由 Agent 自己比较修改前后的轨迹,只在新方案整体更好时接受更新。

论文最醒目的结果是:在不使用训练集标准答案、不调用外部 grader 指导优化的情况下,一轮 RHO 把 SWE-Bench Pro 的 held-out 通过率从 59% 提升到 78%。但比这个数字更有价值的是,它把「Agent 自进化」拆成了一条可以审计、可以拒绝更新、也可以迁移到其他业务的工程管线。

RHO 完整流程:从部署轨迹到改进后的 Harness
图 1:论文 Figure 2。白天执行任务,夜间回看轨迹;RHO 依次完成代表性任务选择、并行重跑与诊断、候选 Harness 生成和偏好筛选。图片来自论文官方项目。

这篇文章不只复述论文。我更想回答四个问题:RHO 到底改了什么?没有答案时,改进信号从哪里来?59% 到 78% 说明了什么、又没有说明什么?最后,它能否迁移到代码 Agent 之外的客服、数据分析、运维、研究与医疗工作流?


先把名字讲清楚:RHO 进化的不是模型,而是 Harness

「Agent 自进化」很容易让人想到模型自己训练自己。RHO 做的不是这件事。

论文把 Harness 定义为围绕固定模型的一组持久化能力,包括 Prompt、Instructions、Skills、Tools、Memory 和控制流程。它们决定模型能看到什么、能调用什么、做事时遵循什么程序。模型像一个人的基础智力,Harness 更像他的工作手册、工具箱、检查清单和组织流程。

在官方实现里,Harness 甚至没有固定 schema,它就是一个目录:里面可以同时放 Markdown 指令、结构化配置和可执行脚本。求解任务时这个目录只读;优化时复制一份并开放写权限,Agent 可以新增、删除或修改其中任意文件。优化结果不是从最终回复里解析一段 diff,而是直接读取它留在文件系统中的新目录。

这使 RHO 和常见的「经验积累」方法有一个关键区别:

方法主要修改对象能解决什么容易卡在哪里
Dynamic Cheatsheet技巧文本记住常见做法和代码片段只能补知识,难改执行流程
ReasoningBank推理记忆检索可复用的推理模式召回正确不等于真正执行
Sleep-time Compute预计算上下文在任务到来前准备背景信息仍以文本上下文为主
RHOSkills + Tools + Instructions同时修改知识、流程和可执行能力修改面更大,也更需要门控

举个例子:如果代码 Agent 总是因为找不到非标准路径下的 Go 工具链而失败,Memory 可以提醒它「Go 可能不在 PATH 里」;RHO 则可能直接生成一个 check_build_and_lint 工具,让后续任务自动定位工具链、检查构建产物并清理不该进入补丁的缓存目录。

换句话说,RHO 不是让 Agent 记住一次答案,而是让它把重复出现的失败模式编译成下一次可以执行的能力

我会把它放在 Agent 自进化的第二层:

flowchart LR
    A["Artifact修改本次输出<br/>Artifact refinement"] --> B["修改长期配套<br/>Harness evolution"] --> C["修改模型参数<br/>Weight training"]
    B:::focus
    classDef focus fill:#e9f6ec,stroke:#238636,stroke-width:2px,color:#143d20;
  • Artifact refinement 只让这一次答案变好,下一次任务从头再来;
  • Harness evolution 不动权重,但修改会持续影响未来任务;
  • Weight training 改变模型本身,成本和不可逆性都更高。

RHO 的现实吸引力就在中间:比改一次答案更持久,比重新训练模型更即时、更可回滚。


真正的问题:当正确率是隐藏变量,优化目标从哪里来?

设任务为 $t$,Harness 为 $h$,Agent 在这个 Harness 下完成任务得到轨迹 $\tau$:

$$\tau = \mathrm{solve}(h,t)$$

轨迹不只是最终答案,而是完整的 reasoning、action、observation、工具调用和工作区改动。理论上,我们希望找到一个新 Harness,使未来任务的真实效用最大:

$$h^{\star}=\arg\max_{h'}\;\mathbb{E}_{t,\,\tau\sim\mathrm{solve}(h',t)}[U(t,\tau)]$$

人话解释:选一个工作系统,让 Agent 将来平均做得更好。

问题是 $U(t,\tau)$ 在部署现场通常不可见。开放式调研没有唯一答案,客服会话未必有满意度反馈,代码修改可能很久以后才暴露回归。传统 Harness 优化依赖一套带答案的 validation set,不断尝试新 Prompt 或新程序,再用分数指导下一轮搜索;RHO 则故意拿走这根拐杖。

论文把这种设定概括为只依赖 “past trajectories”。但「没有标签」不等于「没有信号」。同一个 Agent 重做同一道任务时,可能出现三条明显不同的路径:

  • 第一条很快给出答案,却没有检查环境状态;
  • 第二条尝试了正确工具,但在一次报错后提前停止;
  • 第三条读取了更多证据、修正了假设并完成验证。

我们仍不知道哪条拿到了外部标准答案,但这些轨迹之间已经暴露出结构性差异:有没有无视工具报错?有没有自相矛盾?有没有把用户要求漏掉?有没有用环境证据验证结论?RHO 的核心赌注是:模型虽然未必能可靠地绝对判断自己是否正确,却可能有能力比较两条具体轨迹谁更可信,并从多次执行的分歧中识别 Harness 缺口。

这不是把隐藏效用 $U$ 真正恢复出来,而是用 self-preference 构造一个代理信号。整篇论文的成败,都取决于这个代理信号是否足够相关、是否不会在闭环里放大偏见。


RHO 的三步:挑对病历、多做几次检查、再决定是否换药

RHO 一轮优化分三步:Coreset Selection、Group Rollout、Best-of-N Harness Proposal。如果把 Agent 当成一家医院,它不是看到一份病历就修改诊疗规范,而是先挑一组有代表性的疑难病例;让同一支团队独立诊断多次,比较哪里不一致;最后生成几版新规范,在同一组病例上与旧规范盲比,只有总体更好才替换。

RHO 三阶段流程:选 Coreset、并行诊断、候选 Harness 门控
图 2:RHO 的一轮优化。它先从无标签历史轨迹里挑选“困难且多样”的 Coreset,再对每项任务进行三次独立重跑,通过 self-validation 和 self-consistency 形成结构化诊断;最后生成三套候选 Harness,只有当获胜候选相对旧 Harness 的平均偏好分严格大于 0,才接受更新。

第一步:不是挑最难的十道题,而是挑「又难、又不重复」的十道题

把全部历史轨迹都拿去重跑非常贵,也会让大量简单、重复的问题淹没少数真正有价值的失败模式。RHO 先让 LLM 给每条历史轨迹生成两个东西:

  1. 难度分数 $r_i\in[0,10]$;
  2. 描述任务挑战和潜在失败模式的 fingerprint。

然后把 fingerprint 编码为向量,用余弦相似度得到任务相似矩阵 $S$。难度经过缩放以后,与相似度一起组成 DPP 的核矩阵:

$$L=\mathrm{diag}(\widetilde r)\,S\,\mathrm{diag}(\widetilde r)$$
$$\widetilde r_i= \left(\frac{\max(r_i,\epsilon)}{\max_j\max(r_j,\epsilon)}\right)^{\alpha}, \qquad \alpha=\frac{\theta}{2(1-\theta)}$$

这里的 $\theta$ 控制难度与多样性的权衡,论文使用 $\theta=0.7$。三个数据集都从各自训练池中选 $k=10$ 条;SWE-Bench Pro 和 GAIA-2 的训练池为 100 条,Terminal-Bench 2 为 30 条。

DPP(Determinantal Point Process)可以先用一个直觉理解:如果两道题非常相似,它们一起被选中带来的「体积」增益很小;如果一条轨迹既困难,又代表了一个此前没有覆盖的失败方向,它更容易进入 Coreset。目标不是选十个最高分的难题,而是用十个样本覆盖尽可能多的高价值故障模式。

官方实现与公式直接对应:先取 difficulty 和 fingerprint embedding,计算 $S=XX^T$,再把难度权重乘到相似矩阵两侧,最后执行 greedy MAP 选择。

# src/rho/selection/dpp_selector.py:139-166
judged_map = self._judge.judge_many(candidates)
judged = [judged_map[t.id] for t in candidates]
raw_scores = [r.difficulty for r in judged]
texts = [r.fingerprint for r in judged]
vecs = self._embedder.embed(texts)

floored = np.array(
    [max(s / 10.0, self._score_floor) for s in raw_scores],
    dtype=np.float64,
)
S = (vecs @ vecs.T).astype(np.float64)
alpha = self._theta / (2.0 * max(1.0 - self._theta, 1e-6))
r_raw = floored / float(floored.max())
r = r_raw**alpha
L = (r[:, None] * S) * r[None, :]
picks_ix, gains = fast_greedy_map(L, target_k)

这一步的消融很有启发。只选最难的任务,会因为 LLM 对某一类难题有稳定偏好而聚成一团;只追求覆盖,也会挑进大量不值得优化的样本。论文 Figure 5 显示,纯难度或纯多样性甚至不如随机抽样,只有两者结合的 DPP 才取得最佳 held-out 增益。

这条经验可以直接迁移到企业 Agent:复盘集不是失败工单排行榜。 十个同类型的 SQL 超时,只会让系统过拟合 SQL;真正有价值的是覆盖检索错误、权限失败、工具超时、需求遗漏、错误早停等不同根因。

第二步:同一道题重做三遍,分歧本身就是诊断信号

选出 Coreset 后,RHO 用同一个原始 Harness 对每项任务并行求解 $G=3$ 次。这里的三次执行不是为了多数投票选答案,而是为了制造一组可以互相对照的行为样本。

诊断分成两个维度:

  • Self-validation:逐条查看轨迹是否违背任务要求,是否存在错误工具调用、虚假假设、漏读环境证据和过早停止;
  • Self-consistency:横向比较三条轨迹的计划、工具顺序、结论与工作区改动,找出真正影响结果的分歧。

论文把两类信号合并为每个任务的改进指令:

$$I_t=\mathrm{rank}_{\mathrm{val}}(t,\{\tau_{t,g}\}) \cup \mathrm{rank}_{\mathrm{con}}(t,\{\tau_{t,g}\})$$

其中 rank_val 不是外部 grader,而是 Agent 对单条轨迹的自检;rank_con 也不是看三份答案文字像不像,而是分析行为为什么走向不同结果。官方 prompt 强制输出 JSON,包括每条轨迹的质量分析、失败模式、分歧根因、一条高层 Harness 改进方向,以及 $0$ 到 $1$ 的 severity。

论文用了两个很克制的词:“self-validation”“self-consistency”。前者问「这条路内部站得住吗」,后者问「为什么同一个我走出了三条不同的路」。二者结合,比直接把原始日志扔给一个优化 Agent 更容易抽出稳定的系统问题。

一个代码任务的诊断可能是:三条轨迹中有两条修改了错误模块,一条沿调用链定位到真实入口;共同缺陷是修改前没有从失败测试追踪真实执行路径。高层改进方向应该是「编辑前建立 requirement-to-code-path ledger」,而不是把这道题的文件名硬编码进 Skill。

这里非常像线上故障复盘。一次事故通常混合着偶然性;同一条件下多次执行的共同失败,才更可能来自 Harness 的系统缺陷。反过来,如果三次都顺利完成,这条任务 severity 应该很低,不应该仅因为日志很长就推动一次修改。

第三步:生成三套新 Harness,但自我偏好只负责门控,不负责证明真理

RHO 汇总 Coreset 的结构化诊断,让 Agent 独立生成 $N=3$ 套候选 Harness。优化器拥有完整目录写权限,所以候选可以修改 instructions、增加 Skills,也可以新建可执行工具。

然后,每套候选 Harness 都重新完成十个 Coreset 任务。对每个任务,Agent 将候选轨迹与固定的旧 Harness 轨迹做成对比较,给出 $[-10,10]$ 的相对偏好分。候选 $h_j$ 的平均分为:

$$S_j=\frac{1}{|\mathcal D_{\mathrm{core}}|} \sum_{t\in\mathcal D_{\mathrm{core}}} \mathrm{rank}(t,\tau_t^{(j)},\tau_t^{(0)})$$

最终取 $S_j$ 最大的候选,但只有满足下面的门槛才更新:

$$h_{\mathrm{next}}= \begin{cases} h_{j^\star}, & S_{j^\star}>0\\ h_0, & S_{j^\star}\le 0 \end{cases}$$

也就是论文所说的更新必须 “strictly greater than zero”。候选修改失败、超时、目录与原 Harness 完全相同,都会在评估前被丢弃;所有候选都不够好时,本轮结果就是 no-op,而不是硬选一个版本上线。

# src/rho/loop.py:402-429
for candidate_result, eval_trajs, scores in zip(
    candidate_pool, grouped_eval_trajs, grouped_scores
):
    candidate_result.eval_trajs = eval_trajs
    candidate_result.scores = scores
    candidate_result.mean_score = (
        statistics.mean(score.value for score in scores) if scores else 0.0
    )

winner = max(candidate_pool, key=lambda result: result.mean_score)
accepted = winner.mean_score > 0

这个门控值得肯定,但不要把它理解成「证明新 Harness 更好」。论文自己的实验已经说明,self-preference 更像一个保守筛选器,不是完美排序器:SWE-Bench Pro 三个候选的 held-out 平均分是 0.79,最终被自我偏好选中的版本是 0.78,另一个没被选中的候选反而达到 0.85。它成功避开了最差版本,却没有找到真实测试上的最好版本。

因此,RHO 的 Pairwise Ranking 解决的是:「在没有标签时,如何给上线决策增加一道相对门槛?」它没有解决:「如何在没有真值时证明更新一定正确?」


同一个模型既答题又诊断,这不是论文的漏洞,但确实是风险中心

我之前一直强调,Agent 自进化系统最好让生成模型和评估模型分离,避免自偏好形成错误正反馈。RHO 刻意挑战了这条工程经验:实验中 difficulty judge、solver、diagnoser、optimizer 和 pairwise ranker 都由同一个 GPT-5.5 backbone 承担。

论文不是没有意识到这个问题。它用角色与工作区隔离降低信息串扰:

角色能看到什么不能看到什么
Solve当前任务、只读 Harness其他 rollout、诊断、候选分数
Diagnose当前任务、三条轨迹、原 Harnessground truth、held-out grader
OptimizeHarness、按 severity 排序的诊断测试集标签、候选真实分数
Rank同一任务的新旧轨迹、两套 Harnessground truth、其他候选排名

成对比较还固定展示候选与基线的位置,并在解析后反转分数,用来缓解 pairwise judge 的位置偏差;解析失败或执行失败一律记为 0,使失败更接近拒绝更新,而不是意外通过。所有 prompt、轨迹、候选 Harness、diff、分数、接受标记和耗时都会持久化,便于之后审计与重新打分。

这些设计让「同一个模型」不等于「同一个上下文里自说自话」。但它仍然共享同一套偏见:如果 backbone 系统性偏爱更长的回答、漂亮的日志或某种工具使用风格,角色隔离无法消除这种共同偏差。尤其当优化器学会迎合 ranker,而 ranker又由同一个模型实现时,多轮迭代可能出现 self-confirmation loop。

所以我对 RHO 的判断不是「生成与评估可以永远用同一个模型」,而是:在完全没有标签的冷启动环境中,同 backbone 的结构化自我比较可以成为有用的弱信号;一旦进入高风险生产环境,仍应叠加确定性验证、独立评估器、人工审批和真实线上指标。


59% 到 78%:提升是真的,但不能只看这一行数字

论文用同一个 Codex-style CLI Agent、GPT-5.5 high reasoning effort,在三个领域做一轮优化。SWE-Bench Pro 与 GAIA-2 各用 100 条训练池任务和 100 条 held-out 任务;Terminal-Bench 2 的 89 项任务按哈希顺序分成 30 条训练池与 59 条 held-out。三个数据集都由 DPP 选 10 条 Coreset,Group Rollout 和 Harness Proposal 都取 3;优化阶段不读取 ground-truth grader,最后才在 held-out split 上测通过率。

这个 held-out 设计是有效隔离,但实验环境仍有需要披露的口径:Terminal-Bench 2 对「不得读取测试目录、官方解法和 verifier 日志」的限制只靠 Prompt 约定,并非 sandbox 强制;GAIA-2 则把上游每轮一次 send_message_to_user 的上限提高到四次。作者说明没有观察到 reward gaming,且三项可选的 judge-relaxation 开关在主实验中都关闭;这些细节意味着结果可认真对待,但复现或横向比较时不能只抄最终分数。

与无标签经验方法对比

方法Harness 表面SWE-Bench ProTerminal-Bench 2GAIA-2
Vanilla Codex0.590.710.29
Dynamic CheatsheetSkills0.620.730.30
ReasoningBankMemory0.610.730.28
Sleep-time ComputeMemory0.640.730.32
RHOSkills + Tools0.780.760.37

最强证据不是只在 SWE-Bench Pro 上涨了 19 个百分点,而是三个形态不同的任务都提高,并且三种主要的无标签 Memory/Skill 基线没有出现同等幅度。论文认为原因之一是 RHO 的修改面更宽:它可以把诊断落到具体流程和工具,不只是在上下文前面追加经验文本。

但三个数据集提升并不均匀:SWE-Bench Pro 的绝对增益是 +0.19,Terminal-Bench 2 只有 +0.05,GAIA-2 是 +0.08。这说明 RHO 不是一个固定倍率的通用增强器;它的收益取决于失败有多大比例能被 Harness 修复,以及历史任务和未来任务是否共享环境规律。

与依赖验证集的 Meta-Harness 对比

方法是否需要 validation labels优化阶段 Agent callsSWE-Bench Pro
RHO1030.78
Meta-Harness,1 轮410.62
Meta-Harness,10 轮3200.80

这张表不能简单写成「无标签 RHO 打败有标签方法」。单轮 Meta-Harness 的调用数只有 RHO 的 40%,并不是严格 matched compute;十轮 Meta-Harness 最终达到 0.80,但付出了约 3.1 倍的优化调用,还需要 validation labels。更准确的结论是:在这套实验里,RHO 用一次较重的离线回溯,在没有标签的约束下接近了多轮验证集搜索的性能。

计算成本不能藏在“单轮”两个字后面

SWE-Bench Pro 一轮 RHO 的 103 次优化阶段 Agent 调用来自:30 次原 Harness rollout、10 次 diagnosis、3 次 candidate optimization、30 次候选重跑和 30 次 pairwise ranking。除此之外,Coreset Selection 还对 100 个候选任务做 100 次辅助 LLM difficulty judgment,并运行一次本地 embedding;103 这个数没有把这部分共同选样成本算进去,也不包括 100 个 held-out 测试任务。

论文报告 SWE-Bench Pro 上 RHO 的串行 Agent 耗时总和约 23.1 小时,在 10 路 Agent 与 10 路 grader 并发的基础设施上,端到端仍约 3.2 小时。它比人工标注便宜多少,论文没有给美元口径;它证明的是不需要标签,不是优化免费。


真正发生改变的不是 Prompt 文案,而是 Agent 的行为分布

只看通过率,很容易把 RHO 理解成自动写了一份更长的 AGENTS.md。论文 Figure 3 与 Figure 4 提供了更有说服力的机制证据:不同 benchmark 最终学到的东西不同,执行行为也真的发生了变化。

RHO 在三个任务环境中生成的 Instructions、Skills 与 Tools
图 3:论文 Figure 3。RHO 不是统一追加一段经验,而是按环境生成不同的 Instructions、Skills 与可执行工具。图片来自论文官方项目。

在 SWE-Bench Pro 中,Harness 学会复用历史里的已验证修复、从失败测试追踪真实代码路径、建立需求账本、运行定向 smoke test,还生成了 check_build_and_lintrun_targeted_tests。这些改变让 Agent 更频繁地验证工作,也更愿意把长任务继续做完。

在 GAIA-2 中,任务运行在动态、异步环境里,Harness 更强调时间、用户回复通道、动作分解和目标确认,并生成列出函数、读取 schema、调用函数的环境 helper。论文报告新的环境工具平均每项任务会运行约 20 次,说明它不只是存在文件夹里,而是真正进入了执行路径。

Terminal-Bench 2 反而提供了一个重要反例:生成的脚本在 held-out 任务里一次也没有被执行,提升主要来自 instructions 里的 procedural playbook。也就是说,RHO 不一定非要「造工具」;当瓶颈是黑盒环境中的检查顺序和收尾流程时,一套可执行的操作规范可能比新脚本更有效。

RHO 前后的成功曲线与动作分布变化
图 4:论文 Figure 4。上排显示按步骤累计解决的任务比例,下两排对比 Vanilla 与 RHO 的动作类型分布。SWE-Bench Pro 中 Verify 动作增加 61%,Terminal-Bench 2 与 GAIA-2 则更偏向实际执行。图片来自论文官方项目。

这也是我认为论文最有价值的部分:Harness 优化的验收不应该只问“目录里新增了什么”,还要问“Agent 的轨迹行为是否真的改变”。 Skill 文件写得再漂亮,如果 held-out 任务从未加载、从未触发、从未改变工具序列,它就只是上下文占位符。


消融实验告诉我们:最值钱的不是反思,而是把反思拆成结构化信号

很多 Agent 系统已经会在失败后执行 reflection:把日志交给模型,让它总结教训,再改一次 Prompt。RHO 为什么不直接这么做?

论文给了一个很干净的对照:让优化器看到相同的原始轨迹、拥有相同的 Harness 修改权限,但跳过独立 diagnosis;SWE-Bench Pro 最终只有 0.60,而完整 RHO 是 0.78。差异不来自「能不能改工具」,而来自中间有没有先做结构化的 self-validation 与 self-consistency。

诊断版本SWE-Bench ProTerminal-Bench 2GAIA-2
完整诊断0.780.760.37
去掉 self-consistency0.560.750.27
去掉 self-validation0.700.730.30
原始轨迹直接优化0.600.750.29

不过这里要小心读表。论文说明这是一项固定路径、$n=1$ 的 controlled ablation,用来测某个诊断 cue 的边际贡献,不能直接当作完整流水线关闭组件后的稳定性能。作者又分别独立重跑了两次,缺失单一 cue 的结果并没有跌到表中那么低;但 $n=2$ 仍然只能算迹象,不能算充分的稳定性证明。

对工程实践最可迁移的结论是:

  1. 不要让一个 LLM 同时完成「读日志、找根因、设计修复、修改文件」四件事;
  2. 先把每条轨迹是否完成、用了什么证据、在哪里早停分别结构化;
  3. 再比较多个 rollout 的分歧;
  4. 最后只把聚合后的高层改进方向交给 Harness 优化器。

这其实不是更多 reflection,而是把一次模糊反思改造成一条有中间产物的编译管线。


哪些领域可以迁移?先看四个条件,不要先看行业名字

RHO 能否迁移,不取决于任务是不是「AI 应用」,而取决于任务过程是否满足四个条件:

flowchart LR
    A{"任务可以安全重放吗?"} -->|No| X["不适合原版 RHO"]
    A -->|Yes| B{"轨迹包含可检查证据吗?"}
    B -->|No| Y["先补观测与日志"]
    B -->|Yes| C{"失败能被 Harness 修复吗?"}
    C -->|No| Z["考虑模型训练或人工流程"]
    C -->|Yes| D{"历史分布能代表未来吗?"}
    D -->|Weak| S["仅做 shadow / 人工审核"]
    D -->|Strong| R["可以试点 RHO-style 优化"]

1. 软件工程与代码 Agent:最适合

代码任务天然有丰富轨迹:文件读取、调用链、编译输出、测试结果、diff 和 Git 状态都可以被复查;仓库也通常能在容器或 worktree 中重置。可进化对象包括仓库导航 Skill、构建检查脚本、测试选择策略、diff hygiene 与提交前 checklist。

但生产落地时,我不会像论文那样完全不用 grader。单元测试、静态分析、类型检查和安全扫描都是便宜、确定性的信号,应该放在 self-preference 之前,而不是为了追求「纯无标签」主动丢掉。

2. 数据分析与 BI Agent:很适合,但要防止把偶然查询写成规则

历史轨迹里通常有 SQL、schema、查询结果、图表与用户追问。多次重跑可以暴露 Agent 是否稳定选择正确数据源、是否在 join 后检查行数膨胀、是否验证时间口径和空值。Harness 可以生成 schema 探查工具、查询前置检查和指标口径 Skill。

风险是业务口径会变化。一个季度前正确的表和过滤条件,可能成为今天的数据泄漏或错误规则。所有进化产物都应带来源、时间、适用域和失效条件。

3. DevOps、SRE 与云资源运维:诊断适合,真实重放要改造

故障轨迹包含日志、指标、命令和环境状态,很适合做失败模式聚类和 procedural playbook 优化。但真实的重启、扩容、删除资源并不允许为了 Group Rollout 重做三次。

迁移方式不是直接照搬,而是把 replay 放进数字孪生、沙箱、历史快照或只读诊断环境。生产动作只能让候选 Harness 做 dry-run、计划生成和证据收集,最终写操作仍走审批与权限门控。

4. 客服与企业知识工作:适合偏好比较,不适合偷偷自动上线

客服没有唯一标准答案,但同一工单的多份候选可以比较:是否遗漏关键约束、是否引用了真实政策、是否升级给正确团队、是否承诺了不存在的能力。RHO 可以进化检索策略、升级条件、表单检查和回复模板。

问题是历史轨迹可能包含过时政策、用户隐私和带攻击性的提示内容。进入诊断前必须做脱敏、权限裁剪与来源过滤;生成的新 Skill 也要经过政策 owner 审核。

5. 研究、情报分析与深度检索:可以迁移“分歧诊断”,很难自证事实

研究 Agent 的多次 rollout 非常适合暴露搜索路径、来源选择和结论不一致。Harness 可以学会优先一手资料、建立 claim-evidence ledger、区分事实与推断、检查发布日期。

但三条轨迹一致,不代表事实正确——它们可能共同引用了同一个错误来源。这里必须增加外部证据质量检查与来源多样性,不能把 self-consistency 当 truth。

6. 医疗、金融、法律与现实世界执行:只能迁移框架,不能直接迁移自治权

这些领域的任务可能不可逆、责任重大,而且错误往往不会立刻显现。可以使用 RHO 的 coreset、结构化诊断、候选生成和审计记录来帮助专家改进 SOP,但不应该让同一个模型用自我偏好自动改写临床、交易或合规规则并部署。

领域安全重放过程证据Harness 可修复比例推荐用法
软件工程完整试点,并叠加真实测试
数据分析中高沙箱重放 + 数据口径审批
客服中高中高Shadow ranking + 人工抽样
DevOps/SRE低到中快照/仿真重放,不自动执行生产动作
研究检索强化来源验证,避免一致性等于真实性
医疗/金融/法律只辅助改 SOP,专家最终批准

如果要在真实项目里做,我会从 RHO-lite 开始

论文仓库已经提供完整研究实现,以及面向 Claude Code 和 Codex CLI 的 retrospection 脚本。但真实团队不应该第一天就允许 Agent 自动重写自己的持久化 Harness。更稳妥的落地顺序是:

  1. 先把轨迹记录完整。 至少保留任务、环境观察、工具输入输出、文件 diff、最终回复、时间和版本;敏感字段在进入优化链路前脱敏。
  2. 定义 Harness 的可编辑边界。 Instructions、Skills 和 helper scripts 分目录;权限、安全策略、密钥配置与生产写入能力列入 denylist。
  3. 建立按失败模式分层的候选池。 不直接拿最近十条失败;先生成 task fingerprint,再平衡严重度、频率和多样性。
  4. 只在可重置沙箱里 Group Rollout。 对不可逆任务使用历史快照、仿真或只读 probe,不为了收集分歧重复真实副作用。
  5. 分离 diagnosis 与 optimization。 诊断先输出结构化 JSON,修复器只能看到经过过滤的高层问题,不直接把所有原始用户内容写进长期 Skill。
  6. 候选永远在 staging。 每版 Harness 都有内容寻址 ID、diff、来源任务和生成理由;禁止直接覆盖 live 目录。
  7. 门控采用证据分层。 确定性测试 > 独立 grader > self-preference > 人工抽检;高风险修改必须有人批准。
  8. 先 shadow,再 canary。 新 Harness 先旁路运行,不影响真实用户;通过回归后只给小比例任务,观察真实失败率、成本和行为漂移。
  9. 所有更新可回滚。 保存原 Harness、候选分数、被拒绝版本和线上指标;一旦异常,回滚的是一个目录版本,而不是重新猜哪句话改坏了。
flowchart LR
    T["Trajectories"] --> Q["Scrub + Quarantine"]
    Q --> C["Coreset"]
    C --> D["Diagnose"]
    D --> P["Candidate Harnesses"]
    P --> V1["Deterministic checks"]
    V1 --> V2["Independent grader"]
    V2 --> V3["Self-preference"]
    V3 --> H["Human approval"]
    H --> SH["Shadow"]
    SH --> CA["Canary"]
    CA --> LIVE["Live + rollback"]

这比论文流程多出来的隔离、独立验证、人工批准和灰度,并不是对 RHO 的否定。论文研究的问题是「没有标签时还能否产生改善信号」;生产系统要回答的是「在错误信号一定会出现的前提下,怎样限制它能造成的伤害」。两者目标不同。


这篇论文没有解决的六件事

第一,多轮进化是否越走越好,仍然未知

论文只验证一轮 retrospective optimization,并明确不声称多轮收益会复合,甚至不声称它会单调增加。单轮里无害的偏好误差,多轮后可能积累成风格塌缩、工具膨胀和规则冲突。

第二,Self-preference 能避开最差候选,但不一定找到最好候选

0.85 的 SWE-Bench Pro 候选输给了最终选中的 0.78 候选,说明 pairwise judge 与真实效用仍有明显排序误差。正分门槛是一个风险控制机制,不是真值证明。

第三,所有实验只用了一个 backbone 和一种 Agent 框架

GPT-5.5 high reasoning effort 同时承担所有角色。换成能力更弱、工具理解更差或偏好校准不同的模型后,诊断质量、候选多样性和门控可靠性可能同时下降。跨模型与跨框架迁移仍待验证。

第四,结果可能部分来自 benchmark-specific adaptation

学到非标准工具链位置、grader 习惯和环境 helper,本来就是 Harness 的价值;但这也说明优化结果是环境特定的,不等于形成了通用智能。论文没有完成正式的 cross-benchmark transfer study。

第五,历史轨迹可能把攻击永久写进 Harness

如果 Agent 在浏览网页或读取工单时遭到 prompt injection,恶意内容会进入 trajectory。RHO 又把 trajectory 当成唯一优化输入,就可能把一次临时攻击蒸馏成长期 Skill 或脚本。原论文将这一点列为安全限制;实际系统至少需要数据 provenance、内容隔离、可疑轨迹 quarantine 和更新 diff 审批。

第六,成本仍然很高,而且收益口径不是经济口径

一次 SWE-Bench Pro 优化包含 100 次选样判断、103 次优化阶段 Agent 调用和独立 held-out 测试。论文做了较完整的调用与 wall-clock 披露,但没有回答每提升一个百分点要花多少钱,也没有和人工维护 Harness 的成本做对照。


我的判断:RHO 最重要的贡献,不是“Agent 可以自己批改自己”

如果只看标题,很容易把这篇论文讲成一个刺激的故事:没有答案,Agent 也能在黑暗中进化。但真正值得带走的,并不是相信模型已经拥有可靠的自我纠错能力。

RHO 更扎实的贡献,是给无标签 Agent 运行日志找到了一种中间用途。过去,我们要么把日志当监控数据存起来,要么把成功/失败经验压缩成 Memory;RHO 把日志变成可以驱动 Harness 工程的材料,并为这条链路补上了四个关键结构:

  • 用困难度与多样性共同决定复盘什么;
  • 用同任务多次执行把偶然错误变成可比较的分歧;
  • 把自检与一致性诊断独立出来,不让优化器直接对原始日志自由发挥;
  • 用候选对照与正分门槛允许系统选择“不更新”。

它也补上了我之前「Agent 自进化飞轮」里最难落地的一段:从轨迹信号到具体 Harness 修改,中间如何组织诊断、生成候选和门控。论文说明,即使没有完整标签,这条链路也不是只能靠拍脑袋;但它没有推翻另一条原则——评估器自身仍然需要评估,自动更新仍然需要权限边界。

所以,我会把 RHO 定位成一套弱监督条件下的 Harness CI/CD:历史轨迹像 bug report,Coreset 像回归测试选择,Group Rollout 像复现与差分诊断,候选 Harness 像多个修复分支,Pairwise Ranking 像没有标准答案时的临时 code review,acceptance gate 则是最低限度的合并规则。

它让 Agent 在黑暗里不至于原地不动,但真正决定系统能走多远的,仍然是沿途有没有外部路标、护栏和刹车。

Agent 自进化不是让模型相信自己,而是把它的自我怀疑组织成一条可比较、可拒绝、可回滚的工程流程。


参考资料

  1. Evolving Agents in the Dark: Retrospective Harness Optimization via Self-Preference,arXiv v3,2026。本文的主要来源;方法、实验、消融、限制与伦理讨论均以 v3 为准。
  2. 论文 HTML 全文。用于核对 Algorithm 1、Tables 1–4、Figures 2–5 与附录实现细节。
  3. RHO 官方项目页。包含论文、代码、流程图与试用入口。
  4. wbopan/retro-harness。官方研究实现,MIT License。
  5. DPP Coreset 实现。对应论文 §4.1。
  6. Group Rollout、候选评估与接受门控。对应论文 Algorithm 1 与 §4.2–4.3。
  7. 结构化诊断实现。对应 self-validation 与 self-consistency。
  8. Pairwise Ranking 实现。对应候选 Harness 的 self-preference 门控。
  • Copyrights © 2024-2026 Hwk