
说实话,我刚开始接触聊天机器人开发的时候,对”意图识别”和”实体提取”这两个概念是完全懵的。听起来很高大上对吧?感觉像是人工智能领域才会用到的高级词汇。但后来我发现,这两个东西其实是聊天机器人能够”听懂人话”的核心所在。简单来说,意图识别就是让机器明白用户到底想要干什么,而实体提取则是帮机器抓住用户话里的关键信息。比如你说”明天下午三点叫我去开会”,机器人需要识别出你的意图是”设置提醒”,同时提取出”明天”、”下午三点”这些实体信息。
在声网这样的实时互动技术平台上搭建聊天机器人时,这两项能力的好坏直接决定了用户体验。想象一下,如果你跟机器人说”帮我订一张明天去上海的高铁票”,它却给你推荐了机票或者直接答非所问,那种挫败感估计大家都有过。这篇文章我想系统地聊聊这两个技术到底是怎么实现的,以及在开发过程中可能会遇到哪些坑。
这个问题其实可以反过来想:如果没有这两项能力,聊天机器人会变成什么样?答案是,它只能做一些关键词匹配的工作。你说”天气”,它给你天气;你说”播放音乐”,它给你音乐。但现实生活中的对话哪有那么多固定的关键词?每个人表达同样需求的方式可能天差地别。
我有个朋友之前吐槽说,他家的智能音箱特别笨。你问它”今天热不热”,它能答;但你换一种问法”用不用带伞”,它就懵了。这背后其实就是意图识别能力不足的表现。真正好的聊天机器人应该能够理解不同表达方式背后的相同需求,这才是它”智能”的体现。
而实体提取的重要性在于,即使机器人知道你想要什么,但如果抓不住具体信息,它还是没法帮你办事。还是以订票为例,它知道你想要订票,但如果你不说清楚日期、目的地、车次,它总不能帮你随机选一个吧?所以实体提取解决的是”做这件事需要哪些具体参数”的问题。

从技术角度来说,意图识别本质上是一个分类问题。机器需要把用户说的话归到预先定义好的几个类别里。比如一个电商客服机器人,可能的意图类别就包括”查询订单”、”申请退款”、”咨询产品”、”投诉建议”等等。机器需要根据用户输入,判断它属于哪个类别。
这个过程看起来简单,做起来其实挺复杂的。因为同样的意图可以用完全不同的方式表达,而且有时候用户表达得很模糊,甚至会有拼写错误、语法问题。举个简单的例子,用户想说”我想查一下我的订单状态”,但可能打成了”我想查一查我的订单zhuangtai”,这种情况下机器还是得正确识别出他的意图是”查询订单”。
目前业界主流的意图识别方法大概可以分为三类。第一类是基于规则的方法,这种方法就是人工编写大量的匹配规则。比如如果用户说的话里包含”多少钱”、”价格”、”费用”这些词,就归类为”询问价格”意图。这种方法的好处是可控,坏处是规则写不胜写,而且很难覆盖所有的表达方式。
第二类是基于机器学习的方法。这种方法需要先准备一批标注好的数据,也就是人工标注每句话对应的意图类别,然后用这些数据训练一个分类模型。当模型训练好之后,给它一句新的话,它就能预测出最可能的意图。这种方法比规则法灵活得多,但需要的数据量不小,而且模型效果很大程度上取决于数据的质量和数量。
第三类就是现在最火的深度学习方法,特别是各种预训练语言模型。这些模型在海量文本上进行了预训练,已经学到了丰富的语言知识。只要在特定任务的数据上做少量微调,就能取得很好的效果。像BERT、RoBERTa这些模型在意图识别任务上表现都相当出色。当然,这种方法对计算资源的要求也相对较高。
在开发声网的聊天机器人时,我发现意图识别有几个点特别容易踩坑。首先是意图的粒度问题。意图分得太粗,机器人没法精准响应;分得太细,又会导致数据稀疏,模型很难学好。比如”订机票”要不要分成”订国内机票”和”订国际机票”?这需要根据实际业务需求来定,而不是一味追求精细。
然后是意图边界的处理。用户的输入有时候可能同时涉及多个意图。比如”我想退掉上周买的那个耳机,顺便问一下你们什么时候发货”。这既包含”退货”意图,又包含”物流咨询”意图。怎么处理这种多意图情况?常见的做法是设计一个主 intent 和 slot filling 结合的框架,或者让模型输出多个意图标签。

如果说意图是”做什么”,那实体就是”对谁做”以及”做成什么样”。在NLP领域,实体提取有一个专门的名字叫命名实体识别,简称NER。它要解决的就是从文本中识别出特定类型的信息片段。
常见的实体类型包括时间(如”明天下午三点”)、地点(如”北京西站”)、人物(如”张经理”)、组织(如”声网公司”)、产品名称、数字表达式等等。不同业务场景下,需要提取的实体类型也不一样。医疗领域的机器人可能要提取药品名称、剂量、症状;金融领域的则要提取金额、账户名、理财产品名称。
我刚开始做实体提取的时候,有一个特别天真的想法:是不是给每个实体类型写一套正则表达式就能搞定了?结果很快发现这条路走不通。正则只能处理格式非常规整的情况,而现实中的表达方式太灵活了。同样是表达时间,”三天后”、”下周三”、”2024年1月15日上午”这些写法完全不一样,正则根本覆盖不过来。
早期实体提取主要靠手工特征和传统机器学习。比如用CRF(条件随机场)模型,配合词性标注、词形特征等人工设计的特征。这个方法在当年效果还可以,但非常依赖特征工程的质量,而且泛化能力有限。
后来深度学习时代来了,BiLSTM-CRF成了主流方案。这个模型能够自动学习序列特征,不需要人工设计那么多特征。再后来,预训练模型出现后,BERT+CRF的组合成了新的标配。BERT强大的语言理解能力配上CRF对序列标签的建模能力,在很多实体识别数据集上都取得了突破性的效果。
这里我想特别提一下实体的边界问题。很多时候,用户输入里的实体边界并不清晰。比如”我想订一张从北京到上海的高铁票”,这里”北京”是出发地实体,”上海”是目的地实体。但如果是”我想订一张京沪高铁票”,那”京沪高铁”整体才算一个实体。模型需要学会在不同的上下文中正确判断实体的边界在哪里。
提取出实体只是第一步,很多时候还需要对实体进行规范化。比如用户说”大后天”、”下下周”、”腊月二十”,这些都需要转换成标准的时间格式。还有像”三千”、”3k”、”3000块”这些不同的金额表达,都需要统一成某种标准格式。
这部分工作通常需要结合规则和词典来做。因为很多表达方式是有规律的,可以用规则来转换;还有一些是约定俗成的说法,需要维护一个映射词典。比如”番茄”和”西红柿”指的是同一种东西,”土豆”和”洋芋”也是。这些同义词的规范化对后续的业务处理很重要。
在实际的聊天机器人系统中,意图识别和实体提取通常不是孤立进行的,而是紧密配合的两个环节。一个常见的架构是 pipeline 模式:先做意图识别,确定用户要做什么;再做实体提取,抽取完成这个意图所需的具体参数。
举个例子。用户说”帮我查一下张三2024年1月份的业务办理记录”。首先,意图识别模块判断这是”查询业务记录”意图。然后,实体提取模块从这句话里抽出”张三”(人物实体)和”2024年1月份”(时间实体)。这两个实体就是执行查询操作必须的参数。
另一个常见的架构是联合模型,就是用一个模型同时做意图识别和实体提取。这种方法的好处是两个任务可以互相促进,比如知道是”订票”意图,模型在识别地点实体时就会更准确,因为订票场景下的地点通常就是出发地和目的地。Joint BERT 就是这类方法的代表性工作。
不过联合模型也有缺点,就是模型结构更复杂,训练难度更大。在资源有限的情况下,pipeline 方式其实是个更务实的选择。而且 pipeline 方式更容易做错误分析,比如实体识别错了,我们可以单独优化实体识别模块,而不影响意图识别部分。
不管是意图识别还是实体提取,模型效果很大程度上取决于训练数据的质量和数量。但高质量的标注数据真的很难搞。首先,你得找对领域熟悉的人来做标注,不然连标注结果都可能错。其次,标注的一致性很难保证,同一句话不同的人可能有不同的理解。还有,真实场景中的表达方式太丰富了,想通过有限的标注数据覆盖所有情况几乎是不可能的。
我的经验是,数据增强技术在这里很有用。比如对句子进行同义词替换、随机删除、交换词语位置等操作,人工合成一些新的训练样本。这种方法在图像领域早就成熟了,在NLP领域也同样有效。当然,增强的幅度要控制好,变了之后语义不能变。
另外,在冷启动阶段如果没有足够的数据,可以先用规则顶一阵子。规则虽然覆盖面有限,但至少能保证核心场景可用。然后在运行过程中逐步收集用户的真实 query,用这些数据来迭代优化模型。这是一个渐进式的过程,急不来。
自然语言的一大特点就是歧义性。同一个词在不同场景下可能指代完全不同的东西。比如”银行”,在”我要去银行”里是地点实体,在”银行存款利率”里又可能和金融产品相关。模型需要结合上下文才能正确理解。
对话系统中的上下文依赖问题更复杂。用户可能说”把那个改成明天下午三点”,”那个”到底指什么?必须结合之前的对话才能知道。还有用户的输入可能是省略句,比如用户先问”明天天气怎么样”,然后又说”那后天呢”,这个”那后天呢”其实是”那后天天气怎么样”的省略。
处理上下文依赖通常需要在模型中引入对话历史信息。简单的方法是把历史对话拼接起来作为输入;复杂一点的方法会用专门的记忆网络来存储和检索历史信息。这块也是当前研究的热点之一。
训练出一个效果不错的模型只是第一步,真正的挑战在于把它上线并持续优化。模型在线上跑的时候,面对的是真实用户,什么情况都可能遇到。有的用户输入特别长,有的特别简短,有的充满网络流行语和各种缩写。
监控和反馈机制很重要。应该记录下模型判断错误的case,定期分析这些错误案例,看看是意图识别错了还是实体提取错了,是数据问题还是模型问题。然后针对性地补充数据、调整策略。这是一个持续迭代的过程,没有一劳永逸的解决方案。
大语言模型的出现给这个领域带来了很大的变化。像GPT系列模型展现出了惊人的语言理解和生成能力,它们能不能直接用来做意图识别和实体提取?我想说,大模型确实很强,但在特定的业务场景下,直接用大模型可能不是最优选择。大模型的推理成本高,响应延迟大,而且有时候它的输出不太可控。
更实际的用法可能是用大模型来辅助数据标注、生成训练数据,或者在复杂场景下做联合推理。基础的任务仍然可以用轻量级的专门模型来做。这就像声网的SD-RTN®网络一样,不同的场景用最适合的技术方案,而不是一刀切。
另外,多模态也是一个趋势。未来的聊天机器人可能不仅处理文字,还会处理语音、图像、甚至视频。用户可能发一张照片问”这件衣服还有别的颜色吗”,机器人需要理解图像内容才能回答。这对意图识别和实体提取都提出了新的挑战。
写了这么多,其实核心想说的就是:意图识别和实体提取是聊天机器人的两项基本功,看起来原理不复杂,但要做好真的需要花不少心思。从数据收集、模型选型到上线优化,每个环节都有坑,也都有值得深挖的地方。希望这篇文章能给正在做或者打算做聊天机器人开发的朋友一些参考。有问题随时交流,大家一起进步。
