意图识别:消息进来该走哪条路
作者:程序员马丁
Ragent AI —— 从 0 到 1 纯手工打造企业级 Agentic RAG,拒绝 Demo 玩具!AI 时代,助你拿个offer。
上一篇讲了 Query 改写,RAG 系统的多轮对话能力已经比较完整了:会话记忆让模型记住了上下文,Query 改写让检索系统也能理解上下文,检索效果大幅提升。
但你把这套系统上线之后,会发现一个尴尬的问题。
用户说“你好,我想咨询一下”,系统拿“你好我想咨询一下”去向量数据库里检索,召回了退货政策、保修条款、配送时效三个 chunk,然后模型基于这些 chunk 回答:“您好,关于退货政策,我们提供七天无理由退货服务……”——用户只是打了个招呼,你给人家讲退货政策?
用户说“我查一下我的年假余额”,系统去知识库里检索年假余额,召回了公司年假制度:正式员工每年享有 10 天带薪年假……,模型回答:“根据公司年假制度,正式员工每年享有 10 天带薪年假。”——用户想知道自己还剩几天年假,不是问年假制度。这个问题应该调 HR 系统的 API,不是查知识库。
问题出在哪?你的 RAG 系统是一根筋的——不管用户说什么,都往知识库里检索。就像一家医院没有分诊台,所有患者来了都直接送去内科,牙疼的、骨折的、做体检的全挤在内 科门口。
今天要讲的就是给 RAG 系统装一个分诊台——意图识别与问题路由。用户消息进来,先判断它应该走哪条路:查知识库、调工具、直接闲聊、还是反问用户补充信息,然后把请求分发到对应的处理流程。
为什么需要意图识别
1. 一根筋的 RAG 系统会出什么问题
不做意图识别,所有消息都走 RAG 检索,会遇到三类问题:
| 用户消息类型 | 走 RAG 检索的结果 | 实际应该怎么处理 |
|---|---|---|
| 闲聊(你好、谢谢、哈哈) | 召回不相关的 chunk,模型基于不相关内容强行回答,比不检索还差 | 模型直接回答,不需要检索 |
| 工具调用(查我的订单、我还剩几天年假) | 知识库里没有用户的个人数据,检索不到有用信息,模型说“找不到相关信息” | 调 Function Call / MCP 查实时数据 |
| 模糊问题(有什么推荐的吗、怎么办) | 检索结果分散在多个主题,模型乱答一通 | 反问用户补充信息,明确意图后再处理 |
闲聊走检索,比不检索还差——这一点很多人没意识到。RAG 系统的生成策略里通常有一条规则:“基于以下参考资料回答用户问题”。如果检索到的 chunk 和用户问题 完全不相关,模型要么硬着头皮基于不相关的内容回答(答案很奇怪),要么触发兜底回复“抱歉,找不到相关信息”(用户只是说了句你好,你说找不到相关信息?)。
如果不走检索,模型直接回答“你好”,反而更自然。
2. 医院分诊台的类比
意图识别的作用,就像医院的分诊台。
患者来了不是直接看病,先到分诊台:护士问你哪里不舒服,然后告诉你该去哪个科室。牙疼去口腔科,骨折去骨科,做体检去体检中心,不确定什么病的先去全科看看。
RAG 系统也一样。用户消息进来,先经过意图识别这个分诊台:
- 问产品信息、政策规定 → 去“知识库科室”(RAG 检索)
- 查订单、查年假、提交退货 → 去“工具科室”(Function Call / MCP)
- 打招呼、说谢谢 → 去“前台”(直接回复)
- 说不清楚想要什么 → “请您再描述一下症状”(引导澄清)
没有分诊台的医院效率低、体验差;没有意图识别的 RAG 系统也是一样。
四种意图类型
在电商客服场景下,用户消息可以分为四种意图类型。这个分类体系不是固定的——不同业务场景可能有不同的分类方式,但这四类覆盖了大多数场景。
1. 知识检索(Knowledge Retrieval)
用户在问一个知识库能回答的问题。这类问题的特点是:答案存在于你的知识库文档里,是“静态”的、通用的知识。
典型问题:
- iPhone 16 Pro 的退货政策是什么?
- 保修期内屏幕碎了能免费换吗?
- 你们的配送范围覆盖哪些城市?
- 会员等级有什么权益?
处理方式:走完整的 RAG 检索流程——Query 改写 → 向量检索 → 重排序 → 生成答案。
2. 工具调用(Tool Invocation)
用户想查询个人数据、实时信息,或者执行某个操作。这类问题的特点是:答案不在知识库里,需要调用外部系统的 API 才能获取。
典型问题:
- 帮我查一下订单 #12345 的物流状态(查个人订单数据)
- 我还剩几天年假?(查 HR 系统)
- 帮我申请退货(执行操作)
- 今天有什么优惠活动?(查实时数据)
处理方式:走 Function Call / MCP 流程——识别出需要调用哪个工具,传入参数,执行工具,把结果返回给模型生成最终答案。
怎么区分知识检索和工具调用?关键看答案的来源。如果答案在你的知识库文档里(退货政策、保修条款、产品参数),就是知识检索;如果答案需要查数据库、调 API、访问外部系统(某个订单的状态、某个人的年假余额、实时库存),就是工具调用。
3. 闲聊对话(Chitchat)
用户在闲聊、打招呼、表达感谢、开玩笑,不涉及具体的业务问题。
典型问题:
- 你好
- 谢谢你的帮助
- 你是 AI 还是真人?
- 今天心情不好
- 哈哈,你真有趣
处理方式:模型直接回答,不走检索,也不调工具。System Prompt 里定义好闲聊时的回复风格就行。
前面说过,闲聊消息走 RAG 检索反而更差。模型自己就能很好地处理这类对话,不需要知识库的辅助。
4. 引导澄清(Clarification)
用户的问题太模糊,系统无法确定该走哪条路。这时候不应该硬答,而是反问用户补充信息。
典型问题:
- 有什么推荐的吗?(推荐什么?手机?配件?)
- 怎么办?(什么怎么办?退货?维修?)
- 帮我看看(看什么?订单?产品?)
- 出问题了(什么产品?什么问题?)
处理方式:不检索也不调工具,直接返回一个引导性的问题,让用户补充关键信息。
引导澄清不是万能的,不能动不动就反问用户。如果用户的问题虽然简短但意图明确(比如“价格呢”,在聊 iPhone 16 Pro 的上下文中意图很清楚),就不应该反问,而是结合对话历史直接处理。只有在真的无法判断意图时才引导澄清。
5. 四种意图对比
| 意图类型 | 触发条件 | 处理流程 | 典型示例 |
|---|---|---|---|
| 知识检索 | 问知识库里有的通用知识 | Query 改写 → 检索 → 生成答案 | 退货政策是什么 |
| 工具调用 | 查个人数据 / 实时信息 / 执行操作 | Function Call / MCP | 查我的订单状态 |
| 闲聊对话 | 打招呼 / 感谢 / 闲聊 | 模型直接回答 | 你好、谢谢 |
| 引导澄清 | 问题模糊、信息不足 | 反问用户补充信息 | 有什么推荐的 |
实际业务中,意图分类体系可能更细。比如电商场景可能拆出“投诉”“催单”“比价”等专门的意图类别。但核心思路不变:先分类,再路由。从这四种基础类型开始,根据业务需要逐步细化。
意图识别的三种方案
知道了要分哪几类意图,接下来的问题是:怎么判断一条用户消息属于哪个类别?
1. 规则匹配方案
最简单直接的方案:用关键词和正则表达式判断意图。
public class RuleBasedClassifier {
/** 闲聊关键词 */
private static final Set<String> CHITCHAT_KEYWORDS = Set.of(
"你好", "您好", "谢谢", "感谢", "再见", "拜拜",
"哈哈", "嗯嗯", "好的", "收到", "明白了"
);
/** 工具调用关键词 */
private static final Set<String> TOOL_KEYWORDS = Set.of(
"我的订单", "查订单", "订单号", "物流状态",
"年假", "余额", "申请退货", "提交",
"修改地址", "取消订单"
);
public String classify(String query) {
// 完全匹配闲聊关键词(短消息)
if (query.length() <= 6 && CHITCHAT_KEYWORDS.contains(query)) {
return "chitchat";
}
// 包含工具调用关键词
for (String keyword : TOOL_KEYWORDS) {
if (query.contains(keyword)) {
return "tool";
}
}
// 消息太短且不是闲聊,可能需要澄清
if (query.length() < 5) {
return "clarification";
}
// 默认走知识检索
return "knowledge";
}
}
规则匹配的优缺点很明显:
| 维度 | 表现 |
|---|---|
| 速度 | 极快(微秒级) |
| 准确率 | 低——只能匹配写死的关键词,覆盖不了用户的各种表达方式 |
| 成本 | 零(不调模型) |
| 维护成本 | 高——每发现一个 bad case 就要加一条规则,越加越多越加越乱 |
规则方案最大的问题是无法理解语义。“帮我看看剩几天假”没有命中“年假”关键词,就会被错分为知识检索。“能退吗”——是问退货政策(知识检索)还是想发起退货(工具调用)?规则无法区分。
规则方案适合做第一层快速过滤——把最明确的意图快速识别出来(“你好”就是闲聊,“查订单 #12345”就是工具调用),不确定的交给大模型处理。
2. 大模型分类方案
用大模型做意图分类,核心是设计好分类 Prompt。
2.1 分类 Prompt 的设计
你是一个意图分类助手。根据对话历史和用户的最新消息,判断用户的意图类别。
意图类别定义:
1. knowledge - 知识检索:用户在询问产品信息、政策规定、操作指南等知识库中的内容。
示例:"iPhone 16 Pro 的退货政策是什么""保修期多久""配送范围覆盖哪些城市"
2. tool - 工具调用:用户想查询个人数据、实时信息,或执行某个操作。
示例:"查一下我的订单状态""帮我申请退货""我还剩几天年假"
3. chitchat - 闲聊对话:用户在打招呼、感谢、闲聊,不涉及具体业务问题。
示例:"你好""谢谢""你是AI吗""今天心情不好"
4. clarification - 引导澄清:用户的问题太模糊,缺少关键信息,无法确定意图。
示例:"有什么推荐的""