工作流节点的容错设计
RedEarth 的工作流由一串节点组成,比如“抓取 RSS → 去重 → 大模型摘要 → 推送消息”。最早的实现很简单:任何一个节点抛出异常,整条流程立刻终止,并标记为失败。
这个设计在大部分时候没问题,直到有一天大模型接口超时,导致那天的摘要完全没有发出来。
问题:并不是所有失败都应该中断流程
回头看那条工作流,其中有一个节点是“给每条资讯补充翻译”。这个节点失败了,最合理的结果是“发一份没有翻译的摘要”,而不是“什么都不发”。
但另一些节点失败就必须停下,比如“抓取”失败了,后面根本没有数据可处理,继续执行只会产生空消息。
所以问题的本质是:节点失败后该怎么办,只有编排流程的人知道,引擎不应该替用户决定。
方案:节点级的 on_error 配置
我给每个节点加了一个 on_error 配置项:
| 取值 | 行为 |
|---|---|
abort(默认) | 节点失败,整条流程终止,和原来一样 |
continue | 节点失败,记录错误,把上一步的输出原样传给下一步,流程继续 |
默认值保持 abort,这样已有的工作流行为完全不变,只有用户明确选择的节点才会降级。
几个细节
- 降级时传什么数据。失败节点没有输出,我选择把它的输入透传下去。这样“补充翻译”失败时,下游拿到的仍是未翻译的原始数据,结构不变。
- 运行记录要能看出降级。流程最终状态是“成功”,但运行详情里会把失败的节点标红并保留错误信息,否则问题会被悄悄掩盖。
- 和重试的关系。节点先按自己的重试策略重试,全部重试失败以后才看
on_error。临时的网络抖动由重试解决,持续的故障才走降级。
小结
容错策略不是越宽松越好,也不是越严格越好。把选择权交给编排流程的人,同时保证默认行为不变、降级过程可追溯,是我觉得比较稳妥的做法。
