Browse this library

Chinese source article

3.1.1 · MEA 状态循环

从 Manage-Execute-Audit 循环推导任务状态、动作合约、停止条件和最小实现。

View original Markdown ↗

论文:LongHorizon-Harness: Advancing Long-Horizon Agents for Real-World Tasks 作者:Ziyu Ma, Hailang Huang, Shun Zou, Yong Wang, Shidong Yang, Yiming Hu, Fei Wei, XiangXiang Chu(DreamX Team, Alibaba Group) arXiv:2608.01964(2026-08-03) GitHub:AMAP-ML/LongHorizon-Harness Website:lh-harness.pages.dev

1. 任务状态与 MEA 循环

LongHorizon-Harness 把长任务从一段不断增长的对话, 改写成可验证的任务状态转移. Manager 维护目标与进度, Executor 在 fresh context 中执行一个有界子任务, Auditor 再从环境读取证据.

三个角色的数量并非关键, 未经验证的执行声明不能进入任务事实才是 MEA 循环的约束. 角色分工、状态合约和审计门共同阻止一次错误自评沿后续轮次传播.

执行轨迹为何会发生状态漂移,LLM Agent 承担 long-horizon 任务时, 需要持续推理、反复调用工具, 并在相互依赖的步骤之间修正方案. 许多 Agent Harness 却把任务执行、任务状态和完成度评估放在同一个不断增长的上下文中. 上下文越长, 模型越难区分已验证事实与自己的推测.

错误自评还会沿轨迹传播. Agent 一旦误判「已经完成」, 后续计划就会建立在错误状态上, 形成 state drift. 模型决定单轮能做什么, Harness 决定结果能否被验证、保留并继续推进, 论文的改动集中在后一个问题.

1.1. Manage-Execute-Audit 的状态分工

论文把 long-horizon 执行重新定义为一个任务状态管理问题(task-state management problem):

  • 任务状态显式地放在执行之外维护;
  • 状态只允许用从环境独立验证过的事实来更新;
  • Agent 不再「边执行边自我评估」,而是由外部机制客观判定环境里发生了什么。

核心机制是 Manage-Execute-Audit(MEA) 三角色循环:

角色 职责 关键点
Manager 维护原始目标、已验证进度、下一子任务 基于审计事实重新规划,而非凭上下文里的自我感觉
Executor 执行当前子任务 全新(fresh)上下文执行,避免被长历史污染
Auditor 只读验证环境结果 检查文件、界面、日志、测试,产出 audit report

跨轮决策只读取结构化 task state 与 audit reports。Manager 依据审计过的事实做下一轮规划,这就切断了「错误自我评估」的传播链。Executor 的原始交互轨迹不会直接进入下一轮执行上下文;持久记录仍可保留轨迹供复查,但它不能绕过审计门成为任务事实。 论文还提出轻量 AgentAdapter:在不修改原生 agent loop 的前提下,可插拔互换模型与 harness 后端(Claude Code、Codex 等),且 Manager / Executor / Auditor 可分别配置不同模型或后端,以平衡质量、速度与成本。GUI 交互通过外部 computer-use MCP 提供,harness 本身不捆绑特定实现。

三类基准上的收益与开销,同一 backbone(Qwen 3.7-Plus)+ 同一执行后端(Claude Code)对比:

基准 指标 基线 LongHorizon-Harness 提升
WeaveBench(114 任务) PassRate 51.8% 80.7% +28.9 pt
WeaveBench Overall 0.702 0.835 +0.133
OSWorld 2.0(108 任务) Binary 2.8% 8.3% 3.0×
OSWorld 2.0 Partial 21.5% 35.2% +13.7 pt
Terminal-Bench 2.1 Success rate 69.7% 77.2% +7.5 pt

跨模型迁移:Claude Opus 4.7 在 OSWorld 2.0 34 任务子集上,binary 从 20.0% → 34.3%,partial 从 55.8% → 66.9%。Codex + GPT-5.6 Luna 在 Terminal-Bench 2.1 上达 83.1%。 Token 分解显示 Manager 仅占 WeaveBench / OSWorld / Terminal-Bench 总 token 的 2.8% / 8.1% / 2.0%,Auditor 占 19.4% / 24.8% / 38.1%——独立验证是主要额外成本,但 Terminal-Bench 上总 token 反而减少 24% 且成功率更高,说明框架不施加固定 token 倍数,而取决于底层模型需要多少执行与恢复轮次。 WeaveBench 覆盖 14 类真实任务域(Web 前端、数据分析、运维调试、设计、游戏、文档、空间推理、桌面设置、科研教育、创意生产、工程计算、个人服务、行政合规、商业金融、医疗等),八个子域 PassRate 全面提升,增益不集中在单一类别。

独立审计的成本与边界,独立 Auditor 提高了状态可信度, 也引入额外推理、环境读取和工程依赖. 这些成本随任务类型变化: CLI 任务可以复用确定性测试, GUI 任务往往需要更多观察和更长输出.

实验结果还没有把所有长任务都变成高成功率问题. OSWorld 2.0 的 binary 成功率仍为 8.3%, 因此 MEA 更适合被理解为状态控制机制, 而不是替代底座模型能力的通用解法.

  • 绝对成功率仍低:OSWorld 2.0 binary 8.3% 说明全桌面长任务远未解决;harness 是倍增器而非银弹。
  • 审计开销:每轮一次环境验证,Auditor token 可达总量近四成;复杂 GUI 任务成本显著上升(Qwen 3.7-Plus 在 OSWorld 上 output token 从 28.9K → 104K)。
  • 跨轮记忆压缩:只留 audit report 可能丢失 Executor 轨迹中的细微上下文;Manager 规划能力本身仍有上限。
  • 工程依赖:需要可用的 computer-use MCP、CLI agent 运行时(claude / codex)、以及 per-run 隔离目录与 Dashboard 等人机协同设施。
  • 训练无关:纯推理期 harness 改造,不改模型权重;与 RL 训练 agent 的上限仍由 backbone 决定。

1.2. 状态合约与执行闭环

单轮数据流. LongHorizon-Harness 的单轮数据流可形式化为:

  1. Manager 读取 task state (S_i) 与累积 audit reports (V_{i-1}),构造有界子任务合约 (c_i)(目标、验收标准、边界约束、相关先验证据);也可走 ask 路由请求用户信息或授权。
  2. Fresh-context Executor 在预算内(默认 1800s/轮)执行 (c_i),将环境从 (e_{i-1}) 变为 (e_i),返回 execution report (o_i);原始轨迹随后丢弃。
  3. Read-only Auditor(默认 300s/轮)通过只读工具检查 (e_i),产出 audit report (v_i)。
  4. Manager 将 (v_i) 并入 (S_{i+1}),判定是否满足原任务、是否还有可推进子任务、是否需要用户输入,或是否耗尽 round budget(默认 (N_{\max}=25))。

每轮 run 落盘于 runs/<run-id>/:task state、event stream、audit reports、三角色 trajectories、workspace 产物、final report——使进度可检查、可恢复、可复现。

用户任务 T
    │
    ▼
┌──────────────────────────────────────┐
│  Manager:S_i + V_{i-1} → 子任务 c_i │
└──────────────┬───────────────────────┘
               ▼
┌──────────────────────────────────────┐
│  Executor(fresh context):e_{i-1}→e_i │
└──────────────┬───────────────────────┘
               ▼
┌──────────────────────────────────────┐
│  Auditor(read-only):环境 → v_i     │
└──────────────┬───────────────────────┘
               ▼
        Manager 更新 S_{i+1}
               │
               └── 循环直至完成 / 阻塞 / 预算耗尽

三个角色怎样交换状态合约. MEA 用输入、输出和写权限分隔三个角色。Manager 生成合约,Executor 改变环境,Auditor 再从环境中读取结果。若三者都能随意修改 task state,增加角色只会把同一种自我确认重复三遍。

角色 主要输入 主要输出 不应拥有的权力
Manager 原始目标、当前 task state、历史 audit report、轮次与预算 一个有界 subtask contract,或完成、阻塞、询问用户的路由决定 不能把未经检查的 execution report 直接写成事实
Executor 当前 subtask contract、必要的已验证事实、工作环境和可写工具 环境改动、产物以及 execution report 不能宣布整个任务已经通过,也不能改写历史审计结论
Auditor subtask contract、验收条件、改动后的环境和只读检查工具 带证据的 pass、fail 或 inconclusive,以及发现的偏差 不应修复产物,否则检查者同时变成被检查者

subtask contract 至少应包含本轮目标、允许修改的对象、不可越过的边界、所需先决事实和验收条件。Executor 返回的 execution report 只是一份定位线索,例如「修改了 A 文件并运行了 B 检查」。Auditor 随后直接读取 A 和 B 的真实结果。两份报告即使文字一致,证据等级也不同:前者是执行者声明,后者才是允许 Manager 提交状态的依据。 task state 也不宜写成一大段自由文本。一个最小结构可以分成:

  • goal:原始目标和用户后来确认的变更;
  • constraints:不能修改的范围、权限和资源预算;
  • verified_facts:审计已经确认、带来源的环境事实;
  • completed:已满足的验收条件,而非已经调用过的工具;
  • open_items:尚未满足的条件、依赖和风险;
  • current_contract:当前唯一生效的子任务;
  • status:running、waiting、completed、failed 等可枚举状态;
  • checkpoint:与本轮事实对应的工作区或外部资源版本。

这样的结构使 Manager 能够做滚动计划。它不必在第一轮预言全部二十五轮动作,只需要在每次审计后,根据尚未满足的验收条件选择下一个子任务。设 UiU_i 是第 ii 轮后仍未满足的条件,RiR_i 是当前已核实的依赖,那么下一合约可以写成:

ci+1=Plan⁡(T,Ui,Ri,vi,Bi),c_{i+1}=\operatorname{Plan}(T,U_i,R_i,v_i,B_i),

其中 TT 是原始任务,viv_i 是最新审计,BiB_i 是剩余预算。若审计发现依赖并不成立,Manager 应先修订 RiR_i 和后续顺序;若只是执行失败但目标仍然可达,可以缩小子任务或换一条路径;若缺少用户授权,就进入 waiting,不能把等待伪装成完成。

验证门与状态提交. Auditor 给出的结果至少应区分 pass、fail 和 inconclusive。pass 表示验收条件已有充分证据;fail 表示证据明确反驳完成声明;inconclusive 表示工具不可用、环境异常或现有检查不足以得出结论。第三种结果很重要。把「无法验证」自动当成成功会污染 task state,把它一律当成任务失败又会把基础设施故障归咎于 Executor。 状态提交可以理解为一个验证门:

Si+1=Commit⁡(Si,vi)S_{i+1}=\operatorname{Commit}(S_i,v_i)

只有 viv_i 中带有环境证据的事实能够进入 verified_facts。若结果为 fail,Manager 记录失败模式和仍有效的局部产物,再生成修复合约;若结果为 inconclusive,则保存当前 checkpoint,优先恢复检查能力。这里的「提交」不要求进度只能增加。审计可能发现之前通过的条件被新改动破坏,此时对应完成项必须撤销。跨轮记录保持的是证据链可追溯,不是虚假的单调完成率。

验证门还需要与子任务边界对齐。例如合约要求「修复解析器并保证旧格式测试不回归」,Auditor 只确认新样例通过,就不能给整份合约 pass。反过来,验证器也不能自行扩张范围,把与当前目标无关的告警都判成任务失败。验收条件决定检查什么,环境证据决定条件是否成立,二者共同限制 Auditor 的裁量。

一个逐轮状态例. 考虑任务「修复 CSV 导入中的引号解析,并让相关测试通过」。初始状态 S0S_0 只包含目标、禁止改动公共 API 的约束和空的已验证事实。

  1. 第 1 轮规划:Manager 生成合约 c1c_1,要求定位失败样例和解析路径,只读调查,不修改代码。Executor 找到复现命令并报告某个转义分支可疑。Auditor 独立运行该样例,确认错误可以稳定复现,并记录失败输出。S1S_1 新增的事实是「样例确实失败」和「调用路径经过该解析器」,而不是「根因已经找到」。
  2. 第 2 轮执行:Manager 基于 S1S_1 要求修复解析分支,边界是保留公开接口。Executor 修改实现并称新样例已通过。Auditor 运行目标测试后发现成功,但现有回归测试有一项失败,于是返回 fail,同时保存目标样例已经修复这一局部事实。S2S_2 记录回归症状,完成状态仍未提交。
  3. 第 3 轮修订:Manager 不再重复原修复,而是生成只处理回归的合约。Executor 调整边界条件。Auditor 同时运行目标样例、相关回归测试和接口检查,全部满足后返回 pass。S3S_3 才把该验收条件标为完成。
  4. 最终门:Manager 对照原始目标发现所有条件已覆盖,生成 final report;若全量检查又暴露新问题,就撤销完成判断并进入下一轮。

这个例子里,Executor 每轮都可以使用 fresh context,因为定位信息、失败证据和约束已经进入外置状态。跨轮保存的是「哪个样例在什么命令下失败」「哪个修改通过了哪组检查」这些可重新核实的事实,对话语气不参与下一轮决策。

checkpoint、rollback 与错误传播. 论文的 run 目录保存 task state、报告、轨迹和产物,为恢复提供了材料。但可恢复不等于机械重放。一次可靠 checkpoint 应把 task state 与环境版本绑定:本地任务可以关联 workspace 快照或 commit,GUI 任务需要记录可重新读取的页面状态,外部 API 写入还应保存资源标识。进程中断后,系统先读回环境并核对 checkpoint,再决定继续、回滚或重新规划。 rollback 也有边界。代码和版本化文件通常可以回到旧快照;已经发送的消息、已经触发的远端操作往往只能补偿,不能真正撤销。因此,Manager 在生成合约时需要区分可逆写入和不可逆副作用。Auditor 的只读约束可以防止检查阶段再引入新副作用,却不能自动解决 Executor 已经产生的外部写入。

MEA 切断错误传播主要靠两个门。第一道门是 fresh-context Executor:前一轮的猜测不会作为完整聊天历史自动进入下一轮。第二道门是 Auditor:执行声明必须经过环境验证才会写入 task state。不过,错误仍可能从三个地方穿过:Auditor 使用了过弱的验证器,Manager 错误解释了正确的 audit report,或者环境本身发生了未记录的外部变化。因此系统要保留验证命令、观察结果和环境版本,使后续轮次能够推翻旧结论,而不是只保存一句「已通过」。

开销与对照实验应怎样看. MEA 增加了 Manager 和 Auditor 调用,也增加了环境检查与进程启动成本。论文的 token 分解说明 Manager 占比较小,Auditor 是主要额外开销;但 token 只是其中一项。评估系统成本还应报告墙钟时间、模型调用次数、工具调用次数、环境重置成本、失败后的重试轮数,以及每个成功任务的总消耗。某个框架总 token 更少,可能来自更早停止,也可能来自减少无效恢复;仅看平均输入长度无法区分。

要判断提升来自哪里,对照实验必须尽量固定 backbone、执行后端、工具权限、任务集合和预算。至少需要比较:单会话基线与完整 MEA;保留 Manager 但没有独立 Auditor;有 Auditor 但 Executor 继续继承完整历史;以及不同验证强度下的结果。指标除了最终成功率,还应包含误报完成率、因 inconclusive 退出的比例、平均轮数和成功任务成本。若同时更换模型、Harness 和预算,成绩提升就不能单独归因于任务状态管理。

角色消融也要避免一个误区:三角色优于单角色,并不能推出「角色越多越好」。决定能力的是权限分离、信息边界和验证门。若把 Auditor 合并为一个确定性的测试程序,只要它仍然独立读取环境,也可能保留关键收益;反之,即便增加五个模型角色,只要它们共享同一段未经核实的叙事,错误仍会沿着上下文继续传播。

1.3. 长任务的压力、漂移与停止条件

长任务到底长在哪里. 把轮数拉长,任务并不会自动变成 long-horizon。一个网页按钮连续点一百次,交互很多,状态却几乎没有分叉;修复一个跨包依赖问题可能只调用十几次工具,但中间要保留约束、等待构建、判断回归、撤销错误修改,还要在失败后从可信位置继续。后者对 harness 的要求高得多。更合适的描述由四个量共同组成:依赖深度 DD、状态分支数 BB、跨轮约束数 CC 和不可逆动作数 II。 可以把某个任务的执行压力粗略写成:

H=D (1+log⁡(1+B))+αC+βI.H = D\,(1+\log(1+B)) + \alpha C + \beta I.

这里引入 HH 帮助分析,论文没有使用这个指标。它揭示了一个容易被步数掩盖的事实:二十步全是只读查询,与二十步里夹着迁移数据库、发送邮件和修改远端权限,难度相差很大。前者失败后重跑即可,后者每次重试都要先确认环境里已经发生了什么。LongHorizon-Harness 把 task state 放到执行上下文之外,正好对准了 CC 和 II 带来的压力。

依赖深度也不能用工具调用总数替代。若十个子任务可以并行,它们的关键路径可能只有两层;若第十步必须读取第九步生成的版本号,再把它写进远端配置,关键路径就是十层。Manager 规划时应保存依赖图,而非只有一列待办项。一个节点只有在其前驱经过审计后才可进入 ready,这样才能避免「上游只是声称完成,下游已经开始消费」的连锁错误。

从任务目标到可审计条件. 用户目标往往写成「把项目修好」「整理完材料」或「部署到可用」。这些句子可以启动工作,却不能直接交给 Auditor。验证需要把目标拆成可以从环境读取的谓词。例如「修好导入功能」至少可以落成三类条件:目标样例成功、旧格式没有回归、公开接口保持兼容。记验收谓词为 g1,…,gmg_1,\ldots,g_m,完成状态应由它们的合取决定:

G(e)=⋀j=1mgj(e).G(e)=\bigwedge_{j=1}^{m}g_j(e).

若其中某项只能由人判断,例如视觉稿是否符合品牌气质,状态中要明确保留 human_review,不能让模型生成一句赞美就把它算作通过。若某项依赖外部服务,审计报告还要记录观测时间和资源标识,因为今天存在的远端对象,明天可能已经被别人修改。 验收谓词的粒度同样重要。「所有测试通过」看似严格,实际可能把仓库里长期存在的无关失败一起带进来;「新测试通过」又可能漏掉回归。比较稳妥的做法是给合约同时写目标检查与保护检查。目标检查验证本轮希望改变的行为,保护检查验证明确不能破坏的边界。Auditor 的结果随后按条件返回,而非只给一句总评:

条件 观察 结论
带转义引号的 CSV 可导入 目标样例退出码 0,字段值匹配 pass
旧格式保持兼容 相关回归集 37/38 fail
公共 API 未变化 导出签名与基线一致 pass

这张表会让下一轮计划自然收缩到那一个失败项。没有逐条件证据时,Manager 只能重新阅读整段叙述,随后很容易把「大部分通过」误写成「已经完成」。

轮次时间线与恢复语义. 长任务的时间线至少含四个时刻:tpt_p 生成合约,txt_x 执行动作,tvt_v 完成验证,tct_c 提交状态。环境可能在任意两个时刻之间中断。只保存轮末摘要,无法处理「动作已经发生,状态还没提交」这类最麻烦的窗口。

t_p             t_x                 t_v              t_c
规划 ────────── 执行写入 ────────── 独立验证 ─────── 状态提交
                    ▲                   ▲
              中断点 A             中断点 B

中断点 A 恢复时,系统先检查动作的幂等键和环境版本。若目标文件已经是预期哈希,就进入验证,不能再写一次;若环境仍是旧版本,才重新执行。中断点 B 表示验证可能完成,但报告尚未提交。恢复程序需要读取验证产物的时间戳、输入版本和校验和,确认它仍对应当前环境;对应不上就重新验证。恢复围绕状态转移进行,对话记录只提供复查线索。 墙钟时间也要分开记。设一轮规划、执行、审计和环境启动分别耗时 Tm,Te,Ta,TsT_m,T_e,T_a,T_s,串行总时延为:

Tround=Ts+Tm+Te+Ta.T_{round}=T_s+T_m+T_e+T_a.

Auditor 的 token 占比不能直接推出它占据相同的墙钟比例。文件检查可能 token 很少却等待构建十分钟,GUI 截图判断可能 token 较多却数秒返回。真正决定吞吐的是关键路径上的墙钟时间;真正决定费用的是各角色模型调用、沙箱占用和外部工具成本。部署时应同时画出两条曲线:成功率随预算的变化,以及每个成功任务的平均成本。只报其中一条,容易把昂贵重试制造的增益误认成架构效率。

Auditor 会怎样失效. 只读并不等于可靠。Auditor 可能读错位置、拿到缓存结果、用过期的测试命令,或把「进程正常退出」错当成「业务结果正确」。一个常见陷阱是验证器与 Executor 共享同一份错误假设:Executor 修改了错误的配置副本,Auditor 又恰好读取那份副本,两者意见一致,真实服务仍未改变。 缓解方法是把证据和目标对象绑定。文件类任务记录规范化绝对路径与内容哈希;服务类任务记录 endpoint、资源 ID 与响应中的版本;GUI 任务除了截图,还可读取可访问性树或后端状态。对于缓存敏感的检查,报告中保存运行命令、开始时间、结束时间和输入 checkpoint。证据越接近用户真正关心的结果,越不容易被中间产物骗过。

第二类失效来自验证覆盖不足。假设任务有五项独立条件,Auditor 每项正确检查的概率均为 qq。在一个极简独立假设下,整体验证全部可靠的概率约为 q5q^5。即使 q=0.95q=0.95,结果也只有约 0.7740.774。真实条件当然不独立,但这个算例足以说明:长任务会累积验证风险,不能因为单项检查看起来很强,就默认总体验收同样可靠。高风险条件可安排两个异构检查,例如测试结果配合最终状态查询;低风险条件则不必重复调用昂贵模型。

第三类失效是 Auditor 被要求判断它看不到的事实。没有网络权限却要确认远端部署、没有账户权限却要确认邮件已发送,都只能返回 inconclusive。这个结果不会让系统显得漂亮,却保护了状态。把不可见当成功,后续所有计划都会建立在空地上。

预算分配和停止条件. 轮次上限 NmaxN_{max} 只是收尾阶段一道保险。更实用的停止判断需要观察边际进展。设第 ii 轮后新增通过的验收权重为 ΔPi\Delta P_i,花费为 KiK_i,则单位成本进展为:

ηi=ΔPiKi.\eta_i=\frac{\Delta P_i}{K_i}.

连续几轮 ηi=0\eta_i=0,可能表示执行策略卡住、验证器不可用,或目标需要用户授权。Manager 此时应切换策略、缩小合约或进入等待,不应原样重复同一轮。若进展存在但成本快速上升,可以把剩余条件按风险排序:先完成决定任务成败的硬条件,再处理低风险修饰项。 角色模型可以按职责分档。Manager 的输入结构化且输出短,通常可以使用较小模型;Executor 面对代码、桌面或复杂工具,能力要求最高;Auditor 的选择取决于验收方式。能由确定性程序完成的检查直接运行程序,涉及语义或视觉判断时再调用模型。论文的 AgentAdapter 允许按角色替换后端,使预算随职责分配,省下三份同档模型的固定开销。

环境漂移与并发写入. MEA 默认每轮都能从环境中读取事实,但真实环境未必静止。用户可能在 Agent 工作期间手动修改文件,另一个服务可能更新远端对象,网页内容也会自行刷新。若 Manager 把 tit_i 时刻的审计结论直接带到 ti+2t_{i+2},中间变化没有被记录,所谓 verified fact 已经失效。 因此审计事实应带作用域和版本。文件事实绑定内容哈希,数据库事实绑定事务版本或更新时间,API 事实绑定资源 ID 与 ETag。下一轮合约消费某条事实前,先核对它的版本条件。设审计得到事实 ff 时环境版本为 ziz_i,动作要求的前置条件可以写为:

Pre⁡(ai+1)=(z=zi)∧f.\operatorname{Pre}(a_{i+1})=(z=z_i)\land f.

版本不一致时,正确状态是 stale,随后重新读取和规划。继续执行会覆盖别人的修改;把全部外部变化都当失败,又会让系统在活跃环境里寸步难行。Manager 要判断变化是否触及当前合约的读写集合:无关文件改变可以忽略,输入对象改变则必须撤销计划。 并发执行还会产生另一类问题。两个 Executor 都从版本 z0z_0 出发,一个写成 z1z_1,另一个稍后写成 z2z_2,后者可能吞掉前者结果。仅在轮末审计,已经来不及恢复丢失更新。解决办法是写入时使用 compare-and-swap、文件基线哈希或资源版本条件;冲突应回到 Manager,而非让 Executor自行选择覆盖。

GUI 环境最难版本化。截图只能证明某一瞬间的像素,不能稳定标识后台状态。可以组合窗口标题、可访问性节点、页面 URL、关键资源 ID 和截图哈希,得到一个近似 checkpoint。它仍然比代码仓库的 commit 弱,所以高风险 GUI 写入需要更窄的合约,并在动作后立即审计。

人工接管的状态协议. 长任务里有些决定天然需要用户:授权付款、选择两种都合理的产品方向、确认不可逆删除,或提供系统无法读取的凭证。Harness 若把这些情况统一记成 failed,会混淆能力不足与权限边界;若为了保持自动化率自行猜测,又会越权。 waiting 状态至少保存四项:已经验证的进度、等待用户回答的问题、不同答案会影响的后续分支,以及环境是否需要保活。用户返回后,Manager 不能把整段任务从头重播,只需把回答作为新的约束写入 task state,再核对等待期间发生的环境漂移。若远端会话已经过期,则先恢复环境,随后继续原依赖图。

提问也要有边界。能从环境读取的事实不应反复问用户;技术实现细节通常由执行层决定;只有答案会实质改变结果、权限或不可逆成本时,才值得中断。这样的协议把人工接管限制在真正需要决策的位置,避免 Agent 一遇到不确定性就把工作抛回来。 最终报告同样属于状态机。它应从已验证条件生成,列出完成项、未完成项、仍然存在的风险和可复查证据。Executor 的过程描述可以帮助定位,却不能直接进入完成清单。若任务在预算耗尽时结束,报告应保留可继续的 checkpoint,状态是 stopped_with_progress 或同类枚举,而非用一段乐观措辞把半成品包装成完成。

1.4. 最小实现、适用边界与复用方式

一份最小 MEA 实现. 不采用完整仓库,也可以用一个很小的状态机保留核心语义。循环每轮只做一次规划、一次执行和一次审计:

while state.status == "running":
    contract = manager.plan(state)
    if contract.requires_user:
        state.wait(contract.question)
        break

checkpoint = environment.snapshot(contract.scope)
    execution = executor.run(contract, fresh_context=True)
    audit = auditor.verify(contract, environment, read_only=True)

if audit.status == "pass":
        state.commit(audit.facts, checkpoint=environment.version())
    elif audit.status == "fail":
        state.record_failure(audit, checkpoint)
    else:
        state.record_inconclusive(audit, checkpoint)

短短十几行隐藏了几个必须由实现守住的不变量。fresh_context=True 要确保 Executor 没有偷偷继承上一轮聊天;snapshot(scope) 只覆盖合约涉及的资源,避免昂贵的全环境复制;verify 的工具权限必须在运行时限制为只读;commit 还要检查审计所依据的环境版本仍是当前版本。缺掉任何一项,代码看起来仍像 MEA,语义却已经变了。 测试这段循环时,可以准备固定的假 Manager、Executor 与 Auditor。让 Executor 声称成功但不改环境,状态不能前进;让它修改环境后超时,恢复逻辑应进入验证;让 Auditor 返回 inconclusive,完成项不能增加;让环境在审计后提交前改变,commit 必须拒绝旧报告。这样的测试比让三个模型自由聊一百轮更能证明 Harness 是否真的实现了审计状态转移。

何时不值得使用 MEA. 一次只读查询、几秒内完成且没有副作用的任务,三角色循环可能比任务本身还贵。验收条件无法从环境观察、只能依赖同一个模型主观判断时,独立 Auditor 的收益也有限。还有一类任务,环境变化快到 checkpoint 立即过期,若系统没有版本控制能力,外置状态只会保存大量陈旧事实。 可以用风险来决定是否启用完整循环。动作可逆、依赖浅、验证便宜时,单执行体加终局检查已经足够;依赖变深或需要跨会话恢复时,加入外置 task state;出现不可逆动作、多人并发或高昂失败成本,再启用逐轮 Auditor 和严格版本门。Harness 不该把每个问题都做成一场仪式,它的价值来自让验证强度跟风险匹配。

评测里再补两条曲线. 最终成功率把整条轨迹压成 0 或 1,看不出系统是在第一轮就跑偏,还是推进到九成后死在一个外部故障上。对长任务,可以记录经过审计的加权进度:

Pi=∑jwj1[gj 在第 i 轮已通过]∑jwj.P_i=\frac{\sum_j w_j\mathbb{1}[g_j\text{ 在第 }i\text{ 轮已通过}]}{\sum_jw_j}.

把 PiP_i 随轮次画出来,会得到进度曲线。曲线持续上升但最终未通过,说明系统能推进却缺少收尾或恢复;曲线反复下降,通常意味着新动作破坏旧条件,checkpoint 与保护检查需要加强;曲线很早变平,则要检查 Manager 是否不断生成相似合约。 第二条是未核实声明率。设 Executor 报告中共有 nn 个可检验声明,其中 uu 个未经 Auditor 支持就进入 task state,则:

U=un.U=\frac{u}{n}.

理想的验证门应使 U=0U=0。这个指标比统计 Agent 说了多少次「完成」更接近问题本身,因为语言模型可以换一种措辞表达同样的自我确认。实现时不必对所有自然语言逐句分类,只需检查进入 verified_facts 和 completed 的记录是否都有 audit evidence ID。 恢复能力则可用故障后的有效进展损失衡量。若注入故障前进度为 PbP_b,恢复稳定后为 PrP_r,损失为 L=Pb−PrL=P_b-P_r;再记录恢复所需轮数与成本。好的系统不一定零损失,例如不可逆外部变化可能迫使它撤回一项进度,但应能解释损失来自哪里。只报告恢复后最终成功率,会掩盖系统是否把大量已完成工作重做了一遍。

这三组数字与论文已有的 PassRate、Overall、token 分解并不冲突。成功率回答「收尾阶段做成没有」,进度曲线回答「中间怎样推进」,未核实声明率回答「状态是否被自我叙述污染」,恢复损失回答「遇到故障后保住了多少工作」。Long-horizon 系统的差异,往往正藏在后三项里。

这些过程指标还可以帮助解释跨基准差异。Terminal-Bench 的终态往往能由测试命令读取,Auditor 容易得到强证据;OSWorld 涉及桌面应用、登录态和视觉界面,同一个动作是否完成更难稳定观测。因而,同样的 MEA 结构在不同基准上的收益不能只归结为模型强弱,验证器覆盖率和环境可观测性也会改变上限。部署团队若发现 Auditor token 持续上涨,先看它是否在反复弥补弱观察,而非立刻缩短审计提示词。

进一步说,进度曲线也适合选择 checkpoint。系统不必每轮保存完整环境,可以在高权重条件刚通过、不可逆动作即将发生、或外部依赖完成切换时保存。这样既控制存储成本,也让恢复点靠近真正有价值的进展。固定每五轮保存一次虽然简单,却可能恰好跳过最需要保护的状态。

状态提交必须满足的约束. 1. 状态外置:task state 不在 Executor 上下文里「顺便维护」,而是 harness 层的显式记录。 2. 验证先于提交:只有经 Auditor 独立确认的事实才能进入持久 task state;LLM 自评不算数。 3. 跨轮记忆受控:下一轮决策读取结构化 task state 与 audit report;Executor 原始历史不能绕过审计门进入事实状态。 4. 子任务有界:每轮只执行一个明确定义的 subtask contract,避免「一个会话干到底」。 5. 后端可替换:AgentAdapter 保证换模型/换 harness 不改 MEA 语义。

与单循环 Harness 相比,MEA 的差别包括:

路线 核心手段 与 LongHorizon-Harness 的关系
上下文压缩(CompactionRL、Self-Compacting 等) 在单会话内摘要/删历史 仍假设「一个 growing context」;LH-Harness 直接拆会话
Reflexion / 反思循环 模型读自己的失败反思 反思仍可能自洽地错;LH-Harness 要求环境客观证据
Verifier / RLVR 训练期学验证 LH-Harness 是推理期 harness,可与 verifier 训练互补
Orchard / OpenForge 训练期在真实 harness 里 rollout 解决 train-deploy mismatch;LH-Harness 专注部署期状态管理
Argus 四角色 + verification-gated 状态进化 更重的 campaign 级 runtime;MEA 是 lighter 的三角色审计环

可复用的任务状态结构. 无论是否采用 LH-Harness 代码,以下抽象可直接迁移到任意 long-horizon agent 系统:

  1. Audited State Transition:每一轮推进 = 「规划 → 执行 → 审计 → 状态提交」,而非「执行 → 自我感觉完成」。
  2. Fresh Context Executor:执行层每轮 blank slate,规划层靠结构化 state 而非 raw chat log。
  3. Subtask Contract:子任务必须带 acceptance criteria,Auditor 可机械对照。
  4. Single Source of Cross-Round Memory:明确指定「什么可以跨轮」——通常是 verified facts,不是 model narrative。
  5. Role Budget Split:Manager 便宜、Auditor 中等、Executor 昂贵——架构上允许按角色分配模型档位。

CLI 入口:uv tool install lh-harness → lh-harness init → lh-harness run --task @task.md --dashboard。评测复现见 repo 内 eval/WeaveBench-harness/ 与 eval/OSWorldv2-harness/。