OmniRoute:统一接入 AI 模型与编码工具
同一台开发机上同时使用 Codex、Claude Code 和 Cursor 时,模型接入很快会变成重复劳动:每个工具都要保存不同的 Base URL 和密钥,某个提供商限流后还得手工换模型,用量则散落在多个控制台。OmniRoute 把这层工作收拢到运行在本机或自有服务器上的统一网关。客户端只连接一个地址,网关再按指定模型、自动策略或自定义组合路由(Combo)选择已经接入的上游。
这种统一并没有把所有 AI 推理搬到本地。OmniRoute 自身负责认证、路由、回退和用量观察;提示词与工具上下文仍会发送给最终选中的模型提供商。OmniRoute 的准确定位是个人或小团队可控的 AI 接入层,而非“离线模型运行器”。
GitHub 仓库信息
| 信息 | 内容 |
|---|---|
| 项目标题 | OmniRoute |
| 项目描述 | 一个采用 MIT 许可证的 AI 网关,通过统一端点连接多种模型提供商和编码工具,并提供配额感知路由与自动回退。 |
| GitHub 仓库 | diegosouzapw/OmniRoute |
| 官网地址 | https://omniroute.online |
| 主要开发语言 | TypeScript 94.89%,另含 JavaScript、Shell、Python 和 Dockerfile |
| 开源许可证 | MIT |
| 最近代码更新 | 2026-09-07(GitHub pushed_at,核对日期:2026-09-08) |
项目定位
OmniRoute 的核心接口兼容 OpenAI、Anthropic 和 Gemini 的常见调用形态。对于客户端而言,主要变化只有两项:把请求地址改为 OmniRoute,把认证信息改为 OmniRoute 签发或接受的 Key。模型提供商(Provider)的真实凭据、健康状态和模型选择留在 Dashboard 管理。
统一 API 是 OmniRoute 的主干,Dashboard 用于配置和观察,编码工具、自建脚本或兼容 SDK 都能共用同一个接入层。网关只有在候选池中还存在凭据有效、健康且有额度的连接时,才能把失败请求送到下一个目标。接入多个名称不同但实际共享同一额度池的连接,也不会增加真实可用额度。
安装方式
使用 npm
固定提交中的 package.json 将 Node.js 版本限制为 >=22.22.2 <23 || >=24.0.0 <27。新环境优先选择 Node.js 24 LTS,避免使用不在范围内的 Node 23。确认版本后安装全局命令并启动:
node --version
npm install -g omniroute
omniroute --version
omniroute不带版本号的 npm install -g omniroute 会安装 npm 注册表当时的默认发布版本,不保证等于本文分析的源码版本 3.8.51。安装后先记录 omniroute --version;需要可重复环境时,在 npm 确认目标版本存在后使用 npm install -g omniroute@<verified-version> 固定版本。
仓库文档给出的默认 Dashboard 地址是 http://localhost:20128,兼容 API 的基础地址是 http://localhost:20128/v1。命令启动后,至少确认页面能打开,再继续添加 Provider。本次研究没有查询 npm 注册表、执行安装命令或启动 OmniRoute;这里描述的是固定提交中的官方使用路径,包版本需要单独核验。
使用 Docker
只想运行已经构建的镜像时,可以把服务限制在回环地址,并用具名卷保存数据:
docker run -d \
--name omniroute \
--restart unless-stopped \
--stop-timeout 40 \
-p 127.0.0.1:20128:20128 \
-v omniroute-data:/app/data \
diegosouzapw/omniroute:<verified-version><verified-version> 必须替换为镜像仓库中已经存在并经过验证的具体标签,同时记录镜像摘要。README 原始示例使用 latest,但 latest 会随发布变化;本文也没有核验 3.8.51 镜像标签,因此不把源码分支版本直接写成可用镜像版本。
项目 README 对内存给出了工作负载建议:Dashboard 和轻量聊天场景使用 1024 MB Node heap 时,容器至少准备 2 GB;单个编码 Agent 建议设置 OMNIROUTE_MEMORY_MB=8192,容器至少准备 10 GB。这些数字来自项目文档,不是本文的性能实测。
仓库还提供多 profile 的 Compose 文件,包含 Web Provider、容器内 CLI、语义记忆等扩展。第一次使用没有必要全部打开。尤其是 cli profile 会挂载 /var/run/docker.sock,这近似于把宿主 Docker 控制权交给容器,只应在可信的单租户机器上理解风险后启用。
第一次有效调用
这条路径的目标不是只看到 Dashboard,而是让一个请求经过 OmniRoute 到达上游,并能从响应或 Dashboard 中找到路由结果。
1. 连接一个 Provider
启动后打开 Dashboard,在 Providers 中连接一个自己有权使用的提供商。README 声称新安装可通过 OpenCode Free 免认证调用,但免费服务的可用性、区域、模型和额度都会变化。稳定使用应添加自己的合法 Provider,并确认连接状态和默认模型。
随后在 Dashboard 的 Endpoints 或 API Keys 页面创建 OmniRoute Key。即使只在本机试用,也建议从一开始使用 Key,这样迁移到局域网或服务器时不会依赖匿名访问。
2. 确认模型目录
把占位值替换为 Dashboard 生成的 OmniRoute Key:
export OMNIROUTE_API_KEY="YOUR_OMNIROUTE_KEY"
curl http://localhost:20128/v1/models \
-H "Authorization: Bearer $OMNIROUTE_API_KEY"成功信号是返回可调用的模型列表,而不是 401 或空的错误页。如果这里失败,先区分 OmniRoute Key 是否无效,再检查 Provider 自身的 OAuth 或 API Key,不要同时重配两层认证。
3. 完成一次对话
curl -i http://localhost:20128/v1/chat/completions \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"messages": [
{"role": "user", "content": "用一句话解释这个网关的作用"}
]
}'一次完整成功应同时看到 HTTP 2xx 和有效 completion 正文。-i 会显示响应头,可以继续检查 request id 与 X-OmniRoute-Decision 等诊断信息;Dashboard Usage 用于核对这次请求记录,Dashboard Health 用于查看 Provider 健康状态。把请求记录、连接健康和路由头分开观察,才能定位响应来自哪条路径。
接入编码工具
OmniRoute 提供两种接法。临时运行适合先验证,不写入客户端配置;setup-* 适合把验证过的连接保存下来。
临时运行
先用 --dry-run --json 检查将要注入的环境变量和参数:
omniroute run codex --model <provider>/<model> --dry-run --json
omniroute run codex --model <provider>/<model>
omniroute run claude --model <provider>/<model> --dry-run --json
omniroute run claude --model <provider>/<model><provider>/<model> 是占位值,应从 Dashboard 的模型目录选择。--dry-run 用于预览,不代表目标 CLI 已成功调用模型;去掉该选项并在 CLI 中完成一次真实请求后,才算接入闭环。
持久配置
omniroute setup-codex --dry-run
omniroute setup-codex
omniroute setup-claude --dry-run
omniroute setup-claude静态阅读集成文档显示,Codex 配置写入 ~/.codex/<name>.config.toml,Claude Code profile 写入 ~/.claude/profiles/<name>/settings.json,OpenCode 使用 ~/.config/opencode/opencode.json。这些命令会修改用户配置,因此应先查看 dry run,并备份已有的同名 profile。
Cursor 的配置保存在不透明的 SQLite 数据中。setup-cursor 只输出手工配置步骤,不应直接改写 Cursor 数据库。Cursor、Continue、Kilo 等 OpenAI 兼容客户端通常填写:
Base URL: http://localhost:20128/v1
API Key: YOUR_OMNIROUTE_KEY
Model: auto 或准确的 provider/modelClaude Code 是最常见的地址误区。ANTHROPIC_BASE_URL 使用根地址 http://localhost:20128,不要追加 /v1;Codex 和大多数 OpenAI 兼容客户端则使用 http://localhost:20128/v1。优先让 setup-* 生成配置,可减少这类协议差异造成的 404。
自动路由与 Combo
在请求中把 model 写成 auto 时,OmniRoute 会读取当前启用的连接、凭据、模型目录、健康和配额信息,临时构造候选池并评分。这个候选池按请求生成,不需要先保存一条 Combo,也不会自动采用用户已经保存的 Combo。
| 模型值 | 选择倾向 | 使用判断 |
|---|---|---|
auto | 默认平衡,优先最近成功路径 | 不确定从哪个模型开始时使用 |
auto/coding | 更偏向代码任务质量 | 编程、重构和代码解释 |
auto/fast | 更偏向低延迟 | 交互补全或短问答 |
auto/cheap | 更偏向低成本 | 批量、可容忍质量波动的任务 |
auto/offline | 更偏向剩余额度和可用余量(headroom) | 想优先利用有余量的连接,不代表本地离线推理 |
auto/smart | 更偏向质量并增加探索 | 允许路由器尝试更优候选 |
auto/lkgp | 明确选择最近成功路径 | 希望优先复用已验证连接 |
auto/offline 中的 offline 是路由权重包名称,文档描述的重点是配额余量。只要最终目标是云端 Provider,请求内容仍会离开本机。
自定义 Combo 用于明确控制候选顺序、回退和路由策略。创建后,请求中的 model 必须填写 Combo 的准确名称。不要创建名为 auto 的持久 Combo,官方文档明确不推荐这种命名冲突。
分类和层级过滤采用失败时放行(fail-open):没有候选匹配时,系统可能回退到完整候选池。这项行为优先保证可用性,不提供严格的成本边界。若“不得使用付费模型”是硬要求,必须从候选池中排除付费 Provider 和模型;预算只能作为附加保护,还要用实际请求验证 fail-open 后的选择结果,不能只依赖 auto/cheap 或分类标签。
管理 Provider 和模型
日常管理可以按“连接、模型、策略、观察”四个对象排查:
- 连接保存某个 Provider 的 API Key、OAuth 或会话信息,并暴露健康与额度状态。
- 模型目录决定客户端可以使用的模型标识,以及某个连接默认指向哪个模型。
- 路由策略决定多个可用候选如何排序;Combo 则为一组候选保存更明确的编排。
- Usage、Health、请求 ID 和路由决策头用于解释一次请求最后去了哪里。
免费 Provider 返回 429、401 或模型不支持导致的 400 并不罕见。回退策略可以降低一次故障的影响,但不能替代合法凭据、额度管理和服务条款核对。使用网页会话或 OAuth Provider 时,还要确认账号共享、自动化访问和组织安全策略是否允许这种接入方式。
安全地远程使用
.env.example 的本地默认包含 REQUIRE_API_KEY=false。这对回环地址上的首次启动方便,却不适合作为公网配置。远程暴露前至少完成以下调整:
- 开启客户端 API Key 校验,并在 Dashboard 设置登录保护。
- 使用 TLS 反向代理,只开放必要的 API 和 Dashboard 入口。
- 限制来源 IP、VPN 或私有网络范围,管理接口采用更严格的入口策略。
- 为普通推理和管理分别签发 Key;只有确实需要管理 API 的调用方才授予
managescope。 - 检查反向代理、应用日志和监控中是否记录请求正文、认证信息或 URL 查询参数。
OmniRoute 把路由分成三类。PUBLIC 是显式列入公开清单的登录、状态、初始化和只读健康路径;CLIENT_API 覆盖 /v1/* 等模型接口,在有效开启 REQUIRE_API_KEY 时要求 Bearer Key;MANAGEMENT 覆盖 Provider、Key 和设置管理,要求 Dashboard session 或带管理作用域(manage scope)的 Key。无法分类的路径会按 MANAGEMENT 处理,这是默认拒绝(fail-closed)的安全策略。
认证信息优先放在 Header:
Authorization: Bearer YOUR_OMNIROUTE_KEYURL token 兼容方式只留给无法发送 Header 的客户端,因为 URL 可能进入浏览器历史、代理访问日志和遥测系统。普通推理 Key 与管理 Key 也不应混用;一旦普通客户端泄露带 manage scope 的 Key,影响范围会从模型调用扩大到配置管理。
数据、日志与备份
OmniRoute 的本地优先意味着配置和主要控制面由自己保管,同时也把数据治理责任交给部署者。本地 SQLite、数据目录和日志可能包含 Provider 信息、用量、提示词片段或故障上下文,应纳入以下运维动作:
- 限制数据目录的操作系统权限,不把卷备份上传到公开位置。
- 需要静态加密时,按
.env.example使用STORAGE_ENCRYPTION_KEY,并把密钥与备份分开保存。 - 保留升级前备份,定期验证恢复流程,而不只确认备份文件存在。
- 通过
APP_LOG_TO_FILE=true明确启用文件日志后,再设置轮转、保留周期和访问权限。 - 删除或脱敏用于排障的请求样本,避免把真实业务提示词粘贴到公开 Issue。
上游 Provider 仍能看到收到的请求。敏感代码、客户数据或内部文档是否允许发给某个模型,取决于 Provider 条款、企业协议、区域要求和自身数据分类,不能由“网关运行在本地”代替这项判断。
常见问题
安装完成但无法启动
先执行 node --version 并对照项目的 engines 范围。Node 版本不匹配可能表现为登录页异常或原生模块加载失败。npm 输出 ERESOLVE 或 peer dependency warning 也不必直接等同于失败;应以安装命令退出状态、omniroute 能否启动和健康接口结果为准。
macOS 若出现 better-sqlite3 ABI 或原生模块错误,项目排障文档给出的修复方式是:
cd "$(npm root -g)/omniroute/app"
npm rebuild better-sqlite3这会在全局安装目录重新构建原生依赖,需要本机具备相应编译工具。仍失败时保留完整 Node 版本和原始错误,不要反复删除数据目录。
Docker 中 localhost 被重置
先强制 IPv4 检查:
curl -4 http://localhost:20128/api/monitoring/health若 IPv6 的 localhost 解析导致连接重置,使用 127.0.0.1,并确认端口映射写成 127.0.0.1:20128:20128。健康接口可用只能说明服务存活,不能证明某个 Provider 已认证或有额度。
返回 401
401 可能来自两层。OmniRoute 自身的 401 先检查 Bearer Key、REQUIRE_API_KEY 和客户端 Base URL;Provider OAuth 或 Key 失效则到 Dashboard 查看对应连接。响应中的 request id 和路由类别头能帮助区分错误发生在网关认证还是上游调用。
返回 429 或持续回退
429 通常表示速率或免费额度耗尽。减少并发、等待额度恢复、添加另一个合法连接,或选择有余量的模型,比无上限重试更有效。自动回退在没有健康候选时也会结束,并且无法绕过 Provider 的额度和账号限制。
需要收集诊断信息
omniroute doctor
curl http://localhost:20128/api/monitoring/health配合 Dashboard Health、请求 ID 和已启用的文件日志定位问题。提交 Issue 前删除 Key、Cookie、Provider token、提示词和内部 URL;只保留复现所需的版本、操作系统、Node 版本、错误码和脱敏日志。
适用场景与替代方案
OmniRoute 更适合已经同时使用多个 AI 编码工具或 Provider,希望统一入口、路由和观察,同时愿意维护本地服务与凭据的人。小团队也可以在私有网络内共享一组受控端点,前提是团队认真配置认证、数据权限、预算和 Provider 条款。
以下场景采用成本可能高于收益:
- 只使用一个官方客户端和一个稳定 Provider,没有统一路由需求;直接使用官方 SDK 或客户端配置更简单。
- 必须在完全断网环境处理数据;应选择本地推理运行时,例如 Ollama、llama.cpp 或企业内部推理平台。
- 需要成熟的组织级策略、审计、成本归集和高可用托管;可以评估 LiteLLM、Portkey、OpenRouter 或云厂商网关,并按同一组安全与合规要求比较。
- 只想在模型之间做代码级负载均衡,不需要 Dashboard 和大量 Provider 适配;更小的 OpenAI 兼容代理可能更易维护。
采用前最有价值的下一步,是先接入两个自己确实有权使用的 Provider,用同一条测试提示分别调用准确模型、auto/coding 和一个自定义 Combo,然后对照路由决策、延迟、费用与失败表现。这个小实验比 Provider 数量或免费额度宣传更能说明 OmniRoute 是否适合自己的工作方式。
版本与验证边界
本文固定到默认分支 release/v3.8.51 的提交 fcc2dcd,package.json 版本为 3.8.51;核对时最近已发布 Release 为 v3.8.50。动态的 Provider 数量、免费额度、模型目录和节省比例没有作为稳定事实写入正文。
本次通过 GitHub API 读取仓库元数据、README、关键使用文档、根目录和选择性一级目录。递归目录树请求未完整返回,因此没有声称覆盖全部源码。没有安装依赖、执行仓库代码、启动容器、登录 Provider 或发送真实模型请求;命令、配置和排障结论属于固定提交下的静态核验,运行效果仍需在自己的环境验证。