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 再次执行同一组校验。通过后,才保存权威的 ResearchTaskSpec 和 ResearchPlan。这时的 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时,尚未搜索资料或调用工具。
参考资料
- GitHub Spec Kit:Specification-Driven Development:规格、计划与任务拆分的关系。
- OpenAI:A practical guide to building agents:以用户目标组织 Workflow 的方法。
- JSON Schema:Required Properties:对象属性与必填字段的校验规则。