《Agentic Design Patterns》第 2 章导读:路由(Routing)

《Agentic Design Patterns》第 2 章导读:路由(Routing)

本文是对开源书籍《Agentic Design Patterns》第 2 章的解读与导读,内容忠实呈现原文,并附个人思考。

原书在线阅读:https://adp.xindoo.xyz/ | 翻译项目代码仓库:https://github.com/xindoo/agentic-design-patterns


上一篇我们聊了第 1 章的提示词链------它解决的是"线性、有依赖"的确定性任务流。但现实世界远没有那么规整:智能体经常会遇到**需要"看情况决定下一步怎么做"**的场景。用户问的问题五花八门,有时是查订单、有时问产品、有时要技术支援、有时干脆没说清楚------这些根本没法用一条固定的流水线走到底。

这正是第 2 章**路由(Routing)**模式要解决的问题:让智能体能根据输入内容和当前状态,动态决定把流程引向哪个专门工具、函数或子流程。


一、什么是路由:从"固定路径"到"动态仲裁"

路由把条件逻辑 引入智能体的运行框架,让系统从"固定的执行路径"变成"动态评估标准、从一组可能动作中做选择"。它让系统变得更灵活、更有上下文感知能力。

书里用一个客服智能体的例子讲得很清楚:带路由能力的智能体拿到用户查询后,会先对查询分类、判断意图,然后据此分流:

  1. 分析用户的查询;
  2. 基于其意图 路由查询:
    • 意图是"检查订单状态" → 路由到与订单数据库交互的子智能体或工具链;
    • 意图是"产品信息" → 路由到搜索产品目录的子智能体或链条;
    • 意图是"技术支持" → 路由到访问故障排除指南的链条,或升级到人工;
    • 意图不清楚 → 路由到澄清子智能体或提示词链。

你看,这里没有"一刀切"的回复路径,而是像路由器一样,把不同的请求分发给不同的"出口"。

二、路由的四条实现思路

路由模式的核心组件是"做评估、指方向"的那套机制。书中给出了四种主流实现方式,各有取舍:

实现方式 原理 特点
基于 LLM 的路由 让语言模型分析输入,输出一个指示目的地的标识符(如"订单状态/产品信息/技术支持/其他") 灵活、能理解复杂语义;有推理成本
基于嵌入的路由 把输入转成向量嵌入,与各路由的嵌入比较相似度,路由到最相似的那个 适合"语义路由",决策依据是含义而非关键词
基于规则的路由 用关键词、模式、结构化数据配合 if-else / switch 判断 快、确定性高;但对细微或新颖输入缺乏灵活性
基于机器学习模型的路由 训练一个判别式分类器,把路由逻辑编码进模型权重 是监督微调出来的专门组件;注意它与"基于 LLM 的路由"不同------它不在推理时跑提示词

这里有个容易混淆的点值得留意:基于 ML 模型的路由 和 基于 LLM 的路由 不是一回事。前者是微调出来的一个判别分类器,路由逻辑固化在权重里;后者是推理时用生成式模型跑提示词来输出决策。虽然可以从 LLM 生成合成数据来增强前者的训练集,但两者的"决策主体"完全不同。

另外,路由机制并不是只能放在最前面。书里强调:它可以在操作周期的多个节点 实现------可以在开始 给主任务分类、可以在处理链中间 决定后续动作、也可以在子程序期间从一组工具里挑选最合适的一个。

三、应用场景

  • 人机交互(虚拟助手、AI 导师):先解析自然语言意图,决定是调信息检索工具、升级到人工、还是切换到课程下一个模块------突破线性对话,做上下文响应。
  • 自动化数据/文档管道:把邮件、支持工单、API 载荷按内容/元数据/格式分类,分发到销售线索、数据转换、升级等不同工作流。
  • 多工具/多智能体系统:充当"高级调度器"。比如一个由搜索、总结、分析等不同智能体组成的研究系统,用路由器按当前目标分派任务;AI 编码助手也用路由来识别编程语言和意图(调试/解释/翻译),再把代码片段交给对的工具。

一句话总结它的作用:路由把智能体从"预定义序列的静态执行器",升级成"能在变化条件下决策最有效方式"的动态系统。

四、代码实战一:用 LangChain(LangGraph 风格)实现路由

书中给出两种实现。第一种用 LangChain 的 RunnableBranch,搭建一个"协调器 + 三个模拟子智能体"的结构,按意图(booker / info / unclear)分发请求。

bash 复制代码
pip install langchain langgraph google-cloud-aiplatform langchain-google-genai google-adk deprecated pydantic
python 复制代码
## Copyright (c) 2025 Marco Fago
## 此代码根据 MIT 许可证授权。
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough, RunnableBranch

llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", temperature=0)

## --- 定义模拟子智能体处理程序 ---
def booking_handler(request: str) -> str:
    return f"预订处理程序处理了请求:'{request}'。结果:模拟预订操作。"

def info_handler(request: str) -> str:
    return f"信息处理程序处理了请求:'{request}'。结果:模拟信息检索。"

def unclear_handler(request: str) -> str:
    return f"协调器无法委托请求:'{request}'。请澄清。"

## --- 定义协调器路由链(判断委托给谁)---
coordinator_router_prompt = ChatPromptTemplate.from_messages([
    ("system", """分析用户的请求并确定哪个专家处理程序应处理它。
     - 如果请求与预订航班或酒店相关,输出 'booker'。
     - 对于所有其他一般信息问题,输出 'info'。
     - 如果请求不清楚或不适合任一类别,输出 'unclear'。
     只输出一个词:'booker'、'info' 或 'unclear'。"""),
    ("user", "{request}")
])

coordinator_router_chain = coordinator_router_prompt | llm | StrOutputParser()

## --- 定义委托逻辑 ---
branches = {
    "booker": RunnablePassthrough.assign(output=lambda x: booking_handler(x['request']['request'])),
    "info": RunnablePassthrough.assign(output=lambda x: info_handler(x['request']['request'])),
    "unclear": RunnablePassthrough.assign(output=lambda x: unclear_handler(x['request']['request'])),
}

delegation_branch = RunnableBranch(
    (lambda x: x['decision'].strip() == 'booker', branches["booker"]),
    (lambda x: x['decision'].strip() == 'info', branches["info"]),
    branches["unclear"]  # 默认分支
)

coordinator_agent = {
    "decision": coordinator_router_chain,
    "request": RunnablePassthrough()
} | delegation_branch | (lambda x: x['output'])

## --- 示例用法 ---
def main():
    print("--- 运行预订请求 ---")
    print(coordinator_agent.invoke({"request": "给我预订去伦敦的航班。"}))
    print("\n--- 运行信息请求 ---")
    print(coordinator_agent.invoke({"request": "意大利的首都是什么?"}))
    print("\n--- 运行不清楚的请求 ---")
    print(coordinator_agent.invoke({"request": "告诉我关于量子物理学的事。"}))

main()

这套代码的逻辑 :coordinator_router_chain 先用提示词让 LLM 把请求分类成 booker / info / unclear 三者之一;RunnableBranch 拿到 LLM 的"决策"后,把原始请求交给对应的 handler。整个 coordinator_agent = 先路由出决策 → 再把请求分发给选中的处理程序 → 抽出最终输出。它模仿了多智能体框架里"中央协调器按意图把任务委托给专门智能体"的基本模式。

五、代码实战二:用 Google ADK 实现

第二种实现走的是 Google 智能体开发工具包(ADK) 的路子。ADK 的哲学和显式计算图不太一样:路由通常通过定义一组离散的 "工具" 来实现,选择哪个工具由框架内部逻辑用底层模型去匹配。

python 复制代码
from google.adk.agents import Agent
from google.adk.runners import InMemoryRunner
from google.adk.tools import FunctionTool

def booking_handler(request: str) -> str:
    return f"已模拟对 '{request}' 的预订操作。"

def info_handler(request: str) -> str:
    return f"对 '{request}' 的信息请求。结果:模拟信息检索。"

booking_tool = FunctionTool(booking_handler)
info_tool = FunctionTool(info_handler)

booking_agent = Agent(
    name="Booker", model="gemini-2.0-flash",
    description="处理所有航班和酒店预订请求。", tools=[booking_tool]
)
info_agent = Agent(
    name="Info", model="gemini-2.0-flash",
    description="提供一般信息并回答用户问题。", tools=[info_tool]
)

coordinator = Agent(
    name="Coordinator", model="gemini-2.0-flash",
    instruction=(   # 定义委托指令
        "你是主协调器。你唯一的任务是分析传入的用户请求"
        "并将它们委托给适当的专家智能体。不要尝试直接回答用户。\n"
        "- 对于任何与预订相关的请求,委托给 'Booker' 智能体。\n"
        "- 对于所有其他一般信息问题,委托给 'Info' 智能体。"
    ),
    sub_agents=[booking_agent, info_agent]  # 子智能体的存在默认启用 LLM 驱动的自动流
)

runner = InMemoryRunner(coordinator)
# 然后通过 runner.run(...) 处理用户的预订/信息请求并提取最终响应

关键区别在于:ADK 里定义 sub_agents 后,委托自动由"自动流"机制驱动,不需要像 LangChain 那样手写分支逻辑。这种"开箱即用"的委托对明确定义了离散操作集的系统更简单,而 LangGraph 的图结构则更适合路由逻辑本身就很复杂的场景。

六、速览

  • 问题背景:智能体要频繁响应各种输入和情况,单一线性流程应付不来。没有"选择正确工具/子流程"的机制,系统就僵化、无自适应能力。
  • 解决方案:通过把条件逻辑引入运行框架,让系统先分析查询意图,再动态把控制流导向最合适的专门工具/函数/子智能体;决策可由 LLM、预定义规则或嵌入相似性驱动。
  • 实践建议 :当智能体必须根据用户输入或当前状态、在多个不同工作流/工具/子智能体之间做决策时使用路由模式。典型如客服机器人区分销售、技术支持与账户管理问题。

可视化总结

图 1:路由模式------使用 LLM 作为路由器,把输入分派给不同的专门处理流程。

关键要点

  • 路由让智能体能根据条件动态决定工作流的下一步;
  • 它突破线性执行,让系统能处理多样输入并自适应调整行为;
  • 路由逻辑可用 LLM、规则系统或嵌入相似度实现;
  • LangGraph、Google ADK 等框架用不同架构为路由提供了结构化实现方式。

结语与个人思考

如果说提示词链解决的是"怎么把一件事按顺序做好 ",那么路由解决的就是"面对一件不确定的事,该先往哪条路走 "。两者通常会在一个真实系统里配合使用:先路由定方向,再用链条把选定的子流程做扎实。整套书的主线其实就是这样一层层叠加的------单看每个模式都不复杂,难的是把它们合理地编排进一个系统。

值得留意的工程取舍:

  • LLM 路由 vs 规则路由:规则路由快且确定性强,但碰到没学过的说法就抓瞎;LLM 路由灵活但每多一次推理就多一份延迟与成本。实践中常做成"规则兜底 + LLM 兜语义"的组合。
  • 注意"路由外溢" :LLM 是概率模型,分类偶尔会飘。工程上要给"分类不确定"留后路(比如 unclear 分支、重试、置信度阈值),这正是书里那个"如果意图不清楚→路由到澄清子智能体"的用意。

下一步建议阅读第 3 章 并行化(Parallelization)------当多个子任务互不依赖时,如何让它们同时跑以提升性能,和路由/链条形成完整的工作流三件套。


本文基于开源书籍《Agentic Design Patterns》(https://github.com/xindoo/agentic-design-patterns ,在线阅读 https://adp.xindoo.xyz/ )整理,供学习交流,版权归原作者所有。

相关推荐
hai3152475431 小时前
语言学集合定律
人工智能·算法
国科安芯1 小时前
低轨卫星导航授时载荷中高精度定时控制器的时钟稳定性与抗辐射特性研究
网络·人工智能·低轨卫星·商业航天·授时·抗辐射·时钟稳定
大圣编蚕1 小时前
Schrodinger Suites 2026 专业版全面介绍:药物发现与材料科学计算一体化平台
人工智能
云和数据.ChenGuang1 小时前
JAVAEE AI工程师路线图
java·人工智能·java-ee·fastapi·springai·langchain4j
Latchh1 小时前
PDF提取到文字后怎样发现乱码
图像处理·人工智能·计算机视觉·pdf
mit6.8241 小时前
论拼多多的反向计划经济秩序
人工智能
熊猫钓鱼>_>1 小时前
从2D平铺到3D沉浸:我用HarmonyOS 7端侧AI做了一个全程数据不出设备的空间化私密相册
前端·人工智能·3d·华为·华为云·harmonyos·鸿蒙
YOLO数据集集合1 小时前
空中目标检测数据集 | 空中目标检测 无人机识别 鸟类检测 低空安防 反无人机数据集 鸟类 直升机9154期
人工智能·目标检测·计算机视觉·无人机·空中目标·反无人机
Carl_奕然1 小时前
【智能体】Loop 的四种设计模式之:Event-Driven Loop(2026 最新版)
人工智能·驱动开发·python·设计模式