“查一下订单,如果可以免费取消就取消,再看看明天的房间。”这句话里至少有查询订单、取消订单和查询房间三个目标。如果识别器只返回三个标签,系统仍然不知道先做什么、什么情况下取消,以及取消失败后是否继续查房。
本文介绍如何用任务图表示复合意图中的任务、参数、依赖和条件,并提供校验与回放代码。通过这些例子,可以了解多标签分类与任务规划的区别,以及先后、条件和备选关系的表示方法。
下载任务图 Schema、示例与测试代码。它与多轮状态文章共用酒店业务标签,但使用独立的 task-graph/2.0 契约,保留第一批接口不变。
一、区分多参数、多意图与同类多任务
| 输入 | 实际结构 | 不应怎样处理 |
|---|---|---|
| 订北京酒店,明天入住,住两晚 | 一个目标、多个参数 | 给每个参数都建一个意图 |
| 查订单,也告诉我早餐时间 | 两个不同目标 | 只保留最后一句 |
| 北京订一间,上海也订一间 | 两个同类任务 | 用标签集合去重成一个预订 |
多标签分类通常回答哪些类别存在;任务抽取还需要回答有几个任务、各自参数是什么、彼此有什么关系。两者可以协作,但输出的信息量不同。
第一批契约使用意图数组下标绑定参数,并禁止重复标签。它可以表示部分多意图请求,但无法完整表示两个独立的预订任务。本篇增加稳定任务 ID,让标签描述任务类型,ID 标识具体任务。
二、任务之间的依赖关系
复合请求常见几种关系:并列、先后、条件和备选。
“查订单,也查房间”可以是并列;“先查订单,再告诉我它的取消规则”有信息依赖;“免费才取消”有业务条件;“没双床就看看大床”则有备选分支。
列表排在前面,不一定意味着后一个必须等前一个成功。数据库查询可以并行,但展示顺序仍然固定;反过来,模型输出数组里相邻的两个任务,可能有非常强的依赖。
因此应把依赖显式写出来。也应保留不确定性:“取消以后再查房”究竟要求取消成功,还是只要求取消流程结束?如果这个差异影响业务行为,就需要追问或由明确的产品约定处理,程序不应自行假定用户选择了哪一种处理方式。
三、构建任务图
为了消除“再看看”的歧义,示例采用明确表达:
先查订单 DEMO-A。如果可以免费取消,就取消。无论是否取消,都查一下上海明天的房间。
任务关系如下:

订单查询后,取消受免费条件约束,查房独立继续
三个任务分别保存参数。取消任务依赖查询结果;查房也在查询之后进行,但不会因取消条件不成立被跳过。完整结构如下:
{
"schema_version": "task-graph/2.0",
"status": "known",
"question": null,
"tasks": [
{
"id": "lookup",
"intent": "order_query",
"params": {"order_id": "DEMO-A"},
"depends_on": [],
"guard": null
},
{
"id": "cancel",
"intent": "cancel_booking",
"params": {"order_id": "DEMO-A"},
"depends_on": ["lookup"],
"guard": {
"source_task": "lookup",
"field": "can_cancel_free",
"equals": true
}
},
{
"id": "rooms",
"intent": "room_search",
"params": {"city": "上海", "check_in": "明天"},
"depends_on": ["lookup"],
"guard": null
}
]
}
“明天”保留为用户表达,进入真实查询之前仍需按会话时间和时区归一化。图中的参数只表示识别到的信息,不证明业务参数已经完整有效。
四、验证执行条件
第一批用自然语言保存条件,避免识别时丢失约束。本篇对一个具体条件进一步结构化:从订单查询结果读取布尔字段 can_cancel_free,与 true 比较。
这是教学业务接口的约定,不是所有酒店 API 都有的通用字段。真实应用可能需要同时查询订单产品、取消政策、当前时间和费用,再计算这个事实。计算结果需要可靠的数据来源和有效期,不能仅依据用户所说的“免费”。
代码不会执行任意条件字符串,也不支持模型生成 Python 表达式。当前只允许订单查询提供这个条件,并检查查询与取消指向同一订单,防止错误使用其他订单的查询结果。
条件有三种状态:已知为真、已知为假、尚无证据。“没有查到”不等于 false,也不等于默认 true。第三种状态应等待、重查或澄清,而不是直接进入执行。
五、任务图的结构与语义校验
JSON Schema 可以约束字段与类型,但仅靠它难以表达所有跨节点关系。附件的校验器检查:
- 任务 ID 唯一,标签与参数属于允许目录。
- 依赖引用的任务存在,不能依赖自己。
- 图中不存在循环依赖。
- 条件来源必须是显式依赖,并且具备对应的事实能力。
- 免费取消的事实必须与取消任务指向同一订单。
- 未能明确解释的请求,只返回澄清问题,不混入待执行任务。
例如 A 等 B、B 又等 A,程序永远无法开始。又如条件引用一个不存在的 lookup2,即使 JSON 格式正确,也不可能得到证据。
结构正确与语义正确需要分别检查。比如模型漏掉“不要取消”,仍可能生成一张内部一致的取消任务图。结构校验负责发现坏引用和循环,语义校验负责确认任务是否忠实表达了用户需求。
六、为同类任务分配独立 ID
“北京订一间,上海再订一间”的结构可以是:
{
"schema_version": "task-graph/2.0",
"status": "known",
"question": null,
"tasks": [
{"id": "beijing", "intent": "book_room", "params": {"city": "北京"}, "depends_on": [], "guard": null},
{"id": "shanghai", "intent": "book_room", "params": {"city": "上海"}, "depends_on": ["beijing"], "guard": null}
]
}
这里按明确的先后解释“再”;如果业务不应要求北京预订成功才能安排上海,则应先确认或改用不同依赖语义。实际系统应区分“等待完成”和“等待成功”,本文的最小示例只把 completed 视为调用方确认成功完成的任务集合。
跨轮修改时,任务 ID 更重要。用户说“上海那间改成双床”,应该更新上海任务,不能仅凭标签 book_room 找到第一个预订就修改。
七、处理否定、冲突与备选分支
“不要取消,只查订单”应只生成查询任务。把取消节点放入图,再给它加一个永远为假的条件,会增加误用机会,也把明确否定混成了业务条件。
“取消 DEMO-A,同时把它改到明天”涉及同一订单的冲突目标。除非用户明确表达了备选或先后意图,否则应该澄清。例如询问“你希望取消这笔订单,还是保留订单并改期?”
“有双床就订双床,没有就订大床”需要有优先级且互斥的备选分支。当前教学图没有实现通用 AND、OR、ELSE,也没有实现分支汇合。需要这些能力时,应扩展版本化契约和测试;两个预订节点必须设置互斥条件,否则可能同时下单。
八、运行条件分支示例
在解压后的工程根目录执行:
python3 batch2/task_graph.py
python3 batch2/tests.py
第一条命令使用人工构造的任务图,分别回放条件证据缺失、为假和为真的情况:
| cancancelfree | cancel 节点 | rooms 节点 |
|---|---|---|
| 缺失 | waiting_evidence | read_candidate |
| false | skip_condition_false | read_candidate |
| true | requires_business_validation | read_candidate |
这张表来自实际运行结果。这里用模拟查询结果演示分支如何变化,代码不连接真实订单。
其中 read_candidate 只表示依赖已经满足,可以交给业务路由进一步处理;requires_business_validation 明确表明写操作还要验证参数、权限、费用和确认状态。任何字段都不代表订单已经取消。
九、任务图、调度与执行的分工
任务图描述用户希望完成什么,调度系统决定如何安排执行,工具服务负责具体动作与结果。把三者分开,可以分别检查漏识别、错误调度和工具故障。
真实服务还要补齐任务持久化、幂等键、失败重试、取消传播、结果过期、授权与执行审计。对于部分成功的请求,需要向用户解释哪些已完成、哪些失败;不能在一个节点失败后笼统地返回“操作失败”,也不能把整个计划宣称成功。
第一批的 slot_updates 与本篇任务图也不能直接混用。前者更新对话状态,后者描述复合需求结构。工程中可增加显式适配层,将识别到的任务 ID 绑定到状态与执行记录;接口字段的含义发生变化时,应更新版本并提供迁移说明。
十、复合意图测试方法
至少准备几组成对案例:有条件与无条件、条件为真与缺失、同标签的一个任务与两个任务、有顺序与无顺序、明确否定与真实取消、指代唯一与多个候选。
测试应分层进行。先检查识别器是否保留任务和关系,再检查校验器是否拒绝无效任务图,再用模拟事实验证分支。最后才验证真实工具执行、失败恢复和权限控制。用预设任务图做回放,不能替代第一层的模型识别测试。
复合意图识别需要记录每个任务的 ID、参数和依赖关系。任务图将这些信息明确表示出来,便于校验,也便于发现需要向用户澄清的内容。
继续阅读:标签体系设计、多轮状态与任务恢复、未知意图与澄清。