大模型意图路由实战:多意图识别与智能分发
摘要
在智能对话系统、Agent平台和客服机器人中,意图识别是基础,但真正的工程难点在于意图路由——即识别出用户意图后,如何精准、高效地将请求分发到正确的业务处理单元。传统方案常将所有请求送入单一LLM进行意图识别和路由决策,导致算力浪费、时延升高。本文从工程实战角度,提出一套分层意图路由架构,通过规则层、轻量模型层和大模型兜底层三级流水线,将90%以上的常规请求拦截在前两层,仅将复杂歧义请求交给大模型处理。结合线上智能客服案例,详细拆解路由策略设计、置信度截断、多意图拆分与分发逻辑,并提供基于Spring AI Alibaba的完整Java实现。
一、引言:意图路由为何重要
意图识别解决了“用户想干什么”,而意图路由解决的是“这个需求应该由谁处理”。在大型对话系统中,后端往往挂接着多个业务模块:订单查询、物流跟踪、退款处理、人工客服、FAQ问答、第三方API调用等。如果路由错误,用户体验直接受损;如果路由效率低,系统资源被白白浪费。
然而,实际线上流量中,绝大部分用户请求都是高频、简单、意图明确的,比如“查物流”“转人工”“退款”。这些请求完全可以用极低成本的规则或轻量模型进行快速路由,根本不需要大模型介入。只有少部分复杂、歧义、多意图的请求才真正需要大模型的深度理解能力。
因此,分层意图路由成为大模型工程落地的核心优化手段之一。
二、意图路由的核心挑战
- 多意图叠加:用户一句话可能包含多个意图,如“查一下我的订单到哪了,顺便帮我催一下”,需要拆分成多个子意图并分别路由。
- 语义歧义:同一句话在不同上下文中有不同含义,例如“我要退了”可能指退货,也可能指退出登录。
- 上下文依赖:多轮对话中,意图可能需要结合历史信息才能准确判断。
- 路由目标多样性:可能路由到不同服务、不同工具、不同知识库,甚至需要并行路由。
- 成本与效果的平衡:简单请求用大模型路由是浪费,但规则过于复杂又难以维护。
三、分层意图路由架构设计
3.1 总体架构
采用经典的三层漏斗模型,与意图识别分层流水线一脉相承,但更强调路由决策:
用户输入Query
↓
【第一层:规则路由】正则/关键词/模板匹配
├─命中 → 直接路由到对应业务处理器(毫秒级)
└─未命中 → 进入【第二层:轻量模型路由】
↓
轻量分类器输出意图+置信度
├─置信度≥阈值且意图单一 → 直接路由
├─置信度≥阈值但意图多个 → 按主次路由或并行路由
└─置信度<阈值或意图混淆 → 进入【第三层:LLM精细路由】
↓
LLM解析意图、拆分多意图、消歧,输出路由指令
↓
路由分发,样本回流
3.2 各层职责与选型
| 层级 | 技术方案 | 路由能力 | 适用场景 | 时延 | 成本 |
|---|---|---|---|---|---|
| 规则路由 | 关键词词典、正则表达式、固定模板 | 精确匹配固定模式,直接映射到处理器 | 高频固定请求:问候、转人工、查物流等 | <5ms | 零算力 |
| 轻量模型路由 | 轻量BERT/TextCNN/SVM + 置信度阈值 | 处理句式变体,输出意图标签和置信度 | 语义明确但表达多变的常规请求 | 10-50ms | 极低 |
| LLM精细路由 | 大模型Prompt工程 + Function Calling | 多意图拆分、语义消歧、复杂上下文理解 | 歧义、多意图、口语化、多轮对话场景 | 500-2000ms | 高 |
3.3 路由策略细节
- 单意图高置信:直接路由到对应处理器。
- 多意图高置信:按置信度排序,支持并行路由或顺序路由(取决于业务是否允许同时处理)。
- 低置信/混淆:交给LLM,LLM输出结构化路由指令(如JSON),包含意图列表、目标处理器、参数等。
- 兜底路由:如果LLM也无法确定,路由到默认处理器(如转人工或澄清询问)。
四、线上实战案例:智能客服多意图路由
4.1 业务背景
某大型电商平台智能客服,日均对话量150w+,后端挂载订单服务、物流服务、退款服务、投诉服务、人工客服等10+个业务模块。初期采用“全量LLM意图识别+路由”方案,导致:
- 日均LLM调用量150w次,GPU成本高昂;
- 平均响应时延900ms,高峰期超时严重;
- 简单请求(如“转人工”)也走大模型,浪费资源。
4.2 分层路由改造
第一层:规则路由(拦截68%)
维护高频意图关键词库和正则模板,直接映射到处理器:
| 关键词/正则 | 意图 | 路由目标 |
|---|---|---|
| 转人工、人工客服 | manual_service | 人工客服队列 |
| 物流、快递、到哪了 | logistics_query | 物流查询服务 |
| 退款、退货、退钱 | refund_apply | 退款服务 |
| 投诉、差评 | complaint | 投诉工单系统 |
| 你好、在吗 | greeting | 欢迎语模块 |
| 帮助、怎么用 | help | FAQ模块 |
| 第二层:轻量模型路由(拦截22%) | ||
| 训练轻量BERT分类模型,输出意图标签和置信度,阈值设为0.85。对于模型输出的多意图情况,如果主意图置信度≥0.85且次意图<0.5,则按主意图路由;否则进入LLM。 | ||
| 第三层:LLM精细路由(穿透10%) | ||
| 针对复杂请求,使用LLM进行意图拆分和路由规划,输出JSON格式: |
{
"intents": [
{"intent": "logistics_query", "confidence": 0.9, "params": {"order_id": "12345"}},
{"intent": "complaint", "confidence": 0.7, "params": {"reason": "物流太慢"}}
],
"route_strategy": "parallel",
"target_services": ["logistics_service", "complaint_service"]
}
系统根据该JSON并行调用多个服务,汇总结果返回。
4.3 落地效果
- LLM调用量从150w/日降至15w/日,成本降低90%;
- 平均RT从900ms降至65ms;
- 用户满意度提升5%,因简单请求响应更快;
- 复杂多意图请求处理准确率提升,因LLM专注于真正需要深度理解的场景。
五、Java代码实现(基于Spring AI Alibaba)
下面展示如何用Spring AI Alibaba实现分层意图路由。第一层规则路由使用正则和关键词映射;第二层轻量模型使用简单关键词打分模拟(实际可替换为ONNX小模型或独立服务);第三层使用ChatClient调用通义千问进行精细路由。
5.1 环境准备
Maven依赖:
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>1.0.0-M3.2</version>
</dependency>
application.yml:
spring:
ai:
dashscope:
api-key: ${DASHSCOPE_API_KEY}
chat:
options:
model: qwen-plus
5.2 核心代码
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.regex.Pattern;
@Service
public class IntentRouterService {
// 第一层:规则路由表
private final Map<String, RouteRule> ruleRoutes = new LinkedHashMap<>();
{
ruleRoutes.put("manual_service", new RouteRule(
Pattern.compile(".*(转人工|人工客服|找人工).*"), "manual_service"));
ruleRoutes.put("logistics_query", new RouteRule(
Pattern.compile(".*(物流|快递|到哪|发货|派送).*"), "logistics_service"));
ruleRoutes.put("refund_apply", new RouteRule(
Pattern.compile(".*(退款|退货|退钱|退了).*"), "refund_service"));
ruleRoutes.put("complaint", new RouteRule(
Pattern.compile(".*(投诉|差评|态度差).*"), "complaint_service"));
ruleRoutes.put("greeting", new RouteRule(
Pattern.compile("^(你好|您好|hi|hello|在吗).*"), "greeting_module"));
ruleRoutes.put("help", new RouteRule(
Pattern.compile(".*(帮助|怎么用|使用说明).*"), "faq_module"));
}
// 第二层:轻量分类器(模拟)
private final LightIntentClassifier lightClassifier = new LightIntentClassifier();
// 第三层:大模型
private final ChatClient chatClient;
private final ObjectMapper objectMapper = new ObjectMapper();
public IntentRouterService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
/**
* 路由入口
*/
public RouteResult route(String userInput) {
// 第一层:规则路由
for (RouteRule rule : ruleRoutes.values()) {
if (rule.pattern().matcher(userInput).matches()) {
return new RouteResult(
List.of(new Intent(rule.intent(), 1.0)),
List.of(rule.targetService()),
"rule",
userInput
);
}
}
// 第二层:轻量模型路由
List<Intent> lightIntents = lightClassifier.classify(userInput);
if (!lightIntents.isEmpty()) {
Intent mainIntent = lightIntents.get(0);
if (mainIntent.confidence() >= 0.85 &&
(lightIntents.size() == 1 || lightIntents.get(1).confidence() < 0.5)) {
// 单意图或主意图明显,直接路由
return new RouteResult(
List.of(mainIntent),
List.of(mapIntentToService(mainIntent.intent())),
"light_model",
userInput
);
}
// 多意图但不够置信,进入LLM
}
// 第三层:LLM精细路由
return llmRoute(userInput);
}
private RouteResult llmRoute(String userInput) {
String prompt = """
你是智能路由助手,请分析用户输入,输出JSON格式的路由指令。
可用意图:logistics_query, refund_apply, complaint, order_query, manual_service, faq, other。
路由目标:logistics_service, refund_service, complaint_service, order_service, manual_queue, faq_service。
要求:
1. 如果包含多个意图,在intents数组中列出所有意图及置信度。
2. 如果多个意图需要同时处理,route_strategy设为"parallel",否则"sequential"。
3. target_services列出需要调用的服务。
4. 只输出JSON,不要有其他内容。
用户输入:%s
""".formatted(userInput);
String response = chatClient.prompt().user(prompt).call().content();
try {
JsonNode json = objectMapper.readTree(response);
List<Intent> intents = new ArrayList<>();
json.get("intents").forEach(node -> {
intents.add(new Intent(
node.get("intent").asText(),
node.get("confidence").asDouble()
));
});
List<String> services = new ArrayList<>();
json.get("target_services").forEach(node -> services.add(node.asText()));
return new RouteResult(intents, services, "llm", userInput);
} catch (Exception e) {
// 解析失败,兜底到默认服务
return new RouteResult(
List.of(new Intent("fallback", 0.5)),
List.of("clarification_service"),
"fallback",
userInput
);
}
}
private String mapIntentToService(String intent) {
return switch (intent) {
case "logistics_query" -> "logistics_service";
case "refund_apply" -> "refund_service";
case "complaint" -> "complaint_service";
case "order_query" -> "order_service";
case "manual_service" -> "manual_queue";
case "faq" -> "faq_service";
default -> "other_service";
};
}
// 内部类:路由规则
record RouteRule(Pattern pattern, String intent, String targetService) {
RouteRule(Pattern pattern, String targetService) {
this(pattern, targetService, targetService);
}
}
// 内部类:意图
public record Intent(String intent, double confidence) {}
// 内部类:路由结果
public record RouteResult(List<Intent> intents, List<String> targetServices, String source, String rawInput) {}
// 轻量分类器模拟(基于关键词打分)
static class LightIntentClassifier {
private final Map<String, List<String>> intentKeywords = new HashMap<>();
{
intentKeywords.put("logistics_query", List.of("物流", "快递", "到哪", "发货", "派送"));
intentKeywords.put("refund_apply", List.of("退款", "退货", "退了", "不要了"));
intentKeywords.put("complaint", List.of("投诉", "差评", "态度差"));
intentKeywords.put("order_query", List.of("订单", "买了", "购买", "下单"));
intentKeywords.put("manual_service", List.of("人工", "客服", "转人工"));
}
public List<Intent> classify(String text) {
Map<String, Double> scores = new HashMap<>();
for (Map.Entry<String, List<String>> entry : intentKeywords.entrySet()) {
double score = 0;
for (String kw : entry.getValue()) {
if (text.contains(kw)) {
score += 0.3;
}
}
if (score > 0) {
scores.put(entry.getKey(), Math.min(score, 1.0));
}
}
// 按分数降序
return scores.entrySet().stream()
.sorted((e1, e2) -> Double.compare(e2.getValue(), e1.getValue()))
.map(e -> new Intent(e.getKey(), e.getValue()))
.toList();
}
}
}
5.3 调用示例
RouteResult r1 = intentRouterService.route("帮我查一下快递到哪了");
// 规则命中,source=rule,targetServices=[logistics_service]
RouteResult r2 = intentRouterService.route("我的订单好几天了还没派送,帮我看看");
// 轻量模型命中,source=light_model,targetServices=[logistics_service]
RouteResult r3 = intentRouterService.route("我上周买的衣服没收到,而且质量看着不好,想退了顺便投诉一下");
// LLM处理,可能输出多个意图,source=llm
六、工程避坑指南
- 规则维护成本:规则层只保留最高频、最稳定的模式,避免规则爆炸。定期分析规则命中率和误报率,及时清理低效规则。
- 轻量模型更新:轻量模型需要定期用线上穿透样本进行微调,提升拦截率。
- 置信度阈值动态调整:根据A/B测试数据,平衡拦截率和准确率。阈值过高会导致过多请求进入LLM,过低则可能误路由。
- 多意图并行路由的资源控制:并行调用多个服务时,需要设置超时和熔断机制,避免一个服务拖垮整个请求。
- 上下文处理:多轮对话中,路由决策应结合历史上下文,轻量模型可以引入对话状态特征,LLM可提供对话摘要。
- 监控与告警:监控各层流量占比、平均RT、路由准确率、LLM调用量、错误率等,异常时及时告警。
七、总结
意图路由是对话系统中的关键环节,分层架构能够用极低的成本处理绝大多数简单请求,同时保证复杂请求的精准处理。通过“规则→轻量模型→LLM”三级漏斗,我们实现了成本、时延和效果的最优平衡。本文提供的Java代码基于Spring AI Alibaba,可以直接集成到现有Spring Boot项目中,帮助开发者快速落地分层意图路由。
在未来的演进中,可以进一步引入强化学习优化路由策略,或使用更高效的模型蒸馏技术压缩轻量模型,持续提升系统性能。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)