深度 3:意图路由——"模糊的 query"到底怎么判断

这是「Agent 工程化」系列的深度篇。前面几篇讲了 Agent 的骨架:编排、工具、记忆、护栏。但有一个所有生产 Agent 都绕不开、却很少有人讲透的细节——意图路由:用户一句话进来,系统怎么知道它想干嘛?更难的追问是:怎么知道这句话说不清它想干嘛?


开场:一句"没接住"的话

用户抛过来一句话:

“这个服务怎么老出问题?”

你的意图路由看了一眼,没发现任何强关键词——没有"503"、没有"报错"、没有"日志"。按规则它应该走哪条路?

答案是通用兜底(general)。于是 Agent 用最泛化的知识回了一段"可能是服务有问题,建议检查日志"。

但用户真正的意图是诊断——他想让你查环境、看日志、定位根因。一条本可以精准响应的请求,因为路由判断失误,变成了一次低质量的通用回答。

问题出在哪?路由系统把"这句 query 是清晰的还是模糊的"判断错了——它根本没判断,只是"没命中就当清晰"。

这就是意图路由里最容易被忽略、也最影响体验的一环:模糊度判断。


意图路由的骨架:分类 → 路由 → 执行

先看全貌。一个生产 Agent 的意图路由通常长这样:

高置信

低于阈值

用户 query

意图分类

得分情况

命中某条路由

模糊兜底

执行该路由的工具集

LLM 二次分类或通用回答

关键就在 B 这一步:意图分类的结果不是一个,而是两个——“归哪类” + “归得多确信”。 绝大多数实现只做了前者,漏了后者。

"归得多确信"就是模糊度。它决定了一条 query 是直接走规则,还是值得花更多成本(调 LLM)去确认。


为什么"模糊"这么难判断

三个现实困难:

1. 模糊没有天然标签。
query 就是一句话,没有任何元数据告诉你它清不清晰。"帮我看看"和"帮我看看 order-service 的 OOM 日志"看起来都像诊断意图,但后者信息完整、前者处处是坑。

2. 模糊是相对的。
"这台机器内存溢出了"对 diagnose 路由是清晰的,但对 code 路由就是模糊的。模糊不是 query 的属性,是 query 与路由之间匹配程度的属性——所以必须按路由分别评估。

3. 规则只能覆盖"说得像"的。
规则的强项是命中已知表达(“503”、“报错"这类强词),弱项是处理"没见过的说法”——"这个服务怎么老出问题"这种口语化表达,规则永远覆盖不到。


三种方案:从规则到小模型

方案一:规则打分(最基础,当前实现)

核心思想:别用"是否命中"二值判断,用加权打分量化匹配程度。

INTENT_WORDS = {
    "diagnose": ["503", "404", "报错", "OOM", "失败", "超时", "挂了", "日志"],
    "code":     ["源码", "实现", "在哪改", "代码", "函数", "写法"],
    "pipeline": ["流水线", "构建", "发版", "部署", "Jenkins", "CI"],
}

def score_intent(query: str, intent: str) -> tuple[int, list[str]]:
    """给 query 对某个意图的匹配程度打分"""
    score = 0
    hits = [w for w in INTENT_WORDS[intent] if w in query]
    score += len(hits) * 2          # 强词命中,每个 +2
    if len(query) < 4:
        score -= 1                  # query 过短,降权
    return score, hits

def classify(query: str, threshold: int = 3) -> tuple[str, int]:
    """分类 + 置信度:低于阈值判为模糊"""
    scores = {i: score_intent(query, i)[0] for i in INTENT_WORDS}
    best = max(scores, key=scores.get)
    if scores[best] < threshold:
        return "ambiguous", scores[best]   # 模糊 → 交给 LLM 兜底
    return best, scores[best]

三个设计细节:

  1. 加权而不是命中即走——“503"是强信号(+2),短 query 是降分项(-1),组合起来能区分"说得很像"和"含含糊糊”
  2. 阈值制——不是"没命中就兜底",而是"得分低于阈值才兜底"。这个差别很大:classify("这个服务怎么老出问题") 得分 0 < 3,判模糊进 LLM;classify("503 报错帮忙看看") 得分 2×2+1=5,直接进诊断
  3. 业务实体加分——命中环境名/组件名这类业务词(“order-service”、“prod-环境”)加 1 分,能救回很多半句话

规则的代价:只能覆盖约 80% 说得明确的 query,剩下 20% 的口语化表达要靠兜底。

方案二:规则 + LLM 兜底(过渡形态)

模糊的 query 进 LLM,把四个路由的定义、工具、能力范围写成提示词,让模型做二次分类。

优点:能处理任意表达。缺点:每一条模糊 query 都多一次大模型调用——延迟和成本都不可控。而且"什么时候算模糊"依然依赖规则打分,规则不准,LLM 兜底的门槛就失守。

方案三:3B 小意图模型(演进方向)

意图分类本质是个文本分类任务——不是推理任务。所以它根本不需要大模型:

  • 模型:Qwen2.5-3B / Llama-3.2-3B 级别
  • 训练:几百条标注样本(各意图的正例 + 边界负例)LoRA 微调
  • 部署:vLLM 本地部署,延迟毫秒级
  • 为什么 3B 够:分类任务简单,小模型参数足够;比规则鲁棒(没见过的说法也能分);比大模型便宜快一个数量级

高

低

用户 query

3B 意图模型

置信度

直接路由

大模型二次确认或人工兜底

关键升级:置信度由模型原生给出(softmax 概率),不再靠人工写打分规则。规则维护成本从"改代码"变成"加样本"。


三方案对比

维度规则打分规则 + LLM 兜底3B 小意图模型
延迟最快(毫秒内)模糊时慢(多一次大模型)快(本地毫秒级)
成本几乎为零模糊越多越贵低(自部署)
鲁棒性差(没见过的说法不认)好好
覆盖~80% 明确 query~100%(兜底兜住)~95%(边界仍需兜底)
维护改代码加词改代码 + 调 prompt加标注样本
适用阶段起步期过渡期规模化期

演进路线:别一步到位

生产里的正确做法是渐进式,别上来就训模型:

第一步:规则打分 + 阈值兜底          → 上线观察边界误路由
第二步:模糊 query 进 LLM 二次分类    → 把 LLM 的分支结果沉淀成样本
第三步:用样本训 3B 小模型            → 替换规则,模型给原生置信度

第 2 步到第 3 步之间有个隐藏红利:LLM 兜底期间跑过的每一条模糊 query,都是天然的训练数据(query + LLM 分类结果,人工抽检后进训练集)。过渡形态不白花钱,它在给最终形态攒弹药。


三个最容易踩的坑

坑一:没有阈值,全量进 LLM。
把"模糊度判断"省了,所有 query 先问一遍大模型——延迟、成本、稳定性全崩。规则存在的意义就是让 80% 的请求不经过 LLM。

坑二:阈值拍脑袋。
阈值定得太高,明确的 query 被误判模糊,白白多花钱;定得太低,模糊的 query 走错路由。正确做法:上线后拉真实 query 分布调阈值——统计各意图得分分布,把阈值放在"明确与模糊"的天然分界处。

坑三:只测"说得像的",不测边界。
评测路由时只测"503 报错"这种标准说法,永远发现不了"这个服务怎么老出问题"会走错路。评测集必须包含边界 query——口语化、短句、指代不清的,这才是路由系统真正的薄弱点。


常见疑问

问:路由分类和 RAG 检索是一回事吗?
不是。路由是"判断用户想干嘛、走哪条流程",RAG 是"在知识库里找资料"。但可以联动:路由命中 diagnose 后,诊断流程里再用 RAG 查排障文档。分类在先,检索在后。

问:为什么不用大模型做意图分类?
能做,但不划算。文本分类是简单任务,3B 小模型就够;大模型在这里是"杀鸡用牛刀",而且每次调用都有延迟和成本。大模型的正确用途是模糊兜底和复杂推理,不是批量分类。

问:规则和模型的边界到底在哪?
经验法则是:能确定的地方用规则,不确定的地方用模型。规则管"说得很像"的 80%,模型管"说不清"的 20%。边界本身(模糊度)可以用规则打分估算,也可以用小模型置信度原生获得。


总结:一句话记住它

意图路由的完整答案是"分类 + 置信度":加权打分算匹配程度,低于阈值判模糊进兜底。规则管得住 ~80% 明确 query,模糊的交给 LLM,规模上来后训 3B 小模型拿原生置信度——分类是简单任务,用大模型是浪费。千万别省掉模糊度判断,那是路由系统防误判的最后一道闸。


小结

  • 路由 = 分类 + 置信度:只分类不判确信度,模糊 query 会被静默误路由
  • 模糊是相对的:query 与路由的匹配程度,要按路由分别评估
  • 三方案:规则打分(快、覆盖 80%)、规则+LLM(全、贵)、3B 小模型(鲁棒、置信度原生)
  • 渐进演进:规则 → 规则+LLM → 小模型,LLM 兜底期间的 query 是天然训练数据
  • 三坑:无阈值全量进 LLM、阈值拍脑袋、评测不测边界 query

下一篇深度篇:Skill 与 Tool——剧本和演员的边界,以及 Skill 到底存哪。“Skill 是知识还是执行”“存数据库还是融进 Agent”——把这两个最容易讲含糊的点一次说清。


本系列路线(从 0 到 1): Agent 是什么 → 手写最小 ReAct → Function Calling 与工具设计 → 上下文管理 → Memory 记忆系统 → RAG 知识库 → Skill 自学习 → 编排模式与多 Agent → 给 Agent 装护栏 → 生产部署与可观测 → 评测与回归 → 番外:框架横评 → LangGraph 深挖 → 框架选型决策 → 深度篇:Reflection 反思 → 记忆压缩 → 意图路由 → Skill 辨析 → 更多

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐