今天要讲的就是给 RAG 系统装一个分诊台——意图识别与问题路由 。用户消息进来先判断它应该走哪条路查知识库、调工具、直接闲聊、还是反问用户补充信息然后把请求分发到对应的处理流程。四种意图类型在电商客服场景下用户消息可以分为四种意图类型。这个分类体系不是固定的——不同业务场景可能有不同的分类方式但这四类覆盖了大多数场景。知识检索Knowledge Retrieval用户在问一个知识库能回答的问题。这类问题的特点是答案存在于你的知识库文档里是“静态”的、通用的知识。典型问题iPhone 16 Pro 的退货政策是什么保修期内屏幕碎了能免费换吗你们的配送范围覆盖哪些城市会员等级有什么权益处理方式走完整的 RAG 检索流程——Query 改写 → 向量检索 → 重排序 → 生成答案。工具调用Tool Invocation用户想查询个人数据、实时信息或者执行某个操作。这类问题的特点是答案不在知识库里需要调用外部系统的 API 才能获取。典型问题帮我查一下订单 #12345 的物流状态查个人订单数据我还剩几天年假查 HR 系统帮我申请退货执行操作今天有什么优惠活动查实时数据处理方式走 Function Call / MCP 流程——识别出需要调用哪个工具传入参数执行工具把结果返回给模型生成最终答案。怎么区分知识检索和工具调用关键看答案的来源。如果答案在你的知识库文档里退货政策、保修条款、产品参数就是知识检索如果答案需要查数据库、调 API、访问外部系统某个订单的状态、某个人的年假余额、实时库存就是工具调用。闲聊对话Chitchat用户在闲聊、打招呼、表达感谢、开玩笑不涉及具体的业务问题。典型问题你好谢谢你的帮助你是 AI 还是真人今天心情不好哈哈你真有趣处理方式模型直接回答不走检索也不调工具。System Prompt 里定义好闲聊时的回复风格就行。前面说过闲聊消息走 RAG 检索反而更差。模型自己就能很好地处理这类对话不需要知识库的辅助。引导澄清Clarification用户的问题太模糊系统无法确定该走哪条路。这时候不应该硬答而是反问用户补充信息。典型问题有什么推荐的吗推荐什么手机配件怎么办什么怎么办退货维修帮我看看看什么订单产品出问题了什么产品什么问题处理方式不检索也不调工具直接返回一个引导性的问题让用户补充关键信息。引导澄清不是万能的不能动不动就反问用户。如果用户的问题虽然简短但意图明确比如“价格呢”在聊 iPhone 16 Pro 的上下文中意图很清楚就不应该反问而是结合对话历史直接处理。只有在真的无法判断意图时才引导澄清。四种意图对比意图识别的三种方案知道了要分哪几类意图接下来的问题是怎么判断一条用户消息属于哪个类别规则匹配方案最简单直接的方案用关键词和正则表达式判断意图。规则匹配的优缺点很明显规则方案最大的问题是无法理解语义 。“帮我看看剩几天假”没有命中“年假”关键词就会被错分为知识检索。“能退吗”——是问退货政策知识检索还是想发起退货工具调用规则无法区分。规则方案适合做第一层快速过滤 ——把最明确的意图快速识别出来“你好”就是闲聊“查订单 #12345”就是工具调用不确定的交给大模型处理。大模型分类方案用大模型做意图分类核心是设计好分类 Prompt。2.1 分类 Prompt 的设计你是一个意图分类助手。根据对话历史和用户的最新消息判断用户的意图类别。 意图类别定义 1. knowledge - 知识检索用户在询问产品信息、政策规定、操作指南等知识库中的内容。 示例iPhone 16 Pro 的退货政策是什么保修期多久配送范围覆盖哪些城市 2. tool - 工具调用用户想查询个人数据、实时信息或执行某个操作。 示例查一下我的订单状态帮我申请退货我还剩几天年假 3. chitchat - 闲聊对话用户在打招呼、感谢、闲聊不涉及具体业务问题。 示例你好谢谢你是AI吗今天心情不好 4. clarification - 引导澄清用户的问题太模糊缺少关键信息无法确定意图。 示例有什么推荐的怎么办帮我看看出问题了 判断规则 - 结合对话历史判断相同的话在不同上下文中意图可能不同 - 如果用户的问题涉及我的查一下等个人化表述通常是工具调用 - 如果问题在问通用的规则、政策、产品信息通常是知识检索 - 只有在真的无法判断意图时才分类为 clarification - 以 JSON 格式输出格式为{intent: 分类结果, confidence: 置信度} - 不要输出 JSON 以外的任何内容 对话历史 {history} 用户最新消息{query}几个设计要点每种意图都有明确定义和示例 这是 Few-shot 的典型用法给模型足够的参考。定义要写清楚边界——什么算知识检索什么算工具调用不能让模型猜强调结合对话历史判断 同样一句“能退吗”在不同的对话上下文中意图不同。第一轮对话时大概率是问退货政策知识检索前面在聊某个具体订单时大概率是想发起退货工具调用输出JSON格式 方便程序解析。加 confidence 字段可以在置信度低时触发兜底策略clarification要谨慎使用 Prompt 里明确说“只有在真的无法判断时才分类为 clarification”避免模型动不动就要求澄清2.2 分类效果与边界情况大模型分类的准确率通常在 90% 以上但有一些边界情况需要注意混合方案推荐规则匹配速度快但准确率低大模型分类准确但有延迟和成本。把两者结合起来就是混合方案规则做第一层快速过滤大模型做第二层精确分类 。流程是这样的规则层只处理高置信度 的明确场景短消息且完全匹配闲聊关键词“你好”“谢谢”→ 直接判定为闲聊包含明确的工具触发词且带具体参数“查订单 #12345”→ 直接判定为工具调用其他所有情况 → 交给大模型分类这样做的好处是大部分闲聊消息不需要调模型 用户打招呼、说谢谢这种高频场景规则就能搞定省了一次 API 调用复杂场景有模型兜底 语义模糊、上下文相关的消息交给大模型判断准确率有保障成本可控 实际场景中闲聊和明确的工具调用大约占 30%~40% 的消息量这部分都可以被规则层拦截三种方案的对比问题路由的架构设计路由器模式意图识别完成后需要一个路由器把请求分发到不同的处理流程。整体架构是这样的路由器的职责很简单拿到意图分类结果调用对应的处理器。每个处理器各自负责自己的逻辑互不干扰。用 Java 代码表示路由器的核心逻辑就是一个 switchpublic String route(String intent, ListMessage history, String query) throws IOException {switch (intent) {case knowledge:// 知识检索路径Query 改写 → 检索 → 生成答案return handleKnowledgeRetrieval(history, query);case tool:// 工具调用路径Function Call / MCPreturn handleToolInvocation(history, query);case chitchat:// 闲聊路径直接调模型生成回答return handleChitchat(history, query);case clarification:// 澄清路径返回引导问题return handleClarification(history, query);default:// 兜底默认走知识检索return handleKnowledgeRetrieval(history, query);}}default 分支走知识检索是一个安全的兜底策略。知识检索路径本身就有兜底机制——如果检索不到相关内容模型会说“抱歉找不到相关信息”。这比走错其他路径比如误调了工具要安全得多。意图识别在 RAG 完整链路中的位置把意图识别加入后完整的 RAG 链路变成了这样注意意图识别的位置在会话记忆之后Query改写之前 。为什么在会话记忆之后因为意图识别可能需要对话历史来做判断。用户说“好的帮我退了吧”如果不知道前面在聊什么无法判断这是工具调用确认退货操作。为什么在 Query 改写之前因为 Query 改写只在知识检索路径上才需要。如果意图是闲聊或工具调用根本不需要做 Query 改写直接走对应的路径就行。生产环境的注意事项意图分类的准确率监控意图分类的错误通常不会被用户直接感知到——用户只知道系统回答得不好不知道是因为意图分错了导致走了错误的处理路径。所以需要主动监控。建议记录每次分类的完整信息{session_id: session-001,query: 好的帮我退了吧,intent: tool,confidence: 0.92,method: llm,history_length: 4,latency_ms: 280,timestamp: 2025-03-07T14:30:00Z}定期抽检分类日志关注几个指标分类准确率 人工标注后计算目标 90% 以上各意图的分布比例 如果某类意图占比异常比如 clarification 占了 30%可能是 Prompt 太保守动不动就要求澄清误分类的典型案例 哪些消息被分错了错分为什么类别原因是什么针对性调整 Prompt 或补充规则规则层命中率 规则层拦截了多少比例的请求如果太低不到 10%说明规则太少如果太高超过 60%检查一下规则是否太激进导致误分意图分类失败的兜底大模型返回结果可能出现几种异常情况返回了格式不规范的 JSON比如多了个换行或注释返回了未定义的意图类别比如模型自己编了个 complaintAPI 调用超时或失败这些情况都需要兜底。前面代码里已经做了处理——解析失败或意图不合法时默认走知识检索。public IntentResult safeClassify(ListMessage history, String query) {try {IntentResult result classify(history, query);// 置信度太低也走兜底if (result.confidence 0.5) {return new IntentResult(knowledge, 0.5);}return result;} catch (Exception e) { log.warn(意图分类失败默认走知识检索: {}, e.getMessage());return new IntentResult(knowledge, 0.5);}}为什么兜底走知识检索而不是引导澄清因为知识检索路径自带兜底——如果检索不到相关内容生成策略里有兜底回复“抱歉未找到相关信息建议您联系人工客服”。而引导澄清会让用户觉得系统“太笨了什么都要问”体验更差。意图边界的动态调整业务发展过程中意图分类体系可能需要扩展。比如初期knowledge / tool / chitchat / clarification 四类中期加入 complaint投诉、urgent催单等细分类别后期不同产品线可能有不同的意图体系建议把意图分类体系做成配置化 的// 意图定义配置可以放在数据库或配置文件中ListIntentDefinition intents List.of(new IntentDefinition(knowledge, 知识检索,用户在询问产品信息、政策规定、操作指南等通用知识,List.of(退货政策是什么, 保修期多久)),new IntentDefinition(tool, 工具调用,用户想查询个人数据、实时信息或执行某个操作,List.of(查我的订单, 帮我申请退货)),// 新增意图只需加配置不改代码new IntentDefinition(complaint, 投诉,用户在表达不满或投诉,List.of(我要投诉, 态度太差了)));意图定义配置化之后加新意图只需要修改配置不需要改代码也不需要重新部署。Prompt 模板从配置中动态生成规则层的关键词也从配置中加载。小结与下一篇预告这篇讲了意图识别与问题路由核心要点回顾“一根筋”的RAG系统有问题 所有消息都走 RAG 检索闲聊消息检索到不相关内容反而更差工具调用消息在知识库里找不到答案四种意图分类 知识检索查知识库、工具调用调 API、闲聊对话直接回答、引导澄清反问用户三种实现方案 规则匹配快但准确率低、大模型分类准但有延迟、混合方案推荐规则做快速过滤 大模型做精确分类意图识别在RAG链路中的位置 会话记忆之后、Query 改写之前。意图识别需要对话历史作为输入Query 改写只在知识检索路径上才需要兜底策略 分类失败时默认走知识检索这是最安全的路径结合前面所有篇章到这里多轮对话 RAG 系统的完整链路已经很清晰了用户提问→会话记忆读取/保存对话历史→意图识别判断走哪条路→路由分发知识检索路径 Query 改写 → 向量检索 重排序 → 生成答案工具调用路径 Function Call / MCP → 模型生成最终答案闲聊路径 模型直接生成回复澄清路径 返回引导问题→保存assistant回复到会话记忆从数据入库到多轮对话从检索生成到工具调用再到意图识别和路由RAG 系统的各个环节已经全部讲完了。但有一个关键问题还没有回答你怎么知道你的RAG系统好不好检索召回的 chunk 是不是用户想要的模型生成的答案是不是忠实于检索到的内容端到端的用户满意度怎么样哪个环节是瓶颈靠人工抽检能发现一些问题但效率太低覆盖不全。你需要一套系统化的评估方法用数据来量化 RAG 系统每个环节的效果找到短板驱动优化。下一篇咱们来聊 RAG系统的评估与优化 ——怎么量化评估检索准确率、生成忠实度、端到端满意度怎么通过数据驱动持续优化 RAG 系统的各个环节。