PilotDeck 智能路由引擎全拆解:难度识别、降级策略与 Token 节省的 3 大机制
【免费下载链接】PilotDeckTask-oriented AI Agent productivity platform项目地址: https://gitcode.com/OpenBMB/PilotDeck
PilotDeck 是一款任务导向的 AI Agent 生产力平台,它的智能路由引擎会自动识别任务难度、在多模型之间降级容错,并统计 Token 节省成本。本文带你零门槛读懂这套路由系统:判定模型如何给任务"打分"、降级链路何时触发、省下的 Token 又是怎么算出来的。
为什么需要智能路由引擎?
用过大模型的朋友都有同款烦恼:大模型聪明但贵、小模型便宜但弱。人工逐个切换模型既麻烦又容易选错。
PilotDeck 的解决方案是让路由器替你做决定——每条用户消息发送前,路由引擎都会经过一次"模型选型",把请求派给最合适的模型。整套引擎位于 src/router/ 目录,核心只有两句话:
- decide(决策):这条消息该用哪个模型?
- execute(执行):调用失败时如何降级、重试、兜底?
下面拆解它的 3 大机制。
路由决策四步走:从一条消息到一次模型请求
打开 RouterRuntime.ts,decide()函数就是决策总入口,一次完整决策按以下顺序进行:
| 步骤 | 做什么 | 对应模块 |
|---|---|---|
| ① 场景判定 | 用户显式指定模型 > 子智能体 > 默认场景 | decideScenario.ts |
| ② 难度分级 | 判定模型给任务打 tier(档位)标签 | classifyAndRoute.ts |
| ③ 缓存感知切换 | 读缓存比换模型重发便宜时,保留当前模型 | RouterRuntime.ts |
| ④ 媒体能力改道 | 消息带图片但模型不支持?自动换到支持的模型 | mediaRequirements.ts |
其中第 ③ 步的"粘性模型"很实用:会话中途换模型意味着整段上下文要重新计费,路由器会算一笔账——继续用旧模型读缓存,比切到新模型重新预填充更便宜吗?不是的话,果断切走。
难度识别:判定模型如何给任务"分级"
这是 Token Saver 的核心。PilotDeck 内置了 4 个任务档位,定义在 schema.ts 中:
| 档位 | 典型任务 |
|---|---|
simple | 打招呼、确认、单步问答、简单文件写入 |
medium | 单次工具调用、短文本生成、1-2 个文件读写 |
complex | 需要多子智能体并行编排、任务委派 |
reasoning | 多文件操作、数据分析、多步工作流、调研报告 |
每个档位在配置里绑定了不同的模型:简单任务交给便宜的小模型,深度推理才动用旗舰模型。
判定是怎么做的?路由器会调用一个便宜的小模型当"裁判",提示词由 generateJudgePrompt.ts 生成,要求裁判只返回一个形如<tier>medium</tier>的档位标签。细节上有很多防翻车设计:
- 3 次重试 + 超时熔断:裁判请求默认超时保护,失败后回落到默认档位,绝不让"选型"卡死主流程;
- 短消息继承机制:像"好的""继续""开始"这类确认词(isShortContinuation),会直接继承上一轮的档位,避免被误判成简单任务;
- 子智能体策略:可配置为
judge(子任务也参与分级)或skip(跳过判定、继承主模型)。
一旦判定为complex,还能触发AutoOrchestrate:路由器把主智能体"升格"为只规划、不分身干活的编排者,真正干活的原子步骤全部委派给子智能体执行(见 applyOrchestration.ts 与 schema.ts 中的编排提示词)。
降级策略:模型"罢工"时的三道保险
模型调用失败是常态,PilotDeck 用三层机制保证可用性:
1️⃣ Fallback 降级链
在pilotdeck.yaml的router.fallback里按场景配置后备模型列表(默认最多尝试 5 组)。哪些错误"值得降级"由 runFallbackChain.ts 判定:限流、服务端错误、欠费(billing)、模型不存在(model_not_found)都会触发换模型;而上下文超长不会降级——它该走的是压缩而不是换模型。
2️⃣ 智能重试
- 零用量重试(zeroUsageRetry.ts):模型返回了空气(0 Token)就重发,默认最多 2 次,延迟递增;
- 瞬态重试:网络抖动、超时类错误采用 LiteLLM 风格的指数退避 + 随机抖动,避免雪崩式重连。
3️⃣ 熔断器(Circuit Breaker)
ProviderHealthTracker.ts 为每个 provider 维护一套状态机:
healthy ──3次连续失败──▶ degraded ──5次连续失败──▶ open(30秒内跳过该provider) ▲ │ └──────────── 探测成功 ◀──── half_open ◀─ 30秒冷却 ──┘熔断器让路由"远离正在着火的房子",而半开探测又能第一时间发现它"救活"了。
💡内容锁定规则:一旦回复开始流式输出文字,降级和重试就全部关闭——否则会向用户重复输出两段答案。这个权衡与 OpenAI/Anthropic 官方客户端一致。
Token 节省:省钱是怎么算出来的
省了多少钱不能靠感觉,得靠账本。TokenStatsCollector.ts 会记录每一次请求的:
- 实际成本:按
router.stats.modelPricing配置的输入/输出/缓存读取单价计算(支持$或¥每百万 Token); - 基准成本:假设"没有路由、一直用基准模型"会花多少钱,基准模型由
router.stats.baselineModel指定; - 节省额:
savedCost = 基准成本 − 实际成本,按小时、按会话、按档位、按模型多维汇总,追加写入stats.jsonl。
也就是说,你不用猜路由有没有帮上忙——打开统计面板就能直接看到"今天智能路由帮你省了多少钱"。
配置速查:pilotdeck.yaml 中的关键路由字段
所有路由行为都收敛在pilotdeck配置文件的router段,字段一览如下:
| 功能 | YAML 路径 | 说明 |
|---|---|---|
| 总开关 | router.enabled | 关闭后所有请求直通agent.model |
| 默认场景模型 | router.scenarios.default | 路由兜底选用的provider/model |
| 裁判模型 | router.tokenSaver.judge | 负责难度分级的便宜小模型 |
| 任务档位 | router.tokenSaver.tiers.<name>.model | 每个档位绑定一个模型 |
| 降级链 | router.fallback | 按场景配置后备模型列表 |
| 成本统计 | router.stats.modelPricing | 各模型单价,用于节省计算 |
Web 端也可以在"智能体 → 路由"设置页直接修改,保存时会通过配置 API 做校验与热加载(详见 53-router-settings-api.zh.md)。
小结:一张图看懂三大机制
| 机制 | 解决的问题 | 核心源码 |
|---|---|---|
| 难度识别 | 该用贵模型还是便宜模型 | tokenSaver/ |
| 降级容错 | 模型挂了/限流了怎么办 | fallback/、health/ |
| Token 节省 | 省钱效果是否真实可见 | stats/ |
PilotDeck 智能路由引擎的设计哲学一句话概括:把"选模型"这件费心且烧钱的事,变成一套可观测、可降级、可核算的自动化流水线。想深入细节,建议从 RouterRuntime.ts 的decide()与execute()两个函数入手,配合 tests/router/ 下的确定性测试,可以快速建立完整心智模型。
【免费下载链接】PilotDeckTask-oriented AI Agent productivity platform项目地址: https://gitcode.com/OpenBMB/PilotDeck
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考