智能体的意图识别:理解用户真实需求
智能体的意图识别:理解用户真实需求
引言
痛点引入
你有没有遇到过这样的场景?
周末想订个“带浴缸的亲子主题酒店,周末入住,市中心,不能离太古里太远,最多两公里,预算2000以内/晚,最好有送早餐和儿童乐园”,对着手机上的智能助手喊完一串,它却只给你跳出来一堆离太古里3公里开外、或者不带浴缸、或者价格超了3000的普通酒店;
你是一个电商运营,想让你的智能客服机器人自动识别老客户的“老客专属优惠券兑换查询+最近30天的物流延迟赔付政策咨询”混合需求,结果机器人要么直接弹出优惠券的通用规则忽略了查询/赔付,要么直接甩给你转人工的链接,让你白瞎了部署这套系统的几十万预算;
甚至你在写代码的时候,用GitHub Copilot或者Cursor这类AI编程助手,你明明输入的是“写一个Python脚本,用Scrapy框架爬取知乎某话题下1000条高赞回答的正文、点赞数、评论数、作者ID,并把结果存到MongoDB数据库里,要处理反爬虫(UA伪装、代理IP池)、要避免重复爬取(基于URL哈希的布隆过滤器)”,结果它写出来的脚本要么没有代理IP池逻辑,要么布隆过滤器是基于内存的重启就失效,要么MongoDB的连接方式不安全(硬编码了密码)——这些情况,本质上都指向了一个核心技术难题:智能体(不管是对话式、协作式、工具调用式)到底能不能真正理解用户输入背后的“真实意图”,而不是仅仅停留在字面匹配?
随着大语言模型(LLMs)、多模态感知、强化学习等技术的爆发式发展,智能体已经从早期的“ Siri式语音闹钟+简单指令助手”进化到了如今的“能自主思考、调用工具、与人/环境交互的自主Agent”——比如能帮你完成“订酒店+买机票+查景点攻略+约导游”全流程旅行规划的Multi-Agent协作系统,比如能帮你完成“需求拆解+代码生成+单元测试+Bug修复+代码部署”全流程软件开发的DevOps Agent,比如能在游戏里自主探索、制定策略、对抗玩家的游戏Agent。
但无论智能体的能力有多强大,意图识别都是它与人类交互的“第一道门槛”,也是决定它后续行为是否有效的“核心基石”——如果第一道门槛就踏错了,后续的工具调用、行动规划、结果交付都会变成无用功,甚至会给用户带来严重的困扰(比如订错了机票日期、买错了商品尺寸、把客户的隐私信息泄露给了第三方)。
解决方案概述
幸运的是,经过近20年的发展(从早期的基于规则/模板的意图识别,到后来的基于传统机器学习的意图识别,再到现在的基于大语言模型的意图识别),意图识别技术已经取得了长足的进步,尤其是大语言模型的出现,更是让意图识别的准确率、泛化能力、理解复杂/模糊/混合/隐含/多轮意图的能力得到了质的飞跃。
在这篇文章中,我将作为一位资深的软件工程师和技术博主,带你从问题背景、核心概念、技术发展历史、各类技术方案的原理解析(包括基于规则/模板的、基于传统机器学习的、基于深度学习的、基于大语言模型的、基于多模态的)、核心算法实现(Python代码)、系统架构设计、实际场景应用、最佳实践Tips、常见问题FAQ、未来发展趋势等方面,全方位、深入地讲解“智能体的意图识别”这一核心技术,让你不仅知其然,更知其所以然,甚至能够自己动手搭建一个简单但实用的意图识别系统。
最终效果展示(可选)
为了让你对本文的内容有一个更直观的了解,我先展示一下我们最终会实现的一个简单但实用的电商客服混合意图识别系统的效果:
用户输入(单轮混合意图):
客服你好,我是咱们的老会员,我的会员卡号是V123456789,想查一下我账户里还有多少张老客专属的满200减50的优惠券能用,另外我上周买的那件M码的红色连衣裙(订单号是O987654321),物流显示卡在成都中转站已经3天了,能不能帮我查一下什么时候能送到,要是再延迟的话有没有什么赔付政策?
系统识别的意图(结构化输出):
{
"user_id": "V123456789",
"intent_list": [
{
"intent_id": "QUERY_MEMBER_COUPON",
"intent_name": "查询老客专属优惠券",
"confidence": 0.99,
"slot_list": [
{
"slot_name": "coupon_type",
"slot_value": "老客专属满200减50",
"confidence": 0.98
},
{
"slot_name": "coupon_status",
"slot_value": "可用",
"confidence": 0.97
}
],
"order": 1
},
{
"intent_id": "QUERY_LOGISTICS",
"intent_name": "查询物流状态",
"confidence": 0.99,
"slot_list": [
{
"slot_name": "order_id",
"slot_value": "O987654321",
"confidence": 1.0
},
{
"slot_name": "product_info",
"slot_value": "M码红色连衣裙",
"confidence": 0.96
}
],
"order": 2
},
{
"intent_id": "QUERY_LOGISTICS_DELAY_COMPENSATION",
"intent_name": "查询物流延迟赔付政策",
"confidence": 0.98,
"slot_list": [
{
"slot_name": "order_id",
"slot_value": "O987654321",
"confidence": 1.0
},
{
"slot_name": "delay_days",
"slot_value": "3天(预估)",
"confidence": 0.95
}
],
"order": 3
}
],
"is_multiple_intent": true,
"is_implicit_intent": false,
"is_multimodal_intent": false,
"context_intent_relation": null
}
系统后续的工具调用计划(Agent自主规划,基于识别的意图):
{
"tool_list": [
{
"tool_name": "get_member_coupon_info",
"tool_input": {
"user_id": "V123456789",
"coupon_type": "老客专属满200减50",
"coupon_status": "可用"
},
"tool_order": 1
},
{
"tool_name": "get_logistics_status",
"tool_input": {
"order_id": "O987654321"
},
"tool_order": 2
},
{
"tool_name": "get_logistics_delay_compensation_policy",
"tool_input": {
"order_id": "O987654321",
"delay_days": "3天(预估)"
},
"tool_order": 3
}
]
}
看到了吗?这个系统不仅识别出了用户的三个混合意图,还准确地提取了每个意图对应的关键槽位信息,甚至还给出了每个意图和槽位的置信度,为后续Agent的自主规划和工具调用提供了坚实的基础——这就是我们想要的“真正理解用户真实需求”的意图识别系统。
准备工作(可选,但强烈推荐)
环境/工具
为了让你能够跟着本文的内容自己动手实现一个意图识别系统,我建议你先准备好以下的开发环境和工具:
- 操作系统: Windows 10/11、macOS Ventura/Sonoma、Linux(Ubuntu 22.04 LTS/CentOS 7+)——推荐使用Linux或者macOS,因为大语言模型的部署和传统机器学习模型的训练在这两个系统上会更方便。
- 编程语言: Python 3.9+——因为现在主流的意图识别框架(比如NLTK、spaCy、Transformers、LangChain、Rasa、Haystack)都是基于Python开发的。
- Python包管理工具: pip 23.0+ 或者 conda 23.0+——推荐使用conda,因为它可以创建独立的虚拟环境,避免不同项目之间的依赖冲突。
- 深度学习框架: PyTorch 2.0+ 或者 TensorFlow 2.12+——推荐使用PyTorch,因为现在主流的预训练语言模型(比如BERT、GPT、LLaMA、ChatGLM)都是基于PyTorch开发的,而且Hugging Face的Transformers库对PyTorch的支持更好。
- 大语言模型(可选,但强烈推荐):
- 如果你有足够的GPU资源(至少16GB VRAM),可以部署开源的大语言模型,比如Meta的LLaMA 2(7B/13B/70B)、清华大学的ChatGLM 3(6B/12B/66B)、阿里巴巴的通义千问(Qwen 2,0.5B/1.5B/7B/14B/72B);
- 如果你没有足够的GPU资源,可以使用云服务商提供的大语言模型API,比如OpenAI的GPT-4/GPT-3.5 Turbo API、Anthropic的Claude 3 Opus/Sonnet/Haiku API、Google的Gemini Pro/Ultra API、百度的文心一言API、阿里巴巴的通义千问API、腾讯的混元API;
- 本文中,为了让更多的读者能够跟着实现,我会同时提供基于开源预训练语言模型(比如Hugging Face的bert-base-chinese、albert-base-v2-chinese)的传统意图识别实现和基于云服务商API(比如OpenAI的GPT-3.5 Turbo API、阿里巴巴的通义千问API)的大语言模型意图识别实现。
- 意图识别框架(可选,但推荐):
- 如果你想自己动手实现一个从0到1的意图识别系统,可以不用任何框架;
- 如果你想快速搭建一个意图识别系统,可以使用Rasa(开源的对话式AI框架,包含意图识别、实体提取、对话管理等功能)、LangChain(大语言模型应用开发框架,包含意图识别、工具调用、Multi-Agent协作等功能)、Haystack(大语言模型检索增强生成(RAG)框架,包含语义搜索、意图识别、问答系统等功能);
- 本文中,我会先讲解从0到1的意图识别实现(包括基于规则/模板的、基于传统机器学习的、基于深度学习的),然后再讲解基于LangChain和通义千问API的大语言模型意图识别实现,最后再简单介绍一下基于Rasa的意图识别实现。
- 数据库(可选,用于存储意图标注数据、对话历史、布隆过滤器等):
- 结构化数据:MySQL 8.0+、PostgreSQL 15+;
- 非结构化数据:MongoDB 6.0+;
- 内存数据库:Redis 7.0+;
- 本文中,我们会使用Redis来存储基于URL哈希的布隆过滤器(可选,用于避免重复爬取意图标注数据),使用MySQL来存储意图标注数据和对话历史,使用MongoDB来存储识别的意图结果和工具调用结果。
- 其他工具:
- Jupyter Notebook/JupyterLab:用于编写和调试Python代码;
- Git/GitHub:用于版本控制;
- Postman:用于测试API接口;
- Draw.io/Figma:用于绘制架构图、流程图等;
- VS Code/PyCharm:用于编写Python代码——推荐使用VS Code,因为它轻量、免费、插件丰富。
基础知识
为了让你能够更好地理解本文的内容,我建议你先掌握以下的前置知识:
- Python编程基础: 变量、数据类型、运算符、条件语句、循环语句、函数、类、对象、模块、包等;
- 机器学习基础: 监督学习、无监督学习、半监督学习、强化学习、训练集、验证集、测试集、过拟合、欠拟合、特征工程、模型评估指标(准确率、精确率、召回率、F1分数、混淆矩阵等)等;
- 深度学习基础: 神经网络、激活函数(ReLU、Sigmoid、Tanh等)、损失函数(交叉熵损失、均方误差损失等)、优化器(SGD、Adam、AdamW等)、梯度下降、反向传播、卷积神经网络(CNN)、循环神经网络(RNN)、长短时记忆网络(LSTM)、门控循环单元(GRU)、注意力机制(Attention)、Transformer等;
- 自然语言处理(NLP)基础: 文本预处理(分词、去停用词、词形还原、词干提取等)、词向量(Word2Vec、GloVe、FastText等)、序列标注(命名实体识别(NER)、词性标注(POS)等)、文本分类(情感分析、意图识别等)、问答系统(QA)、机器翻译(MT)等;
- 大语言模型(LLMs)基础: 预训练语言模型(PLMs)、微调(Fine-tuning)、提示工程(Prompt Engineering)、检索增强生成(RAG)、思维链(CoT)、思维树(ToT)、Agent等;
- API开发基础: RESTful API、JSON、HTTP请求方法(GET、POST、PUT、DELETE等)、Flask/FastAPI等——本文中,我们会使用FastAPI来开发意图识别系统的API接口。
如果你还没有掌握以上的前置知识,我推荐你先学习以下的学习资源:
- Python编程基础: 《Python编程:从入门到实践》(Eric Matthes著)、廖雪峰的Python教程(https://www.liaoxuefeng.com/wiki/1016959663602400);
- 机器学习基础: 《机器学习》(周志华著,西瓜书)、《统计学习方法》(李航著)、吴恩达的机器学习课程(https://www.coursera.org/learn/machine-learning);
- 深度学习基础: 《深度学习》(Ian Goodfellow、Yoshua Bengio、Aaron Courville著,花书)、吴恩达的深度学习专项课程(https://www.coursera.org/specializations/deep-learning)、李沐的动手学深度学习课程(https://zh.d2l.ai/);
- 自然语言处理(NLP)基础: 《自然语言处理实战》(Hobson Lane、Cole Howard、Hannes Hapke著)、《Python自然语言处理》(Steven Bird、Ewan Klein、Edward Loper著)、CS224N:自然语言处理与深度学习(斯坦福大学,https://web.stanford.edu/class/cs224n/);
- 大语言模型(LLMs)基础: 《大语言模型:原理与实践》(李沐、赵亮著)、Hugging Face的Transformers文档(https://huggingface.co/docs/transformers/index)、LangChain的文档(https://python.langchain.com/docs/get_started/introduction);
- API开发基础: 《Flask Web开发:基于Python的Web应用开发实战》(Miguel Grinberg著)、FastAPI的官方文档(https://fastapi.tiangolo.com/zh/)。
核心概念
在正式讲解意图识别的技术方案之前,我们首先需要明确几个核心概念——这些概念是理解意图识别技术的基础,如果你对这些概念已经有了一定的了解,可以跳过这一部分,但我还是建议你再仔细看一遍,因为不同的人对这些概念的理解可能会有一些细微的差别,而这些细微的差别可能会影响到后续的技术方案选择和实现。
什么是智能体?
首先,我们需要明确什么是智能体(Agent)——因为本文的主题是“智能体的意图识别”,如果我们连“什么是智能体”都不清楚,那后面的内容就无从谈起了。
核心概念
智能体(Agent)是人工智能领域中的一个核心概念,它的定义有很多种,其中最经典、最被广泛接受的是斯坦福大学的Russell和Norvig在《人工智能:一种现代的方法》一书中给出的定义:
智能体是一个能够通过传感器感知环境,并通过执行器作用于环境的实体。
这个定义非常简洁,但它包含了智能体的三个核心要素:
- 传感器(Sensors): 用于感知环境的状态或变化——比如对话式Agent的传感器是麦克风(语音输入)或键盘/鼠标(文本输入),协作式Agent的传感器是API接口(接收其他Agent的消息),工具调用式Agent的传感器是网络爬虫(感知互联网的信息)或摄像头(感知物理世界的图像);
- 执行器(Actuators): 用于作用于环境的状态或变化——比如对话式Agent的执行器是扬声器(语音输出)或屏幕(文本输出),协作式Agent的执行器是API接口(发送消息给其他Agent),工具调用式Agent的执行器是浏览器自动化工具(比如Selenium、Playwright,用于自动下单、自动注册等)或物理机器人(比如扫地机器人,用于清扫地面);
- 大脑(Brain): 用于根据传感器感知到的环境信息,做出决策,并控制执行器执行相应的动作——这是智能体的核心部分,也是意图识别技术的应用场景之一(意图识别是大脑做出决策的第一步)。
除了Russell和Norvig给出的经典定义之外,随着大语言模型的出现,现在还有一种更流行、更具体的大语言模型智能体(LLM Agent)的定义:
大语言模型智能体是一个以大语言模型为核心大脑,能够自主感知环境、理解用户意图、制定行动计划、调用外部工具、与人/环境交互、反思优化自身行为的自主实体。
这个定义在Russell和Norvig的经典定义的基础上,增加了几个大语言模型智能体特有的核心要素:
- 自主感知(Autonomous Perception): 不需要人类的明确指令,就能够主动感知环境的状态或变化;
- 理解用户意图(Understanding User Intent): 这是本文的主题;
- 制定行动计划(Planning): 根据感知到的环境信息和理解到的用户意图,制定一系列的行动步骤;
- 调用外部工具(Tool Use): 当自身的知识或能力不足以完成任务时,能够主动调用外部工具(比如搜索引擎、数据库、计算器、浏览器自动化工具等);
- 反思优化(Reflection): 能够根据执行器的执行结果,反思自己的决策和行动计划是否正确,并在后续的交互中进行优化;
- 自主学习(Autonomous Learning): 不需要人类的监督,就能够从交互经验中学习新的知识或技能。
问题背景
智能体的概念并不是最近才出现的——它的历史可以追溯到20世纪50年代,当时人工智能领域刚刚诞生,研究者们就开始尝试构建能够自主行动的实体(比如1951年Claude Shannon构建的“Theseus”迷宫求解机器人,1956年Allen Newell和Herbert Simon构建的“Logic Theorist”逻辑推理程序)。
但在大语言模型出现之前,智能体的发展一直受到很大的限制——主要原因是:
- 知识表示困难: 很难将人类的知识和经验表示成计算机能够理解的形式;
- 推理能力有限: 传统的智能体只能基于预先设定的规则或模板进行推理,无法处理复杂、模糊、未知的情况;
- 泛化能力差: 传统的智能体只能处理特定领域、特定场景的任务,无法泛化到其他领域或场景;
- 交互能力弱: 传统的智能体只能与人类进行简单、单向的交互,无法进行复杂、双向、多轮的交互。
直到2022年11月OpenAI发布了ChatGPT之后,大语言模型的爆发式发展彻底改变了这一现状——大语言模型具有强大的知识表示能力、推理能力、泛化能力和交互能力,使得构建真正“智能”的自主Agent成为了可能。
智能体的分类
根据不同的分类标准,智能体可以分为不同的类型——常见的分类标准包括:
- 根据感知和执行的范围分类:
- 软件Agent(Software Agent): 只存在于数字世界中,通过API接口或网络爬虫感知数字环境,通过API接口或屏幕输出作用于数字环境——比如对话式AI助手、电商客服机器人、DevOps Agent、Multi-Agent协作系统等;
- 物理Agent(Physical Agent,也称为机器人): 存在于物理世界中,通过摄像头、麦克风、激光雷达等传感器感知物理环境,通过机械臂、轮子、扬声器等执行器作用于物理环境——比如扫地机器人、自动驾驶汽车、工业机器人、服务机器人等;
- 混合Agent(Hybrid Agent): 既存在于数字世界中,也存在于物理世界中——比如自动驾驶汽车(它不仅需要感知物理世界的路况,还需要感知数字世界的地图信息、交通信号灯信息等)。
- 根据交互的对象分类:
- 人机交互Agent(Human-Computer Interaction Agent,HCI Agent): 主要与人类进行交互——比如对话式AI助手、电商客服机器人、教育机器人等;
- 机机交互Agent(Machine-Machine Interaction Agent,MMI Agent): 主要与其他Agent或计算机系统进行交互——比如Multi-Agent协作系统中的各个子Agent、API网关、消息队列等;
- 混合交互Agent(Hybrid Interaction Agent): 既与人类进行交互,也与其他Agent或计算机系统进行交互——比如DevOps Agent(它不仅需要与人类开发人员进行交互,还需要与代码仓库、CI/CD系统、云服务器等计算机系统进行交互)。
- 根据是否具有自主决策能力分类:
- 反应式Agent(Reactive Agent): 没有内部状态,也没有自主决策能力,只能根据当前感知到的环境信息,做出预先设定的反应——比如早期的Siri式语音闹钟、简单的指令助手等;
- 慎思式Agent(Deliberative Agent): 具有内部状态,也具有自主决策能力,能够根据当前感知到的环境信息和内部的知识库/记忆,制定行动计划,并执行相应的动作——比如现在的大多数大语言模型Agent;
- 混合式Agent(Hybrid Agent): 结合了反应式Agent和慎思式Agent的优点——对于简单、紧急的情况,使用反应式Agent做出快速反应;对于复杂、不紧急的情况,使用慎思式Agent做出深思熟虑的决策——比如自动驾驶汽车(对于突然出现的行人,使用反应式Agent做出紧急刹车的快速反应;对于路线规划,使用慎思式Agent做出深思熟虑的决策)。
- 根据是否具有学习能力分类:
- 静态Agent(Static Agent): 没有学习能力,只能使用预先设定的规则、模板或模型,无法从交互经验中学习新的知识或技能;
- 动态Agent(Dynamic Agent): 具有学习能力,能够从交互经验中学习新的知识或技能,并在后续的交互中进行优化——比如现在的大多数大语言模型Agent。
智能体的架构
不管是哪种类型的智能体,它的架构通常都包含以下几个核心模块:
- 感知模块(Perception Module): 对应智能体的传感器,用于感知环境的状态或变化,并将感知到的信息转换成计算机能够理解的形式——比如对于对话式Agent,感知模块的功能是将语音输入转换成文本输入(语音识别,ASR),或者将文本输入进行预处理(分词、去停用词等);
- 意图识别模块(Intent Recognition Module): 对应本文的主题,用于从感知模块输出的信息中,识别出用户的真实意图,并提取出每个意图对应的关键槽位信息;
- 对话管理模块(Dialogue Management Module,仅适用于对话式Agent): 用于管理多轮对话的上下文,维护用户的状态和智能体的状态,并根据意图识别模块的输出和上下文信息,决定智能体的下一步动作——比如是追问用户补充缺失的槽位信息,还是调用外部工具获取所需的信息,还是直接生成回答;
- 知识库/记忆模块(Knowledge Base/Memory Module): 用于存储智能体的知识库(比如通用知识、领域知识)和记忆(比如短期记忆、长期记忆、对话历史)——短期记忆通常存储当前对话的上下文信息,长期记忆通常存储用户的历史交互信息、智能体的历史执行结果等;
- 规划模块(Planning Module): 用于根据意图识别模块的输出、对话管理模块的输出(仅适用于对话式Agent)、知识库/记忆模块的输出,制定一系列的行动步骤;
- 工具调用模块(Tool Use Module): 用于根据规划模块的输出,调用外部工具获取所需的信息或执行相应的动作;
- 反思优化模块(Reflection Module): 用于根据工具调用模块的输出或用户的反馈,反思自己的决策和行动计划是否正确,并在后续的交互中进行优化;
- 执行模块(Execution Module): 对应智能体的执行器,用于根据反思优化模块的输出(如果有)或规划模块的输出(如果没有),生成回答或执行相应的动作——比如对于对话式Agent,执行模块的功能是将文本回答转换成语音回答(语音合成,TTS),或者直接输出文本回答。
为了让你对智能体的架构有一个更直观的了解,我绘制了一个大语言模型对话式Agent的通用架构图(使用Mermaid架构图):
从这个架构图中可以看出,意图识别模块是连接感知模块和对话管理模块/规划模块的桥梁,是整个大语言模型对话式Agent架构中不可或缺的核心模块——如果没有意图识别模块,感知模块输出的信息就无法被对话管理模块/规划模块理解,后续的所有动作都会变成无用功。
什么是意图?
接下来,我们需要明确什么是意图(Intent)——因为意图识别的目标就是“识别用户的真实意图”,如果我们连“什么是意图”都不清楚,那我们就无法定义意图识别的任务,也无法评估意图识别系统的性能。
核心概念
意图(Intent)是自然语言处理(NLP)和对话式AI领域中的一个核心概念,它的定义也有很多种,其中最经典、最被广泛接受的是从用户的角度给出的定义:
意图是用户通过输入(语音/文本/图像/视频)想要表达的真实目的或需求。
这个定义非常直观,但它也有一个缺点——就是太过于抽象,无法直接用于计算机的处理。因此,在实际的意图识别系统中,我们通常会将意图形式化地定义为一个分类标签(Classification Label),每个分类标签对应一个特定的用户目的或需求——比如对于电商客服机器人,我们可以定义以下的意图分类标签:
QUERY_MEMBER_COUPON:查询老客专属优惠券;QUERY_LOGISTICS:查询物流状态;QUERY_LOGISTICS_DELAY_COMPENSATION:查询物流延迟赔付政策;PLACE_ORDER:下单;CANCEL_ORDER:取消订单;RETURN_PRODUCT:退货;EXCHANGE_PRODUCT:换货;COMPLAIN:投诉;PRAISE:表扬;TRANSFER_TO_HUMAN:转人工。
除了将意图形式化地定义为一个分类标签之外,在实际的意图识别系统中,我们通常还会为每个意图定义一些关键槽位(Slots)——槽位是意图的参数,用于填充用户需求的细节信息,比如对于QUERY_MEMBER_COUPON这个意图,我们可以定义以下的关键槽位:
coupon_type:优惠券类型(比如老客专属满200减50、新客专属满100减20、节假日专属满500减100等);coupon_status:优惠券状态(比如可用、已使用、已过期、未激活等);user_id:用户ID/会员卡号;start_date:查询的起始日期;end_date:查询的结束日期。
为了让你对“意图+槽位”的形式化定义有一个更直观的了解,我举一个简单的例子:
用户输入:
客服你好,我是咱们的老会员,我的会员卡号是V123456789,想查一下我账户里还有多少张老客专属的满200减50的优惠券能用。
形式化的意图+槽位表示:
{
"intent": "QUERY_MEMBER_COUPON",
"confidence": 0.99,
"slots": {
"user_id": {
"value": "V123456789",
"confidence": 1.0
},
"coupon_type": {
"value": "老客专属满200减50",
"confidence": 0.98
},
"coupon_status": {
"value": "可用",
"confidence": 0.97
}
}
}
看到了吗?“意图+槽位”的形式化定义非常清晰、非常结构化,非常适合计算机的处理——后续的对话管理模块、规划模块、工具调用模块都可以直接使用这个结构化的表示。
意图的分类
根据不同的分类标准,意图可以分为不同的类型——常见的分类标准包括:
- 根据意图的数量分类:
- 单意图(Single Intent): 用户的输入中只包含一个意图——比如“查一下我的物流状态”;
- 混合意图(Multiple Intents,也称为多意图): 用户的输入中包含两个或两个以上的意图——比如“查一下我的物流状态,再查一下物流延迟赔付政策”。
- 根据意图的明确程度分类:
- 显式意图(Explicit Intent): 用户的输入中明确地表达了自己的意图——比如“我要下单买那件M码的红色连衣裙”;
- 隐含意图(Implicit Intent,也称为隐式意图): 用户的输入中没有明确地表达自己的意图,需要智能体根据上下文信息、领域知识、常识知识来推断——比如“那件M码的红色连衣裙现在多少钱?”,用户的显式意图是“查询商品价格”,但隐含意图可能是“如果价格合适的话,我就下单买”;再比如“今天的天气真热啊”,用户的显式意图是“描述天气”,但隐含意图可能是“帮我开一下空调”(如果用户是在和智能家居助手对话的话)。
- 根据意图的轮次分类:
- 单轮意图(Single-Turn Intent): 用户的意图只通过一轮输入就能表达清楚——比如“查一下我的物流状态,订单号是O987654321”;
- 多轮意图(Multi-Turn Intent): 用户的意图需要通过多轮输入才能表达清楚——比如:
- 用户第一轮输入: 查一下我的物流状态;
- 智能体输出: 好的,请提供一下您的订单号;
- 用户第二轮输入: O987654321;
- 此时,用户的真实意图才表达清楚:查询订单号为O987654321的物流状态。
- 根据意图的模态分类:
- 单模态意图(Unimodal Intent): 用户的意图只通过一种模态的输入就能表达清楚——比如只通过文本输入、只通过语音输入、只通过图像输入;
- 多模态意图(Multimodal Intent): 用户的意图需要通过两种或两种以上模态的输入才能表达清楚——比如:
- 用户的文本输入: 帮我买一件和这个一样的连衣裙;
- 用户的图像输入: 一张M码红色连衣裙的照片;
- 此时,用户的真实意图才表达清楚:买一件和照片中一样的M码红色连衣裙。
- 根据意图的领域分类:
- 领域特定意图(Domain-Specific Intent): 用户的意图只适用于特定的领域——比如电商领域的“下单”、“退货”、“换货”,旅游领域的“订酒店”、“买机票”、“查景点攻略”;
- 通用意图(General Intent): 用户的意图适用于多个领域——比如“问候”、“告别”、“感谢”、“道歉”、“查询时间”、“查询天气”。
意图识别的任务定义
在明确了“什么是意图”和“意图的分类”之后,我们就可以形式化地定义意图识别的任务了——根据意图的分类,意图识别的任务可以分为不同的类型,常见的任务类型包括:
- 单意图分类(Single Intent Classification): 这是最基础的意图识别任务,目标是将用户的输入分类到预定义的单意图标签集合中的某一个标签,并给出分类的置信度;
- 混合意图分类(Multiple Intent Classification): 这是比单意图分类更复杂的意图识别任务,目标是将用户的输入分类到预定义的单意图标签集合中的某一个或某几个标签,并给出每个标签的置信度和顺序;
- 隐含意图识别(Implicit Intent Recognition): 这是比混合意图分类更复杂的意图识别任务,目标是不仅识别出用户的显式意图,还要识别出用户的隐含意图;
- 多轮意图识别(Multi-Turn Intent Recognition): 这是比隐含意图识别更复杂的意图识别任务,目标是结合多轮对话的上下文信息,识别出用户的真实意图;
- 多模态意图识别(Multimodal Intent Recognition): 这是目前最复杂的意图识别任务之一,目标是结合两种或两种以上模态的输入信息,识别出用户的真实意图。
在本文中,我们将重点讲解单意图分类、混合意图分类、多轮意图识别这三种最常见、最实用的意图识别任务,同时也会简单介绍一下隐含意图识别和多模态意图识别。
什么是槽位填充?
在明确了“什么是意图”之后,我们还需要明确什么是槽位填充(Slot Filling)——因为在实际的意图识别系统中,意图识别和槽位填充通常是两个紧密相关的任务,很多时候我们会将它们合并成一个任务来处理(称为意图识别与槽位填充联合任务)。
核心概念
槽位填充(Slot Filling)是自然语言处理(NLP)和对话式AI领域中的一个核心任务,它的目标是从用户的输入中提取出预定义的关键槽位信息,并将其填充到对应的槽位中,同时给出每个槽位填充的置信度。
槽位填充本质上是一个序列标注任务(Sequence Labeling Task)——序列标注任务的目标是为输入序列中的每个元素(比如每个词、每个字符)分配一个预定义的标签。常见的序列标注任务包括:
- 命名实体识别(Named Entity Recognition,NER):为输入文本中的每个词分配一个标签,识别出文本中的人名、地名、组织机构名等命名实体;
- 词性标注(Part-of-Speech Tagging,POS):为输入文本中的每个词分配一个标签,标注出每个词的词性(比如名词、动词、形容词等);
- 槽位填充:为输入文本中的每个词分配一个标签,识别出文本中的关键槽位信息。
槽位填充的标签体系
在槽位填充任务中,最常用的标签体系是IOB标签体系(也称为BIO标签体系)——IOB是Inside、Outside、Beginning的缩写,它的定义如下:
- O(Outside): 表示当前词不属于任何槽位;
- B-XXX(Beginning-XXX): 表示当前词是槽位XXX的开头;
- I-XXX(Inside-XXX): 表示当前词是槽位XXX的内部(不是开头)。
除了IOB标签体系之外,还有一些扩展的标签体系,比如:
- IOBE标签体系: 在IOB标签体系的基础上,增加了E-XXX(End-XXX)标签,表示当前词是槽位XXX的结尾;
- IOBES标签体系: 在IOBE标签体系的基础上,增加了S-XXX(Single-XXX)标签,表示当前词是一个单独的槽位XXX(即槽位XXX只包含一个词)。
在实际的槽位填充任务中,IOB标签体系是最常用的——因为它简单、有效,而且大多数预训练语言模型和序列标注框架都支持它。
为了让你对IOB标签体系有一个更直观的了解,我举一个简单的例子:
用户输入(中文分词后的结果):
[“客服”, “你好”, “,”, “我”, “是”, “咱们”, “的”, “老会员”, “,”, “我的”, “会员卡号”, “是”, “V123456789”, “,”, “想”, “查”, “一下”, “我”, “账户”, “里”, “还有”, “多少”, “张”, “老客”, “专属”, “的”, “满”, “200”, “减”, “50”, “的”, “优惠券”, “能”, “用”, “。”]
预定义的槽位:
user_id:用户ID/会员卡号;coupon_type:优惠券类型;coupon_status:优惠券状态。
IOB标签序列:
[“O”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “B-user_id”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “O”, “B-coupon_type”, “I-coupon_type”, “O”, “I-coupon_type”, “I-coupon_type”, “I-coupon_type”, “I-coupon_type”, “O”, “O”, “O”, “B-coupon_status”, “O”, “O”]
填充后的槽位:
{
"user_id": {
"value": "V123456789",
"confidence": 0.99
},
"coupon_type": {
"value": "老客专属满200减50",
"confidence": 0.98
},
"coupon_status": {
"value": "能",
"confidence": 0.97
}
}
看到了吗?通过IOB标签体系,我们可以很容易地从用户的输入中提取出预定义的关键槽位信息,并将其填充到对应的槽位中。
意图识别与槽位填充的联合任务
在实际的意图识别系统中,意图识别和槽位填充通常是两个紧密相关的任务——因为:
- 槽位信息可以帮助识别意图: 比如如果用户的输入中包含“订单号”这个槽位,那么用户的意图很可能是“查询物流状态”、“取消订单”、“退货”或“换货”;
- 意图信息可以帮助填充槽位: 比如如果用户的意图是“查询物流状态”,那么我们只需要关注“订单号”、“product_info”等与物流查询相关的槽位,而不需要关注“coupon_type”、“coupon_status”等与物流查询无关的槽位。
因此,很多时候我们会将意图识别和槽位填充合并成一个联合任务来处理(称为Joint Intent Detection and Slot Filling,JIDSF)——联合任务的目标是同时识别出用户的意图和填充出预定义的关键槽位信息,这样不仅可以提高任务的准确率,还可以提高任务的效率。
在本文中,我们将重点讲解意图识别与槽位填充的联合任务——因为它是实际的意图识别系统中最常用的任务。
意图识别系统的性能评估指标
在设计和实现了一个意图识别系统之后,我们需要对它的性能进行评估——只有通过性能评估,我们才能知道这个系统的好坏,才能对它进行优化。
对于意图识别任务和槽位填充任务,我们通常会使用不同的性能评估指标——下面我们将分别介绍。
意图识别任务的性能评估指标
意图识别任务本质上是一个文本分类任务——因此,我们通常会使用文本分类任务的性能评估指标来评估意图识别任务的性能,常见的性能评估指标包括:
-
准确率(Accuracy): 准确率是指分类正确的样本数占总样本数的比例,它的计算公式如下:
Accuracy=TP+TNTP+TN+FP+FN Accuracy = \frac{TP + TN}{TP + TN + FP + FN} Accuracy=TP+TN+FP+FNTP+TN
其中:- TP(True Positive):真正例,即被分类器正确分类为正例的样本数;
- TN(True Negative):真负例,即被分类器正确分类为负例的样本数;
- FP(False Positive):假正例,即被分类器错误分类为正例的样本数;
- FN(False Negative):假负例,即被分类器错误分类为负例的样本数。
准确率是一个非常直观的性能评估指标,但它也有一个很大的缺点——就是在类别不平衡的数据集上,准确率会失去参考价值。比如如果我们有一个电商客服机器人的意图识别数据集,其中95%的样本都是“问候”意图,只有5%的样本是其他意图——那么如果我们的分类器将所有的样本都分类为“问候”意图,那么它的准确率会达到95%
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)