Agent 任务规划与执行计划
一个能执行的计划,需要比“先分析、再检索、最后总结”更具体。系统必须知道成功是什么、每一步依赖什么、哪些结果值得复用,以及偏离目标之后怎样处理。计划因此可以实现成一份有版本、可校验的运行时对象;展示给用户的步骤列表只是它的一种视图。
本文用导购任务说明这些机制。示例中的商品、日期和字段用于设计演示,不代表真实业务数据。
1. 先判断是否需要动态规划
多步骤并不自动意味着要使用 Agent。只要步骤和分支能够稳定枚举,工作流、状态机和普通代码就可以实现,通常也更容易检查。
动态规划更适合运行中才知道的信息会改变路径的任务:缺失条件是否必须追问、哪类证据需要补充、候选工具是否能替代、用户的新要求影响哪些中间结果。即使存在这些问题,稳定的主干仍可保留为工作流,只把无法预先确定的语义判断交给模型。
| 任务特点 | 起步选择 |
|---|---|
| 一次查询或简单生成 | 单次调用及必要校验 |
| 步骤固定、接口和条件明确 | 工作流或状态机 |
| 目标明确,但路径依赖运行时证据 | 工作流结合局部执行循环 |
| 长任务且有多个阶段和依赖 | 显式计划、检查点及恢复机制 |
计划增加了生成、审查和维护成本。应当通过任务成功率和恢复能力证明它的价值,而不是以步骤多、图复杂作为成熟度指标。
2. 用 G4C 检查计划是否完整
G4C 是一种方便组织设计问题的助记框架,并非行业统一标准。它把计划拆成目标、上下文、选择、检查点和纠偏五部分。
| 要素 | 应保存的信息 | 常见缺陷 |
|---|---|---|
| Goal | 用户目标、交付物、成功判据 | “效果好”“更专业”等无法检验的要求 |
| Context | 已知事实、缺口、假设、硬约束和偏好 | 把推测当成规划前提 |
| Choice | 路径、步骤依赖、简要决策依据 | 只列动作,不说明为何需要 |
| Checkpoint | 检查位置、规则和证据要求 | 最后才发现上游数据有误 |
| Correction | 重试、澄清、局部重规划或停止条件 | 每次失败都从头再来 |
例如“推荐更划算的裤子”仍然不够明确。可以将目标细化为:返回至多三款同类商品,满足用户确认的尺码、预算和配送日期,并解释与参考商品的差异。若没有足够候选,则返回实际数量和缺失原因,不能为凑数放松硬约束。
模型可以提出成功标准,但不能擅自把它提升为用户要求。若用户没有说明价格上限,系统可以按参考价格排序并披露假设;涉及采购、支付等正式操作前,再确认所需条件。
3. 把业务约束写进可检查的计划
下面给出一个简化结构。目标和约束引用稳定 ID,步骤引用前置产物,便于后续定位影响范围。
{
"plan_id": "recommendation_12",
"version": 1,
"goal": "给出满足已确认条件的裤装候选",
"constraint_version": 3,
"success_checks": [
"所有候选通过硬约束校验",
"每款商品有价格与履约证据",
"未确认信息明确披露"
],
"steps": [
{
"id": "resolve_requirements",
"depends_on": [],
"output": "requirements",
"on_failure": "clarify"
},
{
"id": "search_products",
"depends_on": ["resolve_requirements"],
"output": "candidates",
"on_failure": "retry_or_alternative"
},
{
"id": "verify_fulfillment",
"depends_on": ["search_products"],
"output": "eligible_candidates",
"checkpoint": "size_stock_delivery"
},
{
"id": "rank_and_explain",
"depends_on": ["verify_fulfillment"],
"checkpoint": "final_constraints_and_evidence"
}
]
}
规划器负责提出这个结构,运行时负责验证和执行。on_failure 是受控的恢复策略名称,不应允许模型输出任意代码。目标、约束和授权也应分别管理:目标没有改变,不代表当前授权仍然有效;生成了“下单”步骤,更不代表用户同意下单。
已知事实和假设需要分栏保存,例如“用户当前选择 M 码”和“历史通常购买 M 码”。约束进入每次相关决策的上下文,同时还要在查询参数、候选过滤和执行网关中校验。仅在提示词中反复强调,无法替代系统约束。
4. 检查点要拦住错误扩散
检查点的作用是检查一个产物是否足以支持后续步骤。它应放在高影响的边界:关键事实确认后、候选集形成后、对外写入前,以及一个阶段即将交接时。数量由风险和依赖决定,没有统一的“每三步检查一次”规则。
检查也需要分层。字段是否存在、金额是否超限、文件是否在允许范围内,可以用代码验证;推荐解释是否得到证据支持,可能需要语义评估与抽样人工复核。让生成计划的模型再看一遍,不能视为独立证明。
{
"checkpoint_id": "size_stock_delivery",
"plan_version": 1,
"result": "failed",
"issues": [
{
"candidate_id": "product_B",
"rule": "delivery_before_deadline",
"evidence_id": "delivery_quote_42",
"observed": "到货日期超过用户要求"
}
],
"suggested_action": "replace_candidate"
}
这个失败不必让整个任务重来:参考商品、用户尺码和城市仍然可用,重新寻找受影响的候选即可。检查结果要包含时间、数据版本和证据引用,因为库存、政策或用户约束变化后,过去通过的检查也可能失效。
5. 线性步骤何时升级为 DAG
线性计划简单,适合串行依赖明显、执行量较小的任务。只有确实存在独立工作、并行收益或复杂依赖时,再使用有向无环图(DAG)。
例如候选商品已确定后,价格信息与配送信息可以分别查询,汇合后再过滤。但“没有数据依赖”还不够:两个节点若写同一份状态、争用配额,或有业务顺序要求,仍然需要串行、隔离或冲突解决机制。
确认条件 → 检索商品 ┬→ 查询价格 ─┐
└→ 查询配送 ─┴→ 过滤并排序 → 输出校验
模型生成依赖关系后,代码至少应检查节点 ID 唯一、引用存在、无循环、目标可达,以及输入输出是否匹配。调度器还需定义汇合规则:依赖全部成功才能继续,还是允许部分结果?节点失败后取消哪些后继?已经运行中的后继怎样停止?
不宜把循环恢复直接画成普通 DAG 的回边。可以保持每个计划版本是 DAG,将重试和重规划放入外层状态机;新计划使用新版本,并明确旧节点的终止和复用状态。
节点至少区分等待依赖、就绪、执行中、成功、失败和取消。失败节点的后代不能只因为“等待时间足够长”就继续执行;调度器应检查它们需要的产物是否仍然有效。一个节点有多个前置步骤时,必须明确是全部完成才能就绪,还是特定分支成功即可推进。
可运行的节点记录还应包含输入引用、输出格式、工具资格、超时、重试策略和幂等要求。状态改为成功时,需同时关联可读取的产物与执行回执;只有内存里的布尔标记而没有产物落盘,会导致重启后出现“步骤已完成,但结果找不到”。对于并发产生的输出,应预先规定写入命名空间、合并规则和版本冲突处理,而不是让后完成者任意覆盖前一个结果。
6. 审查计划,并限制修订循环
较复杂任务可以在执行前增加“生成—校验—修订”。校验器先做结构和确定性规则检查,再对目标遗漏、证据不足、步骤缺失等语义问题给出具体意见。
生成候选计划
→ 校验结构、约束、工具资格和依赖
→ 存在可修复问题:按问题清单修订
→ 存在关键缺口:澄清或返回阶段性方案
→ 校验通过:保存版本并进入执行
每轮修订都应指向一个可解释的问题。总轮数、时间和 token 预算由调度器限制,不能只写在提示词里。反复修订而没有减少问题时,应停止并暴露缺口。对于信息简单、风险低的任务,不需要额外搭建多模型评审流程。
计划执行期间,用户可能新增条件。此时先更新约束版本,阻止不再满足条件的待执行节点,再分析已有产物是否需要失效。更多恢复细节见动态重规划与长任务恢复。
7. 如何证明计划有帮助
离线测试应覆盖“正常完成”和“前提变化”。例如工具超时、返回空数据、候选不足、用户中途排除某品牌、实时状态过期。对每个案例检查目标是否保留、关键约束是否可执行、依赖是否合理、错误能否在扩散前被发现。
线上指标应区分计划完成与任务成功。所有步骤都显示完成,仍可能没有满足用户要求。可同时记录计划结构通过率、硬约束违规率、检查点漏检、步骤成功率、恢复成功率、最终任务成功率,以及延迟和成本。
重规划次数也需要结合原因解释:次数下降可能说明初始计划更好,也可能说明系统不再发现问题。评价应回到具体产物和用户目标,而不是追求某个中间数字越低越好。
计划定义整体路径,执行循环与工具选择决定下一步如何行动。两者共享同一份目标、约束和证据,才能在运行中保持一致。