概览
router pattern 是一种 multi-agent 架构,其中路由步骤会对输入进行分类,并将其定向到专用智能体,再将结果合成为一个组合响应。当组织知识分布在不同 verticals 中时,这种模式尤其有效。这里的 verticals 指彼此独立的知识领域,每个领域都需要带有专用工具和提示词的智能体。 在本教程中,你将构建一个多源知识库 router,并通过一个贴近真实企业场景的示例展示这些优势。系统将协调三个专家:- 一个搜索代码、issues 和 pull requests 的 GitHub agent。
- 一个搜索内部文档和 wiki 的 Notion agent。
- 一个搜索相关线程和讨论的 Slack agent。
为什么使用 router?
router pattern 提供以下优势:- 并行执行:同时查询多个来源,与顺序方法相比可降低延迟。
- 专用智能体:每个 vertical 都有针对其领域优化的专用工具和提示词。
- 选择性路由:并非每个查询都需要每个来源,router 会智能选择相关 verticals。
- 定向子问题:每个智能体都会收到针对其领域定制的问题,从而提升结果质量。
- 清晰合成:来自多个来源的结果会被组合成单个连贯响应。
概念
本教程将介绍以下概念:- 多智能体系统
- 用于工作流编排的 StateGraph
- 用于并行执行的 Send API
设置
安装
本教程需要langchain 和 langgraph 包:
LangSmith
设置 LangSmith,以检查智能体内部发生的情况。然后设置以下环境变量:选择 LLM
从 LangChain 的集成套件中选择一个聊天模型:- OpenAI
- Anthropic
- Azure
- Google Gemini
- AWS Bedrock
- HuggingFace
- OpenRouter
1. 定义状态
首先,定义状态 schema。本教程使用三种类型:AgentInput:传递给每个 subagent 的简单状态,只包含查询AgentOutput:每个 subagent 返回的结果,包含来源名称和结果RouterState:主工作流状态,用于跟踪查询、分类、结果和最终答案
results 字段使用 reducer(Python 中的 operator.add,JS 中的 concat 函数)将并行智能体执行的输出收集到单个列表中。
2. 为每个 vertical 定义工具
为每个知识领域创建工具。在生产系统中,这些工具会调用真实 API。在本教程中,使用返回模拟数据的 stub 实现。本教程跨 3 个 verticals 定义 7 个工具:GitHub(搜索代码、issues、PRs)、Notion(搜索文档、获取页面)和 Slack(搜索消息、获取线程)。3. 创建专用智能体
为每个 vertical 创建一个智能体。每个智能体都有领域专用工具,以及针对其知识来源优化的提示词。三个智能体都遵循相同模式,只有工具和系统提示词不同。4. 构建 router 工作流
现在使用 StateGraph 构建 router 工作流。该工作流有四个主要步骤:- 分类:分析查询,并确定用哪些子问题调用哪些智能体
- 路由:使用
Send并行 fan out 到选定智能体 - 查询智能体:每个智能体接收简单的
AgentInput,并返回AgentOutput - 合成:将收集到的结果组合成连贯响应
5. 编译工作流
现在通过用边连接节点来组装工作流。关键是将add_conditional_edges 与路由函数一起使用,以启用并行执行:
add_conditional_edges 调用通过 route_to_agents 函数将 classify 节点连接到 agent 节点。当 route_to_agents 返回多个 Send 对象时,这些节点会并行执行。
6. 使用 router
使用跨多个知识领域的查询来测试 router:7. 理解架构
router 工作流遵循清晰模式:分类阶段
classify_query 函数使用 structured output 分析用户查询,并确定要调用哪些智能体。路由智能就在这一阶段:
- 使用 Pydantic model(Python)或 Zod schema(JS)确保输出有效
- 返回
Classification对象列表,每个对象都包含source和定向query - 仅包含相关来源,不相关来源会被直接省略
使用 send 并行执行
route_to_agents 函数将分类结果映射到 Send 对象。每个 Send 都指定目标节点和要传递的状态:
AgentInput,只包含 query 字段,而不是完整 router 状态。这使接口保持清晰且明确。
使用 reducer 收集结果
智能体结果通过 reducer 流回主状态。每个智能体返回:operator.add)会拼接这些列表,将所有并行结果收集到 state["results"] 中。
合成阶段
所有智能体完成后,synthesize_results 函数会遍历收集到的结果:
- 等待所有并行分支完成,LangGraph 会自动处理
- 引用原始查询,确保答案回应用户提出的问题
- 合并所有来源的信息,避免冗余
部分结果:在本教程中,所有选定智能体都必须完成后才会进行合成。
8. 完整可运行示例
下面是整合所有内容的可运行脚本:9. 进阶:有状态 router
到目前为止构建的 router 是无状态的,每个请求都会独立处理,调用之间没有记忆。对于多轮对话,你需要一种有状态方法。工具包装方法
添加对话记忆的最简单方法,是将无状态 router 包装为一个可由对话式智能体调用的工具:完整持久化方法
如果你需要 router 本身维护状态,例如在路由决策中使用之前的搜索结果,请使用 persistence 在 router 层级存储消息历史。10. 关键要点
当你具备以下需求时,router pattern 尤其适用:- 不同 verticals:彼此独立的知识领域,每个领域都需要专用工具和提示词
- 并行查询需求:适合同时查询多个来源的问题
- 合成需求:需要将多个来源的结果组合为连贯响应
后续步骤
- 了解用于 agent-to-agent 对话的 handoffs
- 探索用于集中编排的 subagents pattern
- 阅读 multi-agent overview,比较不同模式
- 使用 LangSmith 调试和监控 router
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

