你有没有遇到过这种情况——
你让AI Agent帮你做一个表格,它打开Excel,输入数据,调整格式,一切看起来都很顺利。
然后你说,"顺便把这个数字改成上季度的。"
Agent开始了。它打开浏览器,找到数据源,复制粘贴,回到Excel,重新计算——等等,它忘了刚才已经把格式调好了。它开始重新调格式。然后又忘了数据源在哪。重新搜索。
20步之后,什么都没完成。
这不是Agent的能力问题。这是Agent的"记忆"问题。
更准确地说,不是Agent记不住,而是Agent不知道"完成了"意味着什么。
现在大部分Agent的工作方式是这样的:每执行一步,就把这一步的截图、文字描述、交互记录堆到上下文里。上下文越来越长,越来越乱。Agent迷失在自己制造的信息垃圾里。
这就像你在一个杂乱无章的办公桌上工作,每个文件都压在另一个文件上面,你不知道哪些已经处理完了,哪些还没开始。
一篇来自多机构联合团队的最新论文,给出了一个漂亮的解法。
你的Agent不是笨,是没人告诉它"什么叫做完"
先说一个反直觉的结论。
让Agent在长任务中失败的首要原因,不是模型不够聪明,而是Agent把自己的"完成声明"当成了真正的完成。
什么意思?
现在的Agent工作流程大致是这样的:大模型看一遍上下文,决定下一步做什么,执行,然后自己判断"这个子任务是不是完成了"。
问题就出在最后一步。
Agent说"我下载好了"——但其实文件没保存到磁盘。Agent说"我填完表格了"——但其实最后一列是空的。Agent说"我改好了"——但它改的是5分钟前那个版本,现在的文件已经被其他操作覆盖了。
Agent嘴硬得很。而且它说服自己的速度,比它完成工作的速度快得多。
StructAgent这篇论文的核心洞察就是:一个Agent系统里,做事的和验收的,必须是两拨人。
做事的人(Actor)负责执行。验收的人(Verifier)负责确认。做事的人说"搞定了"不算。验收的人说"搞定了"才算。
这不是什么新概念。人类社会的所有靠谱组织都是这么运转的。厨师炒好菜,服务员端给客人——这个流程没错。但如果厨师自己当服务员、自己记账、自己写大众点评,你觉得这家店能活多久?
Agent系统的所有混乱,本质上都是"既当运动员又当裁判"造成的。
给Agent装一个"因果账本"
那StructAgent具体做了什么?
它在Agent内部建了一个"因果账本"。论文里叫Unified Causal State。
这个账本记录三样东西:
第一,当前要做什么。 不是模糊的"完成表格制作",而是"确保A1单元格内容与数据源一致,B列格式为货币格式,总计行公式校验通过"。每一条都是可验证的。
第二,发现了什么。 执行过程中碰到的文件路径、URL、提取的数据字段、中间计算结果。这些是"资产",后面要用。
第三,验证过了什么。 已经有证据支持的结论。这不是Agent自己说"我做完了",而是Verifier检查过的——"A1单元格确实等于数据源第3行第2列,我检查过了。"
关键来了:这个账本的每一次更新,都必须由验证器签字。
Actor说"我下载了图片"——不行,Verifier必须用file_grep去磁盘上检查,文件确实存在、大小不为零,才算数。
Actor说"我改完了文档格式"——不行,Verifier必须用writer_verify检查段落属性,全部符合才算数。
这就像财务报销。你说花了多少钱不算。发票才算。
Agent相当于一个人报销了一整年差旅费,全凭自己说。不出问题才怪。
账本逻辑比你想的更有用
有了这个账本之后,很多看似高级的能力,就变成账本的"自然附赠功能"了。
进度恢复。 任务中断了?账本上有完整记录——哪些需求已验证,哪些还是Pending,哪些已经有冲突被标记为Invalidated。不需要重放全部历史,直接读取账本就能继续。
精准修复。 出错了?账本能告诉你问题在哪:是证据不够(软失败)还是与已验证需求冲突(硬失败)。前者重新执行就行,后者说明你的策略可能有问题,需要换方案。
经验沉淀。 账本记录了哪些执行模式反复出现。Agent可以把这些模式提取为可复用的工具。下次遇到类似场景,直接从工具库调用,不用重新试错。
这个设计最妙的地方在于:这些能力不是"额外开发"的,是账本本身的属性。
就像你一旦有了精确的银行流水,预算管理、财务分析、税务审计都是自然附带的能力。不需要再单独设计一套系统。
但我必须告诉你被忽略的两个关键细节
第一处:验证探针的类型选择,比验证本身更重要。
StructAgent设计了7种验证探针:文件检查、URL匹配、UI元素检测、电子表格验证、文档验证、幻灯片验证、Shell命令。
但并不是每个任务都需要全部7种。
论文的消融实验显示:VS Code和操作系统任务从结构化验证中受益最大(因为有文件、Shell输出、URL这些"硬证据")。而纯浏览器任务,截图验证仍然占大头。
这意味着:你给Agent装什么"感官",直接决定了它能"确认"什么。
这就像给质检员配放大镜和配显微镜的区别。工具决定了你能看到什么。你能看到什么,决定了你能确认什么。
第二处:剩余失败中,30%仍然是验证器自己的失误。
论文对83条得分为零的轨迹做了审计。结果出人意料——Actor执行失误只占33%,Planner规划失误占30%,但Verifier验证失误也占了30%。
最大的单一失败类型是"状态验证":系统接受弱证据、遗漏已完成条件、或未能检测到后续动作使早期进展失效。
换句话说,即使把验证独立出来,验证本身仍然会出错。
这告诉我们一个更深层的道理:分解Agent的职责是必要的,但不是充分的。你还需要持续优化每一个子模块。分工只是起点,不是终点。
这条思路可以用在哪里
StructAgent解决的其实是一个通用问题:长序列任务中的进度可信度问题。
不仅仅是操作电脑。任何需要"多步执行+中间验证"的场景,都可以用这个思路。
代码Agent。 你说"修复这个bug并写测试"。Agent做了10个文件改动。哪些改对了?哪些改坏了?哪个改动引发了新的问题?现在大部分代码Agent的处理方式是"全改完再一起检查"。StructAgent的思路是:每个文件改动必须有对应的验证(单元测试通过、类型检查通过、lint警告清除),只有验证通过的改动才算"完成"。
客服Agent。 "帮我退掉这笔订单并申请优惠券"。Agent发起了退款、填了优惠券申请表、发了确认邮件。但退款真的成功了吗?优惠券真的到账了吗?用StrucAgent的逻辑:退款必须用API查询返回"已退款"状态;优惠券必须在账户余额页可见。每个子目标都有对应的验证动作。
数据分析Agent。 "分析这个数据集,生成报告,发送给老板"。Agent清洗了数据、跑了模型、画了图、写了结论。但数据清洗有没有去掉有效样本?模型假设是否满足?图表坐标轴标注是否正确?每一步都需要独立的验证。
核心原则就一条:不能让同一个人定义"完成"并宣布"完成"。
你做你的。我查我的。查完了,才算数。
你现在就能做的三件事
第一,给你的Agent任务加"可验证中间点"。
不要再发"帮我完成XX"这种指令了。改成:"帮我完成XX,每完成一步,请提供可验证的证据。比如改了文件给我路径和diff,下载了数据给我文件大小和行数。"
这不需要改代码,只需要改prompt。
第二,把你的验收标准和执行指令分开。
如果你在用多Agent系统,让一个Agent负责规划+执行,另一个Agent负责验收。不要混在一起。验收Agent只看"证据是否充分",不看"执行Agent是否辛苦"。
如果你在用单Agent系统,在prompt里加一句:"在宣布任务完成前,请逐一列出每项需求的验证状态:哪些已验证(附证据),哪些尚未验证。"
第三,记录你的失败模式。
每次Agent出问题,记三件事:是哪个子目标失败了?是真的没做完,还是做完了但没验证?如果有验证环节,是没验证到,还是验证错了?
搞清楚了这三个问题,你就知道该强化哪一部分。
StructAgent这篇论文,没有发明什么惊天动地的算法。
它做的事情很简单:把"谁负责做"和"谁负责验证"分开,把"做了"和"做完了"分开。
简单,但关键。


因为绝大多数系统的崩溃,都不是因为做的人不够努力。而是因为做的人同时也是给自己打分的人。
信任不是靠声明建立的。信任是靠验证建立的。
夜雨聆风