CIR:harness 恢复别只看平均成功率
Agent 跑长任务时,harness 负责把环境观测塞进上下文,出错了再来一次 look——这叫 refresh。评测时大家习惯报一个平均成功率:刷新了涨 3 个点,就算「恢复有用」。问题是:同一个操作,既能把失败轨迹救回来(rescue),也能把本来会成功的轨迹搞砸(harm)。平均分把这两种方向压成一个数,你看不到张力,更谈不上「什么时候该动手」。[1]
北京师范大学与贝壳的肖书尧等人在 arXiv:2610.00372(When Harnesses Lose the Signal: Causal Evaluation of Recovery in LLM Agents,预印本标注 2026-09-30)把恢复写成因果决策:从同一执行状态分出「刷新 / 不刷新」两条续跑,分开 rescue 与 harm,再看价值随时间怎么变。他们据此训练轻量策略 Causal Intervention Router(CIR):只用决策前可见信息,判断「现在值不值得干预」。在 ALFWorld 长程家务任务、Qwen3-14B、ReAct 风格 harness 上,从不刷新的 70.33% 提到 73.33%(+3.00 个百分点,95% CI [0.67, 5.67]);评测里所有观测正确(clean)的轨迹一次都没动;增益主要落在两步过期观测上。机制对照还表明:刷新带来的好处不能只归因于环境新返回的那段文字。[1]
站内已经从几条线碰过 harness:MoMHa 谈准确率 / 安全 / token 三目标搜索;Bad Genius 谈反事实信号怎么进化 harness;控 harness 控成本 谈路由与账单;轻量对照 Grow the Harness, Not the Context 谈「先扩外围再堆上下文」。CIR 补的是另一块:恢复操作本身也要当决策评,而不是事后看平均分——同状态配对、拆 rescue/harm、再选择性施加。[2]
平均成功率藏不住的张力
LLM agent 并不独自行动。外部 harness 在模型与环境之间传观测、维护上下文、协调长序列动作。观测过期或缺失时,错误会顺着后续步扩散;harness 的常见反应是再查一次环境,即 refresh。既有工作用反思、外部反馈或搜索改进恢复(Reflexion、Self-Refine、CRITIC、LATS 一类),评测却多半停在整体成功率,或只标失败落在哪一步。这些摘要说不出恢复改了哪些轨迹:同样的平均增益,背后可能是少量可靠 rescue,也可能是大量 rescue 被大量 harm 对冲掉。自我纠正在反馈不可靠时,还可能把本来正确的回答改坏——这正是「看起来像在恢复、实际在扰动」的另一面。[1]
这带来两件结构性困难。第一,普通单次跑只看见一种结局——恢复了或没恢复;没有对照结局,就说不清结果是不是恢复造成的(Holland 经典「因果推断的根本问题」在轨迹级重现)。第二,时机要紧:出错之后,后续动作与反馈会改局面,眼下有用的干预,晚点可能无效甚至有害。有用的评测必须从同一状态比较两种选择,并在不同时间重复比较。作者把中心问题收成一句:对这条轨迹,refresh 到底有没有用?以及预期收益何时盖过风险。正平均效应并不等于可以无条件广用;同样的平均,既可以来自少数稳妥 rescue,也可以来自双向对冲;不大的平均,也可能藏着某一类可识别状态上的大收益。[1]
相关工作里,过程级评测(AgentBoard、MAST、Who&When、CatchBench)擅长定位失败位置与责任;反事实修复线(Causal Agent Replay、CausalFlow、HarnessFix、DoVer)侧重归因或生成修补。CIR 论文划清边界:他们固定恢复操作本身,问的是「从当前状态施加它,结局会变好还是变坏、何时值得施加」——不是再发明一种新反思 prompt,也不是定位该怪哪一步。配对跑让 rescue 与 harm 可直接对照,同一套证据既能评测也能训部署期决策规则。[1]
配对反事实:同状态,有刷新 vs 无刷新
评测单位是任务实例 (i)。在预设点,harness 不改环境,只改给 agent 看的观测。观测条件 (e) 取三类:
- clean:保留当前信息;
- stale:换成更早状态的观测(文中主扰动是两步过期;另有一步过期);
- missing:内容换成固定的「观测不可用」消息。
恢复延迟 (d) 是「改过观测」到「施加恢复」之间的环境动作数;文中测 (d\in{0,1,2,4})。恢复操作 (m) 主要是 refresh:额外执行一次 look,把返回的当前观测追加进 transcript。另有只重规划、不查环境的变体,以及「查了环境但藏住返回内容」的 content-ablated 对照。三元组 ((e,d,m)) 同时规定:agent 看到什么、何时恢复、用哪种操作。[1]
对每个任务与观测条件,执行先跑到延迟 (d),再从完全相同的状态分叉:一支不恢复继续跑,一支施加操作 (m)。两支共享环境状态、分叉前完整历史、同一模型与解码设置,因此结局差可归因于恢复决策。用潜在结局记号:无恢复结局 (Y_i^0(e)),延迟 (d) 施加 (m) 的结局 (Y_i^m(e,d)),实例级效应 (\tau_i^m(e,d)=Y_i^m(e,d)-Y_i^0(e))。确定性重放下,无恢复续跑可在不同延迟比较间共享,所以 (Y_i^0) 不必再带 (d)。[1]
方向拆开更有用:
- rescue:无恢复失败、有恢复成功;
- harm:无恢复成功、有恢复失败。
两边都成功叫「保住成功」,两边都失败叫「失败不变」——加上 rescue / harm,配对比较一共四种结局。实例级效应可写成 (\tau=\mathcal{R}-\mathcal{H})。平均恢复效应 = rescue 率 − harm 率。同一个净效应,既可以来自极少次改写,也可以来自双向频繁改写——只看平均分分不清。配对结局同时提供监督:哪些状态更可能 rescue 而不是 harm。这也改写了「什么叫成功的恢复方法」:不能只看干预后成功率有多高(很多轨迹不干预也会成功),而要问:结局有没有变、往哪边变、在轨迹的哪个时间点变。[1]
实验设定:ALFWorld × Qwen3-14B
任务用 ALFWorld(文本动作完成长程家务)。Agent 是 Qwen3-14B,固定 ReAct 风格 harness,greedy 解码;每跑最多 49 轮模型 turn、64 次环境动作。轨迹在八张 NVIDIA H200 上生成。先无注入错误、无恢复跑一遍,称为 factual trajectory;再在该轨迹环境动作的 25% 处改观测。主扰动是两步 stale(用两步之前的观测替换当前);另做一步 stale 与 missing。Refresh = 额外 look + 把返回观测追加进 transcript。[1]
任务若能到达选定干预点、且历史够构造所需 stale 观测,称为 prefix-feasible;分叉前两跑历史须一致。主队列与独立队列检验效应是否可复现;机制队列拆 refresh 成分;评测队列测 CIR。部分分析只保留 factual 成功任务;为核对过滤是否扭曲结论,也报告保留全部 prefix-feasible 的完整队列:主队列 106(其中 factual 成功 93),独立队列 100(factual 成功 89)。机制对照另用 74 任务集(其中 67 通过配对协议检查)。这些覆盖的是可用的 prefix-feasible 子集,不是完整 ALFWorld 分布;valid_seen / valid_unseen 只是 ALFWorld 切分名。[1]
CIR 在主队列 93 个 factual-成功任务上拟合,在独立的 ALFWorld valid_seen 集合上评测(文中写 76 个 valid_seen,其中 75 个 prefix-feasible)。拟合与评测任务不重叠。每个评测任务测四种观测条件,共 300 个 episode。拟合好的模型与阈值不再在测试集上调参。任一延迟下任务都留在分母里;若任务已结束,结局前向携带,不再施加恢复。主指标是恢复相对无恢复的配对成功差(百分点);置信区间用任务级 cluster bootstrap,保证同一任务的多种条件在重采样里绑在一起。[1]
恢复价值依赖状态与时机
实验要回答三问:刷新何时帮或害?刷新的哪一部分在起作用?CIR 能否把证据变成对新任务的选择性恢复?先看主队列 93 个 factual-成功任务、立即刷新((d=0)):
| 观测条件 | 相对无恢复的成功变化 | 备注 |
|---|---|---|
| clean | −6.45 pp(95% CI [−11.83, −2.15]) | 无恢复本应复现成功,失败即 harm |
| 两步 stale | +7.53 pp(95% CI [−3.23, 18.28]) | 区间跨零,点估计为正 |
| stale − clean 差 | 13.98 pp(95% CI [2.15, 24.73]) | 同操作、不同信息状态 |
后续延迟上 stale−clean 差仍为正(延迟 1/2/4 分别为 18.28 / 15.05 / 13.98 pp)。在这个 factual-成功队列里,clean 下无恢复结局按构造为成功,刷新只能保住或伤害,造不出 rescue——所以作者又把 factual 失败加回来做完整队列分析。独立 89 任务 factual-成功队列在每个测过的延迟上保持同一排序:stale 下效应比 clean 更正,差在 8.99–14.61 pp;延迟 2 时 stale +10.11、clean −4.49。[1]
纳入全部 prefix-feasible(主队列含 13 个 factual 失败)后,完整主队列 n=106:clean −3.77 pp(CI [−9.43, 0.94]),stale +6.60 pp(CI [−2.83, 16.04]),差 10.38 pp。配对计数把平均分拆开:clean 上 2 rescue / 6 harm,stale 上 17 rescue / 10 harm。factual-成功队列延迟 1、stale 下,正的平均分来自 15 rescue 对 4 harm;clean 下刷新把 6 次成功改成失败。独立完整队列 n=100 上,对应效应是 0.00 与 +4.00 pp——点估计仍偏向 stale,但区间更宽。结论很直白:恢复价值不是 refresh 操作的固定属性;它取决于 agent 手里的信息、出错后到达的状态、以及何时动手。无条件一律刷新,会把有用干预与多余干预压进同一个平均成功率。[1]
刷新为什么有用:不全是「新观测内容」
机制对照把 refresh 拆成三件:
- 完整 refresh:查环境,并把返回内容给 agent;
- content-ablated:同样查环境,但藏住返回内容;
- replan-only:不查环境,只让 agent 用已有上下文重规划。
在两步 stale、延迟 4 下,相对无恢复的变化分别是 +13.43 / +10.45 / +1.49 pp(完整 refresh 的 CI [4.48, 22.39];content-ablated [1.49, 20.90];replan-only [−8.96, 11.98])。完整 refresh 救回 10 个任务;content-ablated 与之共享其中 8 个——对这些共享 rescue,新返回的观测内容并不是必要条件。clean、延迟 0 下三种操作分别是 −8.96 / −5.97 / −14.93 pp,方向一致偏害。作者强调:人们常把 refresh 等价于「塞更好的观测文本」;对照说明刷新还有「再查一遍环境 / 打断当前执行流」等成分。只评完整操作,会把「内容」和「干预姿态」绑死,漏掉这层拆分——设计恢复策略时,别默认「内容对了就够」。[1]
CIR:决策前估计值不值得刷新
配对评测能事后告诉你「恢复帮没帮」;线上 harness 必须在两种结局都未知时做决定——这是从「评测工具」走到「选择性恢复」的关键一步,也是论文标题里 Causal Intervention Router 的落点。CIR 的目标写得很清楚:在观测不正确的条件下,相对从不恢复最大化期望增益;同时约束 clean 轨迹上「无恢复成功、策略下失败」的比例不超过 (\epsilon)(文中 (\epsilon=0.02))。只追增益会鼓励频繁刷新打断正确执行;约束项就是在卡这个风险。运行时两种潜在结局都未知,CIR 只能用决策前信息估计 refresh 的价值。[1]
CIR 分清两件事:像不像出错,与刷新会不会改善结局。异常检测只回答前者。有些错误轨迹刷新救不回来;有些看起来正常的轨迹刷新反而会害。CIR 用三个 (\ell_2)-正则逻辑回归((C=0.1))分别估计:观测错误概率 (p_{\mathrm{err}})、无后续恢复的成功概率 (p_0)、立即刷新后成功概率 (p_1)。输入只用候选干预之前可见的信息:动作与推理重复、空操作、观测新颖性、动作–观测一致性、任务进度、上下文预算统计等。两个结局模型按 T-learner 风格分开估,避免「异常概率高」被直接当成「刷新有益」。[1]
据此构造 rescue 分 (s_R=(1-p_0)p_1)、harm 分 (s_H=p_0(1-p_1)),效用 (u_\lambda=s_R-\lambda s_H)((\lambda=2))。rescue 分高 ≈ 继续跑多半失败且刷新多半成功;harm 分高 ≈ 继续跑多半成功且刷新多半失败。作者写明:边际成功概率推不出同一任务被 rescue/harm 的概率(Tian & Pearl 意义上的概率因果),因此这些分不当作 rescue/harm 概率解释,只作决策排序信号。(\lambda) 抬高 harm 权重,使高 harm 分状态更难触发刷新;(\epsilon) 则限制全队列上「把 clean 成功改成失败」的比例上限。[1]
恢复价值会随后续动作与反馈变化,所以 CIR 不在单一固定延迟上赌一把,而是按时间顺序检查候选延迟 (d\in{1,2,4})((d_{\min}=1)),在第一个同时满足「错误概率 ≥ (\alpha)、失败倾向 ≥ (\beta)、效用 ≥ (\gamma)」的时刻刷新,且每条轨迹最多刷新一次;都不满足则整条任务不恢复。阈值在开发数据上选:(\alpha=0.876),(\beta=0.052),(\gamma=0)。拟合时把 93 个训练任务五折出折(OOF)预测,用 OOF 选阈值再在全训练集上重拟——参数与阈值在测试评测前全部固定,拟合与选阈分离。[1]
对照策略包括:从不刷新;顺序异常基线(同一错误检测器,但不预测刷新是否有用);以及训练期干预率与 CIR 对齐的 rate-matched 异常基线。基线阈值同样在 OOF、同一目标与 clean-harm 约束下选,不在测试集上调整。设计意图很清楚:把「选择性恢复」和「只是干预得更勤」拆开。[1]
测试:70.33% → 73.33%,clean 零触碰
在 75 个 held-out prefix-feasible 任务、300 episode 上:
| 策略 / 条件 | 成功率 | 相对从不刷新 | rescue / harm |
|---|---|---|---|
| 从不刷新(全体) | 70.33% | — | — |
| CIR(全体) | 73.33% | +3.00 pp,CI [0.67, 5.67] | 11 / 2 |
| clean | 81.33% → 81.33% | 0.00 | 0 / 0 |
| 一步 stale | 68.00% → 69.33% | +1.33 | 1 / 0 |
| 两步 stale | 60.00% → 69.33% | +9.33 | 9 / 2 |
| missing | 72.00% → 73.33% | +1.33 | 1 / 0 |
CIR 在 16.3% 的 episode 上干预;两步 stale 的 75 个 episode 里干预了 31 次,missing 里只干预 1 次——干预集中在观测收益最大的区域。顺序异常基线干预率 12.7%、增益 +1.67 pp(6 rescue / 1 harm);rate-matched 干预率 15.7%、增益 +2.00 pp(6 rescue / 0 harm)。CIR 点估计最高;相对两个异常基线的边际分别是 1.33 与 1.00 pp(区间都跨零,作者如实报告)。相对从不刷新的 3.00 pp 增益有任务级 sign-flip 检验 (p=0.034)。rate-matched 对照的意义在于:干预频率相近时,CIR 仍多出 5 次 rescue(11 vs 6)——策略看的是干预结局预测,不只是「当前观测怪不怪」。75 条 clean episode 上 CIR 一次都没触发,完整保留从不刷新的成功率。[1]
讨论段收得很干脆:恢复应评成决策,而不仅是操作。配对续跑揭示哪些轨迹被救、哪些被害,以及价值如何随状态与时机变——信息量大于「恢复后成功率」。异常检测不够:观测异常并不蕴含刷新有助。CIR 在行动前同时预测「刷新」与「继续」下的结局,harness 可以先估价值,只在期望为正时干预。换句话说,论文把「会不会恢复」从启发式开关,收成了一个带 clean 风险约束的在线决策问题;测试集上的 +3.00 pp 与 clean 0/0,是这套口径跑通后的结果,而不是凭空加的一个启发规则。[1]
落到 harness 工程时,可以怎么用这套口径
论文本身不做产品集成,但评测协议与 CIR 的形状,对写 agent 外围的人很具体。
先造配对数据,再谈策略。 如果你已经有可重放的轨迹(同一 seed / greedy / 固定工具返回),可以在选定前缀上注入 clean / stale / missing,再分叉「额外 look」与「什么都不做」。日志里至少落四件事:分叉前状态哈希、观测条件标签、是否干预、最终成败。有了这些,rescue / harm 计数是直接算出来的,不必事后猜「这次成功是不是因为刷新」。CIR 的监督也来自同一套配对结局——评测与训练不是两套叙事。[1]
特征只用决策前可见量。 文中列出的重复动作、空操作、观测新颖性、动作–观测一致性、任务进度、上下文预算,都是 harness 侧本来就能打的点。关键约束是:决策时还看不到「刷新后的结局」,所以不能把事后标签泄漏进特征。三个小逻辑回归(错误概率、无恢复成功、刷新成功)比再挂一个大评判模型便宜,也更容易做 OOF 选阈与 clean-harm 约束审计。[1]
默认别无条件 refresh。 主队列立刻刷新在 clean 上是净伤害(−6.45 pp),完整队列上仍是 −3.77 pp;CIR 测试集上 clean 零干预、两步 stale 才吃到 +9.33 pp。工程默认若是「一怀疑过期就 look」,你可能在用平均成功率掩盖 clean 上的 harm。更稳的默认是:有配对证据显示某类状态净益,再打开选择性路由;否则先把「从不刷新」当强基线,把干预率、rescue、harm、clean 触碰率一起看板化。[1]
把「内容」和「干预姿态」分开消融。 content-ablated 对照说明:很多 rescue 不依赖新返回文本。若你的恢复栈里同时有「再查工具」「塞一段摘要」「强制重规划」,尽量做类似拆分,否则你会把功劳全记在「更好的观测」上,后续优化方向也会偏。对成本敏感的栈,这还关系到:一次额外工具调用值不值得——若打断本身贡献大头,也许更便宜的打断方式就够,不必每次拉全量观测。[1]
外推要重跑协议。 本文数字绑在 ALFWorld + Qwen3-14B + ReAct + greedy + prefix-feasible 子集上。换浏览器 agent、编码 agent、或带随机采样的解码,阈值 (lpha,eta,\gamma) 与 (\lambda,\epsilon) 没有理由直接可搬。可搬的是口径:配对、拆方向、按条件与延迟切片、用决策前模型做选择性路由,并用 clean-harm 约束卡风险。[1]
读完可以带走什么
- 别再用单一平均成功率给恢复操作打分。 同操作在 clean 上可以净害、在 stale 上净益;平均分会把 2/6 与 17/10 这类配对计数抹平。
- 评测协议本身可复用: 固定分叉前状态 → 有/无恢复配对 → 报 rescue、harm、不变,再按 (e) 与 (d) 切片。这比「恢复后再报一次成功率」信息量大得多,也比只标失败步骤更贴近部署决策。
- 刷新 ≠ 只塞新观测文本。 content-ablated 与完整 refresh 共享多数 rescue,说明打断与再查询本身也在起作用;设计恢复策略时别默认「内容对了就够」。
- 选择性路由能在不重训底层 agent 的前提下抬成功率,并约束 clean 伤害。 CIR 用决策前特征估错误概率与两种结局概率,阈值在 OOF 上锁死再上测试集——这是可部署的轻量形状,不是再训一个大模型。
- 局限要说清楚: 单环境(ALFWorld)、单模型(Qwen3-14B)、greedy、prefix-feasible 子集而非全分布;stale 主结果部分 CI 跨零;相对异常基线的优势区间也跨零,作者报的是点估计领先。外推到别的 harness / 工具调用栈时,应先重跑配对协议,而不是直接抄阈值。[1]
对站内叙事:MoMHa 问「搜索目标别压成一个标量」;Bad Genius 问「反事实信号怎么进化 harness」;成本文问「默认配置在烧什么」;Grow the Harness 问「先扩外围能力还是先堆上下文」。CIR 问的是更靠执行层的一句:恢复要不要做、何时做——请用配对因果证据回答,而不是用平均成功率自我安慰。 若你正在给现有 agent 加「自动重试 / 自动 look / 自动反思」,这篇论文最值得抄的不是阈值数字,而是「同状态两条续跑 + rescue/harm 分列 + clean 伤害上限」这套评测纪律。[2]
参考与脚注
[1] Shuyao Xiao, Shengling Wang, Xuan Chen, Ke Chao, Ming Cui, Feifei Qian, Chaoyang Mei, Fanlin Meng, Ziming Yu, Junxi Yin. When Harnesses Lose the Signal: Causal Evaluation of Recovery in LLM Agents. arXiv:2610.00372, 2026-09-30. 摘要 · HTML. 文中数字均来自该预印本实验节与摘要,未另行估算。
[2] 站内对照:MoMHa、Bad Genius、控 harness 控成本、Grow the Harness。