当一个 Agent 系统开始具备质量闸门之后,新的问题就会接着出现:
- 如果
Reviewer判定要整体重写,系统怎么回炉? - 回炉过程中失败了,是不是和普通失败一样处理就行?
- 为什么有时候“看起来已经会重试”,但流程还是会跑错?
这章讲的就是当前项目里一个非常真实、也非常工程化的话题:
自动回炉和失败重试,不能只做成“再试一次”,而要做成“按流程语义恢复”。
为什么“失败重试”不是一个简单的 if-else
很多人第一次做重试,会自然写成这种思路:
- 某一步失败
- 如果错误可重试,就 sleep 一下
- 再重新跑这一步
单看这套逻辑没什么问题,但在多 Agent 系统里,它很容易不够。
因为真实系统里,失败不是孤立的。
它发生在某一条“有上下文的流程”里。
比如:
- 普通
Writer revision失败 - 自动回炉阶段的
Writer draft失败
这两个失败虽然都可能是“网络超时”,但它们在流程中的语义完全不同。
如果系统只看“失败步骤名”,而不看“当前处于什么流程语义里”,就很容易恢复错。
当前项目里,普通失败重试是什么样
先看比较基础的一层。
当前项目已经具备了比较完整的失败重试机制:
- 记录
last_error_type - 记录失败的
current_agent / current_step - 判断错误是否可重试
- 控制最大自动重试次数
- 从失败步骤继续,而不是整任务重跑
这已经比很多原型项目成熟很多了。
这套能力主要解决的是:
任务失败后,不要让用户重新从头开始。
在普通线性流程里,这通常已经够用。
自动回炉为什么会让问题复杂化
事情在引入自动回炉后开始变复杂。
当前项目现在有这样一条逻辑:
Writer draftReviewer review- 如果质量闸门结果是
rewrite - 系统自动回炉一次
Writer draft - 回炉成功后再次
Reviewer review - 再进入
Writer revision
这已经不是简单的线性主链路了。
它在主链路中间插入了一段“子流程”。
而子流程一旦失败,系统就必须回答:
我到底是在恢复主链路,还是在恢复自动回炉子流程?
当前项目真实踩过的坑
这不是理论问题,而是当前项目实际跑验证时踩出来的坑。
当时的现象大概是这样:
Reviewer已经判定rewrite- 系统确实触发了
reviewer_auto_rewrite - 自动回炉阶段的
Writer draft因为模型超时失败 - 通用重试机制把它从
draft恢复了 draft后一旦成功,系统却直接掉回了writer_done审批点
结果就是:
自动回炉后的第二次 Reviewer 被绕过去了。
也就是说,系统虽然“会重试”,但恢复语义是错的。
这个坑为什么会出现
根因其实很典型:
系统当时只知道:
- 最近失败的是
Writer / draft
但它不知道:
- 这个
draft不是普通初稿阶段 - 它其实处于“自动回炉中”
于是恢复逻辑就按普通 draft 来处理了。
这说明一个很重要的设计原则:
恢复逻辑不能只根据失败步骤判断,还必须知道当前流程所处的语义状态。
当前项目后来怎么修的
当前项目最后走的是一个很务实、也很有效的方案:
- 给自动回炉阶段增加独立状态标记
具体来说,后来新增了:
auto_rewrite_pending
这个字段的意义就是:
当前任务不只是“在跑 draft”,而是“正在自动回炉的 draft 阶段”。
这一步看起来只是多了一个布尔状态,但实际上把恢复语义补齐了。
auto_rewrite_pending 带来了什么变化
有了这个状态以后,系统就能区分两种完全不同的 draft。
普通 draft
表示当前是在主链路里第一次生成初稿。
成功后通常会:
- 暂停到
writer_done
自动回炉 draft
表示当前是在质量闸门 rewrite 之后,系统主动回炉。
成功后不应该暂停给用户,而应该:
- 清掉自动回炉状态
- 继续再跑一次
Reviewer
这就是“同样是 draft,流程语义却不同”的典型例子。
自动回炉阶段的参数为什么也要单独调
当前项目在修复语义之后,还继续往前做了一步:
给自动回炉阶段单独设置了更稳的调用参数。
比如当前已经落到代码里的策略包括:
- 自动回炉
Writer draft使用更长的超时 - 第二次
Reviewer使用更长的超时 Writer revision也使用更稳的超时和温度参数
这背后的思路很简单:
自动回炉不是普通生成,它本来就更像一次“补救动作”。
既然系统都已经决定要自救了,就应该给它一组更适合自救的调用策略。
更清晰的重试日志为什么重要
当前项目后面还顺手做了一个很实用的优化:
- 自动回炉阶段的失败日志和普通失败日志分开表述
比如会在日志里明确体现:
- 这是普通流程失败
- 还是自动回炉阶段失败
这听起来像文案细节,但其实非常重要。
因为调试的时候,你最怕看到:
- “Writer / draft failed”
却不知道这到底是:
- 初稿生成失败
- 还是自动回炉阶段失败
当流程越来越复杂时,日志必须承担“解释当前语义”的职责。
当前项目已经验证到什么程度
这部分不是纸上设计,而是当前项目已经真实验证过的。
项目后面专门构造了“明显跑题的草稿”去跑这条链路,并确认了完整闭环:
Reviewer / review / completedSystem / reviewer_auto_rewrite / completedWriter / draft / completed- 第二次
Reviewer / review / completed Writer / revision / completedrevision_done
并且这条链路现在还被自动化测试锁住了。
这意味着:
自动回炉不再只是“代码里看起来有这个逻辑”,而是已经被真实跑通并验证过了。
这一章真正想说明什么
当前项目在这条线上最值得借鉴的一点,其实不是“会自动回炉”,而是:
一旦流程变复杂,失败恢复必须按语义做,而不是按步骤名做。
否则系统很容易出现一种错觉:
- 表面上它会重试
- 实际上它恢复到了一条不该去的路径
这是很多 Agent 项目在往复杂流程走时非常容易踩的坑。
这一章的结论
在多 Agent 系统里,自动回炉和失败重试不能只做成通用“再来一次”,而要考虑:
- 当前失败发生在哪个流程语义里
- 恢复后应该接回主链路,还是接回子流程
- 是否需要独立状态标记
- 是否需要单独的模型参数和日志文案
当前项目最终给出的答案是:
- 用
auto_rewrite_pending显式标记自动回炉状态 - 恢复时按自动回炉语义继续,而不是按普通
draft继续 - 回炉成功后强制再走一次
Reviewer
这是一套非常实战的设计。
下一章看什么
当你已经有:
- 自动回炉
- 失败重试
- 冲突确认
- 质量闸门
下一个问题就会变成:
这些关键语义,怎么防止以后改代码时被悄悄改坏?
下一章我们就讲当前项目最近开始补的另一块关键能力:
自动化测试。