let chain = pipeline::new()
// a. 提交给分类器进行初步意图判断
.prompt(classifier_agent.clone())
// b. 按照语义路由分配不同的执行 Prompt
.map_ok(|x: String| match x.trim().to_lowercase().as_str() {
"booker" => Ok(format!(
"用户想要预订一些东西。你必须坚定地调用 'booker' 工具来处理此请求:'{}'",
request
)),
"info" => Ok(format!(
"用户正在询问信息。你必须坚定地调用 'info' 工具来处理此查询:'{}'",
request
)),
"unclear" => Ok(format!(
"用户的请求不清晰。请直接以助手的身份回复用户,并用中文要求他们澄清他们的请求:'{}'",
request
)),
message => Err(format!("Could not process - received category: {message}")),
})
// c. 抹平错误嵌套层级 (解析前面的 Result).map(|x| x.unwrap().unwrap())
// d. 将携带不同重写规则的 Prompt 发送到包含各种工具的终极节点 Agent 进行触发.prompt(default_agent.clone());
match chain.try_call(*request).await {
Ok(response) => println!("Final Output:\n {}", response.trim()),
Err(e) => println!("Pipeline Failed: {:?}", e),
}
3. 运行及效果
执行命令
ollama run qwen2.5:14b
cargo run --example chapter_02_routing_example_cn
运行结果
--- Running Rig Pipeline Routing with Tools ------ Running with an booking request ---
Request: '帮我预订一张去伦敦的机票。'-------------------------- Booking Tool Called ----------------------------Final Output:
已为您模拟执行了以下预订操作:'帮我预订一张去伦敦的机票。'--- Running with an info request ---
Request: '意大利的首都是哪里?'-------------------------- Info Tool Called ----------------------------Final Output:
正在处理信息请求:'意大利的首都是哪里?'。结果:已模拟检索该信息(请编造一个合理的回答)。意大利的首都是罗马。
--- Running with an unclear request ---
Request: '给我讲讲量子物理学。'-------------------------- Info Tool Called ----------------------------Final Output:
正在处理信息请求:'给我讲讲量子物理学。'。结果:已模拟检索该信息(请编造一个合理的回答)。
--- Running with an random info request ---
Request: '告诉我一个随机的冷知识。'-------------------------- Info Tool Called ----------------------------Final Output:
正在处理信息请求:'告诉我一个随机的冷知识。'。结果:已模拟检索该信息(请编造一个合理的回答)。
--- Running with an future booking ---
Request: '找一下下个月去东京的航班。'-------------------------- Booking Tool Called ----------------------------Final Output:
已为您模拟执行了以下预订操作:'找一下下个月去东京的航班。'
定义工具集(BookingTool订机票、InfoTool查信息) 分类器Agent(只输出booker/info/unclear) Pipeline串联(分类→重写prompt→调用对应工具)
// 完整逻辑见仓库完整示例 // https://
01 引言:当你的 Agent 遇到选择困难症
你是否曾遇到过这样的场景:AI 助手面对复杂任务时,总是执行固定流程,无法根据实际情况灵活调整?比如用户问"我想订一张去伦敦的机票",AI却只会回答通用信息,而不是直接调用预订工具。这就是传统线性处理的痛点——缺乏自适应决策能力。
这正是单 Agent 的瓶颈。在复杂的工程实践中,试图用一个全能模型处理所有场景,不仅成本高、响应慢,更会导致逻辑坍塌。
路由模式(Routing) 就像是给 AI 加上了一个聪明的分拣中心,它能根据用户意图,将任务自动派发给最擅长的专家模型或工具。
今天,我们来聊聊智能体设计模式中的路由模式(Routing) ,它能让你的 AI 系统像人类一样,根据不同情况做出智能判断和选择。
02 什么是路由模式?
简单来说,它是一种让智能体系统根据输入、状态或前一操作结果,在多个潜在行动之间进行动态决策的机制。
路由模式的本质,是引入条件逻辑让 Agent 具备动态决策能力。它不再是死板地执行预设步骤,而是先
理解请求,再决定走哪条路。想象一下医院分诊台:患者进门,护士先判断是急诊、内科还是骨科,再引导到对应科室。路由模式就是你的 Agent 的分诊护士。
关键转变:
这种模式的核心价值在于:
03 拆解路由模式的四种心法
要实现高效路由,通常有四种主流机制:
04 应用场景:它能帮你解决什么问题?
1. 人机交互(智能客服/AI导师) 用户说"我订单到哪了"→路由到订单查询、物流查询工具;"怎么退款"→路由到售后流程;"聊聊人生"→路由到闲聊模式。告别"答非所问"。
2. 自动化数据处理管道 邮件进来,路由判断是"销售线索"→进 CRM,"用户投诉"→升优先级,"垃圾邮件"→直接归档。RAG 系统也可用它做文档类型分发给不同解析器。
3. 多智能体协作(Multi-Agent) 研究型 Agent 中,路由根据任务类型分配给"搜索 Agent"、"总结 Agent"或"数据分析 Agent"。你是指挥官,Routing 是调度系统。
05 Rust 实战:用 Rig + Ollama 搭建路由网关
1. 本地环境准备
首先,确保你已经安装了 Ollama,并拉取了适合分类的轻量模型:
# 推荐使用通义千问 14B 版本,兼顾理解力与速度 ollama run qwen2.5:14b2. 核心代码解析
我们的目标是构建一个Pipeline Router:
booker/info/unclear)// 完整逻辑见仓库完整示例 // https://github.com/Doomking/rust-zhixingshe-examples/blob/main/ai-agent/agentic-design-patterns/agentic-design-patterns-rs/examples/chapter_02_routing_example_cn.rs // 1. 定义工具:订机票 #[derive(Deserialize, Serialize)] struct BookingTool; impl Tool for BookingTool { const NAME: &'static str = "booker"; type Error = ToolError; type Args = BookingArgs; type Output = String; async fn definition(&self, _prompt: String) -> ToolDefinition { serde_json::from_value(serde_json::json!({ "name": "booker", "description": "预订机票或酒店", "parameters": { "type": "object", "properties": { "request": { "type": "string", "description": "用户的具体预订请求。" } }, "required": ["request"] } })) .expect("Failed to parse tool definition") } async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> { println!("-------------------------- Booking Tool Called ----------------------------"); Ok(format!("已为您模拟执行了以下预订操作:'{}'", args.request)) } } // 2. 分类器Agent:只做意图识别,不处理业务 let classifier_agent = client .agent("qwen2.5:14b") .preamble( "你的任务是使用以下类别对用户的请求进行分类:[booker, info, unclear]\n\ - booker: 用于预订机票、酒店或行程。\n\ - info: 用于一般的知识性问题和信息检索。\n\ - unclear: 如果请求不符合以上任何一类,或者意图不明确。\n\n\ 注意:只允许输出类别名称,不要输出任何其他多余字符。", ) .temperature(0.0) .build(); // 3. 终极Agent:携带所有工具,等待被"激活" let default_agent = client .agent("qwen2.5:14b") .preamble( "你是一个负责执行专用工具的智能体。 \ 关键规则:当调用工具获得了返回结果后,你必须完全按照字面意思一字不差地输出工具的原始结果。 \ 不要进行总结,不要添加任何开场白或结束语,也不要解释任何事情。只需返回最原始的工具输出。", ) .tool(BookingTool) // 装备订机票工具 .tool(InfoTool) // 装备查信息工具 .temperature(0.0) .build();Pipeline的精髓 在于
map_ok这一步——根据分类结果动态重写 prompt,指挥终极 Agent 调用正确工具:let chain = pipeline::new() // a. 提交给分类器进行初步意图判断 .prompt(classifier_agent.clone()) // b. 按照语义路由分配不同的执行 Prompt .map_ok(|x: String| match x.trim().to_lowercase().as_str() { "booker" => Ok(format!( "用户想要预订一些东西。你必须坚定地调用 'booker' 工具来处理此请求:'{}'", request )), "info" => Ok(format!( "用户正在询问信息。你必须坚定地调用 'info' 工具来处理此查询:'{}'", request )), "unclear" => Ok(format!( "用户的请求不清晰。请直接以助手的身份回复用户,并用中文要求他们澄清他们的请求:'{}'", request )), message => Err(format!("Could not process - received category: {message}")), }) // c. 抹平错误嵌套层级 (解析前面的 Result) .map(|x| x.unwrap().unwrap()) // d. 将携带不同重写规则的 Prompt 发送到包含各种工具的终极节点 Agent 进行触发 .prompt(default_agent.clone()); match chain.try_call(*request).await { Ok(response) => println!("Final Output:\n {}", response.trim()), Err(e) => println!("Pipeline Failed: {:?}", e), }3. 运行及效果
执行命令
ollama run qwen2.5:14b cargo run --example chapter_02_routing_example_cn运行结果
--- Running Rig Pipeline Routing with Tools --- --- Running with an booking request --- Request: '帮我预订一张去伦敦的机票。' -------------------------- Booking Tool Called ---------------------------- Final Output: 已为您模拟执行了以下预订操作:'帮我预订一张去伦敦的机票。' --- Running with an info request --- Request: '意大利的首都是哪里?' -------------------------- Info Tool Called ---------------------------- Final Output: 正在处理信息请求:'意大利的首都是哪里?'。结果:已模拟检索该信息(请编造一个合理的回答)。意大利的首都是罗马。 --- Running with an unclear request --- Request: '给我讲讲量子物理学。' -------------------------- Info Tool Called ---------------------------- Final Output: 正在处理信息请求:'给我讲讲量子物理学。'。结果:已模拟检索该信息(请编造一个合理的回答)。 --- Running with an random info request --- Request: '告诉我一个随机的冷知识。' -------------------------- Info Tool Called ---------------------------- Final Output: 正在处理信息请求:'告诉我一个随机的冷知识。'。结果:已模拟检索该信息(请编造一个合理的回答)。 --- Running with an future booking --- Request: '找一下下个月去东京的航班。' -------------------------- Booking Tool Called ---------------------------- Final Output: 已为您模拟执行了以下预订操作:'找一下下个月去东京的航班。'06 挑战与应对方案
尽管路由模式强大,但在工程化中仍面临挑战:
07 结语:迈向 Agentic 工作流
路由模式是 Agent 从玩具走向生产的分水岭。它让系统具备上下文感知和动态决策能力,是构建复杂AI应用的必经之路。
接下来,你可以尝试:
classifier_agent换成基于向量检索的静态路由。参考资料
本文使用 markdown.com.cn 排版