资讯动态

Semantic Router 的 Elo 评分模型选择:基于在线反馈的动态路由算法指南

发布时间:2026/10/13 22:29:02 来源:尧图企业网站定制
后端API网关模型推理服务AI Agent【免费下载链接】semantic-routerAn open, programmable decision layer for models and compute.项目地址https://gitcode.com/gh_mirrors/sem/semantic-router点击查看免费下载本文围绕 vLLM Semantic Router 项目中的Elo 评分模型选择Elo Rating Selection展开介绍一种基于运行时用户反馈、借助 Bradley-Terry 成对比较框架持续更新模型评分的在线学习式路由策略。读者将掌握该算法的数学原理、Go 核心实现、完整配置方式、反馈提交接口与持久化存储机制并能在实际网关部署中通过elo算法让表现更好的模型在候选集中脱颖而出、被更频繁地选中。Elo 评分选择的核心思想传统的模型路由如 RouteLLM 论文中训练的方式是基于偏好数据训练出的静态路由器模型一次训练、长期生效。而 Semantic Router 的 Elo 评分选择采用了完全不同的路线一套运行时评分系统根据实时用户反馈动态更新模型排名。其基本逻辑是模型收到正向反馈thumbs up时评分增加模型收到负向反馈thumbs down时评分降低随着时间推移表现更好的模型评分攀升被选中的概率也随之提高。这套方法基于Bradley-Terry 模型成对比较框架通过在线学习持续改进模型选择质量——不需要离线训练反馈即学习评分即策略。该实现的核心位于 src/semantic-router/pkg/selection/elo.go代码注释中明确标注其思想参考自 RouteLLM 论文arXiv:2406.18665但在工程形态上改为运行时动态更新。算法工作流程流程可以拆解为以下四步与原文档一致所有模型以初始评分起步默认1500用户在响应后提供反馈赞 / 踩评分依据反馈与期望结果之间的差距进行调整高评分模型被更频繁地选中。其中第 3 步期望结果是关键评分更新不是简单地加分减分而是同时考虑两个模型的相对实力——这正是 Bradley-Terry 模型发挥作用的地方。数学基础Bradley-Terry 期望得分与评分更新期望得分Expected Score模型 A 击败模型 B 的期望概率为E_A 1 / (1 10^((R_B - R_A) / 400))其中R_A 模型 A 的评分R_B 模型 B 的评分E_A 期望得分A 获胜的概率评分更新公式收到反馈后评分按如下公式更新R_A R_A K × (S_A - E_A)其中K K 因子控制波动幅度默认 32S_A 实际结果1 胜0.5 平0 负E_A 期望得分计算示例模型 A评分 1500模型 B评分 1400 A 的期望得分1 / (1 10^((1400-1500)/400)) 0.64 若 A 获胜S_A 1 新评分 1500 32 × (1 - 0.64) 1500 11.5 1511.5 若 A 落败S_A 0 新评分 1500 32 × (0 - 0.64) 1500 - 20.5 1479.5可以看到爆冷获胜时加分多正常获胜时加分少同理爆冷落败时扣分也多。这种不对称性正是 Elo 系统能快速识别真实实力差距的原因。源码级实现EloSelector 的 Select 与 UpdateFeedback在 src/semantic-router/pkg/selection/elo.go 中EloSelector是整套算法的核心类型文档中的核心 Go 代码即来自该文件的实际实现// Select returns the model with highest Elo rating func (s *EloSelector) Select(ctx context.Context, selCtx *SelectionContext) (*SelectionResult, error) { var bestModel string var bestRating float64 math.Inf(-1) for _, candidate : range selCtx.CandidateModels { rating : s.getRating(candidate.Model, selCtx.DecisionName) if rating bestRating { bestRating rating bestModel candidate.Model } } return SelectionResult{ SelectedModel: bestModel, Score: bestRating, Method: MethodElo, }, nil } // UpdateFeedback adjusts ratings based on user feedback func (s *EloSelector) UpdateFeedback(winner, loser string, tie bool) { ratingA : s.getRating(winner) ratingB : s.getRating(loser) // Calculate expected scores expectedA : 1.0 / (1.0 math.Pow(10, (ratingB-ratingA)/400.0)) expectedB : 1.0 - expectedA // Actual scores var actualA, actualB float64 if tie { actualA, actualB 0.5, 0.5 } else { actualA, actualB 1.0, 0.0 } // Update ratings s.setRating(winner, ratingA s.kFactor*(actualA-expectedA)) s.setRating(loser, ratingB s.kFactor*(actualB-expectedB)) }从当前仓库的完整源码看实际实现比示例更丰富包含若干值得注意的增强点1. 选择阶段Select真实实现elo.go第 300-400 行在选出最高分模型之外还做了这些工作按候选模型逐个取分getRatingsForCandidates按分类专属评分优先、全局评分兜底、默认初始评分最后的顺序取分elo.go概率化打分选择得分采用 Bradley-Terry 概率标度P 10^(R/400) / Σ 10^(R_i/400)计算而不是直接使用原始 Elo 分值便于与其他选择器统一比较elo.go成本调节当配置了cost_scaling_factor且上下文携带CostWeight时会对得分做归一化成本惩罚——更便宜的模型获得加分从而实现质量与成本的平衡elo.go置信度计算基于min_comparisons阈值用 sigmoid 函数计算置信度1 / (1 e^(-k*(comparisons-threshold)))比较次数越多置信度越高elo.go结果说明返回的SelectionResult包含Reasoning如 Selected based on Elo rating 1632.0 (win rate: 20/25)支持决策可解释性。2. 反馈更新阶段UpdateFeedback真实实现支持三种反馈模式elo.go模式输入更新方式成对比较同时设置WinnerModel与LoserModel标准 Elo 双向更新正向单模型反馈仅设置WinnerModel评分增加K × 0.1K 因子的 10% 奖励负向单模型反馈仅设置LoserModel评分减少K × 0.1K 因子的 10% 惩罚单模型反馈模式applyWinnerOnlyFeedbackLocked/applyLoserOnlyFeedbackLocked专门服务于只知道单个模型表现好坏、没有对照模型的自动信号式反馈场景例如基于信号检测的隐式反馈elo.go。反馈对象Feedback结构体定义于 selector.go支持Query、WinnerModel、LoserModel、Tie、DecisionName、UserID、SessionID、FeedbackType、Confidence等字段其中UserID可用于按用户个性化学习。3. 分类加权Category-WeightedEloConfig.CategoryWeighted默认开启DefaultEloConfig中置为true。开启后EloSelector内部维护两套评分表全局评分globalRatings与按决策分类区分的categoryRatingsdecision name → model → rating反馈会同时更新两套评分elo.go。这意味着同一模型在不同类型请求如代码生成与数学推理下可以有各自独立的评分路由决策更具针对性。InitializeFromConfig还可以把配置中已有的静态 ModelScores0-1 区间线性映射到 Elo 评分区间1000 score × 1000即 1000-2000作为冷启动先验elo.go。4. 选择器工厂注册在 src/semantic-router/pkg/selection/factory.go 中当配置method: elo时工厂会调用NewEloSelector(f.cfg.Elo)创建选择器并注册到Registry选择器接口Selector定义于 selector.go统一暴露Select/Method/UpdateFeedback等接口。配置详解原文档给出的配置结构如下它对应真实配置中decision.algorithm部分的elo算法块decision: algorithm: type: elo elo: k_factor: 32 # How quickly ratings change (16-64 typical) initial_rating: 1500 # Starting rating for new models storage_path: /data/elo-ratings.json # Persist ratings auto_save_interval: 1m # Save frequency models: - name: gpt-4 backend: openai - name: gpt-3.5-turbo backend: openai - name: claude-3-opus backend: anthropic对照 src/semantic-router/pkg/config/selection_config.go 中EloSelectionConfig的定义完整的elo配置块支持以下全部参数参数默认值说明initial_rating1500新模型的起始评分k_factor32评分变化速率16-64 为典型区间category_weightedtrue是否启用按分类decision区分的评分decay_factor0.0对历史比较施加的时间衰减0-10 表示不衰减min_comparisons5评分被认为是稳定所需的最小比较次数也用于置信度计算cost_scaling_factor0.0成本考虑因子0 完全忽略成本storage_path空评分持久化文件路径如/var/lib/vsr/elo_ratings.json不设置则仅存内存auto_save_interval30s自动保存频率仅当设置storage_path时生效这些默认值在 elo.go 的DefaultEloConfig()中定义InitialRating: 1500、KFactor: 32、CategoryWeighted: true、DecayFactor: 0、MinComparisons: 5、CostScalingFactor: 0。代码中对应的常量DefaultEloRating 1500.0、EloKFactor 32.0位于同一文件顶部elo.go。注意原文档中的auto_save_interval: 1m与代码默认 30s 都合法实际以配置为准resolveAutoSaveInterval会对非正数等非法值做防御性回退。模型清单部分的name/backend声明用于确定候选模型池若模型在 配置的 ModelParams 中带有Pricing.PromptPer1M单价信息InitializeFromConfig还会将其作为成本表注入选择器供成本调节使用。提交反馈驱动评分更新的入口反馈通过 API 提交原文档给出的接口示例如下# Positive feedback (model performed well) curl -X POST http://localhost:8080/api/v1/feedback \ -H Content-Type: application/json \ -d { request_id: req-123, model: gpt-4, rating: 1 } # Negative feedback (model performed poorly) curl -X POST http://localhost:8080/api/v1/feedback \ -H Content-Type: application/json \ -d { request_id: req-456, model: gpt-3.5-turbo, rating: -1 }需要注意的是文档中的反馈 API 是面向网关部署形态的示例入口在库的源码层面驱动评分更新的真正接口是EloSelector.UpdateFeedback(ctx, *Feedback)。对照 selector.go 中Feedback的字段设计一个完整的成对比较反馈更贴近底层语义大致对应feedback : Feedback{ Query: translate this paragraph, WinnerModel: gpt-4, LoserModel: gpt-3.5-turbo, Tie: false, DecisionName: translation, // 分类加权时指定决策上下文 } selector.UpdateFeedback(ctx, feedback)正向/负向单模型反馈则只需设置WinnerModel或LoserModel其中之一对应 API 中rating: 1/rating: -1的语义。查看当前评分curl http://localhost:8080/api/v1/ratings响应示例{ ratings: { gpt-4: 1632, gpt-3.5-turbo: 1485, claude-3-opus: 1558 }, last_updated: 2024-01-15T10:30:00Z }在库内部EloSelector.GetLeaderboard(category)提供了等价的能力按评分降序返回[]*ModelRating可指定分类空分类则返回全局榜单每个ModelRating还携带Comparisons、Wins、Losses、Ties统计信息elo.go。持久化文件的 JSON 结构StoredRatings也包含version、last_updated、global_ratings与category_ratings字段storage.go与上述响应结构一致。K 因子调优K 因子决定单次反馈对评分的扰动幅度是系统学习速度的总开关K-Factor行为特征适用场景16缓慢、稳定的变化反馈一致的成熟系统32均衡默认值大多数生产环境64快速、剧烈变化快速实验、新部署期从源码实现看K 因子还影响单模型反馈的步长K × 0.1因此调整k_factor会同时缩放两种反馈模式的更新幅度。建议从默认值 32 开始观察一段时间评分演化后再决定是否调整。持久化存储开启storage_path即可让评分跨重启持久化elo: storage_path: /data/elo-ratings.json auto_save_interval: 1m原文档说明该文件具备原子写安全与备份轮转能力这在 src/semantic-router/pkg/selection/storage.go 中有完整的实现佐证原子写saveToFile先写入elo-ratings.json.tmp临时文件再通过os.Rename原子重命名替换正式文件避免写一半导致损坏storage.go自动保存StartAutoSave启动后台 goroutine通过 ticker 周期性检查dirty标志MarkDirty置位仅在评分确实变化时才落盘关闭时执行最后一次最终保存storage.go损坏备份读取时若发现文件损坏会把原文件备份为elo-ratings.json.corrupted后再报错防止现场丢失storage.go数据清洗sanitizeRatings会把异常评分钳制在 100-3000 区间、清除非负统计值防御脏数据storage.go存储接口抽象EloStorage接口LoadRatings/SaveRatings/LoadAllRatings/SaveAllRatings/Close支持文件与内存测试用MemoryEloStorage两种后端便于替换storage.go。启动时NewEloSelector会通过loadFromStorage把文件中的全局评分与分类评分一并载入内存elo.go。可观测性与测试验证EloSelector通过 src/semantic-router/pkg/selection/metrics.go 中的 Prometheus 指标暴露演化过程包括model_elo_ratingGauge当前评分、model_feedback_totalCounter反馈次数以及选择相关的耗时/得分/置信度指标便于监控评分漂移与模型支配情况。仓库测试 src/semantic-router/pkg/selection/selector_elo_test.go 验证了算法的收敛行为模拟 strong-model 分别击败 medium-model、weak-model且 medium-model 击败 weak-model共 10 轮30 次成对反馈后断言strong medium weak的评分次序成立strong-model应累计 20 胜、weak-model应累计 20 负且GetLeaderboard返回的榜单前三名顺序正确——这为反馈越多排名越可靠提供了可执行的验证路径。相关生命周期与持久化行为还可参考 storage_test.go。最佳实践收集一致的反馈确保反馈真实反映输出质量避免噪声数据干扰评分从默认 K 因子起步先观察行为再调整不要一上来就用激进参数启用持久化避免重启丢失已积累的评分配置storage_pathauto_save_interval监控评分漂移留意是否有模型被不公平地长期支配可借助model_elo_rating等指标用先验引导冷启动若已知模型的历史质量可通过InitializeFromConfig的静态 ModelScores 映射或直接设置initial_rating初始化评分让新模型从合理起点开始学习善用分类加权请求类型差异明显的场景建议保持category_weighted: true让每个决策维度拥有独立的评分体系配合成本因子多模型成本差异较大时可设置cost_scaling_factor让评分在质量与成本之间取得平衡。总结Elo 评分选择为 Semantic Router 提供了一条反馈即学习、零训练成本的在线路由路径以 Bradley-Terry 成对比较为数学内核以EloSelector为运行时载体通过UpdateFeedback消费用户反馈并持续刷新全局与分类两套评分最终在每次请求到来时把流量导向当前评分最高的模型。它区别于 RouteLLM 等静态预训练路由器的地方在于——路由策略本身随线上反馈实时演化。结合原子写持久化、自动保存、损坏备份、Prometheus 指标与收敛性测试这套实现可以独立、安全地嵌入生产网关作为多模型调度决策层的一个稳定算法选项。进一步阅读可关注 elo.go、selection_config.go 与 storage.go 三份核心文件。赞分享后端API网关模型推理服务AI Agent【免费下载链接】semantic-routerAn open, programmable decision layer for models and compute.项目地址https://gitcode.com/gh_mirrors/sem/semantic-router点击查看免费下载相关推荐semantic-router 的 Elo 选择算法基于反馈评分驱动的模型路由实践指南semantic router 的 Elo 选择算法基于反馈评分驱动的模型路由实践指南 导读 本文围绕 semantic router 提供的 elo 模型选后端API网关模型推理服务AI Agentsemantic-router 中的 Elo 评分模型选择运行时在线学习选路算法实现指南semantic router 中的 Elo 评分模型选择运行时在线学习选路算法实现指南 本文围绕 semantic router 的 Elo Rating后端API网关模型推理服务AI Agentsemantic-router 的 GMT Router 算法实战基于多轮用户反馈的个性化模型选择semantic router 的 GMT Router 算法实战基于多轮用户反馈的个性化模型选择 gmtrouter 是 semantic router 中后端API网关模型推理服务AI Agent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑