mirothinker — 本课题摘录
读了哪几篇: 03-robustness-rollback(自我纠错:回滚、去重与容错修复)、04-context-and-answer(上下文管理与答案收尾)。
其余几篇本轮没读。
这一家的核心命题对本课题极重要:循环的健壮性不来自模型,来自围着"模型会犯的错"建的一张网。
它对本课题回答了什么
决定四:回滚 —— 把刚加进历史的那条撤掉,当这一轮没发生过
它的场景是开源模型:会把工具调用格式写错 、会拒答、会反复搜同一个词、会吐出坏掉的结构。
做法:每一轮模型说完话之后,先不急着执行,拿几把尺子去量:
模型输出这一轮
↓ 解析层(读懂它):三种格式兼容 + 坏结构抢救
↓ 修复层(改对它):工具名、参数别名、补默认值 —— 不回滚
↓
没有工具调用? ─是─► ◆ 文本里混着工具标签? → 回滚
◆ 命中拒答关键词? → 回滚
都不是 → 正常收尾
↓ 有工具调用
◆ 这个查询刚才查过? → 回滚
↓ 否
执行工具
↓
◆ 结果是「未知工具 / 报错 / 空」? → 回滚
↓ 否
成功 → 连续回滚计数归零
回滚的动作只有四步:轮数减一、连续回滚计数加一、把刚加进去的那条助理消息弹出、然后继续——让模型基于"没出错的历史"重新说一次。 (依据:Agent 库 · MiroThinker · 自我纠错:回滚、去重与对模型输出的容错修复 —— 格式错/拒答/重复查询/结果报错或空四类触发统一走回滚——turn_count 减一、consecutive_rollbacks 加一、pop 掉最后那条 assistant 消息、continue 让模型重来)
这是本课题第三个决定("结果怎么回填")的一个反面选项:不回填,而是把这一轮从历史里抹掉。
前面所有实现的默认动作都是"把错误也写进历史让模型看见"(db-gpt、kun、aider)。 mirothinker 反过来:有些错误不该进历史,因为它们只会污染下一轮。
两者的判据可以这样分:
- 信息型失败(命令报错、字段不存在)→ 写进历史,模型据此改正;
- 格式型失败(写错格式、拒答、重复)→ 抹掉重来,写进历史只会让模型学坏。
回滚不是无限的:连续回滚上限默认 5,连续太多次就"放行"或"结束",防止在同一个坎上死循环。
这条护栏必须有。 没有它,一个总是写错格式的模型会把循环卡死在原地。 注意"成功就归零"——它数的是连续,不是累计。
三层容错,由外到内
| 层次 | 干什么 | 动作 |
|---|---|---|
| 回滚 | 发现这轮废了就撤销重来 | 弹出 + 重试 |
| 就地修复 | 模型输出"差一点点",直接改对而不重来 | 参数别名改名、补必填参数、从系统提示反解工具名 |
| 解析容错 | 把模型吐的坏结构、三种格式统一解析出来 | 结构修复、多格式兼容、过滤空值 |
它的一句话总结:回滚是"重来",修复是"改对",解析是"读懂"。
这个三分法很好用,而且顺序是对的:能读懂就别修,能修就别重来。 重来最贵——它浪费了一整轮的模型调用。
"从系统提示反解工具名"这一条特别有意思: 模型写错了工具名,但正确的名字就在系统提示里,所以能反查着修回去。 这是"就地修"的典型:信息是全的,只是模型拼错了。