端云协同模型路由方案


开篇:现状与难度

现状一句话

现在在做的,是「用大模型给 query 打难度 tag,再按 tag 把请求分给不同档位的模型」。 主线是 Qclaw 端云协同(L1-L8 难度分级)。

贯穿全文的主线

路由的收益来自「把简单请求给便宜模型」,但 cache 复用已经把单价压到了 0.1x。 所以任何路由决策必须先回答一个问题:省下的钱,有没有超过丢掉的 cache?

三条路线(三个方案)总览

全篇其实是三条路线在比,最后收敛成一个。下表是三者的定位与取舍对照。

方案 A 方案 B 方案 C(推荐)
叫什么 大模型打 tag 路由 非大模型本地 router 合并推荐:两级接力
对应章节 维度 1 维度 2 维度 3 + 维度 4
路由器是谁 1.7B 小模型(要推理) LightGBM/ONNX(毫秒级) 规则闸门 + 可学习 selector
判据 语义难度 L1-L8 harness state 四层栈 维度3 定规则,维度4 学选择
在哪跑 服务端 端侧本地 端云协同
时延 280-725ms 毫秒级 取决于走哪层
成本 要付推理钱
实测均分 0.409 0.397 ——(合并后待测)
实测极差 0.220 0.185 ——
状态 已部署,有实测 已跑离线测试 本方案主张

三者的关系不是三选一,是演进 + 合并

方案 A(现有主力,语义强但贵、有延迟)
        +
方案 B(本地快、零成本、已处理 cache)
        ↓  合并
方案 C = 维度3(定规则:什么时候允许切)
        + 维度4(学选择:窗口内切给谁)

为什么 C 不是简单二选一:A 的均分略高但极差大(0.220),B 的极差最小(0.185)。 两者正好互补 —— 用 B 的快判定兜日常,用 A 的语义能力啃难题, 再用维度 3 的规则守住 cache,用维度 4 把「切给谁」从配置升级成学习。


维度 1:现有的「大模型打 tag 难度 → 路由」方案

机制链路

数据清洗 → GT标注(大模型打标,人工抽检)→ 模型PE → SFT微调 → 部署

链条很长:清洗 → 标注 → 人工 check 定 baseline → 小模型摸底 → 微调 → 部署测试, 每一步都要等上一步出结果,且重新打标就得重跑整条链。

当前实测效果

分类器准确率(1.7B)

指标 1.7B-M 多数投票 1.7B-A1 level一致 1.7B 6-level
level 75.09% 88.62% 91.09%
intent 88.69% 92.00% 92.34%
task 71.91% 87.38% 87.62%
modality 94.55% 96.05% 97.42%
caps 82.63% 85.88% 85.34%
safety 98.59% 99.08% 99.08%
In-Vocab 99.82% 100.00% 100.00%

H20 部署压测(qps=5)

P50/P95/P99 (ms) Avg (ms) Prefix Cache 命中率
620 / 1429 / 1907 725 82%
517 / 818 / 879 556 91.7%
280 / 599 / 718 319 92.8%
281 / 339 / 363 284 98.1%

服务映射:L1-L3 本地小模型 / L4-L5 云端小模型 / L6-L8 云端大模型 输出示例{"level":"L4","task":"short_code_task","modality":["code","text"]}

判断

这条链路继续保留并作为 L1 层,但要做三处补强:加 confidence 字段、加缓存边界判定、加切换预算帽。 它的问题不是「该不该做」,而是「只做它不够」。


维度 2:OpenSquilla(本地、时延小)

详细版见 OpenSquilla-详细介绍.md(含完整输入输出契约),本节为汇报用精简版。

机制:四层路由栈(README 的「length/language/code」是简化说法,论文里远不止)

pass 名 做什么
L1 token-complexity filter order admission trivial 请求直接送便宜 fast path
L2 task-type classifier demand construction 区分 coding / reasoning / chat / tool-use,建能力画像
L3 context-aware refiner risk pricing 融入 harness state:上下文压力、工具失败、验证结果、恢复状态、动作不可逆性、下游纠正风险
L4 LightGBM ranker capability matching 对剩余候选排序,选最便宜的够格模型

前三层是确定性过滤器 + 轻量分类器,第四层才是 LightGBM。 论文原话:「LightGBM is the cold-start matching engine, not the market itself」——它只是冷启动引擎,不是终局。

两个视角:论文版(C0-C3)vs 源码实现(R0-R3)

这里有一点需要先说清:

论文 arXiv:2607.11399 源码 squilla_router v4.2 Phase 3
讲什么 harness-native 数据飞轮的框架 分类器实际怎么算
档位命名 C0-C3 R0-R3
核心 四层路由栈 + 飞轮 双流特征 + 3-Head 集成 + 8 步后处理
模型映射 论文里给的是当时配置 tier_registry 注入,随配置变

两者不矛盾:论文讲路由的架构思想,源码讲工程落地。 档位名不同是版本演进;模型映射不同恰恰证明了它的三层解耦有效 —— 换模型只改 YAML,档位定义不动,分类器不重训。

源码实现的三个关键(论文里没写,但决定了它能不能用)

  1. 双流特征:390 维稀疏异构特征喂 LightGBM,1536 维 BGE 稠密向量喂 ONNX MLP,per-class α 融合。 其中 hist 通道把上一轮的路由决策也当特征 —— 天然防抖动。
  2. 3-Head:Main(LightGBM 分类) + MLP(语义) + Aux(判断该不该升降档)。Aux 头是关键,它让「换不换模型」成为一个独立可学的决策。
  3. 8 步后处理:模型输出只是起点,之后 8 步规则修正。Step 1/3/4/5/6 全是单向向上,唯一向下的 Step 2 默认关闭。 Step 7 是 KV-cache 防抖(默认关闭,待重训)。
核心定性:SquillaRouter 输出的 R0/R1/R2/R3任务难度档位(不是意图类别), 下游通过 tier_registry 配置映射具体模型 —— 新模型上线只改 YAML,不重训分类器

① 整体架构:双流特征 → 3-Head 集成 → 四档输出

INPUT
用户输入 + 会话状态(四路通道)
current_user_text当前轮 user message
history_user_texts最近 4 轮 user 文本
prev_assistant上一轮 assistant + usage
context_metadataturn_index / 累计 tokens
STAGE 1
特征提取(双流)

BGE 编码器 BAAI/bge-small-zh-v1.5,hidden_size 512,ONNX INT8 量化,纯本地 CPU 推理。 三段文本各编码一次 → 3 × 512 = 1536 维。

流 A · 390 维拼接特征 → LightGBM
通道维度内容
hc51长度 / 中英文 / code 比例 / 代码块 / 关键词 / 文件路径
tfidf102char-wb (2–4) gram → TruncatedSVD(100)
ctx10turn_index / 累计 tokens / 工具数
hist16上一轮 route_idx / difficulty / margin
bge_x3192三段 BGE → 共享 PCA(64) × 3
asst_hc12上轮 assistant:refusal / clarify / self-doubt
cont_hc2接话提示("继续/请继续")
reasoning_hc5推理意图 / 问号密度 / prev_reasoning_tokens
合计39051+102+10+16+192+12+2+5
流 B · 1536 维原始 BGE → ONNX MLP

三段 BGE(512) 直接 reshape 成 1536 维 → StandardScaler → ONNX MLP → softmax(T=0.81) → 4 类概率。

为什么双流:LightGBM 擅长稀疏 + 异构特征(关键词、长度、历史路由), MLP 擅长密集语义特征(BGE 向量)。两流分头预测后按 per-class α 加权融合。
注意 hist 通道:它把上一轮的路由决策也当特征喂回去 —— 这是天然的防抖动设计,与我们要解决的「相邻轮次来回切」是同一个问题。
STAGE 2
3-Head 集成预测
Main Head
LightGBM
390 维 → 4 类概率
lgbm_main.bin (40MB)
MLP Head
ONNX MLP + Scaler
1536 维 → softmax(T=0.81)
mlp/model.onnx
Aux Head
LightGBM
initial / maintain / upgrade / downgrade
lgbm_aux.bin (3.5MB)
融合公式:fused = α · p_main + (1−α) · p_mlpα = [0.5, 0.05, 0.5, 0.85](per-class)。 Aux Head 不参与分类,专门用于判断这一轮该不该升降档

② 四档输出(route_class → tier → model,三层解耦)

R0 → S 档
闲聊 / 确认 / 简单改写 / 短问答
flash 系
R1 → M 档
默认通用:常规问答 / 写作 / 中等编码
pro 系
R2 → L 档
调试 / 多步推理 / 规划 / 多信号诊断
reasoning 系
R3 → XL 档
架构设计 / 高风险决策 / 复杂恢复
frontier 系
解耦设计(最值得抄的一条):route_classtier(S/M/L/XL)tier_registry[tier]。 分类器永远只输出 4 类抽象档位,具体模型由 router.runtime.yaml 配置注入,支持 8 个 provider profile。 → 这正好解答了「模型池换了要不要重训」:换模型不重训,换档位定义才需要重训。

③ 后处理流水线:8 步规则修正(关键决策全在这里)

从 fused 概率得到 base class 后,还要依次过 8 步规则才输出最终路由。纯模型的判断只是起点,不是终点。

Step 0 · ARGMAX:取概率最大类为 base_class,算 margin = top1 − top2difficulty_score = Σ(i·p_i)(0–3)。
Step 1 · Margin Upgrade:若 margin < 0.10上升一档(R0→R1→R2→R3),R3 不再升。模型自己吃不准时,宁可用强一点的。
Step 2 · Aux Downgrade:aux head 的 downgrade 概率 ≥ 0.55 且不在 R0,则降一档。默认关闭,需评估后开启。
Step 3 · R1 Rescue:若 R0 且 p(R0) − p(R1) < 0.10,强制提到 R1。只向上救援,绝不向下。
Step 4 · Under-routing Safety Net:仍在 R0/R1 但 p(R2)+p(R3) > 0.45,强制提到 R2。防复杂任务发给弱模型。
Step 5 · Flag Overrideshigh_risk → 至少 R2;debug ∧ long_context → 至少 R2;repo_arch → 至少 R1。
Step 6 · Context Rulesturn_index ≥ 4(深度对话)时至少 R1,避免长会话被错误降到 R0。
Step 7 · Sticky Tier(KV-cache 防抖):连续短对话且预测档位低于上一轮时,保留上一轮档位,避免 KV-cache 失效。默认关闭,待重训后启用。
Step 8 · Trivial Ack 兜底:最终 R0 且文本 ∈ {thanks, ok, 收到, 好的, 谢谢…},强制 thinking_mode=T0, prompt_policy=P0
贯穿全部 8 步的设计哲学:宁可贵一点,也不要欠路由。 Step 1/3/4/5/6 全部是单向向上的;唯二的向下通道(Step 2 降级)默认关闭。 这跟我们「判错代价不对称」的判断完全一致 —— 把难题压给小模型,比给简单题多花钱严重得多。

④ 完整示例追踪(两个典型)

"帮我把这个 SQL migration 部署到生产环境,删除 user_logs 表的旧分区。"
FEATURE文本约 30 字符,无代码块、无日志块 → 模型倾向判为普通任务。
3-HEADfused = [0.10, 0.55, 0.25, 0.10] → argmax = R1,margin = 0.30,difficulty = 1.35
FLAGShigh_risk = True(命中「部署」+「生产」+「删除」+「migration」),其余 False。
POSTStep1 margin=0.30 ≥ 0.10 不升档 → Step4 p(R2)+p(R3)=0.35 < 0.45 通过 → Step5 high_risk → 至少 R2 → R1 升到 R2
DERIVEthinking_mode = T3(high)· prompt_policy = P2(充分分析,覆盖关键约束)
最终 route_classR2 → L 档(被规则强制升档)
thinking_modeT3(high)
prompt_policyP2 — 充分分析
关键观察:模型本身预测 R1(普通编辑任务),但规则层基于关键词强行拉到 R2 —— 因为「生产部署 + 删除」是不可逆动作。这正是 L3 risk pricing 里「动作不可逆性」的落地方式: 不靠模型判断,靠关键词硬规则兜底。
"帮我写一个 Python 脚本,把 CSV 转成 Parquet。"
FEATURE文本中等(约 25 字符),无 flag 触发关键词。
3-HEADfused = [0.40, 0.35, 0.20, 0.05] → argmax = R0,margin = 0.05,difficulty = 0.90 (模型对 R0/R1 拿不准)
FLAGS全 False。
POSTStep1 margin = 0.05 < 0.10 → 升档!R0 → R1 → Step3 已满足 → Step4 0.25 < 0.45 通过 → Step5–8 全跳过
DERIVEthinking_mode = T2(不满足 T0/T1 的 margin 阈值)· prompt_policy = P1(diff=0.90 > 0.8,不给 P0)
最终 route_classR1 → M 档(margin 升档救援)
thinking_modeT2(medium)
prompt_policyP1(中性)
关键观察:置信度低时路由器主动升档而不是赌一把。 这条对我们是硬需求 —— 我们的分类器输出目前只有 level,没有 confidence 字段, 护栏层的阈值判断就没有信号可用(见维度 3 关键设计参数)。
动作空间不止「选模型」:route_class(4) × thinking_mode(4) × prompt_policy(3) = 48 种行为, 再乘 5 个 boolean flag 的子状态,实际超过 200 种独立路由行为。 路由不只是换模型,还可以调推理强度和提示词策略 —— 这一维度我们的方案里完全没有,值得单独评估。

输入(三层)

① 模型输入 x_t = (q, h_t) h_t 十项:当前观测、压缩+原始上下文、上下文压力、控制循环状态、可用动作、产物状态、工具历史、恢复状态、验证信号、最近路由决策 四类信号:路由决策信号(含 confidence、ranking margin)/工具调用信号(成功、错误、重试、恢复路径)/上下文管理信号(长度、压缩触发、丢弃证据)/验证与运行时信号(测试结果、judge、成本、延迟)

② 配置输入default_tier=c1confidence_threshold=0.5kv_cache_anti_downgrade_enabledcomplaint_upgrade_enabledupgrade_to_c3_compaction_enabledprovider_routing 绑定表

③ 反馈输入router.feedback.submit { decisionId, rating: up|down|neutral }

输出(三种形态)

① 分档输出 C0-C3 + image_model

模型 定位
C0 deepseek-v4-flash trivial chat、短改写、抽取、轻量编码
C1 deepseek-v4-pro 默认档:常规 agent 工作、编码、调试
C2 kimi-k2.7-code 多步编码、结构化推理、大上下文综合
C3 glm-5.2 最高档,仅此档开 ensemble
image kimi-k2.6 视觉(image_only

② 两种形态:k=1 输出单个模型;k>1 输出 proposer set P_t + 聚合策略 a_t B5 阵容 = deepseek-v4-pro + glm-5.2 + kimi-k2.7-code + qwen3.7-max,glm-5.2 聚合,quorum 3-of-4

③ 会话级三模式direct / router / ensemble,CAS 写入(需 expectedRevision), appliesTo: "next_accepted_turn" —— 变更下一轮才生效,不在中途改

实测

⚠️ 重大修正:它已经处理了 cache 问题

之前我们批评它「每轮切会打散 prompt cache」,这个批评过时了。配置里有两个字段:

kv_cache_anti_downgrade_enabled = true
kv_cache_anti_downgrade_window_seconds = 600   # 10分钟内禁止降级
upgrade_to_c3_compaction_enabled = true        # 压缩后允许升C3

即:每轮评估 + cache 感知闸。我们用「只在边界切」规避,它用「时间窗口内禁止降级」规避,目的一致。 加上 appliesTo: next_accepted_turn,它其实是 cache 友好的。

亮点

  1. 纯本地跑,提示词不出机器 —— 隐私 + 零 API 成本 + 零网络延迟
  2. 路由决策本身不消耗 token —— 传统 ML 分类器,不是再调一次大模型
  3. 只在最高档开 ensemble —— 成本分层极干净
  4. complaint_upgrade:用户抱怨一次自动升一档(限 1 档、限 160 字符)——用真实反馈在线纠偏

与维度 1 的对比

维度1 大模型打tag 维度2 OpenSquilla
路由器本身 1.7B 小模型(要推理) LightGBM/ONNX(毫秒级)
语义理解 强(能懂 task 类型) 中(四层栈,L2 有任务分类)
输入丰富度 只看 query 看整个 harness state(十项)
部署位置 服务端 端侧
判定时延 280-725ms 毫秒级
cache 保护 有(600s 禁降级)
置信度 有(阈值 0.5)

判断

价值不在分类精度(维度1 语义更强),而在于三点: ① 路由决策可以不花 token 钱、不外传、不加延迟;② 输入应该看 harness state 而不只是 query; ③ cache 保护和用户抱怨兜底这两个工程细节,我们直接抄。

建议直接吸收kv_cache_anti_downgrade 时间窗口(与我们边界切叠加:边界切决定何时能改, 时间窗口决定改的方向不能是降级)、complaint_upgrade、分档决定是否值得开 ensemble。


关键实测:双方案端到端对抗(维度 1 vs 维度 2)

这是目前唯一一组两条路线直接对抗的数据。四个模式同跑同一测试集,10/10 全部完成。 评估维度:relevance / correctness / completeness / usefulness。

原始结果

模式 完成 整体均分 极差
Level 映射(大模型方案) 10/10 0.409 0.220
router(非大模型方案) 10/10 0.397 0.185
baseline-glm5.2 10/10 0.385 0.191
baseline-flash 10/10 0.355 0.275

有一点必须诚实:均分前三名的差异在噪声内,不能当结论用

唯一够得上显著的信号是 baseline-flash:0.355,比前三低 7.8%~13.2%, 且极差 0.275 全场最大 —— 全用小模型确实明显更差,也更不稳

更稳妥的结论是:「两个路由方案都『不劣于』全用强模型,而成本更低」, 而不是「大模型方案赢了」。前者站得住,后者会被人一问就穿。

但方向上的信息是真的,而且比均分更有价值

① 「越大越好」不成立 —— 强模型在简单题上是负资产

这条由失分分析给出,比均分可靠得多。上限模型失分集中在三类:

失分类别 具体表现 根因
简单题话太多 自加误导承诺 + 幻觉虚构 强模型倾向补全、扩展、多说
意图误读 把确认句当指令 强模型倾向把一切输入理解成任务
过度自信地臆测 武断断定命令来源 强模型倾向给确定答案而非说不知道

这三条是同一个病:模型越强,越倾向于「多做一点」和「给确定答案」。 而在需要克制、需要先答通用核心的题上,这恰恰是减分项。

→ 结论:在当前评估体系里,更小或更对口的模型反而更好。

② 路由第一次拿到了质量侧的论据,不只是成本侧

之前我们讲路由,卖点一直是省钱。现在可以多一条: router 用更低的成本,拿到了不低于全用强模型的分数(0.397 vs 0.385)。 即「降本 + 不降质」同时成立。这个论据比以前硬。

③ 极差是比均分更实的指标 —— router 最稳

→ 建议:把极差(稳定性)列为第二主指标,跟均分并列。 以前我们只看均分,这条漏了。

对主方案的四条影响

  1. 简单题主动降级,从成本策略升级为质量策略。 以前降级是为了省钱、要小心掉质量;现在有实测支持:简单题交给小模型,分可能更高。

  2. 给强模型加「克制」约束。 三类失分都指向过度发挥。提示词层面可以显式要求:先答通用核心、 不做未经证实的承诺、不确定时说不确定。这比换模型便宜。

  3. 评估体系要补「克制」维度。 现在四个维度(relevance / correctness / completeness / usefulness)全是正向的「多给」, 没有任何一项惩罚「给多了」。实测里强模型因话太多失分,说明评测方其实在惩罚, 但这个信号被均分掩盖了。建议显式加一项 conciseness / 过度回答惩罚。

  4. 两个方案合并的必要性被数据支持了。 大模型方案均分略高但极差大,非大模型方案极差小但均分略低 —— 正好互补。 维度 3 的合并思路(用非大模型的分类器做快判定、用大模型的语义能力做难判定) 在数据上有依据,不只是理论推演。

必须标注的两个不确定性


维度 3:合并推荐方案(缓存边界切 + 场景级兜底)

为什么是这两个

零成本切换窗口(三个)

  1. 会话首轮
  2. 上下文压缩(session compaction)后
  3. 场景切换(新 sub-agent 独立上下文)

成本算账(核心论据)

同一个 10 轮会话,每轮 +4K 上下文,全价 30 元/百万、缓存价 3 元/百万(0.1x):

做法 输入成本 相对
不路由(全旗舰) ¥6.60 基准
每轮切 ¥6.60 0%
缓存边界切 ¥1.74 省 3.8x

为什么每轮切和不路由一样贵? 小模型价格是大模型的 0.1x,命中缓存的价格也正好是 0.1x。 所以「贵模型+命中缓存」和「小模型+缓存全失效」成本完全相同,但前者质量高得多。 每轮切成小模型,等于拿质量换了一个本来就存在的折扣 —— 白换。

五层架构

L0 安全前置      → 凭证/越狱/停止指令,最高优先级,直接短路
L1 难度分级      → L1-L8(复用维度1的分类器,只判定不执行)
L2 场景路由      → 决定是否派生 sub-agent
L3 能力画像选型  → F0-F6 加权打分选模型
L4 服务路由      → 同模型多供应商,按健康/成本/延迟切换(新增层)
护栏             → 置信度阈值 + 级联兜底 + 切换次数预算帽

关键设计参数

与维度 1/2/4 的关系


维度 4:DeleGate —— 端到端 RL 训练 model router

沿用内部代号 DeleGate(强控制器 + 可学习委派接口)汇报只讲三块:主张 / 三样能立刻抄的 / 落地路径。 架构、协议、训练配方等细节挪到 4.5 备查,被追问时再翻,不主动讲。

4.1 主张:强控制器 + 可学习委派接口

一句话:把握全局的应当是强模型

让 frontier 模型当 controller 做任务分解、上下文封装、质量把关、最终合成; 把「为某个子任务选哪个执行模型」封装成一个可调用的工具接口, 接口内部由一个轻量可学习 selector 完成选择。

判断力密集的环节(分解、封装、验收、合成)留给强模型; 适合统计学习的环节(能力与价格的匹配)交给 selector。

为什么不是另外两条路:

定位为原语:model selection 是 orchestration-agnostic 的原语。 编排方案(单 agent 循环 / subagent 树 / 图式 MAS)可以随生态演化, 但「给定任务决定哪个模型来做」永远存在。

4.2 与维度 3 的关系:两级接力(不是竞争)

        ┌───────────────── 维度 3:闸门层 ─────────────────┐
        │  决定「什么时候允许换模型」                        │
        │  依据:缓存边界(首轮 / 压缩后 / 场景切换)        │
        │  输出:允许 or 不允许                              │
        └────────────────────┬─────────────────────────────┘
                             │ 允许切换的窗口
                             ▼
        ┌───────────────── 维度 4:选择层 ─────────────────┐
        │  决定「在这个窗口里选谁」                          │
        │  依据:DeleGate selector(可学习)                │
        │  输出:具体 worker(档位)                         │
        └──────────────────────────────────────────────────┘

一句话讲清关系:维度 3 管能不能切,维度 4 管切给谁。 维度 3 用规则守住 cache 不丢,维度 4 在守住的窗口里把「选谁」从静态配置升级成学习。

为什么 DeleGate 不违反维度 3 的 cache 约束(这是上一版我判错的地方,必须讲清)

委派发生时,worker 拿到的是 controller 封装的独立上下文换 worker 根本不碰 controller 主对话的 KV cache。 它的路由单位是「每次委派」,而委派本身就落在维度 3 的第三个零成本窗口里 (新上下文,本来就没有 cache 可丢)。

→ 所以它不是「每轮切」,是踩在允许切换的窗口上切

它还是维度 3「场景级兜底」那条线的学习化升级: 我们场景级 sub-agent 的模型选择是静态配置;DeleGate 把它变成可学习。 文档自己写明:与 Claude Code subagents 形态相同,本方案是其自然的学习化升级。

适用前提(要诚实):只在 agentic 场景成立——必须存在「强 controller 分解 + 委派」结构。 单轮问答、纯 chat 没有委派,用不上。它是 Qclaw/QClawX 这类场景的演进方向,不是通用路由的全部。

4.3 完整流程图 + 举例

流程(七步)

①  用户请求
      ↓
②  Controller(强模型)推理,遇到适合外包的子任务
      ↓
③  调 delegate(spec, context, requires, constraints)
      ↓
④  Pool card 做可行性过滤 → 候选 worker 集
      ↓
⑤  Selector 双塔打分:效用 = 预估质量 - λ × 预估成本
      ↓
⑥  选中 worker 执行(信息不足可 ask-back 回问,上限 1-2 轮)
      ↓
⑦  结果 + 元信息回到 Controller → 验收 / 重试 / 接管 → 合成最终答案
      ↓
   全过程落盘 → 训练日志 → 反哺 selector

举例:一次销售数据分析

用户:「帮我分析这三个月的销售数据,找出下滑原因,写一份给管理层的汇报。」

Controller(强模型)接手后自己不干细活,拆成三个子任务分别委派:

子任务 spec 要点 Selector 选谁 理由
① 读三个 CSV,算各月总额与环比 结构化、低推理 C1 档(便宜 pro) 小模型足够,且不会过度发挥
② 定位下滑最严重的产品线并归因 多步推理、跨表关联 C2 档(多步编码专长) 需要链式推理但不需顶级判断
③ 撰写给管理层的汇报 文笔、判断、分寸感 C3 档(最高档,可开 ensemble) 错了全盘皆输,值得付溢价

成本对比:全用 C3 要付三份溢价;路由后只有子任务 ③ 付高价。 质量对比:子任务 ① 交给强模型反而可能失分——实测里「简单题话太多、 自加误导承诺 + 幻觉虚构」正是上限模型的三类失分之一。这题给小模型,分可能更高。

ask-back 举例

子任务 ① 的 worker 只拿到了 CSV 表头和前几行(部分上下文原则), 发现没有月份字段,于是返回 need_context("需要日期列或月份标识") 而不是硬算。 Controller 补上正确的日期列,worker 继续,一轮解决(上限 1-2 轮)。

这一步的价值:把「上下文封装错了」从必须事前做对降级成事前给初值、事后可修。 而且 ask-back 率本身就是指标——某个 spec 模式老是回问,说明 controller 的封装 prompt 该修了。

4.4 三样能立刻抄的(不依赖 RL,现在就能做)

① 只暴露档位,不暴露型号

② worker card 文本编码做冷启动

③ ask-back 协议 + ask-back 率监控

另有一条兜底原则,可直接写进维度 3 的护栏层低置信时升档,而不是赌便宜档 —— 把误判成本封死在「多花钱」一侧。 这与维度 3 护栏层的方向完全一致(正确性支配成本)。

4.5 落地路径(三步,每步独立可评测)

阶段 做什么 验证什么
MVP pool card + 价格档启发式 selector + 完整日志管道 验证接口协议与 ask-back 可用,积累第一批真实 spec 数据
V1 数据到位后离线训 encoder selector,替换启发式 对比朴素规则基线,看学习的 selector 是否真有增益
V2 上线轨迹级群组 RL 闭环 跑 pool 热替换、分布外分层压力测试

为什么现在不上 V2:不是杀鸡用牛刀,而是 V2 的前提是 V1 那笔全矩阵开销 (N 个 spec × M 个 worker 全跑一遍),在模型池定型前花不值

建议顺序:先做 MVP 的日志管道(这一步零风险,且早晚必须做) → 模型池与 controller 稳定后再上 V1 → 最后才谈 V2。

4.6 技术细节备查(Q&A 用,不主动讲)

点开看:五组件架构 / 接口协议 / Selector 设计 / 两阶段训练 / 评测设计 / 风险

五组件架构

组件 职责
Controller(强模型) 决定是否委派、切分子任务、撰写 spec、打包上下文、验收、重试或接管、最终合成。不做模型选择
Delegation Tool controller 可见的工具,接收 (spec, context, constraints),工具描述里携带 pool card
Selector(可学习) 接口内部的路由模型,输入 spec 与约束输出 worker 选择。不下发执行指令
Worker Pool 「模型 × 部署配置」打平的异构目录(同一模型不同 effort 档算不同条目)
Feedback Logger 记录 (spec, 选中 worker, 执行统计, 成本) + 后续到达的标注

委派接口协议

delegate(
  task_spec:   str,          # controller 撰写的自包含子任务描述
  context:     list[Item],   # controller 挑选的上下文片段
  requires:    list[enum],   # 能力需求标志,用于可行性过滤
  constraints: {budget_usd, latency_s, output_schema}
) -> {
  result, cost_usd, n_askbacks,
  meta: {worker_tier, exec_stats}   # 只暴露价格档位,不暴露型号
}

配套三条:output_schema 让验收机械化;worker 自主决定执行方式(外部指定反而拦掉自我纠错); ABSTAIN 表示无可行 worker,随附 suggest_split 建议(不静默升级,决策权留给 controller)。

Selector:双塔 encoder

select(task_spec, context_view, requires, constraints, catalog)
-> { choice: worker_id | ABSTAIN, q_hat, c_hat{p50,p90}, propensity, alternatives }
  • catalog运行时输入不是模块常量 → selector 与具体 pool 解耦,能处理未见条目
  • 双塔打分 $z(x,m)=\langle e_x, u_m\rangle/\tau$,task 塔编码一次、worker 塔是缓存向量点积 → 选择时延与目录规模解耦,单次前向毫秒级
  • 效用 $s(x,m)=\hat q-\lambda\hat c_{0.9}$(用 p90 成本,保守)
  • 输出必带 propensity(本次选择在当前策略下的概率),支撑离线去偏评估

两阶段训练

与 LLM 的 SFT→RL 同构,但作用在 selector 上。

  • V1 离线全矩阵预训练:用 controller 在种子任务集上实际跑分解收集 on-policy spec, 每个 spec 跑遍整个目录 → 无选择偏差。副产品:能算出 oracle 路由表,让 regret 可测。 标注成本从 N×M 次评审降为 N 次基准生成 + 廉价比对。
  • V2 轨迹级群组 RL:episode 是请求而非单次委派。 回报用正确性门控 $R=b(1-\alpha\tilde C)$(乘法门控:便宜但做错,一分钱奖励拿不到)。 GRPO 式组内标准化共享轨迹优势,无需 value 网络采样即探索,不额外加扰动。 只有一条轨迹正常服务用户,其余是影子轨迹。
  • 有独立裁判原则:controller 的即时处置(采纳/重试/接管)不作训练信号 —— worker 返回的几乎总是「看起来完成了」,处置会坍缩到接受、信息量低。

评测四档

R1 弱模型联合编排 / R2 强模型 + 学习 selector(主张) / R3 强模型 + 朴素规则(消融)/ R4 强模型直答(成本上界)。 关键实验:分布外分层、无 verifier 开放任务、pool 热替换 30% 压力测试 (R2 应在 O(百次) 委派内恢复,R1 需重训)。

风险

标签天花板(以「与强参考模型一致」定义成功,参考模型的错误会注入标签); 委派开销倒挂(小任务被接口往返吃掉收益);spec 分布漂移(controller 静默升级导致); 责任边界不干净(封装错还是选错,归因不清会污染信号)。

学术侧对照(与本方案不同路线)

Router-R1(UIUC,arXiv:2506.09033) —— router 本身是一个 LLM - 交替执行 think(内部推理)和 route(调用模型),把每次响应整合进演进的上下文 - 三段式奖励:format + final outcome + cost reward(惩罚过度使用贵模型) - 只靠模型描述符就能路由到训练时没见过的第 11 个模型,无需重训 - 效果:7 个 QA 基准超所有基线;EM 0.409(Llama) / 0.416(Qwen);α=0.6 是较好的平衡点 - 多跳 QA 上平均调用次数显著高于普通 QA —— 说明它学会了判断任务难度

DialRouter(arXiv:2604.12385,2026.04) —— 针对多轮对话的 myopic 问题 - MCTS + 用户模拟器探索对话分支,用 reward model 评估累积回报,再 Behavior Cloning 蒸馏成轻量 policy - 配检索式未来状态近似,实现推理时无需再搜索 - 把 KV cache 复用写进了奖励函数 - 效果:成本降约 80%,成功率降到 88.69%

与 DeleGate 的路线差异:Router-R1 是「router 即 LLM(生成式)」, DeleGate 是「selector 即 encoder(表征 + 打分,非生成)」,并明确把 LLM 判断式降级为对照基线。 DeleGate 选后者的理由是可时延、可在线更新、可处理未见目录条目。


维度 5:前沿方法详解(精选 5 个)+ 示例

选这 5 个的理由:它们不在同一层,是五个粒度,可以摞起来用

按路由粒度从细到粗排,正好对应前面四章已经出现的四个层级。 这个顺序说明的是「不是五选一,是五层串联」。

5.1 FrugalGPT   query 级 · 级联        ← 最经典,也是我们的反面教材
5.2 RouteLLM    query 级 · 学习型       ← 数据驱动的代表
5.3 CASTER      sub-task 级 · 双信号    ← 对应维度 4 的委派粒度
5.4 HyDRA       会话级 · 缓存边界       ← 对应维度 3 的主线依据
5.5 腾讯云       服务级 · 网关          ← 对应 L4 服务路由层

5.1 FrugalGPT(Stanford, 2023)—— query 级级联,最经典也最容易踩坑

5.2 RouteLLM(LMSys, 2024)—— 把人类偏好变成可训练信号

5.3 CASTER(arXiv:2601.19793, 2026.01)—— sub-task 级双信号

5.4 Copilot HyDRA(2026.06)—— 缓存边界 + 先筛后选(维度 3 的直接依据)

5.5 腾讯云 AI 网关(2026.06)—— 工程视角,我们 L4 层的现实参照


其余 5 个:一句话速览(不展开,留作 Q&A 备用)

方法 一句话 什么时候会用到
Hybrid LLM(UBC+MS, 2024) 训轻量 router 预测小模型够不够用,质量阈值可调("我要 95% 质量,剩下尽量省") 业务方要直接指定质量档位时
IRT-Router(ACL, 2025) 用项目反应理论建模 query 难度 θ 与模型能力 β,可解释性强于黑盒 router 被追问「凭什么说这个 query 难」时(呼应我们的 L1-L8)
BEST-Route(ICML, 2025) 不只选模型,还选采样次数(难题强模型 Best-of-N,简单题弱模型 1 次) 想把 Best-of-N 也纳入成本优化时
TRouter(ACL, 2026) LLM 自动生成任务分类树 + 合成 QA,解决冷启动无标注 新场景上线没有数据时
TRACER(2026) 从生产日志自动训 surrogate 模型,77 类意图达 83-100% 覆盖率 线上日志攒够之后做自动化

若被追问「还有别的方法吗」,这张表可作补充,既显完整又不占篇幅。


维度 5 的收口(一句话)

这五个不是竞争关系,是五个粒度: - FrugalGPT / RouteLLM 管「单个 query 给谁」 - CASTER 管「MAS 里每个子任务给谁」 - HyDRA 管「一个会话什么时候允许换」 - 腾讯云管「流量怎么分、故障怎么兜」

它们可以同时上,各管一层。 这也解释了为什么前面维度 3 和维度 4 不冲突。


实现规划路线

前面五章回答「选什么」,这一章回答「怎么一步步做出来」。 排序原则只有一条:风险递增、每期独立可验收、任何一期停在这里都不亏。

设计路线时的四个前提(先说清楚,否则排序不成立)

  1. 先观测后动手。所有路由方案的成本收益都建立在「cache 命中率」和「难度分布」两个数上, 现在这两个数没有。在算不清账之前改路由,等于闭眼调参。
  2. 先建闸门后选模型。维度 3 的规则层(什么时候允许切)不依赖任何模型选型, 且它是后续所有策略的安全边界。闸门没建就切模型,出事无法归因。
  3. 按风险递增排序:服务路由(零质量风险)→ 规则降级 → 学习型选择 → RL。 反过来做,任何一步出错都会连带推翻前面。
  4. 标注规范必须 P0 就定死。数据一旦按错误方式采,后面全会系统性跑偏 (CASTER 实证:naive 探索会污染标签,导致路由器高估难度,最终把所有任务都发给强模型,路由白做)。

五期路线总览

名称 核心动作 风险 独立收益
P0 可观测与基线 日志管道 + 成本基线 + 评测集 + 标注规范 看清现状,唯一能回答「值不值得做」的一步
P1 闸门与护栏 L0 安全前置 + L4 服务路由 + 护栏 + 影子模式 极低 服务路由本身就有可用性与成本收益
P2 分级路由上线 复用维度 1 分类器,只在零成本窗口切 成本降幅开始兑现
P3 本地化 + 场景兜底 方案 B 本地分类器管简单判定 + sub-agent 静态档位 路由决策本身变免费、变毫秒级
P4 DeleGate 学习化 MVP 日志 → V1 离线 encoder → V2 轨迹级 RL 选择质量从静态配置升级为可学习

关键路径:P0 → P1 → P2 → P3 → P4(串行) 可并行:评测体系修复(全程)、数据集扩充(P0 起)、模型池梳理(P0-P1)


P0 · 可观测与基线(约 2-3 周)

为什么排第一:这是全案唯一「零风险且不做就永远做不成」的一步。 现在回答不了「一次会话多少钱」「cache 命中率多少」「简单题占几成」, 那么 P2 之后所有降幅承诺都是拍脑袋。

做什么

1. 调用日志管道(最重要,其他都能等) 每条请求必须落这些字段,缺一不可:

session_id / turn_index        → 会话位置(判断是否处于 cache 边界)
scene_tag / agent_role         → 场景与角色(维度 3 的 L2 用)
model / provider / endpoint    → 实际走的模型与供应商
prompt_tokens / completion_tokens
cache_read_tokens              ← 必须单独采,没有它成本模型是空的
cache_creation_tokens
latency_p50 / latency_total
cost_estimate                  → 按当前单价折算
safety_flag                    → L0 命中情况

cache_read_tokens 是这一期的命门。OpenSquilla 实测 cache 命中率 98.1%, Qclaw H20 压测 82%-98%,我们的真实值是多少现在是黑箱。 拿不到这个数,第 3 章那笔「每轮切 ¥6.60 vs 缓存边界切 ¥1.74」的账就永远是纸面推演。

2. 成本基线看板 单次会话成本中位数 / P90、按场景拆分、按难度拆分(如果有标注)、cache 命中率趋势。

3. 评测集 从真实日志分层采样(不要随机采,随机采会被高频简单题淹没), 规模建议 300-500 条起步,覆盖:短指令、长上下文、多轮追问、工具调用、开放推理五类。

4. 标注规范(与数据采集同步定,不能等) 正确做法是用强弱模型表现差异(performance divergence)标注难度: 同一个 query 让强模型和弱模型各跑一次,强对弱错才算真难。 不能只看弱模型的绝对表现——它做砸了可能是它自己太弱,不是任务难。

5. 评测维度补一项 当前是 relevance / correctness / completeness / usefulness 四项,全是正向的「多给」, 没有任何一项惩罚「给多了」。而实测里强模型恰恰因话太多失分(自加误导承诺、幻觉虚构)。 建议显式加 conciseness / 过度回答惩罚,否则这个信号会一直被均分掩盖。

出口判据(Gate 0)

风险与不做清单


P1 · 闸门与护栏(约 3-4 周)

为什么排第二:维度 3 的规则层不依赖任何模型选型, 而且它是后续所有策略的安全边界。闸门没建就切模型,出 badcase 无法归因、无法回滚。

做什么

1. L0 安全前置(最高优先级,直接短路) 凭证/越狱/停止指令识别,命中即短路,不进路由逻辑。

2. L4 服务路由(本期的性价比之王) 同模型多供应商切换:按健康、成本、延迟选 endpoint。

这是全案风险最低、见效最快的一步,理由是: 它换的是同一个模型的不同供应商,不改变模型能力, 所以对质量零影响,但直接带来可用性提升和单价优化。

抄腾讯云的三层高可用: - L1 配额感知预切换:余量 <10% 主动切,专门抓「健康检查全绿但 GPU 已满载」的软故障 - L2 服务内切换 / L3 跨服务切换 - 延迟路由用随机二选一(power-of-two-choices)而不是选当前最快, 避免所有请求涌向同一节点把它打成最慢

抄腾讯云最关键的一条:语义路由用独立子请求调意图识别,识别服务挂了主链路照常跑。 路由器自己绝不能成为单点故障。

3. 护栏层 - 切换预算帽:单会话 ≤3 次(紧急升配豁免) - 迟滞区间:升级 +2 / 降级 -3(防抖动) - 上下文自适应:<8K 跨 1 档即切;8K-32K 跨 2 档;>32K 仅场景切换 - 置信度低于阈值 → 升档而不是赌便宜档(把误判成本封在「多花钱」一侧) - 默认动作是「不动」,不是「重新评估」

4. 影子模式(shadow mode) 路由决策只记录不下发,与线上实际结果对比。这是 P2 灰度前的必过环节。

出口判据(Gate 1)

风险与不做清单


P2 · 分级路由上线(约 4-6 周)

为什么排第三:闸门和护栏就绪,才有条件动模型档位。 本期复用维度 1 已有的分类器(不重新训练),成本最低。

做什么

1. 分类器接入 维度 1 分类器输出 level/task/modality,映射 L1-L8 → 三档服务。 注意实测教训:level 从多数投票 75.09% 涨到 6-level 91.09%, 但 caps 从 85.88% 反而降到 85.34%——继续细分等级精度不涨, 所以不要在这一期追求更细的分级,先跑通链路。

2. 只在零成本窗口切 会话首轮 / 上下文压缩后 / 场景切换,这三个时点 cache 本来就要丢。

3. 抄 OpenSquilla 的三条 cache 感知设计 - kv_cache_anti_downgrade:时间窗口(600s)内禁止把已建立 cache 的对话降级到更弱模型。 与我们的边界切叠加——边界切决定何时能改,时间窗口决定改的方向不能是降级。 - appliesTo: "next_accepted_turn":路由变更下一轮才生效,不在中途改。 - complaint_upgrade:用户抱怨一次自动升一档,限一档、限 160 字符。 用真实反馈在线纠偏,成本几乎为零,比离线调阈值快一个数量级。

4. 灰度节奏 5% → 20% → 50% → 100%,每档至少观察一个完整业务周期,看质量分与成本双指标。

出口判据(Gate 2)

风险与不做清单


P3 · 本地化 + 场景兜底(约 6-8 周)

为什么排第四:P2 跑通后,路由决策本身的成本和延迟才会成为瓶颈 (维度 1 分类器判定时延 280-725ms)。本期把它变成毫秒级、零 token 成本。

做什么

1. 方案 B(OpenSquilla 式本地分类器)上线 LightGBM + ONNX,特征取 token 复杂度、语言、代码密度、上下文压力、工具历史等。 只管简单判定——能确定是 trivial 的直接给 C0/C1 档,不进语义模型。

2. 两级判定

本地快判定(毫秒级、零 token)  → 能确定 → 直接走
        ↓ 不能确定
语义慢判定(维度 1 分类器)      → 出 level + caps + confidence
        ↓ 置信度不足
默认安全档(升档,不赌便宜档)

3. 场景级 sub-agent 静态档位 各场景预设模型档位(对应 DeleGate 的 pool tier),兜住本地和语义都判不准的情况。

4. 抄 OpenSquilla 的 risk pricing 思路 第三层把上下文压力、工具失败、验证结果、恢复状态、动作不可逆性、下游纠正风险算进去。 这正好补上「按长度判难度是肤浅指标」的批评——简短但重逻辑的 prompt 比长摘要更需要推理力。

出口判据(Gate 3)

风险与不做清单


P4 · DeleGate 学习化(约 8-12 周起,建议立项验证)

为什么排最后:V1 的前提是「N 个 spec × M 个 worker 全跑一遍」这笔全矩阵开销, 在模型池定型前花不值。而且此时 P0-P3 已经把成本大头拿走了, 这一期争的是剩余部分的选择质量,属于精加工。

三步(每步独立可评测)

做什么 验证什么
MVP pool card + 档位启发式 selector + 完整 spec 日志管道 接口协议与 ask-back 可用,积累第一批真实 spec 数据
V1 数据到位后离线训 encoder selector,替换启发式 对比朴素规则基线,看学习的 selector 是否真有增益
V2 上线轨迹级群组 RL 闭环 pool 热替换、分布外分层压力测试

三样不依赖 RL、P4 之前就能抄的

  1. 只暴露档位不暴露型号 —— 佐证:DecisionBench 观察到 orchestrator 以 1.5-3.7 倍于随机的比例偏向同厂商模型。若 controller 知道具体型号会形成品牌捷径, 模型池也就热替换不了了。这条建议 P1 就做。
  2. worker card 文本编码冷启动 —— 新模型上线用能力描述文本过编码器就有先验向量, 不用等数据。在线更新时冻结编码器、只更新 M 个 worker 向量,自由度极小、不会灾难性遗忘。
  3. ask-back 协议 —— worker 信息不足返回 need_context 而不是硬着头皮输出,上限 1-2 轮。 把「上下文封装错了」从必须事前做对,降级成事前给初值、事后可修复。 ask-back 率本身就是指标:某个 spec 模式问得多,说明 controller 的封装 prompt 该修了。

出口判据(Gate 4)

风险(诚实列出)


依赖关系(哪些必须串行,哪些可以并行)

                 ┌─────────────────────────────────────┐
                 │  并行轨道(不阻塞主链路)            │
                 │  · 评测体系修复(加 conciseness)    │
                 │  · 评测集扩充与标注                  │
                 │  · 模型池梳理与单价/配额摸底         │
                 └─────────────────────────────────────┘
                              ‖
  P0 观测基线 ──→ P1 闸门护栏 ──→ P2 分级路由 ──→ P3 本地化 ──→ P4 DeleGate
   零风险        极低风险         中风险          中风险        高风险
  看清现状       建安全边界       成本兑现        决策免费      选择质量
     │              │               │              │             │
   Gate0          Gate1           Gate2          Gate3         Gate4

关键路径说明:P0-P4 必须串行,因为后一期的出口判据依赖前一期的产出数据。 但并行轨道全程不阻塞,且评测体系修复越早越好——它决定了所有 Gate 的质量判据是否可信。


明确不做清单(避免范围蔓延)

不做 原因
每轮切 换模型即丢 KV cache,实测每轮切 ¥6.60 vs 缓存边界切 ¥1.74,等于白忙
级联降级(FrugalGPT 式)不加隔离 失败的钱已花,且错误中间步骤会污染共享上下文,误导后续所有 agent
多模型 ensemble 用于交互式 token 涨 5.6x、延迟涨 3x,只适合离线批处理
追求更细的难度分级 实测 6-level 91.09% 但 caps 反降至 85.34%,细分不涨精度
P2 之前上 RL 全矩阵开销在模型池定型前花不值,且此时成本大头已被 P0-P3 拿走
让路由器成为单点故障 必须独立子请求 + 挂了主链路照常跑(抄腾讯云)

里程碑与检查点

里程碑 时点 可对外说的成果
M1 看清账 P0 结束 「我们现在的 cache 命中率是 X%,简单题占 Y%」
M2 边界就绪 P1 结束 「路由安全边界和回滚机制已上线,服务可用性提升」
M3 成本兑现 P2 结束 「成本降 X%,质量不劣于基线」
M4 决策免费 P3 结束 「路由决策从 300ms 降到 50ms,零 token 成本」
M5 选择可学习 P4 V1 结束 「模型池热替换 30% 可在百次委派内恢复」

需要提前备好的资源(不备会卡住某一期)

资源 卡住哪期 说明
各云端模型单价与配额 P0 没有它算不出成本基线
prefix cache 计费数据 P0 最关键,没有它成本模型是空的
端侧实际显存 P3 决定本地分类器能上多大
中文路由准确率基线 P2 分类器在中文场景的表现未知
标注人力(抽检) P0 起 评测集与标注规范需要人工校验
灰度分流能力 P2 5%→20%→50%→100% 需要基础设施支持