基于路由的RAG问答系统:智能分流简单、复杂与无关问题
在构建RAG问答系统时,不同类型的问题需要不同的处理策略。本文将介绍如何通过路由机制,对简单、复杂和无关问题进行分流,从而提升系统的效率与回答质量。
一、为什么需要路由?
传统的RAG系统对所有用户问题都采用相同的“检索-生成”流程。然而,在实际应用中,问题的复杂度差异很大:
-
简单问题:如“公司年假有几天?”——只需基础检索即可。
-
复杂问题:如“对比去年和今年的销售增长率,并分析原因?”——需要多步推理、多次检索甚至调用计算工具。
-
无关问题:如“讲个笑话”——与知识库无关,无需检索。
如果不加区分,对所有问题都执行完整的RAG流程,会导致:
-
简单问题响应慢(检索浪费)
-
复杂问题回答不准确(检索不足)
-
无关问题产生幻觉(强行检索反而引入噪声)
路由的核心思想:先对问题进行分类,再根据类别将请求导向最合适的处理流程。
二、问题分类与处理策略
| 类型 | 特征 | 处理策略 | 示例 |
|---|---|---|---|
| 简单 | 事实性、单跳、答案短 | 基础RAG(快速检索+生成) | “2024年春节是几月几号?” |
| 复杂 | 多跳、比较、总结、推理 | Agent或多步检索+工具调用 | “A产品和B产品的利润差异原因?” |
| 不相干 | 与知识库主题无关、闲聊、恶意 | 通用LLM直接回答(无检索) | “你好”、“讲个笑话” |
通过这种分流,系统可以:
-
简单问题快速响应(节省资源)
-
复杂问题精准处理(动用高级能力)
-
无关问题友好回应(避免检索噪音)
三、路由实现思路
3.1 分类器设计
有三种实现方式:
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 基于LLM | 灵活、准确高 | 耗时、消耗token | 问题类型多样,精度要求高 |
| 基于规则 | 极快、零成本 | 覆盖有限,易误判 | 问题模式固定,可枚举 |
| 基于嵌入分类器 | 速度快、可离线 | 需要标注训练 | 大规模生产环境 |
推荐混合方式:先用规则快速命中明显类型(如“你好”归为无关),其余交给LLM分类。
LLM分类提示词示例
python
classification_prompt = """
将以下用户问题分类为:simple、complex、irrelevant。
- simple:事实性、单步查询、答案短。
- complex:需要多步推理、比较、计算或总结。
- irrelevant:与知识库主题无关或闲聊。
问题:{user_query}
输出仅为一个单词。
"""
3.2 路由分发逻辑
python
def route_question(user_query):
category = classify(user_query) # 返回 'simple' / 'complex' / 'irrelevant'
if category == 'simple':
return simple_rag_chain.invoke(user_query)
elif category == 'complex':
return complex_agent_chain.invoke(user_query)
else:
return general_llm.invoke(user_query)
四、各分支的具体设计
4.1 简单问题:基础RAG
-
检索:向量相似度检索,取Top-3。
-
生成:简洁提示词,要求直接给出答案。
-
优化:可缓存高频问题结果。
python
from langchain.chains import RetrievalQA
simple_qa = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
chain_type_kwargs={"prompt": SIMPLE_PROMPT}
)
4.2 复杂问题:Agent或多步检索
复杂问题通常需要多跳推理。可以使用:
-
ReAct Agent:赋予工具(检索、计算、搜索)。
-
多步检索链:先检索初步答案,再根据答案中的实体进行二次检索。
python
from langchain.agents import create_react_agent tools = [retrieve_tool, calculator_tool, web_search_tool] agent = create_react_agent(llm, tools, COMPLEX_PROMPT)
4.3 不相干问题:通用LLM
-
不检索任何知识库。
-
系统提示:设定为友好助手,可闲聊,但告知无法回答业务相关问题时可引导回主题。
python
response = general_llm.invoke(user_query)
五、LangChain 完整示例
python
from langchain.chains import RetrievalQA
from langchain.agents import create_react_agent
from langchain_core.prompts import PromptTemplate
from langchain_ollama import ChatOllama
# 初始化模型和检索器
llm = ChatOllama(model="qwen2.5:7b")
retriever = vectorstore.as_retriever()
# 定义三个处理链
simple_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)
complex_agent = create_react_agent(llm, tools, ...)
general_llm = llm
# 分类函数(简化版,实际可用LLM)
def classify(query):
if any(kw in query for kw in ["你好", "谢谢", "天气"]):
return "irrelevant"
elif any(kw in query for kw in ["为什么", "对比", "分析", "总结"]):
return "complex"
else:
return "simple"
def router(query):
cat = classify(query)
if cat == "simple":
return simple_chain.invoke(query)
elif cat == "complex":
return complex_agent.invoke({"input": query})
else:
return general_llm.invoke(query)
# 使用
while True:
q = input("问题:")
print(router(q))
六、优化建议与避坑指南
-
分类准确性:LLM分类可能出错,可设置置信度阈值,低置信度时走默认策略(如complex)。
-
性能与成本:路由本身会消耗时间,对于高频场景可缓存分类结果。
-
动态调整:根据用户反馈(如“答案不准确”)可调整路由策略或重新训练分类器。
-
安全:对不相干问题也要防止注入攻击,可增加内容过滤。
七、总结
通过引入路由机制,RAG系统能够:
-
简单问题快速响应,节省资源。
-
复杂问题精准处理,动用多步推理。
-
无关问题友好回应,避免检索噪声。
参考资料:
-
LangChain 文档:Agents, RetrievalQA
-
论文:ReAct: Synergizing Reasoning and Acting in Language Models
本文为原创,转载请注明出处。欢迎在评论区交流讨论!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)