智能体路由设计详解:从规则到语义,打造稳定可控的Agent调度系统
发布时间:2026/10/20 6:27:21 锦皓数字建站

写这一篇的时候我已经在前两篇内容里把智能体的基本工作流和记忆结构理清了。今天聊路由Routing算是我把智能体从玩具 Demo 推到可交付状态时踩得最深的环节。很多人刚接触智能体时容易忽略它反正大模型那么聪明给它几个工具有需求自己就选了。真实情况是——如果进来的请求没有一套规则去决定走哪条路径模型的选择会变得飘忽不定工具调用也会频繁出错整个系统的行为完全没法预期。路由在智能体系统里的角色相当于调度中心。它决定了一个用户请求应该交给哪个模型、哪个工具、哪个子工作流去处理。这个决定看起来简单但它直接影响成本、延迟、回答质量和系统稳定性。这篇文章我会从路由要解决的核心问题讲起拆解几类常见的路由模式然后拿一个完整案例演示怎么落地最后把我调试过程中遇到的各种毛病和排查思路一并整理出来。适合正好在搭智能体、或者已经被路由逻辑折磨过的同学参考。1. 先把路由这件事想清楚它解决的核心问题1.1 一场混乱引发的路由思考我之前做过一个内部知识问答智能体从表面看就是一个聊天框背后接了向量库、SQL 查询接口、文档搜索引擎和好几个不同规格的模型。最初我的想法很简单把所有上下文和工具说明都塞给一个最强的模型让它自己判断用哪个工具。结果上线测试就翻车了——用户问“上个月销售额是多少”模型一会儿去调文档搜索一会儿去查向量库偶尔还试图生成一段 SQL 而不是去调现成的数据接口。同样的问题隔一天问得到的行为完全不同。后来我把那次事故复盘了一下发现关键问题并不是模型能力不够而是缺了一个前置决策层。模型本身很擅长生成文本但让它同时承担“路由决策”和“内容生成”两个任务尤其是工具多、场景杂的时候它很容易靠猜而且每次猜的路径还不一样。路由的出现就是为了把这种不稳定的判断从模型的主链路里抽出来变成显式的、可控制、可观测的规则或者模块。你可以把路由理解成一个分诊台病人来了先判断是内科还是外科内科里再细分是心脏还是呼吸而不是把所有病人都直接推给一个全科医生。分诊的质量决定了后续所有环节的效率。路由正是如此。它未必需要多么复杂的推理能力但它必须稳定、可解释、可回退。1.2 路由到底在哪一层生效很多同学一提到路由第一反应是“给哪个大模型发请求”。这确实是一层但智能体里的路由远不止模型路由。我拆解下来它至少在三层都在起作用。入口层路由解决的是“这个请求属于哪类任务”。比如用户问天气和用户问数据库里的订单数据显然不是同一条处理链路。入口层把请求先分到大的业务域。工具层路由解决的是“某个任务领域中具体调用哪个工具”。比如同样是“查数据”这个任务是查聚合报表接口还是查明细表接口还是查缓存这个决定通常发生在任务已经确定之后。模型层路由解决的是“同一个处理链路里用哪档模型”。简单翻译任务、普通对话可能用又快又便宜的小模型就够了复杂推理、代码生成就需要上更大参数量的模型。这三层路由在实际系统中往往是嵌套的而且每一层都有不同的决策依据和成本收益比。如果混为一谈设计出来的路由逻辑就会很拧巴比如你在入口层用了很重的模型做语义判断结果到了工具层又重复做一次类似的判断白白牺牲延迟。我在后面的案例里会把这三层拆开演示先让读者心里有这样的分层意识。2. 四种常见的路由模式与选型思路2.1 规则路由确定性和高速度规则路由是最朴素、也最“低成本高效”的方案。它的核心逻辑是把输入的某些特征和预定义的映射关系做匹配命中哪条规则就走哪个分支。特征可以是关键词、正则表达式、意图枚举值也可以是结构化参数里的某个字段。比如一个智能体工具是“天气查询”那规则里匹配“天气”这个词匹配上了就直接走天气查询的子工作流。规则路由的优势非常明显首先是确定性同样的输入永远走同样的路径测试和排查都轻松。其次它几乎没有额外延迟也不消耗模型调用成本接近零。但规则路由的短板同样突出覆盖面有限。用户的表达千变万化漏一个同义词规则就失配了。而且规则越多维护成本越高规则之间的优先级冲突也会变得头大。我的建议是如果任务的分类边界非常清晰、输入格式本身就很结构化优先用规则。比如渠道来源、用户类型、环境标识这类请求完全不需要用模型来判断。如果输入是自由文本、自然语言规则只能做兜底。2.2 语义路由让模型来做分类规则路由覆盖不了自由文本这时候就得用语义路由。语义路由的本质是让一个模型对输入做分类输出一个预定义好的意图或者目标路径。它可以基于嵌入向量的相似度匹配也可以是一次结构化的 LLM 分类调用。先说基于向量的思路你把每条可能的路径先写成一段描述文本以及若干示例做成长文本 embedding用户请求也做 embedding然后算相似度取最接近的那条路径。这个方案的优点是可以不依赖大模型推理用向量检索就能完成延迟低可复用性也不错。缺点是它要求每条路径的描述都足够“收敛”否则相似度会飘。再说 LLM 分类把意图列表、路径说明拼进提示词里让模型输出一个结构化的意图值比如{intent: query_sales, confidence: 0.96}。这种方式对开放表达的容忍度最高因为模型理解了语义而不是匹配字符串。这里的代价是要多一次模型调用而且模型输出可能会有不确定性。所以我在正式的工程里一般会要求结果必须符合严格的 JSON Schema不合法就重试或者走兜底路径。2.3 模型路由动态选择大模型模型路由解决的是成本和效果的平衡问题。一个智能体系统如果只接一个最贵的旗舰模型效果一定不会差但成本会很难看。我做过一个客户支持助手闲聊类问题占了将近四成这类问题用轻量模型处理完全够回答质量差别不大但成本差别能到几十倍。模型路由的常见做法是设置分级标准。比如先把请求做一个复杂度评估或者用规则先判断只有涉及代码生成、长文本推理、工具调用链比较深的情况才升级到大模型。还有一种做法是“先小模型后大模型”先用轻量模型直接生成答案同时对答案做一个质量校验置信度不够再切换到大模型重答。这个策略在很多场景下能省不少开支但要小心把小模型生成的错答案直接发出去了需要用额外的校验环节兜住。2.4 多智能体路由中央控制者的分发逻辑当你的系统不再是一个智能体而是一组各司其职的子智能体时路由就升级成了“中央控制者”的分发逻辑。比如说一个系统里有财务问询智能体、技术文档智能体、HR 政策智能体用户的问题进来你不能让每个智能体都出来抢答而是需要一个路由模块先判定问题属于哪个域然后把话权交给对应的子智能体。这种多智能体路由通常会在主控模块维护一张智能体注册表每个子智能体有名字、职责描述、支持的输入格式、健康检查状态。路由模块拿到用户请求后把请求与注册表里的职责描述做匹配选出最合适的一个或者若干个再分发下去。如果多个子智能体可能均沾边还可以设计一个“仲裁”逻辑按匹配分数排序逐个尝试或者直接让用户确认要点哪个。多智能体路由的难点在于控制权力度的把握如果路由模块决定得太死用户的需求跨域时就很容易被切错如果决定得太松又会导致多个智能体乱抢。我的经验是路由模块只做粗粒度的域选择具体的细节调度还是放给子智能体内部去处理这样系统更健壮。3. 动手实现一个带路由的“全能知识管家”3.1 场景设定与路由映射表直接讲概念容易虚我拿一个实际做过的项目来演示。假设我们要做一个“企业全能知识管家”它需要处理三类请求一是规章制度类问题比如“年假怎么休”这类答案在静态文档里二是业务数据类问题比如“这个月各区域销量排名”这类答案需要查数据库三是日常闲聊比如“你好”“谢谢”这类问题不需要任何工具。三类请求的处理链路完全不同。规章类需要走文档检索加摘要业务数据类需要先做自然语言转查询意图再去查库闲聊就直接模型回复。我在系统里设计了一张路由映射表把所有可能的分支列清楚这样后续无论是写规则还是做语义路由都有一个统一的参照。意图标识典型提问示例处理链路兜底路径policy_query年假怎么休、报销流程是什么文档向量检索 生成全量文档检索后重试data_query本月销售额、库存还有多少解析参数 查库 生成转人工表单chitchat你好、辛苦了直接模型回复固定兜底话术ambiguous问题不明确、跨域澄清追问转人工映射表是路由最核心的静态资产后面所有路由逻辑都是围绕它转的。我建议在设计阶段就把它规划好别边写代码边补否则分支会越弄越乱。3.2 用结构化输出实现语义路由器在这个案例里输入基本都是自然语言所以入口层我选了语义路由。具体做法是把意图列表和它们的定义描述放进提示词让模型输出一个结构化的 JSON 对象。为了保证输出稳定我会用函数调用的方式来约束如果框架支持response_format那就直接指定 JSON Schema。下面是一个简化版的路由器核心代码我用常见框架的写法来演示思路。from pydantic import BaseModel from typing import Literal from llm_client import chat class RouteDecision(BaseModel): intent: Literal[policy_query, data_query, chitchat, ambiguous] reasoning: str confidence: float ROUTE_SCHEMA { name: route_decision, description: 判断用户问题属于哪一类处理意图, parameters: { type: object, properties: { intent: { type: string, enum: [policy_query, data_query, chitchat, ambiguous], description: 识别出的意图 }, reasoning: { type: string, description: 判断理由 }, confidence: { type: number, description: 判断置信度0到1之间 } }, required: [intent, reasoning, confidence] } } def semantic_route(user_input: str) - RouteDecision: prompt f 你是系统的路由分诊器。根据用户问题判断应该交给哪条处理链路。 各类意图定义如下 - policy_query: 关于公司制度、规章、流程文档的问题 - data_query: 需要查询结构化数据才能回答的问题 - chitchat: 日常寒暄、无用信息、问候 - ambiguous: 问题过于模糊无法确定属于哪个类别 用户问题{user_input} 只输出 JSON 对象。 resp chat( modelrouting-model, promptprompt, functions[ROUTE_SCHEMA], function_call{name: route_decision} ) return RouteDecision(**resp[arguments])这段代码看起来简单但有几个细节实际踩坑时得留意。首先是confidence字段别只用来展示最好是拿来配合阈值判断。我通常设定一个阈值比如置信度低于 0.6 就当作 ambiguous 处理先向用户反问澄清而不是硬着头皮往某个分支送。其次是reasoning字段别看它只是文本在排查问题时特别有用能定位到模型当初为什么这么分。3.3 给路由配上回退路径路由永远不可能 100% 正确所以必须设计回退路径。我把回退分成两个层面第一层是路由决策自身的回退如果语义路由调用超时或者输出格式不合法直接落回规则路由做关键词匹配再不行就走 ambiguous 分支第二层是业务链路的回退比如路由判定是data_query但后续数据库查询返回异常这时候应该返回一个友好提示并转人工而不是让用户面对一个空结果。我有一个非常深刻的教训早期系统里某一类路由决策成功后下游如果执行失败我直接让模型编一个答案结果用户在问具体数据时模型给出了一串看起来合理但完全没有依据的数字。后来我强制规定所有带数据查询意图的分支数据库执行失败绝对不能生成式兜底只能走“数据暂不可用”的固定文案。回退路径设计的原则是宁可让用户知道系统没搞定也不能给错误但看似可信的结果。3.4 路由决策完成后的参数传递路由决策不只是输出一个意图字符串往往还要顺带解析出该链路需要的关键参数。以我的知识管家为例路由判定为data_query之后下一步工作流要提取“时间范围”、“指标名”、“维度”这些参数。如果这一步也在路由模块里一并完成就能减少一次模型调用。实际操作时我会在同一个结构化输出的 JSON 里加上params字段里面放不同类型对应的参数模板。比如data_query对应{date_range: ..., metric: ..., dimensions: [...]}。这样做的好处是路由模块输出的结构直接就是下游工作流的输入后续的节点不需要再二次解析用户原话。不过要注意参数提取的准确性和路由分类的准确性不是一回事。可能出现意图分类很准但参数提取缺漏的情况比如用户说“对比这两个月的库存变化”模型很可能漏掉“对比”这个比较操作。所以我单独给参数提取留了一轮校验发现必填参数缺失时走澄清追问而不是继续往下执行。4. 路由设计与监控的关键细节4.1 超时、重试和降级路由模块是整个智能体的“咽喉”它一旦卡住整个请求就卡住。所以路由模块的延迟预算必须卡得很紧。我在项目里给语义路由定的耗时上限通常是在 1.5 秒以内如果超过这个阈值要么说明模型服务已经过载要么说明提示词设计得太啰嗦。超时后的降级策略要提前想清楚。比如路由调用超时我可以直接走规则匹配用关键词大致判断意图如果连规则都匹配不上就走 ambiguous 分支让用户重新描述。重试要有限制无限制重试只会雪上加霜。我一般最多重试一次第二次再失败就直接降级。这里插一个工程心得路由提示词不要塞太多与分类无关的上下文。早期我犯过一个错为了让路由更准确把每个意图对应的详细处理流程都写进了路由提示词结果模型每次分类的速度都慢了一倍。实际上路由分类只需要“意图定义和少量示例”处理细节留到下游工作流里读完全不需要路由层知道。4.2 让路由决策可解释可追踪路由如果是一团黑盒出问题的时候排查会非常痛苦。我在设计路由模块时强制要求输出完整的日志记录原始输入、路由模式规则还是语义、路由结果、置信度、耗时、使用的模型、命中的规则编号。这些日志统一打到结构化日志系统里按请求 ID 关联。有了日志之后就可以定期做路由效果复盘。比如我每隔一段时间会导出一批路由决策日志人工抽查里面哪些案例“路由结果正确但回答质量差”哪些“路由结果本身就分错了类”。分错类的案例我会把用户原话补充到路由提示词的示例里让模型下次更不容易复现同样的错误。这其实就是一个简单的主动学习闭环。4.3 路由的成本控制思路路由虽然看起来只是一次模型调用但如果调用量上去了成本也不容小觑。我有两个比较实用的控制手段。第一是规则前置。能确定的事绝不让模型重新判断。比如请求里带了明确的渠道参数channelsales_report那直接在规则层就命中data_query根本不需要走到语义路由。第二是缓存。如果系统和用户是多轮交互同一个用户短期内反复问同一类问题路由结果其实高度相似可以按用户 ID 加问题 hash 做一下路由决策缓存。不过要注意涉及实时数据的时间敏感问题缓存路由决策可能导致下游拿到旧参数所以缓存策略必须结合场景设定有效期。5. 常见问题和紧急问题处理5.1 模型频繁误判怎么办误判是语义路由最让人头疼的问题。我遇到过的情况是用户用口语问“咱们组这个月的奖金发了吗”系统把它分成了 policy_query结果去文档里找了一堆制度文本根本没回答用户真正关心的“发没发”。后来我分析发现问题里带了“奖金”这个词而示例库里的政策类案例也有奖金报销的表述分类器就偏过去了。误判的处理思路有三个。一是调整意图定义和示例把边界写得更清楚比如明确写明“奖金发放状态属于 data_query奖金政策文档属于 policy_query”。二是降低对单次分类的信任引入二次确认对置信度处于中间地带的案例把两个候选意图都展示给用户让用户点选。三是兜底检测如果后续链路发现拿到的内容与查询明显不相关就触发重新路由。5.2 多轮对话中的路由漂移多轮对话场景下路由漂移是另一个高频问题。用户先问“帮我查一下上季度北京区的业绩”系统路由到data_query。接着用户追问“那上海呢”如果系统把这句话单独拎出来做路由分析很可能识别成 ambiguous甚至分到别的意图去。这就是典型的上下文丢失。处理办法是在路由输入里拼接对话摘要。不一定要拼全文而是把当前轮用户的输入和最近一轮的主题摘要放一起再喂给路由模型。比如上面的例子里摘要可以记录“用户正在查询区域业绩数据”那么“那上海呢”接在这段摘要后面意图自然就还是data_query。具体实现时我比较建议单独维护一个上下文摘要变量由对话管理模块统一更新路由模块只负责读取。5.3 路由模块响应慢路由慢通常有三个来源模型服务本身慢、提示词太长、下游多个路由串联。模型服务慢不太好控制但可以通过选更快的模型来优化。提示词太长我上面已经强调过只放必要信息。多个路由串联的问题则要从架构上避免我见过一些系统里入口做一次意图路由工具选择又做一次模型路由中间环节还夹一个文本后处理模型一轮请求下来光路由就消耗了三轮模型调用很难不慢。改进的方法是把能合并的判断合并成一次结构化输出。比如入口路由和参数提取可以放在同一个函数调用里完成工具选择则用规则在本地完成不额外调用模型。5.4 路由结果的安全校验路由在决定“交给谁”的时候实际上也意味着放行了对某些工具或者数据的访问权限。如果不做安全校验很容易出现越权访问。我以前犯过一个错路由判定用户的提问属于数据查询后直接生成 SQL 去查询结果用户问的范围超出了他的权限分区把不该看到的数据拉出来了。正确的做法是在路由模块输出目标链路之后加一个权限校验节点用当前用户角色和路由目标做一次匹配不通过就打回。这听起来像是有额外步骤但安全环节不能省。宁可多一次校验也不要在权限上敞开。6. 路由往后的演进方向6.1 从静态路由走向动态路由固定映射表的路由模式很快会遇到两个瓶颈一是意图类型设计不全新业务接进来要手工扩表二是分类效果依赖人工维护的示例质量。所以越来越多的路由方案开始走动态化路线。动态路由的思路是让路由模块能够读取当前系统里的工具清单、意图描述甚至历史路由效果数据实时调整自己的判断策略。比如新接入一个工具之后不需要手工往映射表里加一条规则而是将工具描述自动注入路由提示词让模型在分类时把它当作一个候选目标。这种做法的上限很高但也对系统的稳定性提出了更大考验毕竟描述注入得越多模型分类就越容易混乱。所以我的建议是渐进式落地先把工具注册机制做好再逐步尝试动态注入。6.2 建立路由评估集路由是系统行为的地基所以它也应该有专门的评估集。我通常会从历史真实请求里抽一批有代表性的案例人工标注它们理想的路由结果做成固定评估集。每次调整路由策略或者模型都跑一遍评估集看准确率有没有退化。评估集不需要特别大一两百条就能发现问题。关键是案例要有代表性每个意图至少覆盖几十条典型表达而且必须包含容易混淆的边界案例。只有把评估跑顺了后续做任何路由优化才敢动手不然就是盲调。这个习惯我坚持了很久越到后期越觉得值。智能体学习系列走到这里路由算是讲得比较透。如果你正在被“模型乱选工具”或者“同样的输入结果不一样”这类问题困扰不妨先停下来把路由层补齐再做其他优化。从我在实际项目里的体验看解决路由这一环很多看似难缠的稳定性问题都会迎刃而解。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。