路由模式概述
虽然通过提示词链进行顺序处理是执行确定性、线性工作流的基础技术,但其适用性在需要自适应响应的场 景中受到限制。现实世界的 Agent 系统必须经常根据偶然因素在多个潜在行动之间进行仲裁,例如环境状 态、用户输入或前一操作的结果。这种动态决策能力,控制流向不同的专门函数、工具或子流程,是通过一 种称为路由的机制实现的。
路由将条件逻辑引入 Agent 的操作框架,使其能够从固定的执行路径转变为这样一种模型:Agent 动态评估 特定标准,从一组可能的后续操作中进行选择。这使得系统行为更加灵活且具有上下文感知能力。
例如,一个设计用于客户查询的 Agent,当配备路由功能时,可以首先对传入查询进行分类以确定用户的意 图。基于此分类,它可以将查询定向到专门的 Agent 进行直接问答、用于帐户信息的数据库检索工具,或用 于复杂问题的升级程序,而不是默认使用单一的预定响应路径。因此,使用路由的更复杂 Agent 可以:
-
分析用户的查询。
-
基于其意图路由查询:
・ 如果意图是"检查订单状态",路由到与订单数据库交互的子Agent或工具链。
・ 如果意图是"产品信息",路由到搜索产品目录的子Agent或链。
・ 如果意图是"技术支持",路由到访问故障排除指南或升级到人工的不同链。
・ 如果意图不清楚,路由到澄清子Agent或提示词链。
路由模式的核心组件是执行评估并指导流程的机制。这种机制可以通过几种方式实现:
-
・ 基于 LLM 的路由:
-
语言模型本身可以被提示分析输入并输出指示下一步或目的地的特定标识符或指 令。例如,提示词可能要求 LLM "分析以下用户查询并仅输出类别:'订单状态'、'产品信息'、'技术 支持'或'其他'。"Agent 系统然后读取此输出并相应地指导工作流。
-
・ 基于嵌入的路由:
-
输入查询可以转换为向量嵌入。然后将此嵌入与代表不同路 由或能力的嵌入进行比较。查询被路由到嵌入最相似的路由。这对于语义路由很有用,其中决策基于 输入的含义而不仅仅是关键词。
-
・ 基于规则的路由:
-
这涉及使用基于关键词、模式或从输入中提取的结构化数据的预定义规则或逻辑(例 如,if‐else 语句、switch case)。这可以比基于 LLM 的路由更快、更确定,但在处理细微或新颖输入 方面的灵活性较差。
-
・ 基于机器学习模型的路由:
-
它采用判别模型,例如分类器,该模型已经在小型标记数据语料库上专门 训练以执行路由任务。虽然它与基于嵌入的方法在概念上有相似之处,但其关键特征是监督微调过程, 该过程调整模型的参数以创建专门的路由功能。这种技术与基于 LLM 的路由不同,因为决策组件不是 在推理时执行提示词的生成模型。相反,路由逻辑被编码在微调模型的学习权重中。虽然 LLM 可能在 预处理步骤中用于生成合成数据以增强训练集,但它们不参与实时路由决策本身。
路由机制可以在 Agent 操作周期内的多个节点实现。它们可以在开始时应用以对主要任务进行分类,在处理 链内的中间点应用以确定后续操作,或在子程序期间应用以从给定集合中选择最合适的工具。
诸如 LangChain、LangGraph 和 Google 的 Agent Developer Kit (ADK) 等计算框架提供了用于定义和管理 这种条件逻辑的显式构造。凭借其基于状态的图架构,LangGraph 特别适合复杂的路由场景,其中决策取决 于整个系统的累积状态。类似地,Google 的 ADK 提供了用于构建 Agent 能力和交互模型的基础组件,这些组件作为实现路由逻辑的基础。在这些框架提供的执行环境中,开发人员定义可能的操作路径以及决定计算 图中节点之间转换的函数或基于模型的评估。 路由的实现使系统能够超越确定性顺序处理。它促进了更自适应的执行流的开发,可以动态且适当地响应更 广泛的输入和状态变化。
概览
是什么:
Agent 系统必须经常响应各种各样的输入和情况,这些无法由单一的线性流程处理。简单的顺序工 作流缺乏基于上下文做出决策的能力。没有为特定任务选择正确工具或子流程的机制,系统仍然是僵化和非 自适应的。这种限制使得难以构建能够管理现实世界用户请求的复杂性和可变性的复杂应用程序。
为什么:
路由模式通过将条件逻辑引入 Agent 的操作框架提供了标准化解决方案。它使系统能够首先分析 传入查询以确定其意图或性质。基于此分析,Agent 动态地将控制流定向到最合适的专门工具、功能或子 Agent。这个决策可以由各种方法驱动,包括提示 LLM、应用预定义规则或使用基于嵌入的语义相似性。最 终,路由将静态的预定执行路径转变为能够选择最佳可能操作的灵活和上下文感知工作流。
经验法则:
当 Agent 必须根据用户输入或当前状态在多个不同的工作流、工具或子 Agent 之间做出决策时, 使用路由模式。它对于需要对传入请求进行分类或分类以处理不同类型任务的应用程序至关重要,例如客户支持机器人区分销售查询、技术支持和帐户管理问题。

-
图 1:路由模式,使用 LLM 作为路由器
关键要点
-
・ 路由使Agent能够根据条件动态决定工作流中的下一步。
-
・ 它允许Agent处理各种输入并调整其行为,超越线性执行。
-
・ 路由逻辑可以使用LLM、基于规则的系统或嵌入相似性实现。
实际应用与用例
路由模式是自适应 Agent 系统设计中的关键控制机制,使它们能够动态改变其执行路径以响应可变输入和内 部状态。其效用通过提供必要的条件逻辑层跨越多个领域。
在人机交互中,例如虚拟助手或 AI 驱动的导师,路由用于解释用户意图。对自然语言查询的初始分析确定 最合适的后续操作,无论是调用特定信息检索工具、升级到人工操作员,还是根据用户表现选择课程中的下 一个模块。这使系统能够超越线性对话流并进行上下文响应。
在自动化数据和文档处理管道中,路由作为分类和分发功能。传入的数据,如电子邮件、支持票据或 API 有 效载荷,根据内容、元数据或格式进行分析。然后系统将每个项目定向到相应的工作流,例如销售线索摄入流程、JSON 或 CSV 格式的特定数据转换函数,或紧急问题升级路径。
在涉及多个专门工具或 Agent 的复杂系统中,路由充当高级调度器。由用于搜索、总结和分析信息的不同 Agent 组成的研究系统将使用路由器根据当前目标将任务分配给最合适的 Agent。类似地,AI 编码助手使用 路由来识别编程语言和用户意图------调试、解释或翻译------然后将代码片段传递给正确的专门工具。
最终,路由提供了创建功能多样化和上下文感知系统所必需的逻辑仲裁能力。它将 Agent 从预定义序列的静 态执行器转变为可以在变化条件下就完成任务的最有效方法做出决策的动态系统。
*
实操代码示例(LangChain)
在代码中实现路由涉及定义可能的路径和决定采取哪条路径的逻辑。像 LangChain 和 LangGraph 这样的框 架为此提供了特定的组件和结构。LangGraph 基于状态的图结构对于可视化和实现路由逻辑特别直观。
以下是基于LangChain的路由模式实用代码示例,涵盖三种典型场景:
*
基础路由模式(基于条件判断)
python
from langchain.chains import LLMChain, SimpleSequentialChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from typing import Literal, Dict, Any
class BasicRouter:
"""基础路由示例:根据输入内容路由到不同的处理链"""
def __init__(self):
self.llm = OpenAI(temperature=0)
# 定义不同专业链
self.tech_chain = LLMChain(
llm=self.llm,
prompt=PromptTemplate(
input_variables=["query"],
template="作为技术专家回答:{query}\n请提供详细的技术解释:"
)
)
self.business_chain = LLMChain(
llm=self.llm,
prompt=PromptTemplate(
input_variables=["query"],
template="作为商业顾问回答:{query}\n请从商业角度分析:"
)
)
self.general_chain = LLMChain(
llm=self.llm,
prompt=PromptTemplate(
input_variables=["query"],
template="请回答以下问题:{query}\n回答:"
)
)
def route_by_keywords(self, query: str) -> str:
"""基于关键词的路由"""
query_lower = query.lower()
# 路由逻辑
if any(keyword in query_lower for keyword in
['python', 'java', '代码', '编程', '算法']):
return self.tech_chain.run(query)
elif any(keyword in query_lower for keyword in
['市场', '营销', '商业', '投资', '利润']):
return self.business_chain.run(query)
else:
return self.general_chain.run(query)
# 使用示例
router = BasicRouter()
print(router.route_by_keywords("如何优化Python代码性能?"))
print(router.route_by_keywords("怎样制定市场营销策略?"))
LLM驱动的智能路由
python
from langchain.chains.router import MultiPromptChain
from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE
class SmartRouter:
"""使用LLM进行智能路由决策"""
def __init__(self):
self.llm = OpenAI(temperature=0)
# 定义不同目的的提示模板
self.prompt_infos = [
{
"name": "code_explanation",
"description": "适合解释代码、编程概念的问题",
"prompt_template": """你是一位编程专家,请解释以下代码或概念:
{input}
请提供详细解释和示例:"""
},
{
"name": "debugging",
"description": "适合调试代码、修复错误的问题",
"prompt_template": """你是一位调试专家,请帮助解决以下代码问题:
{input}
请分析问题并提供解决方案:"""
},
{
"name": "translation",
"description": "适合代码翻译、语言转换的问题",
"prompt_template": """你是一位代码翻译专家,请完成以下翻译任务:
{input}
请提供翻译后的代码:"""
}
]
def create_router_chain(self):
"""创建多提示路由链"""
destination_chains = {}
for p_info in self.prompt_infos:
prompt = PromptTemplate(
template=p_info["prompt_template"],
input_variables=["input"]
)
chain = LLMChain(llm=self.llm, prompt=prompt)
destination_chains[p_info["name"]] = chain
# 默认链
default_chain = LLMChain(
llm=self.llm,
prompt=PromptTemplate(
input_variables=["input"],
template="请回答:{input}"
)
)
# 路由提示模板
destinations = [f"{p['name']}: {p['description']}"
for p in self.prompt_infos]
destinations_str = "\n".join(destinations)
router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(
destinations=destinations_str
)
router_prompt = PromptTemplate(
template=router_template,
input_variables=["input"],
output_parser=RouterOutputParser()
)
router_chain = LLMRouterChain.from_llm(
self.llm,
router_prompt
)
return MultiPromptChain(
router_chain=router_chain,
destination_chains=destination_chains,
default_chain=default_chain,
verbose=True
)
def route_query(self, query: str) -> str:
"""路由查询"""
chain = self.create_router_chain()
return chain.run(query)
# 使用示例
smart_router = SmartRouter()
result = smart_router.route_query("这段Python代码为什么报错:'list index out of range'?")
print(result)
多智能体协作路由系统
python
from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent
from langchain.tools import BaseTool
from langchain.schema import AgentAction, AgentFinish
from typing import List, Tuple, Any, Optional
import json
class MultiAgentRouter:
"""多智能体路由系统:根据任务类型分配给不同的专业Agent"""
def __init__(self):
self.llm = OpenAI(temperature=0, max_tokens=500)
# 定义专业工具(模拟不同的Agent)
self.tools = [
Tool(
name="CodeAnalyzer",
func=self._analyze_code,
description="用于分析代码、解释算法"
),
Tool(
name="DataProcessor",
func=self._process_data,
description="用于处理数据、转换格式"
),
Tool(
name="DocumentSummarizer",
func=self._summarize_document,
description="用于总结文档、提取要点"
),
Tool(
name="ResearchAssistant",
func=self._research_topic,
description="用于研究主题、收集信息"
)
]
# 路由决策器
self.router_prompt = PromptTemplate(
input_variables=["input", "tools"],
template="""根据用户问题,选择最合适的工具:
可用工具:
{tools}
用户问题:{input}
请以JSON格式返回,包含以下字段:
- tool: 选择的工具名称
- reasoning: 选择理由
- confidence: 置信度(0-1)
回答:"""
)
def _analyze_code(self, query: str) -> str:
"""代码分析工具"""
prompt = f"作为代码分析专家,请分析:{query}"
return self.llm(prompt)
def _process_data(self, query: str) -> str:
"""数据处理工具"""
prompt = f"作为数据处理专家,请处理:{query}"
return self.llm(prompt)
def _summarize_document(self, query: str) -> str:
"""文档总结工具"""
prompt = f"作为文档总结专家,请总结:{query}"
return self.llm(prompt)
def _research_topic(self, query: str) -> str:
"""研究助手工具"""
prompt = f"作为研究助手,请研究:{query}"
return self.llm(prompt)
def _route_decision(self, query: str) -> dict:
"""路由决策"""
tools_desc = "\n".join([
f"- {tool.name}: {tool.description}"
for tool in self.tools
])
response = self.llm(
self.router_prompt.format(
input=query,
tools=tools_desc
)
)
try:
# 解析JSON响应
decision = json.loads(response)
return decision
except:
# 如果解析失败,使用简单路由
return self._fallback_route(query)
def _fallback_route(self, query: str) -> dict:
"""备用路由策略"""
query_lower = query.lower()
if any(keyword in query_lower for keyword in
['代码', '编程', '算法', 'debug']):
return {"tool": "CodeAnalyzer", "confidence": 0.8}
elif any(keyword in query_lower for keyword in
['数据', '处理', '分析', '转换']):
return {"tool": "DataProcessor", "confidence": 0.8}
elif any(keyword in query_lower for keyword in
['总结', '摘要', '要点', '概括']):
return {"tool": "DocumentSummarizer", "confidence": 0.8}
else:
return {"tool": "ResearchAssistant", "confidence": 0.6}
def process_query(self, query: str) -> Tuple[str, dict]:
"""处理查询并返回结果和路由信息"""
# 1. 路由决策
decision = self._route_decision(query)
# 2. 执行对应工具
tool_name = decision.get("tool", "ResearchAssistant")
tool = next((t for t in self.tools if t.name == tool_name),
self.tools[-1])
# 3. 执行任务
result = tool.run(query)
# 4. 返回结果和路由信息
return result, decision
# 使用示例
multi_agent = MultiAgentRouter()
result, routing_info = multi_agent.process_query(
"请分析这段Python代码的时间复杂度"
)
print(f"路由决策: {routing_info}")
print(f"处理结果: {result[:200]}...")
状态感知的路由系统
python
from enum import Enum
from dataclasses import dataclass
from typing import Dict, Any, Optional
class UserState(Enum):
BEGINNER = "beginner"
INTERMEDIATE = "intermediate"
ADVANCED = "advanced"
class ConversationStage(Enum):
GREETING = "greeting"
QUESTION = "question"
FOLLOW_UP = "follow_up"
CLOSING = "closing"
@dataclass
class ConversationContext:
"""对话上下文"""
user_state: UserState
stage: ConversationStage
history: list
preferences: Dict[str, Any]
class ContextAwareRouter:
"""上下文感知的路由器"""
def __init__(self):
self.llm = OpenAI(temperature=0)
self.context = ConversationContext(
user_state=UserState.BEGINNER,
stage=ConversationStage.GREETING,
history=[],
preferences={}
)
def update_context(self, query: str, response: str):
"""更新对话上下文"""
self.context.history.append({
"query": query,
"response": response
})
# 根据对话历史更新用户状态
if len(self.context.history) > 5:
self.context.user_state = UserState.INTERMEDIATE
if len(self.context.history) > 20:
self.context.user_state = UserState.ADVANCED
def determine_stage(self, query: str) -> ConversationStage:
"""确定对话阶段"""
query_lower = query.lower()
if any(word in query_lower for word in ['你好', '嗨', 'hello']):
return ConversationStage.GREETING
elif any(word in query_lower for word in ['谢谢', '再见', '拜拜']):
return ConversationStage.CLOSING
elif '?' in query or any(word in query_lower
for word in ['如何', '怎样', '为什么']):
return ConversationStage.QUESTION
else:
return ConversationStage.FOLLOW_UP
def route_by_context(self, query: str) -> str:
"""基于上下文的路由"""
# 更新对话阶段
self.context.stage = self.determine_stage(query)
# 根据用户状态和对话阶段选择策略
if self.context.user_state == UserState.BEGINNER:
template = self._get_beginner_template()
elif self.context.user_state == UserState.INTERMEDIATE:
template = self._get_intermediate_template()
else:
template = self._get_advanced_template()
# 根据对话阶段调整
if self.context.stage == ConversationStage.GREETING:
template = "热情问候用户,并简单介绍你能做什么:{query}"
elif self.context.stage == ConversationStage.CLOSING:
template = "礼貌结束对话:{query}"
# 执行响应
prompt = PromptTemplate(
input_variables=["query"],
template=template
)
chain = LLMChain(llm=self.llm, prompt=prompt)
response = chain.run(query)
# 更新上下文
self.update_context(query, response)
return response
def _get_beginner_template(self) -> str:
return """作为面向初学者的助手,请用简单易懂的语言回答:
问题:{query}
请使用比喻和简单示例:"""
def _get_intermediate_template(self) -> str:
return """作为专业助手,请提供详细的解答:
问题:{query}
请包括关键概念和步骤:"""
def _get_advanced_template(self) -> str:
return """作为专家级助手,请提供深入的分析:
问题:{query}
请包括高级技巧和最佳实践:"""
# 使用示例
context_router = ContextAwareRouter()
# 模拟对话流程
queries = [
"你好,我想学习编程",
"Python是什么?",
"如何安装Python?",
"谢谢你的帮助"
]
for query in queries:
response = context_router.route_by_context(query)
print(f"用户: {query}")
print(f"助手: {response}")
print(f"当前状态: {context_router.context.user_state.value}")
print("-" * 50)
工具调用路由(Function Calling)
python
from langchain.chains.openai_functions import create_openai_fn_router
from langchain.pydantic_v1 import BaseModel, Field
from typing import List, Optional
# 定义工具的结构化模式
class CodeAnalysis(BaseModel):
"""代码分析工具"""
language: str = Field(description="编程语言")
problem_type: str = Field(description="问题类型")
code_snippet: str = Field(description="代码片段")
class DataQuery(BaseModel):
"""数据查询工具"""
dataset_name: str = Field(description="数据集名称")
query_type: str = Field(description="查询类型")
filters: Optional[List[str]] = Field(description="过滤条件")
class DocumentSummary(BaseModel):
"""文档总结工具"""
document_text: str = Field(description="文档文本")
summary_length: str = Field(description="总结长度:short/medium/long")
class FunctionCallingRouter:
"""使用OpenAI Function Calling进行路由"""
def __init__(self):
self.llm = OpenAI(temperature=0, model="gpt-3.5-turbo-0613")
# 定义可路由的工具
self.functions = [
CodeAnalysis,
DataQuery,
DocumentSummary
]
def create_router(self):
"""创建函数调用路由链"""
return create_openai_fn_router(
self.llm,
self.functions,
prompt=PromptTemplate(
template="""根据用户请求,选择合适的工具:
用户请求:{input}
请选择最合适的工具并填充参数:""",
input_variables=["input"]
)
)
def execute_tool(self, tool_call: dict) -> str:
"""执行工具调用"""
tool_name = tool_call.get("name")
args = tool_call.get("arguments", {})
if tool_name == "CodeAnalysis":
return self._execute_code_analysis(**args)
elif tool_name == "DataQuery":
return self._execute_data_query(**args)
elif tool_name == "DocumentSummary":
return self._execute_document_summary(**args)
else:
return "未找到合适的工具"
def _execute_code_analysis(self, **kwargs) -> str:
"""执行代码分析"""
return f"正在分析{kwargs.get('language')}代码,问题类型:{kwargs.get('problem_type')}"
def _execute_data_query(self, **kwargs) -> str:
"""执行数据查询"""
return f"查询数据集:{kwargs.get('dataset_name')},查询类型:{kwargs.get('query_type')}"
def _execute_document_summary(self, **kwargs) -> str:
"""执行文档总结"""
return f"正在总结文档,长度:{kwargs.get('summary_length')}"
def route_and_execute(self, query: str) -> str:
"""路由并执行"""
router = self.create_router()
# 获取路由决策
result = router.run(query)
if hasattr(result, "additional_kwargs") and result.additional_kwargs.get("function_call"):
# 执行工具调用
tool_call = result.additional_kwargs["function_call"]
return self.execute_tool(tool_call)
else:
# 直接返回LLM响应
return result
# 使用示例
fn_router = FunctionCallingRouter()
result = fn_router.route_and_execute(
"请分析这段Python代码的bug"
)
print(result)
最佳实践建议
-
分层路由设计:
python
class HierarchicalRouter:
def __init__(self):
self.routers = {
"level1": self._coarse_router, # 粗粒度路由
"level2": self._medium_router, # 中粒度路由
"level3": self._fine_router, # 细粒度路由
}
def route(self, query: str, context: dict) -> str:
# 多层路由决策
for level, router_func in self.routers.items():
decision = router_func(query, context)
if decision.get("confidence", 0) > 0.8:
return decision["target"]
return "default_chain"
-
路由缓存策略:
python
from functools import lru_cache
class CachedRouter:
@lru_cache(maxsize=100)
def get_routing_decision(self, query_hash: str) -> dict:
"""缓存相似查询的路由决策"""
# 路由逻辑...
-
监控与日志:
python
import logging
class MonitoredRouter:
def __init__(self):
self.logger = logging.getLogger(__name__)
def route_with_logging(self, query: str) -> str:
start_time = time.time()
result = self.route(query)
duration = time.time() - start_time
self.logger.info(f"""
Routing Log:
- Query: {query[:50]}...
- Decision: {result['decision']}
- Confidence: {result['confidence']}
- Duration: {duration:.2f}s
""")
return result
结论
这些示例展示了路由模式在LangChain中的实际应用,从简单到复杂,可根据具体需求选择合适的实现方式。关键是根据业务场景设计合理的路由逻辑和失败处理机制。
-
路由模式是构建真正动态响应式 Agent 系统的关键步骤。通过实现路由,我们超越了简单的线性执行流,使 Agent 能够智能决策如何处理信息、响应用户输入及利用可用工具或子 Agent。