槽位填充(Slot Filling)是任务型对话 NLU 核心,目标是从用户语句提取指定语义字段;整个技术路线从早期 CRF 序列标注、BERT-CRF,演进到 Prompt 小样本、LLM 零样本、多轮对话状态跟踪 DST。传统 CRF 优点是稳定、可解释、延迟低,缺点是依赖标注、跨域弱;大模型 Prompt 路线擅长零 / 少样本、开放域,但存在幻觉、格式不稳定、上下文遗忘问题,工业落地一般采用小模型兜底 + 大模型做开放 / 难例的混合架构。下面按技术演进栈、多轮交互实现、Prompt 模板、优化方案、评测指标完整梳理。
一、技术演进路线对比
| 阶段 | 代表方案 | 核心原理 | 优势 | 短板 | 适用场景 |
|---|---|---|---|---|---|
| 传统统计阶段 | CRF、MEMM | 序列标注,建模标签转移依赖(B/I/O) | 推理快、可解释、边界可控 | 强依赖人工特征、泛化差、不能处理指代、省略 | 垂直固定域、标注充足、低延迟客服 |
| 预训练小模型阶段 | BERT-CRF、JointBERT、Span 抽取 | 预训练上下文向量 + CRF 做标签约束;或者 Span 边界检测 | 精度高、标注量中等、可控、可输出置信度 | 跨域、新槽位需要重新微调,新增槽改训练 | 成熟业务、中高并发、标准槽位 |
| Prompt 大模型阶段 | ICL、Few-shot Prompt、CroPrompt | 指令 + 示例,让 LLM 直接输出槽位 JSON | 零样本、新增槽不用训练、支持开放槽、理解指代 | 幻觉、格式乱、上下文长了遗忘、成本高 | 新业务快速上线、低资源域、开放槽、多轮指代 |
| 混合工业架构 | 小模型(BERT-CRF)主链路 + LLM 难例兜底 | 优先小模型,低置信 / 歧义 / 指代样本路由到大模型 | 兼顾延迟、成本、召回率 | 系统复杂度上升,需要置信度阈值、路由策略 | 绝大多数线上对话机器人 |
CRF 核心价值:建模标签转移约束,比如 B-loc 后面只能跟 I-loc,禁止非法标签跳转,解决局部分类器的标签偏见问题。
二、完整技术栈拆解
- 输入层:ASR 降噪、文本归一化、错别字纠错、时间窗口上下文缓存;多轮场景持久化对话状态(DST)
- 分支 1:传统序列标注链路
- Embedding:Word2Vec / ELMo / BERT
- Encoder:BiLSTM / Transformer
- Decoder:CRF,输出 IOB2 标签序列
- 后处理:规则校验、词典映射、归一化、同义词、正则校验(手机号、日期)
- 分支 2:Span 抽取链路(BERT-Span)
- 不做逐 token 标签,直接预测每个槽的 start、end 位置
- 适合长实体、嵌套实体,很多工业方案替代 CRF
- 分支 3:LLM Prompt 链路
- 检索增强 RAG:从样本库召回相似 Demo(Few-shot)
- Prompt 构造:任务指令 + 槽位 schema + 历史对话 + 示例 + 当前用户句 + 格式约束
- 输出解析:JSON/YAML 提取,格式校验、重试、自校验
- 后校验:值范围、枚举、知识库约束、类型校验
- 调度层(混合架构)
- 置信度阈值:小模型输出置信度高于阈值直接放行;低于阈值送入 LLM
- 特征路由:存在指代、省略、新词、跨域时,直接走 LLM
- 结果融合:两套输出做投票、冲突消解
- 存储 & 状态层:DST 对话状态,保存已填充槽、待澄清槽、用户历史、上一轮意图
三、多轮交互 DST 实现(重点)
多轮槽填充难点:用户经常省略、指代、更正、覆盖旧槽、反问澄清,不是单句独立提取。
- 对话状态数据结构
{
"intent": "book_flight",
"slots": {
"depart_city": "北京",
"arr_city": null,
"date": null,
"flight_class": "经济舱"
},
"history": [{"role":"user","utt":"..."}, {"role":"bot","utt":"..."}],
"pending_slots": ["arr_city","date"]
}
- 三种更新策略
- 增量继承(默认):本轮没有提到的槽,保留上一轮的值;提到新值则覆盖
- 全量重写:每一轮给 LLM 完整历史 + 全部槽位,重新输出整套 slots,适合频繁修改、纠正场景
- 差分更新:只让模型输出发生变化的槽,减少输出长度、降低幻觉
- 澄清交互流程
- 提取后检查 pending_slots,判断必填槽缺失
- 按优先级生成澄清问句(不要一次性问多个)
- 用户回答后,更新状态,再次跑槽填充
- 冲突检测:用户修改已有槽,直接覆盖;出现矛盾值触发确认
- 指代处理:Prompt 里显式要求 “结合上文指代,补全省略内容”,搭配示例演示指代场景
四、Prompt 模板实战(可直接上线)
基础模板(Few-shot ICL)
你是任务型对话NLU模块,做槽位填充。
【Schema】
意图:订机票
必填槽:depart_city出发城市, arr_city到达城市, date日期, flight_class舱位
可选槽:passenger_num人数
规则:
1. 用户没说的槽值填null;
2. 指代、省略必须结合对话历史补全;
3. 严格输出JSON,不要额外解释、不要markdown;
4. 槽值必须在枚举/合理范围内,识别不到写null。
【示例1】
历史:[]
用户:帮我订一张明天上海去广州的经济舱机票
输出:{"depart_city":"上海","arr_city":"广州","date":"明天","flight_class":"经济舱","passenger_num":null}
【示例2】
历史:[{"user":"帮我订机票","bot":"你从哪里出发?"},{"user":"北京"}]
用户:后天走
输出:{"depart_city":"北京","arr_city":null,"date":"后天","flight_class":null,"passenger_num":null}
【对话历史】
{{history}}
【当前用户输入】
{{user_utt}}
只输出JSON:
进阶优化方向:CroPrompt 两阶段 Prompt,先识别意图,再传入意图约束做槽填充,降低跨意图槽混淆,提升 F1arXiv。
五、全链路优化方案(工程重点)
5.1 Prompt 侧优化
- 检索式 Few-shot:不是固定示例,用向量检索召回同领域、同意图、相似句式的 Demo,比随机示例效果稳定很多arXiv
- 格式约束 + 语法校验:强制 JSON,增加 JSON Schema 校验,解析失败自动重试(温度调低)
- 自一致性 Self-Consistency:多次采样,投票选一致结果,降低幻觉
- 分层 Prompt:先 Span 抽取候选实体,再分类映射槽类型,减少大模型负担
- 控制温度:槽填充属于抽取任务,temperature=0~0.2,不要高温度
5.2 小模型(BERT-CRF/Span)优化
- 联合学习:意图识别 + 槽填充 Joint 训练,互相增强
- 数据增强:回译、同义词替换、槽值扰动、语序变换
- 置信度校准:CRF 输出路径概率作为置信度,做路由阈值
- 词典、正则、枚举后校验,硬约束兜底
5.3 多轮 DST 专项优化
- 上下文窗口裁剪:只保留最近 N 轮,避免超长上下文漂移、token 爆炸
- 槽变更标记:区分 “新增”“修改”“删除”,减少全量重算开销
- 槽依赖约束:比如出发日期不能晚于返程日期,规则拦截不合理值
- 澄清策略优化:优先问高价值槽,合并重复澄清,避免连环追问
5.4 部署 & 成本优化
- 流量分层:90% 常规流量走 BERT-CRF 小模型,LLM 只处理 10% 难例,大幅降本
- 缓存:固定 query、固定 schema 的高频请求缓存结果
- 模型微调:LoRA 微调 LLM 在本领域槽数据,比纯 Prompt 更稳、幻觉更少
- 输出解析器:单独写 JSON 解析 + 异常捕获,处理模型额外注释、换行、markdown
六、评测指标(F1 为主,27.8 为示例指标)
槽填充核心指标:Slot F1(精确匹配,槽名 + 槽值同时匹配才算正确)、Sentence Accuracy(整句所有槽全部正确)、意向 F1、澄清轮次、幻觉率。
文中 27.8 一般指低资源零样本基线 Slot F1,经过检索增强、LoRA 微调、混合架构之后可以显著高于该基线。
【相关 FAQ】
问题 1:CRF 和 Span 抽取做槽填充,各自适合什么场景?
回答 1:CRF 适合标准 IOB 标签、短实体、标签转移约束强的场景;Span 抽取直接预测实体起止位置,更适合长实体、嵌套实体,现在很多线上业务用 Span 替代 CRF。
问题 2:大模型 Prompt 做多轮槽填充,最容易踩什么坑?
回答 2:上下文遗忘、指代识别失败、输出 JSON 格式错乱、幻觉编造不存在槽值;优先做上下文裁剪、Schema 强约束、JSON 校验 + 重试、检索式 Few-shot。
问题 3:工业上为什么不直接全量用 LLM 做槽填充,还要保留 BERT-CRF?
回答 3:LLM 单条 token 成本高、延迟不稳定、存在幻觉;BERT-CRF 延迟低、可控、成本极低,把绝大多数简单请求交给小模型,LLM 只处理歧义、指代、新词这类难例,是性价比最高的方案。
问题 4:多轮 DST 里,槽位继承和覆盖怎么设计更合理?
回答 4:默认增量继承,本轮没提到的槽保留;用户明确说出新值、否定、更正时覆盖;如果用户说 “换一个” 这类模糊修改,交给 LLM 做差分更新,同时增加冲突确认逻辑。
【参考资料】
[2024] CroPrompt: Cross-task Interactive Prompting for Zero-shot Spoken Language Understanding
[2024] Hierarchical Pipeline Prompt-based Cross-Domain Slot Filling, TASLP
[2025] BERT-CRF Joint Intent and Slot Filling 工业基线
[2024] Retrieval augmented Few-shot Slot Filling
[2023] DST 对话状态跟踪与多轮槽填充最佳实践
【免责声明】
本技术栈为任务型对话工业落地通用方案,零样本基线 27.8 仅为示例指标;实际 F1 受数据集、领域、标注质量、Prompt 策略、模型底座影响;上线前必须做幻觉、格式、边界 case 专项测试,高可靠业务建议搭配规则 + 词典双重校验。
