OmniRoute 免费供应商排行榜的用量可靠性:24 小时真实成功率如何补上 ELO 排序的盲区
【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute
本篇指南围绕 OmniRoute 的 Free Provider Rankings(免费供应商排行榜)功能展开,重点讲解 #11546 引入的"用量可靠性"(usage reliability)维度:排行榜不再只看 Arena ELO 模型质量分,而是叠加展示每个供应商过去 24 小时实际处理的请求数与成功率。读完本文,你将理解该功能的完整数据链路——从 API 参数、call_logs聚合 SQL,到小样本返回"破折号"的判定规则与前端展示逻辑,并能据此做出更可靠的免费供应商接入决策。
一、背景:ELO 单维排序的盲区
OmniRoute 注册了数百个供应商,其中 150 余个目录条目标记为免费/免鉴权(no-auth、免费档 OAuth 或免费档 API key)。免费供应商的模型质量差异极大,因此 OmniRoute 用Arena AI(LMArena 风格)ELO 分对免费供应商的模型质量打分,并在仪表盘的 Free Provider Rankings 页展示排名。
但仅凭 ELO 排序存在一个致命盲区:一个对所有请求都返回错误的供应商,只要它的模型 ELO 高,依然会排在第一位。连接状态(connection state)描述的是"此刻的凭证与限流",看不到"这个供应商是否真的在成功服务流量"。
#11546 的修复思路是:用量数据(usage data)此前已经由 API 提供,但前端从未主动请求。现在排行榜页显式请求并在表格中展示每个供应商在最近 24 小时窗口内实际服务的请求量与成功率;样本太小的供应商显示破折号(—),而不是一个没有统计意义的数字。
二、数据来源:三个真实信源的 Join
排行榜的分数体系由三个真实来源计算而成(详见 Free Provider Rankings 文档):
- 免费供应商清单:
NOAUTH_PROVIDERS,加上标记hasFree的OAUTH_PROVIDERS/APIKEY_PROVIDERS条目(定义于 src/shared/constants/providers.ts)。 - 模型目录:来自 provider registry(open-sse/config/providerRegistry.ts),并合并运营者手工添加的自定义模型(src/lib/freeProviderRankings.ts 中的
mergeProviderModels,注册表条目在 ID 冲突时优先)。 - ELO 派生的任务适配分:由 Arena ELO 同步引擎(src/lib/arenaEloSync.ts)写入
model_intelligence表,source = "arena_elo"。
Join 逻辑位于 src/lib/freeProviderRankings.ts 的computeFreeProviderRankings:对每个免费供应商的每个模型做三级模糊匹配(findMatchingIntelligence:精确匹配 → 去除尾部版本后缀如kimi-k2.6 → kimi-k2→ 前缀匹配),然后取最高分模型作为Top Model、全体已评分模型的均值作为Avg Score,供应商按 Top Model 分数降序、再按平均分排序。
ELO 分数按榜单归一化到任务适配区间[0.4, 0.98]:
taskFit = 0.4 + 0.58 * ((elo - minElo) / (maxElo - minElo))前端把分数渲染为人类可读标签(Elite / Excellent / Very Good / Good / Average / Below Average),因为它是相对排名质量而非百分比。
三、API 层:withUsage与usageRange参数
排行榜页由公开只读端点 src/app/api/free-provider-rankings/route.ts 支撑,查询参数经 Zod 校验:
GET /api/free-provider-rankings GET /api/free-provider-rankings?category=coding&limit=20 GET /api/free-provider-rankings?configuredOnly=1&withUsage=1&usageRange=24h| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
category | string | (无) | default、coding、review、documentation、debugging之一;省略返回综合排名 |
limit | number | 50 | 钳制到1–100,非法值回退为 50 |
configuredOnly | boolean | false | 只保留至少配置了 1 条(激活)连接的供应商 |
availableOnly | boolean | false | 只保留至少 1 条未耗尽、未限流的连接(隐含 configuredOnly) |
withUsage | boolean | false | 追加每个供应商在窗口内实际服务的统计(reliability.usage) |
usageRange | string | 24h | 可选1h、24h、7d、30d;拼写错误会被 400 拒绝而非静默改写窗口 |
两个值得注意的实现细节:
- 布尔参数宽容解析、严格拒绝:布尔参数会把
"1"/"true"/"yes"统一转换为true(路由文件中的boolParam);而usageRange采用z.enum,注释明确写道"拒绝而非静默转换:一个拼写错误不能悄悄返回与调用方要求不同的窗口"。 withUsage是纯增量、默认关闭:因为它要付出一次对call_logs的聚合查询代价,"只关心排名的调用方不必为此买单"。同时withUsage会连带加载连接快照——源码注释指出,过去单独开withUsage会静默返回没有reliability的排名,现在needsConnectionSnapshot会自动触发快照加载。
响应形如:
{ "rankings": [ { "id": "<provider-id>", "name": "<provider name>", "category": "noauth | oauth | apikey", "topModel": { "modelId": "<registry model id>", "modelName": "<model display name>", "score": 0.0, "eloRaw": 0, "confidence": "high | medium | low" }, "averageScore": 0.0, "modelCount": 0, "reliability": { "state": "healthy | degraded | down", "connections": [{ "testStatus": null, "rateLimitedUntil": null, "state": "healthy" }], "usage": { "requests": 0, "successes": 0, "successRate": null, "avgLatencyMs": null, "lastRequestAt": null, "windowHours": 24 } } } ] }四、用量统计的 SQL 层:getProviderUsageSince
withUsage打开后,引擎调用 src/lib/db/callLogStats.ts 中的getProviderUsageSince(since),在call_logs上做单窗口聚合:
SELECT c.provider, COUNT(*) as requests, SUM(CASE WHEN c.status >= 200 AND c.status < 400 THEN 1 ELSE 0 END) as successes, ROUND(AVG(c.duration)) as avgLatencyMs, MAX(c.timestamp) as lastRequestAt FROM call_logs c WHERE c.provider IS NOT NULL AND c.provider != '-' AND c.timestamp >= @since AND EXISTS ( SELECT 1 FROM provider_connections pc WHERE pc.provider = c.provider ) GROUP BY c.provider从源码结构看,这条查询是有意不直接复用同文件的getProviderMetrics()(后者带两个关联子查询,而call_logs仅按timestamp建索引,关联扫描会主导成本):这里只保留排名真正需要的四列,单次有界GROUP BY即可走idx_cl_timestamp。成功率的定义与邻居查询保持一致——2xx/3xx 计为成功;EXISTS子句则保证已删除连接的供应商不会因历史日志残留为"幽灵节点"(对应 #10714)。
窗口时长由usageRange决定(复用健康矩阵RANGE_MS),默认24h,即 changelog 中"过去 24 小时"的由来。
五、小样本规则:为什么不足 5 次请求就显示破折号
聚合结果经 src/lib/freeProviderRankings.ts 中的attachProviderUsage挂到每个排名的reliability.usage上,其中核心判定是:
successRate: row.requests >= MIN_USAGE_REQUESTS ? row.successes / row.requests : null常量MIN_USAGE_REQUESTS = 5(约 L279),源码注释解释得很直白:"2 次里挂 1 次不等于'坏了一半',没人调用过的供应商也不是'0% 健康'"。样本量低于 5 时successRate置为null,把"没有把握下结论"与"成功率为 0"区分开。
展示侧由纯函数formatUsageReliability(src/lib/freeProviderRankingsUsage.ts,刻意零依赖、可被客户端组件直接引用)把用量归为三种展示形态:
| kind | 触发条件 | 展示 |
|---|---|---|
rate | successRate !== null(窗口内 ≥ 5 次请求) | 百分比数字,如97% |
insufficient | successRate === null且requests > 0(0–4 次请求) | 破折号— |
none | 窗口内无流量或未请求 usage | 破折号— |
百分比还按阈值着色:good(≥ 95%,绿)、fair(≥ 80%,黄)、poor(< 80%,橙);破折号场景显示为中性色,且三种形态都有各自的 tooltip 文案(完整样本数、"请求过少"、"无流量"),即 changelog 所说"too small a sample shows a dash, not a number"。
六、前端:排行榜页如何消费用量数据
仪表盘页面位于 src/app/(dashboard)/dashboard/free-provider-rankings/page.tsx/dashboard/free-provider-rankings/page.tsx),入口为Costs → Free Provider Rankings或直接访问/dashboard/free-provider-rankings。页面包含:
- Top-3 领奖台(前三名免费供应商卡片);
- 完整排名表,列为 Rank / Provider / Top Model / Score / Avg Score /Reliability/ Models / Type;其中 Reliability 列就是 #11546 新增的 24 小时成功率列;
- 类别过滤按钮(All Categories / Default / Coding / Review / Documentation / Debugging)、可用性开关(Configured only / Available only)、Type 过滤与按 Type 分组排序(客户端派生,不触发重新请求)。
关键改动在请求构造处:
// Always: an ELO-only ranking describes a provider that errors on every // call as healthy. `usageRange` matches the health matrix default. params.set("withUsage", "1"); params.set("usageRange", "24h");也就是说,页面现在无条件附带withUsage=1与usageRange=24h——这正是 changelog 所说"用量数据早已由 API 提供,但此前从未被请求"的落点:修复不是新增数据能力,而是把已有能力接进默认视图。Reliability 列与state(连接当前状态)互补:state读的是连接此刻的样子,看不见"每次调用都报错"的供应商,只有调用日志能看见。
七、ELO 分数体系的支撑机制
用量维度建立在 ELO 分数体系之上,理解以下机制有助于解读页面数据(完整说明见 docs/guides/FREE_PROVIDER_RANKINGS.md):
- 数据源:Arena AI 排行榜 API 的
text与code两个榜单;text映射到default/review/documentation/debugging类别,code映射到coding。 - 置信度:按 Arena 投票数分档——
high(≥ 5,000 票)、medium(≥ 1,000)、low(< 1,000)。 - 新鲜度:条目写入
model_intelligence表后7 天过期,停止同步的供应商会自然掉出排名而不是提供陈旧数据。 - 同步开关:同步引擎默认开启,服务启动时运行一次并周期执行,非阻塞、永不致命(上游拉取失败时排行榜展示最后一次有效数据或空态)。两个环境变量(见 ENVIRONMENT.md):
| 变量 | 默认值 | 用途 |
|---|---|---|
ARENA_ELO_SYNC_ENABLED | true | 设为false可关闭出站同步 |
ARENA_ELO_SYNC_INTERVAL | 86400(24h) | 同步间隔(秒) |
- 手动运维:管理端点 src/app/api/intelligence/sync/route.ts(需管理鉴权):
GET查看同步状态、POST触发手动同步(body 可传{"dryRun": true}预览)、DELETE清除全部arena_elo条目。排行榜页为空时,手动POST或重启服务即可重新填充。
八、连接状态过滤与可靠性三态
configuredOnly/availableOnly过滤与reliability标注复用同一份连接快照(零额外查询)。单条连接按健康矩阵同一词汇分类(classifyConnection):
testStatus ∈ {credits_exhausted, banned, expired}→down(终态,不会自愈);rateLimitedUntil仍在未来 →degraded(限流冷却,惰性恢复);- 其余 →
healthy。
供应商级聚合规则为:所有连接down则down;任一非healthy则degraded;否则healthy。需要留意的是:availableOnly会直接丢弃无健康连接的供应商,因此在该过滤下state不会出现down——down只在单独使用configuredOnly时可见。
九、测试覆盖
该功能的纯函数层均有独立单测,可在仓库中直接查看验证:
- tests/unit/freeProviderRankings-usage-display.test.ts:覆盖
formatUsageReliability的none/insufficient/rate分支与色调判定; - tests/unit/freeProviderRankings-filters.test.ts:覆盖
configuredOnly/availableOnly过滤与可靠性标注的纯函数行为。
由于过滤、标注、展示判定都被拆成"完全同步、无副作用"的纯函数(filterFreeProviderRankings、attachProviderReliability、attachProviderUsage、formatUsageReliability),测试无需数据库即可断言全部边界。
十、实战建议:如何组合 ELO 与用量可靠性选供应商
- 先看类别,再看双维度:代码任务用 Coding 过滤,通用对话用 Default/All。同一供应商在不同类别排名可能不同(其 Top Model 随榜单变化)。
- Reliability 列优先于 ELO 分数做排除:一个
97%+绿色成功率 + Elite 分数的供应商是最佳接入目标;ELO 高但成功率< 80%(橙色)的供应商说明模型质量与实际交付存在落差,应谨慎或等冷却结束后复看。 - 破折号不是坏信号,是"未知"信号:
—表示窗口内无流量或请求少于 5 次,不构成失败证据;可以先小额试用再评估。 - 连接多个 Top 供应商,交给 Auto-Combo 决策:同一份 Arena ELO 数据也驱动 Auto-Combo 评分引擎的任务适配因子(open-sse/services/autoCombo/taskFitness.ts,解析顺序
user_override → arena_elo → models_dev_tier → static table)。接入头部免费供应商后,以model: "auto"(如auto/coding)发请求即可按请求质量偏好自动路由,完整 15 因子说明见 Auto-Combo 文档。 - 接入凭证参考:
NOAUTH供应商无需凭证最快接入;OAUTH/APIKEY免费档需要简单注册但常暴露更强的模型,具体步骤见 Free Tiers Guide,完整免费目录见 FREE_TIERS.md。
小结
#11546 的核心价值在于把"模型理论上有多强"(ELO)与"实际交付是否可靠"(24 小时调用日志成功率)放到同一张表里,并以严格的样本量门槛(≥ 5 次请求才给出百分比,否则显示破折号)避免小样本误导。整条链路——Zod 参数校验(route.ts)、有界窗口聚合 SQL(callLogStats.ts)、小样本置空(freeProviderRankings.ts)、展示形态判定(freeProviderRankingsUsage.ts)——均可在仓库中按上述路径逐一核对。
【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考