给 AI Agent 装上智能路由:用 DAG 驱动把每次 API 调用花在刀刃上
引子:每个月烧掉一台 MacBook Pro
三个月前,我打开飞书账单统计面板,看到了一串让我瞬间清醒的数字:
1 | 2026年4月 LLM API 总支出: $1,847.32 |
我的 AI Agent 每天跑几十次自动化任务——数据清洗、代码审查、市场分析、文章写作——每一次都调用当时能拿到的最强模型。好模型确实出好结果,但每一条对话、每一轮回复,哪怕是用户说了句”好的”都要经过千亿参数模型推理一次。
这种感觉就像:你明明只需要拧个螺丝,却每次都要开一台盾构机过来。
问题是——我没办法在事前判断哪轮对话需要”盾构机”,哪轮只需要”螺丝刀”。直到我想起一个经典的工程思路:操作系统里的多级存储体系。
L1 Cache → L2 Cache → RAM → SSD → HDD
数据访问频率越高,用越快的存储;越冷的数据,用越慢但便宜的介质。
如果 LLM 调用也能这样分层呢? 简单的闲聊走免费模型,代码编写走中等模型,只有架构设计、安全审查这种深度推理才走最强模型——而且一旦选定,在接下来几轮对话中保持稳定,避免”上下抖动”。
这就是 Smart Router(智能路由) 的出发点:一个嵌入在 Agent 执行循环内部的 DAG(有向无环图)驱动路由系统。它既不改变 Agent 的任何行为,也不需要你手动标记哪轮该用什么模型——一切自动完成。
而且它只有 500 行 Python。
问题分解:为什么 AI Agent 需要”路由”?
传统 LLM 调用只有一条指令:”拿去,给我调用模型 XXX 回复”。Agent 框架(无论是最原始的 LangChain 还是定制框架)大多也只有一个全局 model 配置。
这在以下场景中会出问题:
| 场景 | 问题 | 典型表现 |
|---|---|---|
| 免费模型够用但你不自知 | 用户说”好的”、”继续”也要过计算 | 账单虚高,推理延迟增加 |
| 高难度任务用错了弱模型 | Agent 不断出错重试 | 往返次数激增,体验变差 |
| 模型频繁切换 | 上一轮用 GPT-4 写了代码,下一轮被切到免费模型继续”审查”同一段代码 | 输出风格断裂,质量下降 |
| 单个模型故障 | API 限流/超时/异常,Agent 卡死 | 任务失败率上升 |
Smart Router 一次性解决这四个问题:它像一个智能交通指挥员,在每一次 LLM 调用前做出路由决策。
架构:四步 DAG 流水线
整个路由逻辑只有 6 个函数、500 行代码,嵌入在 Hermes Agent 的插件体系中。每次对话轮到 LLM 生成回复前,Smart Router 截获控制权,执行一个四步 DAG:
1 | 用户消息 |
Step 1: 分类——你的消息”有多重”?
分类是整个系统的核心。它从用户消息中提取 7 个信号:
1 | signals = { |
然后根据这些信号做路由决策:
1 | def _classify_turn(msg, session_id, kwargs): |
决策树是分层的:最耗资源的判断(推理深度)优先匹配,最便宜的判断(简单聊天)最后匹配。这样设计是为了确保”只要有一丝丝可能需要好模型”,就给它用好模型——省下来的返工成本远大于多花的推理成本。
Step 2 & 3: 执行与兜底
选定 tier 后,use_tier_cX 查配置表获取对应的 provider 和 model:
1 | tiers = { |
如果模型调用失败(超时、限流、服务器错误),fallback_chain 接手:
1 | def _resolve_fallback(tier, error_type): |
注意 fallback_chain 只在 可重试的错误(超时/限流/服务器错误/配额超限)时触发——认证错误、内容过滤等不会降级,直接报错。
Step 4: Hold——防止”精分”
这是最容易被忽略、但实际体验影响最大的设计。
假设用户说:”帮我写一个 Python 脚本来分析 CSV 数据。” 路由判定为 c2(代码任务),分配 qwen3.7-plus。Agent 开始写代码,生成了一百多行。写完之后,用户回复:”好的,谢谢。”
如果没有 Hold 机制,这一轮”好的谢谢”会被重新分类为 c0(简单聊天),路由到免费模型。但问题是——Agent 现在手上还攥着上一轮写的那一百行代码的上下文,它需要在这个上下文中继续理解用户的意图。如果此时切换到免费模型,输出质量会断崖式下跌,甚至出现上下文理解错误。
Hold 机制 解决这个问题:当一个高 tier 被选定后,锁定该 tier 持续 N 轮:
1 | def _apply_hold(tier, session_id): |
效果:同一个会话中,模型切换频率从”每轮一次”降低到”每 5-7 轮一次”。用户体验到的是连贯、一致的输出风格。
真实效果:一个月的账单对比
部署 Smart Router 后,我对比了前后一个月的 API 支出数据:
| 指标 | 路由前 | 路由后 | 变化 |
|---|---|---|---|
| 月 API 支出 | $1,847 | $623 | -66% |
| 平均每轮成本 | $0.042 | $0.014 | -67% |
| 高 tier (c2+c3) 占比 | 100% | 34% | -66% |
| 免费 tier (c0) 占比 | 0% | 28% | +28% |
| 任务失败率 | 8.3% | 6.1% | -27% |
有趣的是,任务失败率不仅没上升,反而下降了 27%。原因很简单:简单任务不再被”大炮打蚊子”——过强的模型有时反而会过度解读简单的指令(比如把”继续”理解成复杂的子任务),而合适的模型给出合适的响应。
Tier 分布饼图(近似):
1 | c0 (闲聊/简单) |
超过四分之一的对话完全走了免费模型——这些是”好的”、”继续”、”谢谢”之类的确认性回复,或者非常简单的查询。之前每个月为这些对话花了近 $500。
部署:只需 1 行配置
Smart Router 是 Hermes Agent 的一个插件。部署只需要两步:
1. 启用插件(在 config.yaml 中):
1 | plugins: |
2. 重启 Agent——下次对话自动生效。
如果你用的不是 Hermes Agent,而是自己的框架,核心思路可以移植:
- 在 LLM 调用前加一个 classify → select 拦截器
- 维护一个 per-session 状态表 记录当前 tier 和 hold 计数器
- 在异常处理中加一个 fallback chain 降级逻辑
总代码量不超过 300 行。
设计背后的几个”反直觉”
1. 免费模型不是”差点也行”
DeepSeek V4 Flash(c0)在处理简单的信息查询、确认性回复时,质量与千亿参数模型几乎无差异。我们在”消息长度 < 200 且无代码需求且无推理需求”的 subset 上做了盲测,用户感知差异 < 3%。
关键 insight:模型能力里存在显著的 “overkill” 区间——不是所有输入都需要模型的全部能力。识别出 overkill 区间,就是省钱的突破口。
2. 降级不是灾难,是机会
当 c3 模型超时时自动降级到 c2,看起来是”服务质量下降”。但实际数据告诉我们:模型超时/限流导致的完全失败,比降级带来的质量损失更严重。一次成功的降级响应远好于一次失败的全力冲刺。
3. 锁定 tier 比”最优分配”更重要
我最开始的版本没有 hold 机制——每轮都重新分类。结果用户反馈”Agent 像精分了”,因为频繁切换模型导致输出风格不一致。加 hold 后,连贯性显著提升。有时候”稳定”比”最优”更重要。
总结
Smart Router 解决了一个非常实际的问题:在 LLM API 成本仍然高昂的今天,如何让每一分钱都花在刀刃上。
它不是通过限制 Agent 的能力来实现省钱——恰恰相反,它通过更精细的模型分配,让简单任务走便宜模型,复杂任务走强模型,中间还有兜底和防抖动机制。最终效果是:成本降低 66%,质量反而提升了。
如果你也在运行 AI Agent,你可以马上做三件事:
- 审计你的 API 账单——有多少调用其实不需要最强模型?
- 建立一个简单的分类器——根据消息长度、关键词、附件的信号做 tier 决策
- 加上 hold 机制——别让你的 Agent “精分”
一句话 Takeaway:给 AI Agent 装路由,不是省钱的妥协,而是精准分配的艺术。
附:相关资源
- Hermes Agent 文档 — 插件系统
- Smart Router 源码 — 本文配套实现,500 行纯 Python,可独立运行
- 博客相关文章:QGS 质量门禁:给 AI Agent 装上刹车和质检
- Hermes Agent 开源项目
封面图:DAG 流水线的抽象可视化,蓝色/紫色科技风









