vLLM Semantic Router:给 Agent 一个 API,把一群模型变成一支队伍
vLLM Semantic Router:给 Agent 一个 API,把一群模型变成一支队伍
现在的 Agent 应用基本都卡在同一道题上:手里有好几个模型,但不知道该把每个请求发给谁。便宜的小模型扛不住复杂推理,最强的大模型发一条"你好"也肉疼;本地模型保隐私但能力有限,云端 API 又要考虑成本和数据出不出得去。结果就是一堆 if/else 硬编码在业务里,改一次模型得动一次上线。
vLLM Semantic Router(简称 vLLM SR)想把这层决策从代码里抽出来。它的定位一句话说明白:"Intelligence beyond any one model."——一个开源的、可编程的决策层,站在 Agent 和一堆模型后端之间。你的 Harness 只管发请求,路由交给它。
这是 vLLM 项目组的新作,Apache 2.0 开源,用 Go 写(Go 1.25)。生态里能看到 AMD、Intel、NVIDIA、微软、Red Hat、IBM、Hugging Face 这些名字。它不光在 GitHub 上火——配套的 Decision 2.0 模型系列在 2026 年 10 月 6 日一度冲上 Hugging Face Trending Collections 第一。
目录
- 一、一个 API,后面站着一群模型
- 二、它解决的到底是什么问题
- 三、架构:数据面、控制面和一个 ExtProc
- 四、路由流水线:从"信号"到"模型池"
- 五、核心对象:Entrypoint、Recipe、Decision
- 六、Mixture of Models:MoM 不是 MoE
- 七、四种部署场景,五种路由模式
- 八、跑起来
一、一个 API,后面站着一群模型
用起来的感受很简单:你的 Harness 里还是那套 OpenAI 或 Anthropic 的调用,只是把 model 换成一个虚拟名字,比如 vllm-sr/auto:
curl -s -D - http://localhost:8899/v1/chat/completions \
-H 'Content-Type: application/json' \
-H 'x-vsr-debug: true' \
-d '{
"model": "vllm-sr/auto",
"messages": [{"role": "user", "content": "Hello!"}]
}'vllm-sr/auto 的意思是"你来挑"。返回的响应头会告诉你它选了什么:x-vsr-selected-decision 是命中的路由名,x-vsr-selected-model 是最终选的模型;加上 x-vsr-debug: true,还会有一串 x-vsr-matched-* 头列出触发了哪些信号。
它同时兼容 OpenAI Chat Completions、OpenAI Responses、Anthropic Messages 三种线格式。也就是说,现有 Harness 不用重写,把 base URL 指过来就行。
关键在于边界划得很清楚:Harness 保留 agent 循环、工具执行和任务状态;Router 只负责"这一次调用该给谁"。模型换了、策略变了,Harness 那一侧零改动。
二、它解决的到底是什么问题
官方给了一张很实在的对照表,把"今天碎片化的痛点"和"接入后"摆在一起:
| 维度 | 如今的碎片化 | 用了 vLLM SR |
|---|---|---|
| 模型 | 不同模型擅长不同任务 | 选择,或组合多个模型 |
| 算力 | 硬件快慢、容量各不相同 | 在已配置的后端之间挑选 |
| 位置 | 边缘、私有、云端混着放 | 让调用留在被批准的范围内 |
| 偏好 | 优先级随任务变 | 自己设质量、延迟、成本的权重 |
一句话概括:把"选模型"这件事,从每个 Harness 的代码里,搬到一份共享的策略里。一次调用需要快的本地模型,另一次需要更长的上下文或跨模型验证——能力、延迟、成本、信任度都随请求、用户、会话和可用基础设施变化,靠硬编码根本跟不上。
三、架构:数据面、控制面和一个 ExtProc
它把自己定位成一个决策层,请求怎么流、配置怎么管,分得很清楚。
数据面处理请求:
- Agent Harness:拥有任务循环、工具执行和持久化任务状态,每次推理调用都要穿过 Router 边界。
- Envoy:接收客户端流量,通过 External Processing(ExtProc) 协议把请求交给 Router,再把处理后的请求转发到上游。
- Semantic Router:抽取信号、评估策略、施加路由专属行为、选择或协调模型候选。
- Backends:已配置的模型服务或厂商端点——Router 不加载它们的模型权重。
控制面负责配置和运维:一份可移植的 Canonical YAML 是路由行为的事实来源;Entrypoint 把公开模型别名映射到 Recipe;Recipe 是一整套策略与运行时状态的隔离边界;CLI 和 Dashboard 做本地搭建与运维;Helm 和 Operator 负责把它部署进 Kubernetes;评估与可观测性则让运维能测试和改策略。
这里有个值得记住的分工哲学:Router 不替代后端调度器。它只管"选哪一类模型",至于"选这个模型的哪个健康副本",那是 Inference Router 的事。所以一个完整请求可能穿过三层路由:
Agent Harness
-> AI Gateway (LiteLLM / agentgateway / Agent Router)
-> Semantic Router (ExtProc,选"逻辑模型")
-> Inference Router (llm-d / vLLM Router / AIBrix,选"物理副本")
-> model replica三层的职责互不重叠:AI Gateway 管入口、凭证、限流;Semantic Router 管"按意图和策略选哪个逻辑模型",选完写进 x-selected-model;Inference Router 管池子内部的副本选择。
四、路由流水线:从"信号"到"模型池"
真正让这套东西"可编程"的,是它的流水线设计。一次被路由的调用会依次经过几个阶段:
graph LR
A["Harness call"] --> B["Signals"]
B --> C["Projections"]
C --> D["Decisions"]
D --> E["Algorithms"]
E --> F["Model pool"]
F --> G["Plugins"]
G --> H["Response"]- Signals(信号):回答"我们知道什么"。有的确定性强,比如关键词、元数据谓词、上下文长度区间;有的用 embedding 或分类模型,识别语义意图、领域、复杂度、PII、越狱企图。信号只描述事实,不选后端,同一个信号能被一个 Recipe 里的多个 Decision 复用。
- Projections(投影):回答"证据怎么合起来"。partition 在重叠命中里选出唯一赢家,score 把加权输入合成一个分,mapping 把分数映射成命名的路由档位。比如"领域证据"形成一个互斥的领域分区,"复杂度 + 上下文 + 验证"形成一个难度分数。
- Decisions(决策):回答"哪条路由合格"。用布尔规则把信号和投影结果组合起来,优先级策略决定谁胜出,并给出候选模型、可选算法和路由内的插件。硬性要求都放在这一层显式表达——授权、仅本地处理、模态、上下文容量、工具兼容性,都应该在比较成本延迟之前就先决定一条路由合不合格。
- Algorithms(算法):回答"选哪个候选/怎么跑"。选择型算法用固定顺序、语义匹配、延迟、反馈挑一个;Looper 型算法用级联(cascade)、评审团(panel)、多轮或工作流协调多次调用。只有一个候选时,最简单的静态行为往往就是对的。
- Plugins(插件):施加路由专属行为,比如改请求参数、上下文压缩、检索、记忆、回放、响应缓存、响应控制。注意区分检测与执行:PII 信号只是"报告命中",到底拦截、改路、改写还是仅观察,取决于 decision 和插件策略。
- Model pools(模型池):把逻辑模型名绑到物理推理端点,池里可以混着本地 vLLM、Ollama、K8s 里的模型和远程 OpenAI 兼容服务。
这套设计的核心价值是复用与隔离:多条策略能复用同一个信号,策略可以独立于模型选择去改,而公开的 Entrypoint 背后,物理模型池可以随便演进。
五、核心对象:Entrypoint、Recipe 和 Decision
配置里反复出现几个概念,理清它们基本就懂了一半:
| 对象 | 作用 |
|---|---|
| Entrypoint | 一个或多个公开模型别名到某个 Recipe 的映射 |
| Recipe | 一整套路由策略与运行时状态的隔离边界 |
| Signal | 关于请求/身份/会话/内容的一条命名事实 |
| Projection | 从信号派生的可复用分数、分区或档位 |
| Decision | 选择合格路由与候选集的一条策略规则 |
| Plugin | 路由专属处理:请求控制、记忆、检索、响应处理 |
| Algorithm | 选择或协调模型候选的方法 |
| Provider model | 可供一个或多个 Recipe 使用的物理推理端点 |
一个 Entrypoint 选中一个 Recipe,这个 Recipe 独占自己的信号、投影、决策、算法、插件、缓存命名空间和路由状态。Provider、存储、Router 自带模型资产可以共享,但一个 Recipe 的策略不会泄漏到另一个。物理模型名直接透传时,会绕过信号、决策、插件、缓存、学习和会话路由——想直连就用真名,想让 Router 掌舵就用虚拟名。
配置长这样:
entrypoints:
- model_names: ["acme/assistant-fast"]
recipe: fast
recipes:
- name: fast
routing:
strategy: priority
decisions:
- name: default-fast-route
description: Route eligible requests through the fast model pool.
priority: 10
rules:
operator: AND
conditions: []
modelRefs:
- model: local/small
use_reasoning: false
- model: local/vision
use_reasoning: false
algorithm:
type: static六、Mixture of Models:MoM 不是 MoE
这是它主推的一个概念,也很容易被误解。Mixture of Models(MoM) 指的是:把一组独立部署的模型,对外呈现为一个虚拟模型。一个 Recipe 针对每次请求选出一个模型、一条级联、一个评审团或一条有界工作流。你的 Harness 只认一个稳定名字,任务循环和工具都还归自己。
它和 MoE(Mixture of Experts) 完全是两码事:
- MoE 是模型架构:一个 checkpoint 内部靠门控机制,在推理时激活一部分专家。
- MoM 是服务系统架构:训练独立、部署独立的模型,在请求时被选中或协调。
所以 MoM 底下可以混着 dense 模型、MoE 模型、托管 API 和本地模型——它们内部架构是什么,不影响路由抽象。
系统里其实有三种"模型",别混:
| 类型 | 例子 | 角色 |
|---|---|---|
| Provider model | vLLM / Ollama / 托管端点 | 真正生成推理响应 |
| Virtual model | vllm-sr/mom-v1-flash |
给客户端一个稳定目标,选中一个 Recipe |
| Router system model | embedding / 分类模型资产 | 帮路由检测意图、风险、相似度等信号 |
执行上有三种模式:选一个(大多数请求走直路)、级联(先用高效模型,检查置信度信号,必要时才升级——用最坏情况延迟换更低的平均成本)、协调多模型(并行比较、多轮推理、工作流,只给少数高精度任务用,不做默认)。
MoM V1 内置了五个 Recipe,按你的诉求挑:
| 公开模型 | Recipe | 决策 |
|---|---|---|
vllm-sr/mom-v1-blend |
Balance:日常质量、延迟、成本平衡 | simple, medium, reasoning |
vllm-sr/mom-v1-lite |
Cost:经济优先,定向升级 | economy, tools, reasoning |
vllm-sr/mom-v1-flash |
Speed:响应快、适合流式对话 | fast, tools, reasoning |
vllm-sr/mom-v1-ultra |
Accuracy:强答案 + 显式编排 | simple, reasoning, review, agent |
vllm-sr/mom-v1-vault |
Vault:全程在你私有部署内处理 | private, sensitive, guard |
其中 Vault 最值得一说:它在每条路径上都关掉客户端工具和 Router 内容存储,guard 决策会当场拦住提示词攻击。它的 Guard 和 PII 跑在默认的 Vela 2.0 0.3B 上(读 8192 token,超了截断),Hazard 任务有 32768 token 的分诊预算,超预算直接 fail closed——预览返回 HTTP 503,且不选任何模型,哪怕后端上下文窗口更大也不放宽。这是典型的"安全优先,宁可拒绝"的取舍。
七、四种部署场景,五种路由模式
它把落地场景拆成四类,各有各的典型难题:
| 场景 | 典型问题 | Router 决定什么 |
|---|---|---|
| Cloud | 各家 API 能力、成本、延迟、可用性都不同 | 由哪个被批准的 provider / 虚拟目标来处理 |
| Data center | 一个共享加速器机队服务各有所长的模型 | 哪类模型池更贴合任务、策略和目标 |
| Edge | 容量有限,数据可能要留在本地或离线可用 | 本地路径够不够用、是否允许升级到远程 |
| Enterprise hybrid | 负载跨租户、区域、信任区 | 在身份、驻留、能力、策略下哪些路径合格 |
横跨所有场景的有五种通用模式:能力路由(先按模态/上下文/工具/语言排除不合格的模型)、专家路由(用语义和确定性信号把代码、数学、研究等导向合适的池子)、目标式虚拟模型(对外稳定名字,对内随便演进)、有界恢复与编排(只在额外调用有可衡量价值时才升级/比较/走工作流)、以及最关键的一条——策略优先路由:在优化算法给剩余候选排名之前,先把授权、位置、数据处理、能力这些硬约束卡掉。
官方的建议也很有分寸:先从简单的决策和静态选择开始,只有当一个信号或算法真的改变了观测到的路由结果,才把它加上去;生产策略变更前,先用探针请求验证代表性流量。它还专门提醒:如果单一后端就够用、策略也不太会变,那就别上 MoM——多模型系统会带来配置、评估、可观测性和运维成本。
八、跑起来
vllm-sr serve 会在 Docker 里跑起一个本地栈:Router(自己提供 OpenAI 兼容 API,默认 standalone 模式跑在 8899 端口)、Dashboard(8700)、以及运行 Router 自带分类器和 embedding 模型的 model runtime。真正回答用户请求的模型跑在别处——Ollama、vLLM 服务或托管 API——你在 Dashboard 里把它们接上。
安装方式任选:
# curl 一键
curl -fsSL https://vllm-sr.ai/install.sh | bash -s -- --channel stable
# pip
python3 -m venv .venv && source .venv/bin/activate
python -m pip install --upgrade vllm-sr
# uv
uv tool install vllm-sr也可以用"Agent 装":把官方给的一段提示词丢给编码 Agent,它会按公开的自包含 skill(https://vllm-sr.ai/install/agent/vllm-sr/SKILL.md)自动完成安装、配置和验证。
装完启动、进 Dashboard 配好第一个管理员、接一个模型、选路由(From scratch 会建一条指向该模型的默认路由),Review 后 Activate,Router 就从这份配置起来了。之后运维就几条命令:
vllm-sr status # 在看什么、是否需要重启
vllm-sr logs router -f # 跟 Router 日志
vllm-sr stop有两点容易踩:
- 硬件:纯 CPU 也能跑,自带模型都跑在 CPU 上,每个 307M 任务模型大约吃 1.3 GB 内存;AMD Instinct MI300X/MI325X 要 ROCm 驱动并
--platform rocm;NVIDIA 需要 Container Toolkit 和--platform cuda(可用但尚未完全验证);macOS 上 Docker 目标只跑 CPU。 - 渠道:官网文档跟的是
main分支,standalone 模式和内置 model runtime 是vllm-sr0.4.0 之后的特性。想跟着文档走,curl 安装时加--channel dev(当前稳定版 0.4.0 还是把 Envoy 放在 Router 前面、没有--gateway选项)。
想先感受一下,可以直接去在线 playground:https://app.vllm-sr.ai/playground,账号 love@vllm-sr.ai,密码 vllm-sr-read。
说回本质。vLLM Semantic Router 不是"又一个模型",也不是"又一个网关"——它把**"这一次请求该给谁"**做成了一个显式的、可版本化、可评估的策略层。对正在把 Agent 推向生产的团队来说,这可能比再多接一个模型更有价值:模型会一直换,而"怎么选"这套逻辑,终于可以只写一遍了。
作者: itech001 来源: 公众号:AI人工智能时代(the-ai-era) 网站: https://www.theaiera.top/ 关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top
本文首发于 AI人工智能时代,转载请注明出处。