技术博客
LLM 大语言模型检索 / RAG

三分钟看懂 LongHorizon-Harness(上):长任务 Agent,为什么会越做越乱?

yiwan-cat2026-08-08 20:35
三分钟看懂 LongHorizon-Harness(上):长任务 Agent,为什么会越做越乱?

你让一个 Agent 做一件小事,它往往挺像个能干的同事:开网页、改文档、跑脚本、整理结果。

但把任务拉长,事情就开始变味。它改到第 18 步时,可能已经忘了第 3 步到底是“已完成”,还是“看起来完成”;某个弹窗点不动,它会在同一个位置反复试;更危险的是,它会把自己刚才说的“应该做完了”,当成下一步继续行动的事实。

这正是长程 Agent 最棘手的地方:难点不一定是某一步不会做,而是如何在几十轮甚至跨多个上下文窗口之后,仍准确知道现实环境里究竟发生了什么

阿里 DreamX Team 的论文 LongHorizon-Harness 给出的答案很克制:别再让一个不断变长的会话同时负责执行、记忆和自证。把跨轮记忆改成一份由独立角色审计过的“任务状态”,然后循环执行 Manage–Execute–Audit(MEA,管理—执行—审计)

图 1 长程 Agent 的两种工作方式:从“历史越滚越长”到“只让验过的事实进入下一轮”

一句话先说结论:LongHorizon-Harness 不是训练一个新模型,而是给现有 Agent 加了一层“受审计的任务状态机”。 论文用相同骨干与执行后端的对照表明,仅替换这层组织方式,Qwen 3.7-Plus 在 WeaveBench 上的完整任务通过率从 51.8% 提高到 80.7%。

下面先拆清楚:它究竟把什么从对话里拿了出来,又如何让“完成”不再只是一句自我报告。

长任务真正会坏在哪里:不是上下文不够长,而是状态不可信

今天的 Agent 框架已经能规划、调用工具、创建子任务,模型的上下文窗口也越来越长。但论文指出,常见执行方式仍有两个结构性问题。

第一,执行轨迹与任务状态塞在同一个持续增长的上下文里。前面点过什么按钮、产出过哪些文件、哪些约束仍未满足,都混在推理草稿、工具回显和失败尝试中。历史越长,真正重要的状态越难被稳定检索;早期错误还会被后续决策反复继承。

第二,执行者和验收者是同一个人。Agent 既修改环境,又根据自己的观察宣布“完成”。可它看到一个页面“差不多对了”,不代表源文件结构正确;它创建了一个文件,也不代表文件内容满足原始约束。一次误判被写进长期记忆,后面每轮规划都可能建立在错误前提上。

可以把这理解成项目协作里的一个反模式:一个人既写代码、又维护项目看板、还自己签验收单。短任务没问题,任务一长,任何一次“我觉得好了”都会变成隐性技术债。

图 2 左侧是不断增长、由 Agent 自我判断的单会话;右侧是只保存审计结论的状态迁移

论文的改写很关键:把长程执行视为一个任务状态管理问题,而不是“把一段更长的提示词交给同一个执行者”。后续每一轮不再继承完整聊天记录,而是只继承“哪些要求已经被外部证据支持、哪些还未完成、哪些被阻塞”。

这台“状态机”里,到底存了什么?

LongHorizon-Harness 把状态显式放在执行过程外。它并不保存所有原始思考,而是维护三类与任务直接相关的结构化记录:

  • Requirement(需求):任务目标、约束与验收要求;

  • Artifact(产物):已经创建或修改的文件、页面、截图等;

  • Fact(事实):从真实环境观察到、供后续决策使用的信息。

每条记录都有 completedpendingblockeduntrusted 等状态,并指向支撑它的审计证据。这个细节很重要:执行者的“我已完成”不是状态更新依据;只有审计得到的干净证据,才允许把一条需求标记为完成。

如果用符号表示,第 $i$ 轮开始时有任务状态 $S_i$。管理者根据原始任务 $T$、已有状态和审计报告集合 $V_i$,产生下一份状态、控制决策和子任务契约:

$$\
(S\_{i+1}, q\_{i+1}, c\_{i+1}) = \Phi\_{\mathrm{mgr}}(T, S\_i, V\_i).\
$$

这里的 $q_{i+1}$ 不只有“继续执行”。它可以是 executedoneblockedask:该停就停、需要用户授权就问、无法推进就明确阻塞,而不是假装任务仍在顺利前进。$c_{i+1}$ 则是一份有边界的子任务契约,写清立即目标、验收标准、约束,以及此轮真正需要的前序证据。

换句话说,对话历史被降级为一次性工作现场;任务状态才是跨轮的正式账本。

MEA 三个角色:把“做事”与“确认做对了”拆开

论文把每个回合组织成一个小闭环。它看起来像多 Agent 分工,真正的核心却是“权限边界 + 证据流向”。

图 3 Manage–Execute–Audit(MEA)循环与角色边界总览


1. 管理者:只看账本,不碰环境

Manager 读取原始目标、当前状态和既往审计报告,决定最值得推进的未完成目标,并写出一份范围受限的合同。它没有直接操作 GUI、终端、文件或网页的权限。

这种“看不见现场”的限制不是削弱它。恰恰因为管理者无法被局部界面细节牵着走,它只能根据已验证的事实重规划:这个子任务依赖是否满足?哪些产物真的存在?如果此处还缺用户信息,是否应当转入 ask

2. 执行者:一次只完成一件事,并且每轮从干净上下文开始

Executor 是唯一允许有意改变环境的角色。它接收原始任务、当前状态、子任务契约以及相关审计报告,在限定预算内完成此轮的操作。GUI 执行者负责截图、点击、滚动、输入;CLI 执行者负责脚本、文件编辑、代码与测试。

关键设计在于 fresh context。一次执行结束后,原始交互轨迹和内部推理都被丢弃。下一轮执行者不会背着前 400 步的失败点击继续跑,而只收到契约所需的少量、可核验背景。

它当然仍会输出执行报告 $o_i$,说明“做了什么、产出了什么、遇到什么问题”。但这份报告只是线索,不是事实证明。

3. 审计者:只读地检查现实,而不是听执行者复述

Auditor 在独立新上下文中接手。它可用执行报告定位文件、窗口、日志或测试,但最终结论必须来自对当前环境的独立检查。

它的权限被限制为只读:不创建、编辑、移动或删除任务产物;审计期间若检测到修改,报告会被标为完整性违规,不能用来支撑“已完成”。审计报告 $v_i$ 会给出三类判断:

  • 完成性completeincompleteblocked

  • 完整性cleansuspectviolation

  • 可写入状态的更新:哪些事实、证据与缺口应该带到下一轮。

所以,跨轮传递的不是“执行者的长篇复盘”,而是审计后的 $v_i$。这让下一轮的 Manager 不必猜“上次到底是不是做完了”。

为什么“新开一个上下文”不会让 Agent 失忆?

乍看之下,把每轮原始轨迹丢掉像是在牺牲记忆。但论文的观点恰好相反:长任务真正需要保留的不是每次鼠标点击,而是最小、可靠、可追溯的进展

例如,执行者花了大量步骤尝试修复一个文档,真正值得留给下一轮的也许只有四件事:文件路径、已经验证的标题数量、尚未满足的格式约束,以及对应审计证据。把这四件事写进状态,下一位执行者更容易接上工作,也更不容易把失败尝试误读为成功。

论文还通过一个轻量的 AgentAdapter 接到 Claude Code、Codex CLI、OpenClaw 等现有后端;它不重写这些后端原有的规划与工具调用循环,而是控制每个角色拿到的上下文、工具权限、执行预算和返回报告。这意味着该思路更像一个可替换的“调度与验收层”,而不是绑定某一家模型的专属能力。

但这里有一条边界必须说清:MEA 不能凭空补上模型不会的能力。 如果某一步的核心瓶颈是视觉识别、数学推理或代码设计本身,独立审计最多帮它发现错了、避免错上加错,并不能直接把错误答案变成正确答案。它解决的是长程执行的可靠性,不是通用智力的替代品。

上篇先把“为什么要把状态拿出对话”讲清了。下篇我们来看更现实的问题:这种额外的管理和审计,究竟换来了多少成功率?又付出了多少 token 与时间成本?


论文与项目

点赞收藏
// 评论0
0 / 500
还没有评论,快来抢沙发