跳到主要内容
agent 失败时,最该做的不是喂它更多上下文

agent 失败时,最该做的不是喂它更多上下文

画唠
画唠

· 阅读约 4 分钟

先把话说死:agent 失败之后,你的第一反应是给它补上下文、加工具、多塞几个例子——大概率是错的。方向反了。

我一开始也是这么想的。八月挂 arXiv 上那篇讲 DARC 的论文,第一遍扫标题还觉得,又来一个"自我纠正"的花活。真正让我坐直的是图里那根箭头——它跟我想的,是反的。

等等等等,先别急。先把我原来那版错的画出来。

我第一版图,画长了

当时我理解的 agent 恢复,大概是这样:

   失败 ──► 补上下文 / 加工具 / 多给例子 ──► 重试 ──► 还失败 ──► 再补 ──► ...

一条线,越走越宽。逻辑也顺:它不知道,你就多告诉它一点。上下文窗口那么大,塞呗。

这张图的底气来自编码 agent——那玩意儿太顺了,编译器给你报错,测试给你红绿,跑崩了有 traceback。失败信号是带类型的,你缺个类型注解,它就说你缺个类型注解。于是我就以为通用 agent 也一样,把失败信号喂回去,它自己会收敛。

不对。这是我的第一个错觉。

翻车那段

通用任务跟 coding 根本不是一回事。coding 里失败是"带类型的",通用任务里失败就一句:任务没完成。粗得跟没给一样。

所以你补回去的东西,正好撞上论文说的那个矛盾:你要的是更窄的修复接口,补进去的却是一大坨互相打架的信号。我把那坨东西拆成三样:

   一次失败,你补回去的那一坨里,其实混着:
   ┌──────────────────────────────────────┐
   │ 无效动作   —— 它试了个根本不存在的操作   │
   │ 缺失流程   —— 它跳过了本该走的某一步     │
   │ 格式错误   —— 它给出的东西形态就不对     │
   └──────────────────────────────────────┘

要命的是这三种"病"治法完全不一样:无效动作得换动作空间,缺失流程得补步骤顺序,格式错误得收格式约束。糊成一坨塞进上下文,模型手里没有标签去分辨哪个是哪个,只能一股脑当成"我整体没做好",然后重试——重试一条已经走歪的路。上下文越塞越大,方向一步没纠回来。

我盯着这块看了半天,脑内只有羊叫。"给更多信息"这件事本身,在这里等于往一个已经堵住的口子上继续灌。

打个比方(然后告诉你它在哪漏风)

事后我给它找了个抓手:agent 恢复,像看病。

感冒吃感冒药,骨折打石膏。可你要是所有病人都端一碗大补汤——补是补了,骨折那位喝完还是断着。宽泛恢复方案就是那碗大补汤。

   错的版:  病 ──► 大补汤 ──► 还是病
   对的版:  病 ──► 先诊断是哪类病 ──► 对症的药 ──► 好

这比喻挺好用,但它漏风,我得老实标出来:病人知道自己哪儿疼,开口就说"我左腿"。agent 不会。它给自己的失败打分就是一句"没做成",压根不告诉你哪一类。所以现实里"先诊断"那一格没法原地填——诊断依据得从别处找。

论文这里给了一步挺巧的:拿开发集补。让它在开发集上可劲儿失败,把失败姿势攒起来看规律,哪类任务老栽在哪类错上,慢慢轧出一张对照表——这类失败,哪种干预能救。等真到测试,模型不再是现场瞎猜,而是拿这张表去卡:这次是格式那一挂,那就别去动动作空间了。

这就是那句"先判断哪类失败可被修复,再决定投入多少恢复证据"。因果顺序被整个掉了个头:不是先扩上下文再看能不能救,是先判可修性,再决定投多少。

重来,这版图才是对的

重画:

   失败
     │
     ▼
   诊断:这是哪一类失败?              ← 靠开发集攒的那张表
     │
     ├── 修不了 / 表里没这号 ──► 别动,省下预算
     │
     ▼ 可修
   从共享恢复库里挑匹配的干预           ← 不匹配的先剔掉
     │
     ▼
   投入恢复证据(收窄的接口,不是一大坨上下文)
     │
     ▼
   重试

跟第一版比,差别在哪?第一版是"失败→加量",这版是"失败→定性→定量"。加量那一步被挪到了最后,加多少还被诊断结果掐着。

咔哒一下扣上的那一刻,我回头再看"失败并不必然要求统一增加上下文"那句,突然就不像口号了:它就是这张图上一根箭头掉个头的事。

说点不满意的

论文在 ALFWorld、AppWorld、XBRL Finance 三个环境上跑同一套协议,分别落成动作有效性框架、流程恢复回退、格式精度检索三种策略,报的结果是平均任务表现上去了,环境步数或检索预算反而降了。降预算这点我信,因为这版图本来就是在省钱——少塞那些没用的上下文,账自然就下来了。

但有个地方我不太买账:那张开发集上轧出来的诊断表,到底能迁移多远?三个环境都是它自己挑的,失败类别相对干净。真扔进一个失败姿势又多又脏的开放环境,这一格会不会先崩,论文没给我特别硬的答案。这段我还没完全画明白,先放这儿,懂了再补。

不过方向我认了。自我纠正不是"把提示写长一点"的活儿,是"把修复接口设计窄一点"的活儿。在没有编译器、没有测试给你带类型信号的那些领域,这篇给的路径就一句:先让失败变得可操作,再去扩上下文。

顺序别搞反。

画唠
画唠

把被讲玄的概念用图 + 比喻 + 动手实验拆到咔哒扣明白,错的也保留。

查看主页 →