Task 不是 Request:从用户目标到可验收任务

从用户目标到 Spec 与 Plan:任务何时可以进入 ready

前两篇讨论了一次 LLM call:应用发送 API Request,模型基于 Context 生成 Response。第三篇往前走一步:用户给出的是一句目标,应用怎样判断它已经可以开始执行?

继续使用统一案例:

调研三个主流 Agent Runtime,并给出选型建议。

直接把这句话交给模型,模型能写出一篇像样的回答。但系统仍不知道“主流”指谁、资料截至哪天、哪些来源可用、报告交给谁,以及什么条件满足后才算完成。一个 completed 的 Response 解决不了这些问题。

本文只讲 C03 的准备过程。它不搜索资料、不调用工具,也不生成调研报告。它的产物是一份经过校验的 Spec 与 Plan,状态为 ready

用户目标
  → LLM 生成候选 Spec 与 Plan
  → Runtime 校验
  → 缺信息则澄清
  → 保存 Spec 与 Plan,进入 ready

这里的“用户目标”是用户在产品里提出的请求;“API Request”则是应用发给模型服务的一次调用。名字接近,层级不同。

C03 要解决什么

先把四个对象分开:

对象 回答的问题 C03 中的例子
用户目标 用户想得到什么? 做出 Agent Runtime 选型
Spec 系统承诺交付什么,怎样算完成? 研究对象、来源规则、验收条件
Plan 准备按什么顺序完成? 取证、整理、比较、检查
API Request 这一次让模型计算什么? 提取候选 Spec Plan 或修订它

Spec 固定交付边界,Plan 描述当前路径。两者都由模型提出候选,但不能由模型单独定稿。

本文借鉴了 GitHub Spec Kit 的规格驱动思路:先从模糊描述形成 Spec,再生成 Plan,最后才能派生可执行任务。Spec Kit 的具体命令、模板和 Git 工作流主要服务于软件功能开发;C03 只借用这组分层关系,用它解释 Agent 如何把用户目标收敛为可执行定义。它是一个有用的实现方式,不是唯一方式。

第一次调用:生成候选,而不是开始调研

应用向模型提交原始目标、开发者指令和输出 Schema。指令要限制模型的行为:只提取用户已经说清的信息;未知字段保留为空,并列入 missing。模型不能擅自决定研究对象或验收标准。

在 C03 中,Schema 约束的候选大致长这样:

{
  "goal": "调研三个主流 Agent Runtime,并给出选型建议。",
  "targets": [],
  "dimensions": [],
  "as_of": null,
  "source_requirements": [],
  "deliverable_format": null,
  "audience": null,
  "acceptance_criteria": [],
  "plan_steps": [],
  "missing": [
    "targets",
    "dimensions",
    "as_of",
    "source_requirements",
    "deliverable_format",
    "audience",
    "acceptance_criteria"
  ]
}

Schema 只保证结果可以被程序读取。它不会让“主流”自动变成三个确定的产品,也不会让“选型建议”自动具备验收标准。候选还不是任务契约。

Runtime:决定澄清还是 ready

模型返回候选后,Runtime 要做三类校验:

校验 检查内容
validate_spec 目标、范围、来源、交付物和验收条件是否齐全且可检查
validate_plan 每条验收条件是否有 Plan Step 负责
validate_dependencies Step 的依赖是否存在,且没有循环

JSON Schema 擅长检查结构,例如 targets 是否是数组、日期是否符合格式。它不理解“报告要专业”无法验收,也无法判断 Plan 是否漏掉了“人工审批”这一维度。这些是 Runtime 的业务规则。

第一轮缺信息时,Runtime 把错误变成澄清问题,例如:

请确认三个研究对象、比较维度、资料截止日期和来源规则。报告给谁使用?哪些条件满足后可以交付?

低风险的默认值可以记录下来;会改变范围、成本、写入权限或验收标准的内容,应由用户确认。

第二次调用:修订候选 Spec Plan

用户补充信息后,应用再次调用 LLM。这次 Context 包含原始目标、第一版候选和用户回答。模型据此修订字段和 plan_steps,例如:

goal: 为内部研究系统选择 Agent Runtime
targets: [OpenAI Agents SDK, LangGraph, Google ADK]
dimensions: [状态管理, 持久化, 人工审批, 可观测性]
as_of: 2026-08-21
source_requirements:
  - 功能事实优先使用官方文档,并保存链接和访问日期
deliverable_format: markdown
audience: 技术负责人和平台工程师
acceptance_criteria:
  - 三个对象均覆盖四个比较维度
  - 关键事实均可追溯到来源
  - 推荐结论写明适用前提、取舍和不确定项
plan_steps:
  - id: P1
    goal: 收集三个对象的官方资料
    depends_on: []
    expected_output: 三份证据包
    covers: [三个对象均覆盖四个比较维度]
  - id: P2
    goal: 提取四个维度的事实并保存来源
    depends_on: [P1]
    expected_output: 可追溯的比较材料
    covers: [关键事实均可追溯到来源]
  - id: P3
    goal: 生成比较矩阵和推荐草稿
    depends_on: [P2]
    expected_output: 报告草稿
    covers: [推荐结论写明适用前提、取舍和不确定项]
  - id: P4
    goal: 检查覆盖度、引用与推荐前提
    depends_on: [P3]
    expected_output: 验收记录
    covers: [三个对象均覆盖四个比较维度, 关键事实均可追溯到来源, 推荐结论写明适用前提、取舍和不确定项]

Runtime 再次执行同一组校验。通过后,才保存权威的 ResearchTaskSpecResearchPlan。这时的 ready 表示任务定义已就绪,不表示 P1 已执行,更不表示调研已经完成。

C03 的真实 Trace

C03 的完整 Python 示例代码见:c03-task-contract 示例仓库

下面是一次真实运行结果。三条事件已经足够还原状态变化:第一次提取发现缺口;用户补充后修订通过;最后由 Runtime 确认。

{"case": "C03", "event": "contract.extracted", "at": "2026-08-21T16:00:09.858880+00:00", "revision": 1, "response_id": "resp_0aae848e9a0061f9016a8876064bbc87d0808c398b499f444f", "status": "needs_clarification", "errors": ["请确认三个具体研究对象。", "请确认比较维度。", "请确认资料截止日期。", "请确认允许采用哪些证据来源。", "请确认交付格式与目标读者。", "请给出可检查的完成条件。", "请给出满足验收条件的执行步骤。"]}
{"case": "C03", "event": "contract.revised", "at": "2026-08-21T16:00:25.093238+00:00", "revision": 2, "response_id": "resp_055bcb12af112e20016a88760a7dc887d0a050b66c4c59aae8", "status": "ready", "errors": []}
{"case": "C03", "event": "contract.confirmed", "at": "2026-08-21T16:00:25.095987+00:00", "revision": 2, "status": "ready"}

第二条记录出现 ready,因为候选已经通过 Runtime 校验;第三条记录才将 revision 2 保存为权威版本。模型负责提取和修订,Runtime 负责状态更新。

Plan 不是执行 Loop

Plan 已经把大目标拆成了步骤,但它仍是一条待执行的路径。后续系统会把 P1~P4 拆成可调度的工作,再通过 Request、Tool Call 和 Observation 推进它们。

C03:Spec 与 Plan 已确认,状态 ready
下一阶段:执行 P1,读取结果,更新状态,再决定下一步

小结

第三篇的过程可以浓缩为一句话:LLM 把用户目标整理成候选 Spec Plan,Runtime 用规则和用户确认把候选收敛为可执行定义。

用户目标 → 候选 Spec Plan → 校验与澄清 → 权威 Spec Plan(ready)

下一篇进入执行层:模型返回 Tool Call 时,真正执行工具的又是谁?


案例实践清单

  • 保存原始用户目标。
  • 用 Schema 约束 LLM 生成候选 Spec 与 plan_steps
  • 将校验错误转成澄清问题,并记录用户补充。
  • 校验 Plan 对验收条件的覆盖和 Step 依赖。
  • 保存候选、权威 Spec Plan、Response ID 与 Trace。
  • 确认 ready 时,尚未搜索资料或调用工具。

参考资料