设计意图识别系统时,应先明确标签定义,再选择模型。假如“取消收费吗”和“帮我取消”都被标成“取消订单”,模型把它们分到一起完全符合训练数据,业务却可能因此误操作。
这篇文章从酒店预订与售后场景出发,给出一套可复用的标签定义方法:如何选择粒度,如何划分意图与槽位,何时需要层级或多标签,以及业务变化后如何维护版本。配套文件包含 7 个标签的定义、正例、反例、允许槽位和能力边界。
下载标签规范、基线代码与任务依赖示例。系列总览见大模型对话系统中的意图识别。
一、根据业务流程划分意图
划分意图时,可以比较两种请求的处理流程、参数要求、权限和完成标准。差异明显时,通常应分成不同标签;如果只是城市或日期不同,则可以用同一意图下的槽位表示。
例如:
| 表达 | 系统需要做什么 | 标签 |
|---|---|---|
| 取消预订会收手续费吗 | 查询规则并解释 | policy_query |
| 帮我取消订单 DEMO-A | 核验订单与条件,进入取消流程 | cancel_booking |
| 取消后退款多久到账 | 查询退款时效或流程 | refund_query |
| 不要取消,只查一下订单 | 查询已有订单 | order_query |
不能简单按主题词划分。上面四句都可能含有“取消”,但查询规则、执行取消、退款咨询与订单查询承担不同职责。
也不应把每个 API 都变成一个用户意图。用户想“查订单状态”,后端可能先查订单、再查支付、再查履约;这些是实现步骤。如果直接用内部 API 名称作为标签,后端接口调整时,标签体系也需要跟着修改。
二、区分意图与槽位
“订北京酒店”和“订上海酒店”通常共享 book_room,城市放进槽位。如果把每座城市都建成一个标签,新城市上线时就必须增加类别、重标数据和重新评估模型。
槽位不仅是从文字中找到实体,还要确定实体在任务中的角色。“从北京出发去上海”有两个城市,但只有任务定义才能决定哪个是出发地、哪个是目的地。酒店例子则需要明确是在查询哪座城市的房源。
一个标签可以写成:
{
"id": "book_room",
"version": "1.0",
"path": "transaction/booking",
"definition": "建立新的酒店预订目标",
"includes": ["我要订房", "预订尚未提交,入住改成后天"],
"excludes": ["现有订单改期", "只想看看房价"],
"allowed_slots": ["city", "hotel", "check_in", "check_out", "room_type"],
"write_capability": true
}
这里把“预订尚未提交,改入住日”放在预订里。只有修改已有订单时,才进入 change_booking。因此标签不能只由当前句子决定,还需要知道任务处于哪个阶段。
附件中的 teaching_required_slots 仅用于教学状态机计算缺失参数。真实预订还可能需要具体产品、入住人、价格、支付方式等信息;示例中的必填字段齐全,只表示可以进入后续业务校验。
三、选择合适的分类粒度
过粗的标签把不同业务分支混在一起,后续仍需第二次识别。比如“售后”可能包含取消、改期、退款咨询与投诉,如果下游不知道应走哪个流程,这个分类就没有提供足够信息。
标签划分过细时,相近类别可能难以区分,标注一致性也更难保证。“询问早餐时间”和“询问退房时间”如果都由同一个政策检索模块处理,可以先共享 policy_query,把主题作为 topic。若后续两类能力有不同数据、合规要求或业务指标,再考虑拆分。
判断是否拆分类别时,可以检查:
- 是否存在稳定、可解释的用户目标差异。
- 下游能否据此减少歧义或选择不同能力。
- 标注者能否根据对话证据一致地区分。
- 每类是否有足够样本,新增类别的维护收益是否明确。
“模型分不开”并不自动说明应该合并,也可能是数据不足。相反,“模型能分开”也不自动说明有必要拆成业务标签。先确定处理需求,再检查模型能力。
四、编写标签定义
除了标签名称,还需要说明适用范围、反例和冲突处理方式:
| 项目 | 需要写清楚的内容 |
|---|---|
| 稳定 ID | 代码与历史数据使用的标识,不随展示名称变化 |
| 定义 | 用户要达到的目标 |
| 正例 | 多种自然表达和必要的上下文 |
| 排除项 | 最容易误入的相似请求 |
| 允许槽位 | 该任务可以接受哪些参数 |
| 阶段约束 | 是否要求已有订单、是否允许继续未完成任务 |
| 能力边界 | 只查询、允许变更,还是系统暂不支持 |
| 不确定处理 | 证据不足时补什么信息、何时澄清 |
| 版本 | 定义何时生效,哪些旧数据需要复核 |
正反例最好成对出现:“取消 DEMO-A”与“先别取消 DEMO-A”,“查房价”与“按这个价格预订”。只提供典型正例,无法说明相似请求应该如何区分。
不要把不存在于输入或上下文中的事实写进答案。如果数据标注必须依靠标注者猜测,应该改成澄清样例,或补充真实可用的上下文。
五、酒店业务标签示例
| ID | 目标 | 重点排除 |
|---|---|---|
policy_query | 咨询设施、入住与取消规则 | 实际操作、退款专门流程 |
room_search | 查询尚未购买的房间、房型和报价 | 提交预订、查询已有订单 |
book_room | 建立新预订及编辑提交前参数 | 修改已有订单 |
order_query | 查询已有订单信息或状态 | 修改订单、退款专门进度 |
change_booking | 修改已有预订 | 新建另一笔预订 |
cancel_booking | 请求取消已有预订 | 咨询规则、被否定的取消 |
refund_query | 咨询退款流程、金额和到账 | 直接付款或发起退款 |
这里对退款咨询单独分类,是示例的业务设计选择。另一个系统可能把它归入订单查询的子类。只要定义一致、处理路径合理,两种设计都可以成立;不应把本表当作所有酒店系统的标准答案。
六、层级分类与多标签分类
层级用于组织从粗到细的概念。例如 information/order、information/policy、transaction/cancellation。它可以帮助导航、分层分析错误和管理团队职责。
但是否采用两阶段分类需要实测。先把请求错分为 information,后续只在信息类里选叶子标签,会将第一次错误传递下去。小规模标签目录可以直接预测叶子 ID,层级只作为管理结构。
多标签则表示同一输入提出多个目标:“查订单,并告诉我早餐时间”。它不是层级更深,而是同时存在两项任务。
还有一种情况是同类多任务:“北京订一间,上海再订一间。”如果用集合保存 {book_room},任务数量就丢失了。应为任务分配独立 ID,再分别保存参数。具体结构见多标签、条件与任务依赖。
七、区分未知意图、歧义与参数缺失
“我要订房”目标明确但缺城市与日期,应继续补槽。“把那个取消”在有两笔订单时是指代歧义,应询问目标。“开一张发票”在没有开票能力的系统中,则是范围外请求。
这三种情况应使用不同的状态字段表示。如果全部归为 unknown,下游程序就无法判断应该补充参数、澄清对象,还是说明当前不支持该功能。
还需要区分语义范围与临时可用性。系统支持查订单,只是订单服务此刻超时,意图依然是 order_query;这是服务失败,不该被重新标成范围外。反之,系统从来没有开票能力,即使模型能识别开票需求,也应返回当前不支持该功能。
对于“以后叫我大英雄”,综合助手可以交给偏好模块;酒店业务识别器可以报告当前范围不支持。能力目录不同,合理标注也会不同。
八、标签变更与数据迁移
设想后来上线了发票功能。旧数据中的“开住宿发票”原来是范围外,新版本要改成 invoice_request。正确做法是创建新标签版本,列出受影响样本,并在新能力已经可用后切换路由。
如果将一个粗标签拆成两个细标签,旧标签往往无法自动映射到唯一的新标签。需要回看原文和上下文,不能只做字符串替换。合并标签虽然容易映射,也可能改变历史指标的分母与业务意义。
可采用以下迁移步骤:先建立新定义与差异说明,抽样复标;再以新旧定义分别回放固定数据,检查路由变化;随后更新标签、模型、Prompt、数据与接口版本;保留回滚所需的旧版本。历史报表使用哪个标签版本也要记录。
九、统一代码中的标签定义
附件 batch2/data/taxonomy.json 保存完整目录,叶子 ID 与第一批 core.py 保持一致。可以在工程根目录检查:
import json
from pathlib import Path
from core import LABELS, SLOTS
catalog = json.loads(Path("batch2/data/taxonomy.json").read_text())
assert {item["id"] for item in catalog["labels"]} == set(LABELS)
for item in catalog["labels"]:
assert set(item["allowed_slots"]) == set(SLOTS[item["id"]])
print("标签 ID 与允许槽位一致")
将标签规范、模型输入和服务校验共用同一份目录,可以避免不同模块使用不一致的定义。比如新增了一个槽位,更新规范之后应同步生成 Prompt 和校验规则,而不是分别维护三份字符串。
标签定义应同时用于数据标注、模型识别和业务处理。把容易混淆的请求整理成正反例,再据此补充语料和比较模型,才能判断改进是否有效。
继续阅读:复杂意图语料、三种基础识别方法实测、未知意图与澄清策略。