Agent 任务拆分为什么总失败:别让子任务靠猜上下文,状态也别只活在对话里
· 阅读需 4 分钟
很多 Agent 任务拆分失败,表面上看像“模型没理解需求”,但我越来越觉得,真正的原因往往更工程化:你把一整条长任务拆成了几个子任务,却没有告诉每个子任务它到底拿到什么、应该产出什么、失败以后怎么恢复。
只要这些边界没先钉住,子任务之间就很容易变成一种很危险的协作方式:靠猜上文。
我见过最典型的失败方式
一个大任务通常会被拆成几步:
- 读取资料
- 生成方案
- 调工具执行
- 汇总结果
看起来很合理,但如果每一步只是“继续往下做”,没有明确 contract,失败会来得很快:
- 第二步不知道第一步到底筛掉了什么
- 第三步拿不到第二步做判断时的关键中间状态
- 第四步不知道一次失败是要重试整条链,还是只重试其中一步
这时模型越努力“自动想办法”,系统反而越不稳定。
任务拆分前,先把步骤 contract 写清楚
我更愿意把每一步先定义成类似这样的对象:
type TaskStep<Input, Output> = {
stepId: string;
input: Input;
outputSchema: Output;
retryable: boolean;
idempotent: boolean;
};
这不是为了写类型体操,而是逼自己回答几个关键问题:
- 这一步到底吃什么输入
- 这一步的结果长什么样
- 失败以后能不能单独重跑
- 重跑会不会产生重复副作用
只要这些问题没答,所谓“拆分”通常只是把一个大黑盒拆成了几个小黑盒。
中间状态一定要落下来
我现在特别反对让关键中间状态只活在对话上下文里。因为一旦:
- 模型窗口变短
- 任务跨进程
- 执行被中断
- 需要做人工接管
这些“只存在上下文里的状态”几乎都会立刻变得不可靠。
所以我更愿意让关键步骤至少留下:
- 当前步骤 id
- 输入快照
- 产出快照
- 版本号
- 是否已产生副作用
这样后面无论是重试、回放还是人工接手,都还有据可依。
重试边界不清,是很多 Agent 编排事故的源头
很多团队一遇到失败就“整条链重试一次”,这在纯生成场景也许还能凑合,但只要链路里有工具调用、外部写入或人工动作,就会越来越危险。
我现在更愿意先区分三类步骤:
- 可纯重放步骤:只做读取或纯计算
- 需幂等保护步骤:会产生外部副作用,但可用幂等键兜底
- 不可自动重放步骤:必须重新确认或人工介入
Agent 任务稳定不稳定,很大一部分就取决于这条边界有没有提前说清楚。
真正稳定的拆分,不是更会自动补救
我现在越来越不把“Agent 会自动想办法”当成褒义。真正稳定的 Agent 任务拆分,反而应该让每一步都不太需要猜:
- 输入是什么
- 输出是什么
- 状态存在哪
- 失败后怎么办
这样系统才不是靠一次次临场发挥往前顶,而是靠边界清楚地推进。
我对 Agent 拆分失败的判断
真正稳定的 Agent 不是会“自动想办法”,而是每一步边界都已经被工程化约束好。拆分本身不是难点,难点是你有没有给每个子任务足够清楚的 contract、状态和重试规则。
这些事情一旦不清,任务越拆越乱;一旦清楚,很多原本看起来像模型能力问题的故障,其实都会退化成普通的软件工程问题。
