跳到正文

Skills

chimera-carry-the-failure-forward

覆盖掉自己反馈变量的重试循环,只把第 2 次的失败展示给第 3 次——于是它又推导出第 1 次已经试过的那个补丁。

模式来源: clean状态: activev0.1.0 · Apache-2.0

由读过该卡片的评审者赋予,而不是文件自我声明的。智能体在处理不可信内容的运行中提炼出的卡片,生来即被标记为受污染,在被检索之前会一直等待评审。

何时会想到它

  • 在写重试循环
  • 智能体反复尝试同一个修复
  • 把验证器输出喂回给模型
  • 每次都失败在同一个地方
  • 每次尝试之间回滚工作区

价值通常在「避免」和「检查」里。「该做」是人人都会写的那一节。

上面的卡片正文是译文。英文原文才是 CLI 导入的内容、智能体运行时读取的内容,也是下方哈希所证明的内容。

触发

你有一个循环:跑一次尝试、评判它、带着反馈再跑一次——一个带校验器的 agent、一个对着测试套件修代码的修复器、一条生成加检查的流水线。预算不止两次尝试,而且两次之间工作区会被回滚,所以每次尝试都从干净状态开始。

这条不适用于在不稳定传输层上的幂等重试——一次因为与你发送的内容无关的原因而失败的网络调用。那里的第 1 次尝试没有任何可学的东西,把它带下去只是多出来的载荷。

该做

  1. 把每次尝试存进一个列表,而不是存进一个会被你反复重新赋值的变量。每次尝试一条记录:校验器的输出、这次尝试实际写下的补丁,以及最先出错的是哪一个工具步骤。
  2. 补丁要从工作区快照里取,取在回滚之前——取真实的 diff,而不是模型对自己改了什么的描述。回滚正是让这件事变得必要的原因:树一旦被回滚,磁盘上就再也没有任何东西记录着那条错误路径,于是下一次尝试重新推导出同一条路径时,不会遇到任何阻碍。
  3. 把重试提示词从每一条记录组装出来,最早的在前,每条都标上它的尝试序号和判定结果,放在一个说明"这些已经试过并且已被回滚"的标题下面。
  4. 给每条记录设上限。Chimera 把回喂的 diff 限制在 2000 个字符,超出部分用标记截断;一份没有上限的三次尝试历史,会把提示词整个占满。
  5. 按失败特征去重。如果两次尝试以同样的方式失败,只留一条,并记下它复发了——重复本身才是信号,第二份副本不是新信息。
  6. 当特征重复出现时,停止继续追加,改动一些结构性的东西:带着累积起来的原因作为规划器(planner)的上下文重新规划(TaskLedger.context() 会把它们渲染在 "Why earlier attempts failed (do NOT repeat these):" 下面),或者升级到更强的模型。围绕同一条死路给出更多反馈,走不出这条死路。
  7. 每次注入历史时发出一个可计数的事件,这样某个基准测试分支才能证明注入确实发生过。

避免

覆盖。在 chimera/core/autonomous.py 里,循环的反馈每一轮都被重建:

feedback = "\n\n".join(p for p in (fb, _verify_fb) if p) or "The attempt did not pass verification."

于是第 3 次尝试是拿第 2 次的失败组装出来的,第 1 次的东西一点都没有。把失败带下去,意味着改成往一个结构里追加——下面是示意,不是引用,因为这个累积版本是本卡片所主张的做法,而不是这个文件目前的做法:

records.append(record_for(index, verdict, patch))   # 每次尝试一条记录
feedback = render(records)                          # 全部尝试,最早的在前

你在 Chimera 里读到这张卡时,要分清哪一半已经就位:反馈的内容覆盖得很好——--diff-feedback 会把这次尝试实际写下的补丁展示给重试(chimera/core/autonomous.py,上限为 _DIFF_FEEDBACK_MAX_CHARS = 2000),而 TaskLedger 会为规划器累积失败原因。没有被覆盖的,是上面那行代码里跨尝试的累积。一张把这些全部说成缺失的卡片,是在反对已经做完的工作。

也要避免只告诉重试它失败了,却不给它看它写了什么。"这次尝试没有通过校验"加上一个失败的测试,足以让模型再试一次,却不足以让它试点不一样的——那个错误的补丁对它是不可见的,工作区里也不再有它,于是重新推导出同一个补丁就成了阻力最小的路径。

还要避免只把管理者的文字叙述带下去,却丢掉校验器的输出。那条失败的断言是整个循环里最可据以行动的一行;评审者关于它的一段话,是一份信息量严格更少的转述。

检查

给组装器加上埋点,跑一个你知道会失败三次的任务,然后在第 3 次尝试的提示词里 grep 一个只在第 1 次尝试里出现过的字符串——它碰过的某个文件名、它 diff 里的某个标识符。在,或者不在;没有部分得分。

第二项检查同样是二元的:数一数注入次数。一次因为守卫条件写错、或者因为 diff 列表为空而根本没有组装出历史的运行,什么都没测量到——而建立在这之上的基准测试分支,测的是管道,不是这个想法。如果计数器读数是零,那不管成功率说了什么,这个结果都是无效的。

风险

锚定是已经预先登记的反向假设,不是空想:把错误的补丁给模型看,可能会把它的注意力固定在那个补丁上,让它产出一条死路的各种变体,而不是另一条路。这就是为什么这个行为在 Chimera 里是可选开启并且被测量的(--diff-feedback),而不是默认打开。把它当成一个需要在你自己的任务上验证的论断,而不是一项已成定论的改进。

第二项代价是上下文预算。三份 diff、三份校验器输出加上一段管理者评审,可能把提示词推过压缩阈值——然后一个没有还原机制的压缩器,会恰好丢掉你花力气建起来的那份累积历史。开启这个之前,先给记录设上限,并且搞清楚你的预算,否则这两套机制会互相打架,而表面症状哪一个都不是。

如何使用

卡片就是数据。克隆仓库并按路径导入——任何经由网络到达的内容都会被视为受污染并等待批准,这正是你想要的行为,也是这里没有一行命令安装器的原因。

git clone https://github.com/brcampidelli/chimera-agent.git
chimera skills-import chimera-agent/skills/chimera-carry-the-failure-forward/SKILL.md

完整性

文件发布版本的 SHA-256。导入方可以据此核对收到的内容与本页展示的一致。

62dcc2aa830e5eb35c554bebf2c1a24454a054bf17bf152ccd59f3497b5e043d

在仓库中阅读该卡片