2026 年大模型应用开发之 Agent 意图路由实战指南,可运行代码(python)

在构建智能体与 RAG 系统时,用户自然语言输入和系统底层执行逻辑之间,天然存在巨大语义鸿沟。

进入 2026 年,行业早已抛弃「单一大模型全权兜底」的粗放式意图识别方案,业界统一落地分层漏斗路由 架构:遵循先快后慢、先低成本后高智能的设计原则,将 80% 的高频标准化请求,在零延迟的轻量化层级直接拦截消化,极致兼顾响应速度、推理成本与识别准确率。

这种设计彻底重塑了意图识别的定位:把传统意图分类问题,升级为全局流量路由问题 ,最终形成以向量检索 + Function Calling 为核心的现代智能体意图路由标准方案。

一、历史演进:三层漏斗 → 两层快慢路径

早期(2023--2025):关键词 + 向量 + 小模型三层漏斗(传统NLU)

由于当时大模型 function calling 不稳定、成本高、延迟大,业界采用三层结构:

一. L1 关键词/正则 :处理固定指令(代表公司 :Cursor、Claude Code、钉钉、飞书、Linux),仅用于绝对固定命令(如 /helpexityes);所有正则有单元测试

实际使用场景举例

  1. Cursor :用户按 Cmd+K 触发内联编辑,检测到关键词 editchange 直接唤起编辑器。
  2. 钉钉机器人 :以 / 开头的指令(/todo/remind)命中正则后直接执行。
  3. Claude Code :用户输入 git status 等 shell 命令,正则匹配后直接执行,不调用 LLM。
  4. 飞书审批机器人:用户回复"同意"、"批准"等固定词,正则匹配后直接流转审批状态。
  5. GitLab CI :根据 commit message 是否包含 [skip ci] 正则决定是否跳过流水线。

二. L2 向量语义 :处理同义改写(为每个意图写 3~20 条示例,生成向量;用户请求向量化后余弦相似度匹配。) 实际使用例子(≥3个)

  1. Zendesk 智能客服:用户说"我忘记密码"、"无法登录",向量匹配到"账号恢复"意图,回复密码重置链接。
  2. Salesforce Einstein:客户发邮件"我想修改发货地址",匹配示例"更改地址"、"换送货地点",自动路由到订单修改机器人。
  3. 美团商家后台:商家说"今日流水"、"营收多少",向量匹配后展示营收仪表盘。
  4. 飞书智能助手(企业版) :员工说"请假三天"、"申请年假",匹配到请假流程。
  5. Notion AI(企业版) :用户问"上季度销售数据",匹配"季度报表"、"销售业绩"示例,拉取数据库。 三. L3 小模型分类(如 gpt-3.5-turbo、Claude Instant):对未命中请求做意图分类,再交给主模型执行;用小模型(gpt-3.5-turbo、Claude Instant、Gemini Flash)纯做意图分类,输出意图 ID,主模型再执行。

小模型的定位:作为兜底,比大模型快且便宜,能处理语义但无法提取槽位。


现在(2026):关键词 + 向量 + 大模型 FC 两层路径

随着大模型 FC 成熟(准确率 >95%、延迟 1--2s、成本下降 80%+),小模型变得尴尬:

  • 比向量慢(500ms+ vs 100ms)
  • 比大模型 FC 不准(分类漂移 + 无法提取槽位 + 不能反问澄清)
  • 维护成本高(需要训练数据、模型更新、部署)
  • 总成本并不低(小模型 + 主模型两次调用 ≥ 单次大模型 FC)

因此,新架构直接移除小模型层,由大模型 FC 接管长尾:

  1. L1 关键词/正则(<1ms,60--80% 请求)
  2. L2 向量语义(30--100ms,15--25% 请求)
  3. L3 大模型 FC(1--2s,5--15% 请求)------ 一次调用完成意图+槽位+执行

二、意图识别具体实现过程

1.原生写法-源码包含关键注释

python 复制代码
# ===================== 【1. 安装依赖(新手第一步!必须做)】 =====================
# 终端执行命令:pip install sentence-transformers requests
# 【新手坑⚠️】不安装依赖直接运行,会报 ModuleNotFoundError 找不到模块
# 【新手坑⚠️】国内网络慢,下载向量模型失败 → 换手机热点运行

# ===================== 【2. 导入工具包】 =====================
import re                          # 正则表达式:用于关键词模糊匹配
import requests                    # 网络请求:调用Minimax官方API接口
from sentence_transformers import SentenceTransformer, util  # 文本转向量+计算语义相似度
import json                        # 解析API返回的JSON数据,防止报错

# ===================== 【3. Minimax Coding Plan 核心配置】 =====================
# 【必填】替换成你的 Minimax API Key(Coding Plan 专用密钥)
# 【新手坑⚠️】密钥填错/漏填/前后多空格 → 报401无权限错误
MINIMAX_API_KEY = "你的Minimax-CodingPlan-API-KEY"

# Minimax 官方固定接口地址(Coding Plan 通用,绝对不能修改!)
# 【新手坑⚠️】手动拼写接口地址错误 → 报404找不到服务器
MINIMAX_API_URL = "https://api.minimax.chat/v1/text/chatcompletion"

# 向量相似度阈值:分数≥0.7 判定为「意思匹配成功」
SIMILARITY_THRESHOLD = 0.7

# ===================== 【4. 第一层:关键词路由(办公场景 日常口语版)】 =====================
# AI规则小本本:{ 意图名称 : [用户日常会说的话] }
# 【新手致命坑⚠️】意图名称 必须和后面 INTENT_EXAMPLES/模型提示词 一字不差!
# 【新手致命坑⚠️】全程办公场景,禁止混入代码相关话术
INTENT_RULES = {
    "问好": ["你好", "哈喽", "在吗", "嗨", "早上好", "晚上好", "有人吗"],
    "查询身份": ["你是谁", "你是干嘛的", "你是什么助手", "你能做什么", "介绍一下你自己"],
    "查询薪资": ["帮我查薪资", "查一下我的工资", "本月工资多少", "查工资条", "薪资明细"],
    "查询考勤": ["帮我查考勤", "我的打卡记录", "今天迟到了吗", "查加班记录", "考勤情况"],
    "请假申请": ["我要请假", "帮我提请假", "请假流程是什么", "怎么请假", "我想请年假"],
    "查询公司政策": ["公司报销政策", "加班规则", "年假规定", "公司制度", "上下班时间"]
}

# ===================== 【函数1:关键词匹配函数】 =====================
# 作用:拿着规则本扫描用户输入,快速匹配意图(优先级最高)
# 参数:user_input = 用户输入的一句话
# 返回值:匹配到的意图 / None(未匹配)
def keyword_intent_route(user_input: str) -> str | None:
    # 遍历规则本中 所有意图 + 对应的关键词列表
    for intent, keyword_list in INTENT_RULES.items():
        # 遍历当前意图下的每一个口语关键词
        for keyword in keyword_list:
            # 匹配用户输入中是否包含关键词
            # 【新手坑⚠️】默认区分大小写,如需不区分 → 加参数 re.IGNORECASE
            if re.search(keyword, user_input):
                print(f"✅【第一层-关键词命中】意图:{intent}")
                return intent  # 匹配成功直接返回,不继续执行
    # 所有关键词都未匹配,返回空
    return None

# ===================== 【5. 第二层:向量语义匹配(✅ 严格使用你的办公场景例句)】 =====================
# 作用:匹配「说法不同、意思相同」的提问(核心能力)
# 【新手致命坑⚠️】意图名称 必须和 INTENT_RULES 完全一致!!
# 【新手致命坑⚠️】这是你指定的办公场景例句,全程保持统一
embedding_model = SentenceTransformer("all-MiniLM-L6-v2")

# 你指定的 办公场景向量匹配例句库(完全保留,不修改)
INTENT_EXAMPLES = {
    "问好": ["你好呀", "在不在", "哈喽助手", "早上好"],
    "查询身份": ["你是什么软件", "你能帮我做什么", "介绍下自己"],
    "查询薪资": ["我想看下工资条", "这个月收入多少", "查我的薪资"],
    "查询考勤": ["我这个月打卡情况", "有没有迟到", "考勤记录"],
    "请假申请": ["我想申请休假", "请假怎么操作", "提请假流程"],
    "查询公司政策": ["公司加班怎么算", "报销流程", "年假天数"]
}

# 预计算:把所有例句转为向量,存储为意图标准特征(启动时计算1次)
intent_vector_map = {}
for intent, examples in INTENT_EXAMPLES.items():
    # 将文本例句转换为向量数据
    example_vectors = embedding_model.encode(examples, convert_to_tensor=True)
    # 计算向量平均值,作为该意图的「标准语义特征」
    intent_vector_map[intent] = example_vectors.mean(dim=0)

# ===================== 【函数2:向量语义匹配函数】 =====================
# 作用:计算用户输入和意图的语义相似度,实现模糊匹配
def embedding_intent_route(user_input: str) -> str | None:
    # 将用户输入的文本转换为向量
    user_vector = embedding_model.encode(user_input, convert_to_tensor=True)
    # 初始化最高相似度分数
    max_score = 0.0
    # 初始化最匹配的意图
    best_intent = None

    # 遍历所有意图的标准向量,计算相似度
    for intent, intent_vector in intent_vector_map.items():
        score = util.cos_sim(user_vector, intent_vector).item()
        # 更新最高分和最匹配意图
        if score > max_score:
            max_score = score
            best_intent = intent

    # 相似度达标,返回匹配意图
    if max_score >= SIMILARITY_THRESHOLD:
        print(f"✅【第二层-向量匹配】意图:{best_intent},相似度:{max_score:.2f}")
        return best_intent
    # 相似度不足,返回空
    return None

# ===================== 【6. 第三层:Minimax 小模型兜底(办公场景意图识别)】 =====================
# 作用:前两层识别失败时,用Minimax小模型AI理解复杂意图
def minimax_small_intent_recognize(user_input: str) -> str:
    # 请求头:Minimax 官方固定格式,禁止修改
    # 【新手坑⚠️】Bearer 后面必须加1个空格 → 否则401认证失败
    headers = {
        "Authorization": f"Bearer {MINIMAX_API_KEY}",
        "Content-Type": "application/json"
    }

    # 办公场景专属提示词:强制输出固定意图,不允许乱回答
    prompt = f"""你是企业智能办公助手,仅输出标准意图:
问好、查询身份、查询薪资、查询考勤、请假申请、查询公司政策、其他
用户输入:{user_input}"""

    # Minimax Coding Plan 官方请求参数
    data = {
        # 【新手坑⚠️】意图识别必须用轻量小模型:minimax-chat-lite
        "model": "minimax-chat-lite",
        "messages": [{"role": "user", "content": prompt}],
        # 【新手坑⚠️】temperature=0 → 输出结果固定,不随机
        "temperature": 0.0,
        # 【新手坑⚠️】新手关闭流式输出,避免处理复杂逻辑
        "stream": False
    }

    # 异常捕获:API报错不会让程序崩溃(新手必备)
    try:
        response = requests.post(MINIMAX_API_URL, headers=headers, json=data, timeout=10)
        response.raise_for_status()  # 主动抛出HTTP错误
        result = response.json()
        return result["choices"][0]["message"]["content"].strip()
    except Exception as e:
        print(f"❌ 小模型调用失败:{str(e)}")
        return "其他"

# ===================== 【核心:Minimax 大模型生成办公回复(Coding Plan 适配)】 =====================
# 作用:识别意图后,调用大模型生成专业、友好的回复
def minimax_office_reply(user_input: str, intent: str) -> str:
    headers = {
        "Authorization": f"Bearer {MINIMAX_API_KEY}",
        "Content-Type": "application/json"
    }

    # 办公助手专属提示词(适配Coding Plan生成逻辑)
    prompt = f"""你是企业智能办公助手,根据用户意图友好、简洁、专业回复:
用户意图:{intent}
用户问题:{user_input}
要求:语气亲切、回答准确、符合办公场景"""

    # Minimax 官方请求体(Coding Plan 专用)
    data = {
        # 【新手坑⚠️】生成回复必须用专业大模型:minimax-chat-pro
        "model": "minimax-chat-pro",
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0.3,
        "stream": False
    }

    # 异常捕获,防止程序崩溃
    try:
        response = requests.post(MINIMAX_API_URL, headers=headers, json=data, timeout=30)
        response.raise_for_status()
        return response.json()["choices"][0]["message"]["content"]
    except Exception as e:
        return f"❌ 回复生成失败:{str(e)}"

# ===================== 【总路由:三层意图识别自动流转】 =====================
# 执行优先级:关键词匹配 → 向量匹配 → 小模型兜底
def agent_intent_router(user_input: str) -> str:
    # 第一层
    intent = keyword_intent_route(user_input)
    if intent: return intent
    # 第二层
    intent = embedding_intent_route(user_input)
    if intent: return intent
    # 第三层
    return minimax_small_intent_recognize(user_input)

# ===================== 【最终运行入口】 =====================
# 对外总接口:用户输入一句话,自动完成全流程
def run_office_agent(user_input: str):
    # 打印分割线,方便查看结果
    print("-" * 60)
    # 打印用户输入内容
    print(f"🗣️ 用户输入:{user_input}")
    # 调用总路由,识别最终意图
    final_intent = agent_intent_router(user_input)
    # 打印最终识别结果
    print(f"🎯 最终识别意图:{final_intent}")

    # 定义办公场景支持的所有合法意图
    valid_intents = ["问好","查询身份","查询薪资","查询考勤","请假申请","查询公司政策"]
    # 合法意图 → 调用大模型生成回复
    if final_intent in valid_intents:
        print("\n🚀 助手正在生成回复...")
        result = minimax_office_reply(user_input, final_intent)
        print(f"\n📄 回复结果:\n{result}")
    # 不支持的意图
    else:
        print("❌ 暂不支持该办公需求")

# ===================== 【测试代码】 =====================
if __name__ == "__main__":
    # 【新手坑⚠️】每次只运行1个测试用例,禁止同时开启多个
    run_office_agent("你好")
    # run_office_agent("你是谁呀")
    # run_office_agent("帮我查一下我的工资")
    # run_office_agent("我要请假")
    # run_office_agent("公司加班规则是什么")

2.🔥 LangChain 0.3+ 办公助手

langchain

python 复制代码
# ===================== LangChain 0.3+ 办公助手(Minimax Coding Plan 适配) =====================
# 【新手坑⚠️】必须安装依赖:pip install "langchain>=0.3.0" langchain-community langchain-minimax sentence-transformers numpy
# 【新手坑⚠️】LangChain <0.3 版本无invoke方法,会直接报错!

# 1. 导入LangChain 0.3 核心组件(官方最新标准)
from langchain_core.runnables import RunnableLambda       # 把普通函数包装成LangChain可执行组件
from langchain_core.prompts import PromptTemplate         # 提示词模板:固定AI的提问格式
from langchain_core.output_parsers import StrOutputParser # 把AI返回的结果转成纯文字
from langchain_community.embeddings import SentenceTransformerEmbeddings # 文字转向量工具
from langchain_minimax import ChatMinimax                 # LangChain0.3官方对接Minimax模型
# 基础工具
import re
import numpy as np

# ===================== 全局核心配置 =====================
# 【必填】替换为你的 Minimax Coding Plan API Key
MINIMAX_API_KEY = "你的Minimax-CodingPlan-API-KEY"
# 向量相似度阈值(≥0.7判定意思匹配)
SIMILARITY_THRESHOLD = 0.7
# 合法意图列表(全程统一,禁止修改)
VALID_INTENTS = [
    "问好", "查询身份", "查询薪资", "查询考勤",
    "请假申请", "查询公司政策", "其他"
]

# ===================== 第一层:关键词路由规则(办公场景口语) =====================
INTENT_RULES = {
    "问好": ["你好", "哈喽", "在吗", "嗨", "早上好", "晚上好", "有人吗"],
    "查询身份": ["你是谁", "你是干嘛的", "你是什么助手", "你能做什么", "介绍一下你自己"],
    "查询薪资": ["帮我查薪资", "查一下我的工资", "本月工资多少", "查工资条", "薪资明细"],
    "查询考勤": ["帮我查考勤", "我的打卡记录", "今天迟到了吗", "查加班记录", "考勤情况"],
    "请假申请": ["我要请假", "帮我提请假", "请假流程是什么", "怎么请假", "我想请年假"],
    "查询公司政策": ["公司报销政策", "加班规则", "年假规定", "公司制度", "上下班时间"]
}

# ===================== 1. LangChain 关键词路由组件 =====================
def keyword_router(query: str) -> str:
    for intent, keywords in INTENT_RULES.items():
        for kw in keywords:
            if re.search(kw, query):
                return intent
    return "vector_router"

# 把普通函数变成LangChain可执行的组件
keyword_runnable = RunnableLambda(keyword_router)

# ===================== 第二层:向量语义匹配(你的原版例句100%保留) =====================
# 加载开源向量模型:将人类语言文字 转换成 计算机能计算的数字向量
embedding = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")

# 你指定的办公场景例句(完全不动)
INTENT_EXAMPLES = {
    "问好": ["你好呀", "在不在", "哈喽助手", "早上好"],
    "查询身份": ["你是什么软件", "你能帮我做什么", "介绍下自己"],
    "查询薪资": ["我想看下工资条", "这个月收入多少", "查我的薪资"],
    "查询考勤": ["我这个月打卡情况", "有没有迟到", "考勤记录"],
    "请假申请": ["我想申请休假", "请假怎么操作", "提请假流程"],
    "查询公司政策": ["公司加班怎么算", "报销流程", "年假天数"]
}

# 预计算所有意图的标准向量:启动程序时计算1次,后续直接使用,提升运行速度
intent_vectors = {}
for intent, examples in INTENT_EXAMPLES.items():
    # 将例句文本批量转换为向量数组
    vecs = embedding.embed_documents(examples)
    # 计算同一意图下所有例句向量的平均值,作为该意图的【标准特征向量】
    intent_vectors[intent] = np.mean(vecs, axis=0)

# ===================== 2. LangChain 向量路由组件(✅ 逐行超详细注释) =====================
def vector_router(query: str) -> str:
    """
    【向量语义匹配函数】第二层意图识别核心
    作用:解决「文字不同、意思相同」的匹配(比如:我想看下工资 = 帮我查薪资)
    :param query: 用户输入的问题/对话
    :return: 匹配到的意图 / 默认跳转到小模型识别
    """
    # 1. 将用户输入的文字 转换为 计算机可计算的向量
    query_vec = embedding.embed_query(query)

    # 2. 初始化变量:记录最高的相似度分数(初始为0)
    max_score = 0.0
    # 3. 初始化默认意图:如果没匹配到,就跳转到第三层小模型识别
    best_intent = "llm_router"

    # 4. 遍历所有【标准意图向量】,逐一计算相似度
    for intent, vec in intent_vectors.items():
        # 5. 【核心公式】计算余弦相似度:值越接近1,代表两句话意思越像
        # 公式:向量点积 / (向量1长度 * 向量2长度)
        score = np.dot(query_vec, vec) / (np.linalg.norm(query_vec) * np.linalg.norm(vec))
        
        # 6. 判断:当前分数 > 历史最高分 + 分数达标(≥0.7)
        if score > max_score and score >= SIMILARITY_THRESHOLD:
            # 7. 更新:最高分数 + 最匹配的意图
            max_score = score
            best_intent = intent

    # 8. 返回最终匹配结果(匹配到的意图 / 跳转到小模型)
    return best_intent

# 【LangChain0.3 强制规范】
# 把普通的Python函数 vector_router 包装成 LangChain 可识别、可执行的组件
# 只有包装后,才能用 .invoke() 方法执行,否则会报错
vector_runnable = RunnableLambda(vector_router)

# ===================== 第三层:Minimax 小模型兜底(意图识别) =====================
small_llm = ChatMinimax(
    api_key=MINIMAX_API_KEY,
    model="minimax-chat-lite",
    temperature=0.0,
)

# 意图识别提示词
intent_prompt = PromptTemplate.from_template("""
你是企业智能办公助手,仅输出标准意图:
问好、查询身份、查询薪资、查询考勤、请假申请、查询公司政策、其他
用户输入:{query}
""")

# LangChain0.3标准链
intent_chain = intent_prompt | small_llm | StrOutputParser()

# ===================== 总路由编排(三层自动流转) =====================
def total_router(query: str) -> str:
    # 第一层:关键词匹配
    res = keyword_runnable.invoke(query)
    if res in VALID_INTENTS:
        print(f"✅【LangChain关键词】识别意图:{res}")
        return res

    # 第二层:向量匹配
    res = vector_runnable.invoke(query)
    if res in VALID_INTENTS:
        print(f"✅【LangChain向量】识别意图:{res}")
        return res

    # 第三层:小模型兜底
    res = intent_chain.invoke({"query": query})
    print(f"✅【LangChain小模型】识别意图:{res}")
    return res

# 总路由:包装成LangChain可执行组件
total_runnable = RunnableLambda(total_router)

# ===================== Minimax 大模型:办公回复生成 =====================
big_llm = ChatMinimax(
    api_key=MINIMAX_API_KEY,
    model="minimax-chat-pro",
    temperature=0.3,
)

# 回复提示词
reply_prompt = PromptTemplate.from_template("""
你是企业智能办公助手,语气友好、简洁、专业:
用户意图:{intent}
用户问题:{query}
""")

# 回复执行链
reply_chain = reply_prompt | big_llm | StrOutputParser()

# ===================== 最终运行入口(核心!超详细注释) =====================
def run_langchain_office_agent(query: str):
    """
    办公助手总执行函数(小白直接调用这个就行)
    :param query: 用户输入的一句话(比如:你好、帮我查工资)
    """
    print("-" * 60)
    print(f"🗣️ 用户输入:{query}")
    
    # ======================================
    # 【核心调用1】
    # total_runnable:总路由组件(负责三层意图识别)
    # .invoke():LangChain0.3 唯一执行方法
    # 执行逻辑:关键词→向量→小模型 自动识别
    # 返回值:最终识别的意图
    # ======================================
    intent = total_runnable.invoke(query)
    print(f"🎯 最终识别意图:{intent}")

    # 判断意图是否合法,合法就生成回复
    if intent in VALID_INTENTS[:-1]:
        print("\n🚀 正在生成回复...")

        # ======================================
        # 【核心调用2】
        # reply_chain:回复生成链
        # 传参字典:必须和提示词的{intent}{query}完全一致
        # 执行逻辑:调用Minimax大模型生成办公回复
        # ======================================
        result = reply_chain.invoke({"intent": intent, "query": query})
        
        print(f"\n📄 助手回复:\n{result}")
    else:
        print("❌ 暂不支持该办公需求")

# ===================== 测试代码 =====================
if __name__ == "__main__":
    # 新手每次只运行1个测试用例
    run_langchain_office_agent("你好")
    # run_langchain_office_agent("帮我查我的工资")
    # run_langchain_office_agent("我要请假")

三. 我的项目实现思路

目前

  1. 关键词 fast-path 已经覆盖了 60-70% 的高频请求(0ms 0 调用,完全不碰任何模型)
  2. 短查询兜底覆盖了 10-15% 的零碎闲聊(同样 0 调用)
  3. 真到第 3 层 LLM 分类的请求只剩 15-25%,这部分目前还是 25s,但触发频率已经低很多

3.1 具体方案

第 1 层:关键词 fast-path

数据结构 :KEYWORD_RULES 元组表

(意图, [关键词列表], [候选意图列表])

5 条规则:

意图 关键词示例
salary 薪酬、工资、总包、奖金、薪资、个税、收入
personal 年假、合同、身份证、手机号、部门、入职
travel 机票、酒店、出差、预订、航班、舱位
knowledge 制度、报销、手册、规定、政策、流程、FAQ
chitchat 生成/写/撰写/面试 + 你是谁/你好/hi/谢谢

决策规则:

  • 子串匹配(lowercase)
  • 平票(多个意图命中数相同)→ 放弃,进下一层
  • 命中 → confidence = 0.93,reason 写清命中词

第 2 层:短查询兜底

逻辑一行:

scss 复制代码
if len(query.strip()) ≤ 15 字 and 第 1 层没命中:
    return chitchat(confidence=0.85)

覆盖:"在吗"、"嗯"、"ok"、"?" 这种没穷举进关键词的零碎闲聊。

为什么是 15 字:业务请求最短也在 "查一下本月薪酬"(8 字)和 "帮我预订明天的机票"(9 字)之间,但这些都已经被第 1 层关键词吃掉了,剩下没命中还短的基本只能是闲聊。阈值放 15 保险。

第 3 层:utility 模型分类

工厂:

get_utility_chat_model()

  • temperature=0(分类要稳定)
  • streaming=False(分类不流式)
  • thinking=关闭(分类不需要思考)
  • max_tokens=1024(短输出)

模型选择:

  • OpenAI provider → gpt-4o-mini
  • Anthropic provider → anthropic_utility_model,留空回退到主模型(MiniMax Coding Plan 现况)

prompt:

  • system:"你是意图分类器,只返回 JSON,意图只能是 5 类之一"
  • human:few-shot 4 个示例 + PydanticOutputParser 生成的 JSON schema + 用户问题

输出强校验 :prompt | llm | parser,parser 用 Pydantic,校验失败自动重试。

后置:置信度门槛

ini 复制代码
python
if result.intent != "chitchat" and result.confidence < 0.7:
    result.intent = "clarify"   # 让 generate_node 反问用户

chitchat 没门槛(本来就不需要高置信度),其他业务意图必须 ≥0.7 才敢路由,否则问用户"你是想查工资还是查差旅?"


3.2、关键设计权衡

选择 另一种做法 为什么这么选
规则优先、模型兜底 全靠模型 模型贵且慢,高频 query 别浪费
关键词放第 1 层 关键词放最后(作"模型没把握时的补丁") 从延迟角度考虑:能 0ms 就别花 1-2s
平票放弃 强制选分最高 "差旅报销制度"同时命中 2 个意图,应该让模型决定而不是按顺序取第一个
confidence 分三档0.93 / 0.85 / 模型给 统一给 1.0 或不给 前端/澄清逻辑可以根据置信度决定要不要反问
chitchat 不设置信度门槛 全部 intent 都卡 0.7 闲聊本来就模糊,强行要求高置信只会让"你好"这种被路到 clarify
reason 字段保留路径标识 统一用模型给的 reason 便于日后 grep 日志统计每层命中率,运维友好
第 3 层用 utility 工厂(而不是主工厂) 都用 get_chat_model() 分类是高频小活儿,应该走小模型;MiniMax 回退到主模型保持向后兼容
第 2 层用"长度"而不是 embedding 上 embedding 路由器 现阶段 YAGNI,长度启发式已经覆盖大部分情况

3.3、每层覆盖率(经验估算)

覆盖率 延迟 LLM 调用
1 关键词 60-70% ~0 ms 0
2 短查询 +10-15% ~0 ms 0
3 utility 模型 +15-25% 1-25s (看模型) 1

累计:75-85% 的请求在前两层就处理完了,彻底跳过 LLM。


3.4、可观测性

每层命中路径都写到 IntentClassification.reason 里:

路径 reason 值
第 1 层 本地快速路径命中关键词:{词}
第 2 层 本地快速路径:短查询(≤15 字)默认 chitchat
第 3 层 模型生成的自然语言原因

加个中间件 grep 这个字段就能算出真实分布。


3.5、向后兼容与可演进性

场景 做法
加新意图 KEYWORD_RULES 加一行 + 在 FEW_SHOTS 加一个示例
新意图太模糊没法列关键词 只加 few-shot,让第 3 层处理
想接 embedding 路由 在第 2、3 层之间插一层,不动现有代码
MiniMax 换成 Claude 官方 .envANTHROPIC_UTILITY_MODEL=claude-3-5-haiku-latest,立即享受小模型加速
改置信度门槛 INTENT_CONFIDENCE_THRESHOLD 环境变量

3.6、测试覆盖

test_intent_chain.py 5 条单测:

  1. 业务关键词命中 → fast-path,LLM 不被触发
  2. 写作类关键词命中 → chitchat,LLM 不被触发
  3. 问候类(你是谁/hi/谢谢) → chitchat,LLM 不被触发
  4. 短查询兜底(在吗/嗯/ok) → chitchat,LLM 不被触发
  5. 长查询 + 无关键词 → 必须进到第 3 层

测法:monkeypatch

get_utility_chat_model,让它一旦被调就抛 AssertionError。验证"该走快速路径的决不触达 LLM"。


3.7、关联文件清单

文件 角色
intent_chain.py 三层编排主体
intent_router_node.py 套成 LangGraph 节点
llm.py:122-173 get_utility_chat_model 工厂
config.py:53-68 大/小模型配置
domain.py IntentClassification 结构
test_intent_chain.py 单测
02-routing-and-model-tiers.md 设计文档
相关推荐
小程故事多_803 小时前
生产级大模型应用后端架构设计指南(从入门到实战)
人工智能·架构·智能体
AI产品测评官4 小时前
2026年AI招聘架构深潜:多Agent协同如何打造主动出击智能体代表?
人工智能·架构
9号达人5 小时前
为什么你应该在 MQ 里用多个消费者,而不是一个
java·后端·架构
星栈6 小时前
Rust 全栈一个 main.rs 搞定启动:migration + CQRS + 投影监听,部署只需一个二进制
后端·架构
lilihuigz7 小时前
AI内容管理系统全面解析:核心功能、关键技术与架构应用指南 - WP站长
人工智能·搜索引擎·架构
掘根8 小时前
【微服务即时通讯】登录注册界面设计
微服务·云原生·架构
400分8 小时前
git踩坑之修改仓库首次提交(根提交)的commit信息
架构
倔强的石头1068 小时前
告别昂贵的ETL——大数据架构下的时序选型指南
大数据·架构·etl
非情剑8 小时前
Tlog实现微服务日志追踪
微服务·云原生·架构