分解不是把句子拆短
分解的目的不是让模型“看起来有计划”,而是降低每个节点的不确定性并暴露控制点。以“完成供应商风险评估”为例,“研究供应商”“分析风险”仍不可执行;“从指定来源提取近 12 个月安全事件并产出带引用的事件表”才有输入、边界和可验收产物。
一个节点应尽量由单一责任主体闭环完成,失败可局部重试或替换,产物能被下游引用。分解后的所有终端产物合并后必须覆盖原始成功条件;否则只是把责任空洞藏进多个节点。
从列表升级为依赖图
顺序列表只能表达先后,任务图还要表达数据、控制、资源和审批依赖。Planner 可以提出候选图,但 Runtime 必须校验无环、引用有效、预算可行,并把图转成唯一状态源。
数据依赖、控制依赖、资源依赖和审批依赖
数据依赖要求上游产物作为输入;控制依赖要求某条件成立后才能运行;资源依赖来自配额、锁、工作区或同一外部账户;审批依赖要求人在看过绑定参数的预览后作出决定。把四者都写成“dependsOn”会让调度器无法正确判断并行、安全与取消。
无依赖任务并行,避免为并行而复制上下文
并行的前提是输入已经冻结、写集不冲突、结果能独立验收。共享一份会变化的 Scratchpad 或向所有节点广播全部对话,会把理论并行变成隐式竞争。独立输入加 Artifact 引用比复制父级上下文更可控。
关键路径决定整体延迟和优先级
关键路径是决定最早完成时间的最长依赖链。优先优化不在关键路径上的节点可能没有端到端收益;相反,提前启动长延迟检索、审批或外部批处理,常比盲目增加并发更有效。运行时应记录估算与实际时长,用历史数据修正计划。
汇聚节点校验完整性、冲突和缺失
Join 不是拼接字符串。它要检查必要节点是否到达可接受终态、Schema 是否兼容、事实是否冲突、来源是否过期,以及失败节点是否允许部分交付。最终决策主体对汇聚后的覆盖范围负责。
子任务契约让计划可执行
下面是精简的 TypeScript 领域模型。它是教学用可执行片段,省略持久化与分布式锁;关键点是把计划和运行事实分开,模型只能生成 TaskSpec,Runtime 才能改变 TaskState。
type TaskState = 'blocked' | 'ready' | 'running' |
'succeeded' | 'failed' | 'cancelled' | 'waiting_approval';
type Dependency = {
taskId: string;
kind: 'data' | 'control' | 'resource' | 'approval';
};
interface TaskSpec {
id: string;
objective: string;
nonGoals: string[];
dependencies: Dependency[];
inputArtifacts: string[];
outputSchema: unknown;
acceptance: string[];
allowedCapabilities: string[];
budget: { deadlineMs: number; maxAttempts: number; maxCost: number };
}
interface TaskRecord {
spec: TaskSpec;
state: TaskState;
planVersion: number;
attempts: string[];
outputArtifacts: string[];
failureCode?: string;
}
完成标准不能只写“生成高质量报告”。它应落到可检查字段、引用覆盖、测试通过或业务状态。失败契约则要区分可重试技术错误、不可重试业务错误、部分完成、等待外部条件和需要人工升级。
Planner 提方案,Runtime 决定能否执行
模型擅长提出语义分解,却不适合独占调度权。Runtime 至少执行四层校验:Schema 有效;图无环且引用存在;每个节点的权限、数据边界与预算合法;整体任务数、深度、并发和累计成本不过限。
高风险节点还要经过策略决策与审批。Planner 不能通过把一个受限动作改名、拆成多个小动作或委派出去来扩大权限;能力预算需要沿任务图向下收窄。
| 问题 | Planner | Runtime |
|---|---|---|
| 要做什么 | 候选任务与语义依赖 | 校验目标覆盖和节点契约 |
| 何时运行 | 优先级建议 | 就绪条件、队列、公平性和资源 |
| 能否执行 | 说明所需能力 | 鉴权、策略、预算和审批 |
| 是否完成 | 解释结果 | 校验产物、回执和后置条件 |
重规划由可观察偏差触发
触发条件应来自状态差异,而不是固定每 N 步“反思”:前置假设被权威事实证伪;工具、资源或数据源不可用;节点产物未通过契约;新信息改变优先级;预算消耗与剩余价值失衡;用户修改目标或取消授权。
触发事件应包含原因码、证据引用、受影响的假设和建议范围。只把一段错误文本丢回 Planner,会让它无从判断是换参数、换工具、插入取证任务,还是终止并升级。
优先局部修复,不无条件推倒重来
先找出直接依赖错误假设或失败产物的下游闭包,标记为失效;已通过独立验证且不依赖该假设的产物继续保留。正在执行的节点按取消语义处理,已经发生的副作用进入账本,绝不能因为任务图被替换而消失。
- 冻结当前计划版本和运行快照;
- 识别触发证据、错误假设和受影响节点;
- 保留已验证 Artifact、审批和外部回执;
- 生成最小补丁:替换、插入、取消或调整依赖;
- 重新校验图、权限、预算与关键路径;
- 原子发布新版本并记录 Why。
计划版本是审计边界。节点结果必须标记产生它的计划版本与输入 Artifact 版本,避免旧任务晚到后污染新计划。
任务图的反向验收
| 反向问题 | 失败信号 | 修复 |
|---|---|---|
| 删除节点会丢失哪项成功条件? | 无法回答,节点只是装饰 | 删除或合并 |
| 每个节点如何证明完成? | 只能由生成者自评 | 增加 Schema、测试、引用或外部回执 |
| Join 遇到冲突怎么办? | 默认让模型“综合” | 定义权威性、时效、升级与部分交付规则 |
| 最坏情况下如何停止? | 递归新增节点或无限重规划 | 全局预算、深度、Deadline 和人工接管 |
实践验收应做故障注入:让一个关键数据源返回过期结果、让一个并行节点超时、让旧版本结果晚到,再检查计划补丁是否只失效必要范围、最终结果是否遗漏,以及 Trace 能否解释每次变更。
主动提取:为什么“按角色拆成研究员、分析师、写作者”不一定是好的任务分解?
迁移判断:某节点已成功写入外部系统,但上游假设后来被证伪,能直接把节点状态改回 pending 吗?
资料与事实边界
以下以官方文档、标准、论文和原始工程资料为主。厂商 API、价格、限额与模型能力会变化,落地时仍需按目标版本做能力探测和回归。
- Anthropic:Building Effective AI Agents — Prompt chaining、并行、Orchestrator-workers 与按证据增加复杂度
- Anthropic:How we built our multi-agent research system — 动态分解、委派契约、重复工作与规模控制的原始工程报告
- OpenAI Agents SDK:Agent orchestration — 模型编排与代码编排、串行和并行模式的官方边界