惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
U
Unit 42
大猫的无限游戏
大猫的无限游戏
H
Help Net Security
G
Google Developers Blog
Recent Announcements
Recent Announcements
B
Blog RSS Feed
罗磊的独立博客
博客园 - Franky
J
Java Code Geeks
S
SegmentFault 最新的问题
D
DataBreaches.Net
C
Check Point Blog
Blog — PlanetScale
Blog — PlanetScale
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
腾讯CDC
博客园_首页
美团技术团队
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
The Cloudflare Blog
aimingoo的专栏
aimingoo的专栏

Bright LGM's Blog

外部性与程序设计 每日一思 每日一思 每日一思 每日一思 每日一思 每日一思 每日一思 成长 平淡与不平淡 每日一思 每日一思 每日一思 每日一思 每日一思 每日一思 每日一思 每日一思 每日一思
LLM 时代的集成意图识别实践
Bright LGM · 2025-03-31 · via Bright LGM's Blog

意图识别是构建可靠人机交互系统的核心技术,其意义在于通过精准判断用户需求,为后续处理提供确定性基础。

尽管大型语言模型(LLM)具备强大的生成能力,但其输出可能生成错误、矛盾甚至违规信息。在金融、医疗、法律等监管严格领域,直接使用 LLM 结果可能引发合规风险,甚至导致重大经济损失或法律纠纷。

因此,多数严谨系统仍采用传统分层架构:首先通过意图识别技术解析用户输入的核心诉求(例如判断用户是查询账户余额、还是咨询理财问题);随后根据预设规则执行对应业务流程,调用专门的数据接口或知识库进行响应。

这种架构的优势在于:意图识别环节可过滤无效请求并拦截高风险输入,处理环节则通过结构化流程确保合规性与结果可靠性,既发挥人工智能的辅助作用,又通过分层设计规避技术不确定性带来的潜在危害。

因此,意图识别仍然是构建智能系统非常重要的一环。

意图识别的技术选择

BERT 类模型

意图识别是一个典型的文本分类问题。在 LLM 之前,广泛采用的是基于 BERT 类或预训练 BERT 类模型进行训练或微调的方法。这类方法通过大量语料训练,能够较好地理解语义,准确识别用户意图。

但是这类方法也存在明显的局限性。因为为了构建这样的模型,我们不得不:

  1. 花时间搜集准备大量语料,并进行标注
  2. 在有 GPU 的专用训练设备上面训练
  3. 部署在有 GPU 的专用推理设备上

这些步骤都将花费大量的时间,并且,由于模型是专用的,线上推理时也容易引起资源浪费问题。

基于 LLM 技术

在 LLM 的时代,意图识别有没有什么更好的做法呢?

LLM 能被广泛接受的原因之一是其强大的通用性。通过将任务描述成提示词,理论上同一个 LLM 能处理任何的问题。因此,LLM 的使用门槛极低,无需收集和标注数据,无需训练和部署模型,只需要将任务描述成提示词即可。

意图识别任务当然也可以用 LLM 提示词来表示。看起来,用 LLM 来识别意图可能是 LLM 时代一个相当不错的选择。准备语料、训练、部署这些繁琐的步骤全部被编写提示词替代了。

基于 RAG 技术

除了上述两种常见的技术之外,还有什么其他方法吗?

LLM 时代另一个被广泛使用的 RAG 技术(Retrieval Augmented Generation)事实上也可以用于处理分类问题。RAG 中的一个关键技术点是基于语义计算相关性。

一个直接的想法是,是不是可以:1. 搜集所有分类的真实文本,组织成一个文本库;2. 在文本库中检索待预测的文本;3. 找到结果中最高相关性的文本对应的分类作为预测分类。

看起来也是可行的,而且它也具备很多优势:

  1. 利用通用模型的能力,无需重头开始训练模型
  2. 结果具备可解释性
  3. 具备很强的可工程优化性,在发现预测不好的文本时,直接将此文本放入文本库即可提升下次预测的准确度

基于 Embedding+MLP 小模型方案

事实上,完全基于相关度的分类也有其问题,其中比较严重的可能是泛化能力偏弱。即,如果文本库中没有相似的说法,则很难正确分类。

有什么办法可以提升泛化能力呢?

我们注意到 RAG 的相关性计算过程是:

  1. 预先将文本库中的所有文本全部编码为向量存储起来
  2. 在预测时,先用同样的模型将待预测文本编码为一个向量,然后再用此和向量和文本库中的全部向量计算相似度

文本的向量化是 RAG 中的关键一环,事实上,生成的文本向量(也称做文本嵌入,即 Embedding)不仅可以用于计算相似度,还可以用来进行分类。

我们可以设计一个简单的 MLP 模型(Multi-Layer Perceptron,即多层感知器模型,是一个简单的多层全连接的神经网络模型),输入为文本向量,输出为分类标签。

这样,我们就可以在预测时,先将文本编码为向量,然后用 MLP 模型进行分类。

这个方案的优势在于:

  1. 依然可以利用通用模型的能力,无需重头开始训练模型
  2. 泛化能力更强,即使文本库中没有相似的说法,也可以通过 MLP 模型进行分类
  3. 由于利用了大部分的通用文本向量模型的能力,MLP 模型的规模可以做得比较小,从而使得 MLP 模型的训练和推理都非常快

集成的意图识别方案

上面介绍了常用的意图识别技术,可以看到有很多各有优劣的技术。那么,在实践时要怎么选择呢?

一般而言,可以综合这些技术,设计一个优势互补的集成的意图识别方案,以便满足实际产品运营过程中的多种不同的诉求,比如:

  1. 如何快速(如分钟级)而稳定地解决某些特定情况(如某些 ML 模型表现不太好的例子)的表现
  2. 在达到较高准确度的同时提升响应速度
  3. 在分布外(不同于预先识别到的场景及语料)的场景下表现也要相对较好

在真实场景中落地时,可以如下结合这些技术:

1
2
3
4
5
6
7
8
9
flowchart TB
用户输入 --> 基于RAG的相似度查找
基于RAG的相似度查找 --> 是否找到高相似度文本{{是否找到高相似度文本}}
是否找到高相似度文本 --> |YES|输出对应的意图结果
是否找到高相似度文本 --> |NO|基于Embedding+MLP进行意图识别
基于Embedding+MLP进行意图识别 --> 检查模型置信度{{检查模型置信度}}
检查模型置信度 --> |高|输出对应的意图结果
检查模型置信度 --> |低|基于LLM进行意图识别
基于LLM进行意图识别 --> 输出对应的意图结果

由于 BERT 类模型可以被更简单通用的基于 Embedding+MLP 的技术替代,所以,这里就可以不考虑选择 BERT 类模型了。

这样的方案的优势在于:

  1. 通过基于 RAG 的相似度查找,可以快速(响应时间约在 300ms 左右)定位到与用户输入高度相似的历史文本,从而提高意图识别的准确性和效率。
  2. 在基于 Embedding+MLP 进行意图识别时,可复用上一步生成的文本向量,提高泛化性的同时,满足效率要求(10ms 左右)
  3. 通过上述两个步骤,希望能处理掉 80%以上的请求,即,可将 80%以上的使用场景响应时间都控制在 300ms 左右
  4. 对于另外的约 20%比较难的用户输入,则采用基于 LLM 进行意图识别,可以利用 LLM 的推理能力输出更准确的结果。这一步耗时通常较长,一般在 1~2s,但是由于只处理 20%的请求,对整体的响应时间影响较小。
  5. 对于整体上表现都不够好的用户输入,可以及时补充到 RAG 的文本库中,如果标注及时,可完成分钟级的意图识别准确度更新

可见,上述方案综合了各类技术的优劣,形成了一个具备高工程落地可行性的方案。

方案的实现

上述集成方案中的基于 RAG 的相似度查找和基于 LLM 进行意图识别两个步骤看起来难度都不算高。具备一定的调用通用大模型能力的背景即可快速完成。

下面主要分享一下工程实现过程中常常会碰到的几个问题。

语料准备

不管是在基于 RAG 的相似度查找,还是在基于 Embedding+MLP 小模型的步骤中都需要用到语料。

  • 基于 RAG 的相似度查找需要预先构建一个文本语料库
  • 基于 Embedding+MLP 小模型则需要构建训练语料及验证语料数据集

事实上基于 LLM 的技术也至少需要一个用于评估的数据集语料。

所以,语料的准备常常是意图识别中最重要也是最复杂的一部分内容。那么,在 LLM 的时代,有没有什么更高效的方法来准备语料呢?

我们当然可以利用 LLM 强大的文本生成能力来辅助快速构建语料了!

具体来说,我们可以先给出一些分类的标签及其说明,然后让 LLM 根据这些标签生成对应的语料。

例如,假设我们有一个“交易查询”的意图,我们可以使用提示词:

用户想要在系统中查询订单详情。假设你是这样的用户,有哪些可能的消息发送到智能客服?以列表的形式返回,列举20个,尽可能包含可能的各种句式、表达方式。可能涉及时间范围、金额范围、商家等。在每一行输出一个,除了消息之外,不要输出任何其他字符

把这样的消息发送给 GPT,看看其生成的语料质量如何,如果不满意则调整一下提示词继续。

在优化好提示词之后,就可以使用 API 调用 LLM 的接口来批量生成语料了。

除此之外,还可以针对搜集到的真实语料用 LLM 进行扩展,可以采用类似这样的提示词:

“{input}”在这一句话里面,{intent_def}。生成10个意思相近的表达。只需输出十行,不要输出任何额外的字符

使用这样的方法,可以快速得到成千上万的语料,然后就可以在此基础上训练模型了。

当然,LLM 生成的语料还是有偏的(跟真实语料不一致),准备一份真实语料用于验证模型表现还是很有必要的。这类语料可以不用太多,因此也相对容易搜集。

持续的语料优化

在模型上线之后,可以通过收集用户与智能客服的交互数据,不断优化语料库和模型。

例如,可以将用户输入的语句进行人工标注,然后与模型预测的结果进行对比,如果预测结果不准确,则可以将这些语句加入到 RAG 语料库中,并可以重新训练 MLP 模型。

当然,也可以用 LLM 自动改写这些识别不好的用户输入,在扩大语料范围和适用性后,再加入 RAG 语料库或重训 MLP。

同时,更进一步,可以识别这些语句的语言模式,然后利用 LLM 参考此模式去生成语料。

比如用户可能不想继续上一个意图,而提出了新意图。典型的输入比如“算了,我不想处理交易了,帮我查询一下如何申购理财产品吧”。

则可以编写提示词:

用户之前在操作功能“{last_function}”,现在办完了或者不想办理这个了,改为想要办理另一个功能“{function}”。假设你是这样的用户,有哪些可能的消息发送到智能客服?以列表的形式返回,列举10个,尽可能包含可能的各种句式、表达方式。在每一行输出一个,除了消息之外,不要输出任何其他字符

利用上述提示词可以让 LLM 批量生成此类的语料,从而处理掉一类的问题。

辅助意图的设计

由于意图识别常常基于单轮的用户输入来实现,而用户的对话具有持续性。因此,很多时候常常不能根据单轮的用户输入推断出有目的性的意图。

比如,用户想要补充信息,输入“日期就用上个月的吧”,此时是无法将输入映射到一个确定的目的性特别强的意图上去。

但是,如果结合上下文,我们就可以知道用户这是在补充信息,而当前的目的性意图与上一轮的是一致的。

因此,在设计意图时,除了设计那些目的性很强的意图之外,还需要设计一些辅助意图,用来描述用户可能的对话行为。在模型识别到此类意图时,可以通过对话的状态保持找到当前的真实意图。

此类辅助意图可以有:

  1. 提供信息
  2. 表达感谢
  3. 确认信息
  4. 否认信息
  5. 转人工

MLP 小模型的训练和部署

MLP 模型的代码实现、训练和评估,可能相对有一定门槛。

这里也可以借助 LLM 强大的代码能力辅助我们完成工作。

编写如下提示词发给 LLM,可以帮我们自动完成大部分的 MLP 编码工作:

帮我生成代码完成功能:
1. 从一系列文本文件中读取文本,文件名为分类名,文件内容每一行为改分类对应的语料
2. 调用bge模型对这些文本生成embedding,并将embedding缓存到一个指定的文件中
3. 构建一个mlp模型,利用embedding的结果构建一个分类器,实现多分类任务,并考虑样本在多个分类中不平衡的情况
4. 实现训练和eval代码

在得到代码之后,可能需要将调用 bge 模型的过程改成调用通用的模型 API。由于 MLP 模型很小,可以在普通的开发机器上完成模型的训练。

在我的场景中,训练一个包含 12w 左右训练数据的模型,采用三层隐层维度 256 的 MLP 模型,只需要 7 分钟左右即可训练完成,准确率可以达到 97%左右(取决于语料质量),而模型大小只有 1.5MB 左右。

模型训练完成之后,如何部署到应用中呢?

模型训练的代码一般使用PyTorch或者Tensorflow这类框架编写完成。但是在部署这类小模型时如果也依赖这类框架执行推理计算,则显得大材小用了。

事实上,对于这类简单的 MLP 模型,我们可以直接用如numpy这类向量计算库完成推理。

将以下提示词发送给 LLM,就可以得到numpy版本的推理代码:

我有一个MLP模型代码如下:
...
请编写一个函数将模型参数保存为numpy格式,然后再编写另一个函数使用numpy加载这个模型的参数进行推理预测

得到的代码稍加改动就可集成到模型意图识别的流程中了。

总结

本文介绍了在 LLM 时代如何搭建一个实用的集成意图识别系统。

通过对常用的意图识别技术手段的分析,结合各种技术的优势,取长补短,分享了一个实用的设计。以最大范围使用通用模型的能力为原则,在落地实现时,可以有效降低工作量。

另外,使用 LLM 生成训练数据和模型代码,我们大大简化了开发过程,并对系统持续演进和优化提供了思路。