首页
/ OmniRoute 架构全解:基于 Next.js 的统一 AI 路由网关设计解析

OmniRoute 架构全解:基于 Next.js 的统一 AI 路由网关设计解析

2026-09-08 11:24:09作者:翟萌耘Ralph

OmniRoute 是一个构建在 Next.js 之上的本地 AI 路由网关与仪表盘,对外暴露单一 OpenAI 兼容端点(/v1/*),将流量路由到多个上游提供方,并内置协议翻译、故障回退、令牌刷新与用量追踪。本文以 docs/i18n/ar/docs/architecture/ARCHITECTURE.md 为骨架(正文为英文,与 docs/architecture/ARCHITECTURE.md 为同源文档),结合仓库源码,系统拆解其分层架构、核心组件、请求生命周期、回退机制、数据模型与弹性设计。读完本文,你将能够理解 OmniRoute 如何让 Claude Code、Codex、Cursor 等 CLI 工具通过一个端点接入数百家上游,并掌握其模块化设计与故障处理思路。

Executive Summary:能力总览

OmniRoute 的核心运行时模型非常清晰:Next.js 的 app routes(src/app/api/*)同时承载仪表盘管理 API 与兼容 API,而共享的 SSE/路由核心(src/sse/* + open-sse/*)负责提供方执行、翻译、流式转发、回退与用量统计。

文档列举的核心能力包括:

  • OpenAI 兼容 API 面:面向 CLI/工具提供(当前文档版本记录 329 个提供方目录条目、89 个执行器实现模块)
  • 请求/响应跨格式翻译:在不同提供方格式之间转换
  • 模型 Combo 回退:多模型序列按顺序尝试
  • 结构化 Combo 步骤provider + model + connection,运行时按 compositeTiers 排序
  • 账户级回退:同一提供方支持多账户切换
  • 配额预检与配额感知的 P2C 账户选择:主聊天路径中按配额挑选账户
  • OAuth + API Key 提供方连接管理:23 个 OAuth 目录条目,由 21 个提供方模块支撑
  • 多模态端点:Embedding(/v1/embeddings,6 个提供方 9 个模型)、图像生成(/v1/images/generations,10+ 提供方 20+ 模型)、音频转录(/v1/audio/transcriptions,7 个提供方)、TTS(/v1/audio/speech,10 个提供方)、视频生成(ComfyUI + SD WebUI)、音乐生成(ComfyUI)、Web 搜索(/v1/search,12 个提供方)、Moderations(/v1/moderations)、Rerank(/v1/rerank
  • 推理模型支持<think>...</think> 标签解析、严格 OpenAI SDK 兼容的响应净化、角色归一化(developer→system、system→user)、结构化输出转换(json_schema → Gemini responseSchema)
  • 本地持久化:提供方、密钥、别名、Combo、设置、定价(110 个顶层 DB 模块)
  • 用量/成本追踪与请求日志
  • 可选云同步:多设备/状态同步
  • 安全与合规:IP 白名单/黑名单、Thinking Budget 管理(passthrough/auto/custom/adaptive)、全局系统提示注入、会话追踪与指纹识别、增强的按账户限流(带提供方专属 profile)、熔断器模式、防惊群互斥锁、基于签名的请求去重缓存
  • 域层与策略:成本规则、回退策略、锁定策略;Context Relay 会话交接摘要;域状态持久化(SQLite 写穿缓存);集中式策略引擎(lockout → budget → fallback)
  • 可观测性:p50/p95/p99 延迟聚合请求遥测、Combo 目标遥测(combo_execution_key / combo_step_id)、关联 ID(X-Request-Id)全链路追踪、合规审计日志(按 API Key 可退出)
  • 生态服务:MCP Server(107 个工具、32 个 scope,支持 stdio/SSE/Streamable HTTP 三种传输)、A2A Server(JSON-RPC 2.0 + SSE)、记忆系统、技能系统、MITM 代理、提示注入防护中间件、ACP 注册表
  • WebSocket 桥接/v1/ws)、GLM Thinking(glmt)一等公民 preset、混合 token 计数、模型别名自动播种(启动时 30+ 跨代理方言归一化)、带 SSRF 防护的安全出站请求、冷却感知的重试(requestRetry / maxRetryIntervalSec)、Zod 启动时运行时环境校验

说明:仓库英文版 docs/architecture/ARCHITECTURE.md 已更新至 v3.8.40(355 providers / 108 executors / 22 个 OAuth 模块),本文主体以关联文档(v3.8 系列 2026-04 快照)为准,并辅以同源更新的信息。

范围与边界

In Scope(范围内):本地网关运行时、仪表盘管理 API、提供方认证与令牌刷新、请求翻译与 SSE 流式转发、本地状态与用量持久化、可选云同步编排。

Out of Scope(范围外)NEXT_PUBLIC_CLOUD_URL 背后的云服务实现、本地进程之外的提供方 SLA/控制面、外部 CLI 二进制本身(Claude CLI、Codex CLI 等)。

仪表盘面(Dashboard Surface)

主页面位于 src/app/(dashboard)/dashboard/ 下,文档记录了以下主要路由:

  • /dashboard — 快速开始 + 提供方概览
  • /dashboard/endpoint — 端点代理 + MCP + A2A + API 端点标签页
  • /dashboard/providers — 提供方连接与凭据
  • /dashboard/combos — Combo 策略、模板、步骤式构建器、模型路由规则、手动持久化排序
  • /dashboard/costs — 成本聚合与定价可见性
  • /dashboard/analytics — 用量分析、评估、Combo 目标健康度
  • /dashboard/limits — 配额/限流控制
  • /dashboard/cli-tools — CLI 接入引导、运行时检测、配置生成
  • /dashboard/agents — 检测到的 ACP 代理 + 自定义代理注册
  • /dashboard/media — 图像/视频/音乐 Playground
  • /dashboard/search-tools — 搜索提供方测试与历史
  • /dashboard/health — 在线状态、熔断器、限流、配额监控会话
  • /dashboard/logs — 请求/代理/审计/控制台日志
  • /dashboard/settings — 系统设置标签页(general、routing、combo defaults 等)
  • /dashboard/api-manager — API Key 生命周期与模型权限

高层系统上下文

系统上下文可以用一张清晰的架构图概括(关联文档中的 Mermaid 源码):

flowchart LR
    subgraph Clients[Developer Clients]
        C1[Claude Code]
        C2[Codex CLI]
        C3[OpenClaw / Droid / Cline / Continue / Roo]
        C4[Custom OpenAI-compatible clients]
        BROWSER[Browser Dashboard]
    end

    subgraph Router[OmniRoute Local Process]
        API[V1 Compatibility API\n/v1/*]
        DASH[Dashboard + Management API\n/api/*]
        CORE[SSE + Translation Core\nopen-sse + src/sse]
        DB[(storage.sqlite)]
        UDB[(usage tables + log artifacts)]
    end

    subgraph Upstreams[Upstream Providers]
        P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/Qoder/GitHub/Kiro/Cursor/Antigravity]
        P2[API Key Providers\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA]
        P3[Compatible Nodes\nOpenAI-compatible / Anthropic-compatible]
    end

    subgraph Cloud[Optional Cloud Sync]
        CLOUD[Cloud Sync Endpoint\nNEXT_PUBLIC_CLOUD_URL]
    end

    C1 --> API
    C2 --> API
    C3 --> API
    C4 --> API
    BROWSER --> DASH

    API --> CORE
    DASH --> DB
    CORE --> DB
    CORE --> UDB

    CORE --> P1
    CORE --> P2
    CORE --> P3

    DASH --> CLOUD

开发者客户端(Claude Code、Codex CLI、OpenClaw/Droid/Cline/Continue/Roo、自定义 OpenAI 兼容客户端)统一接入 /v1/* 兼容 API;浏览器仪表盘走 /api/* 管理 API。核心的 SSE + 翻译引擎向上连接上游提供方(OAuth 类、API Key 类、兼容节点三类),向下连接本地 SQLite 数据库与用量表。可选云同步通过 NEXT_PUBLIC_CLOUD_URL 指向上游云服务。

仓库同源英文版还导出了对应的渲染图,可参考 请求管线图(来源:diagrams/request-pipeline.mmd)与 三层弹性模型图(来源:diagrams/resilience-3layers.mmd,另见 docs/architecture/RESILIENCE_GUIDE.md)。

OmniRoute 请求管线架构图:从客户端经兼容 API、SSE 翻译核心到上游提供方

OmniRoute 三层弹性模型架构图:账户/提供方可用性、令牌过期与流安全防护

核心运行时组件

1)API 与路由层(Next.js App Routes)

主目录结构:

  • src/app/api/v1/*src/app/api/v1beta/*:兼容 API
  • src/app/api/*:管理/配置 API
  • next.config.mjs 中的 Next rewrites 将 /v1/* 映射到 /api/v1/*

重要的兼容路由(均在仓库中存在,已验证):

  • src/app/api/v1/chat/completions/route.ts
  • src/app/api/v1/messages/route.ts
  • src/app/api/v1/responses/route.ts
  • src/app/api/v1/models/route.ts — 包含 custom: true 的自定义模型
  • src/app/api/v1/embeddings/route.ts — Embedding 生成(6 个提供方)
  • src/app/api/v1/images/generations/route.ts — 图像生成(4+ 提供方,含 Antigravity/Nebius)
  • src/app/api/v1/messages/count_tokens/route.ts
  • src/app/api/v1/providers/[provider]/chat/completions/route.ts — 每提供方专属聊天
  • src/app/api/v1/providers/[provider]/embeddings/route.tssrc/app/api/v1/providers/[provider]/images/generations/route.ts
  • src/app/api/v1beta/models/route.tssrc/app/api/v1beta/models/[...path]/route.ts

管理域 API 一览:

  • Auth/settings:src/app/api/auth/*src/app/api/settings/*
  • Providers/connections:src/app/api/providers*;Provider nodes:src/app/api/provider-nodes*
  • 自定义模型:src/app/api/provider-models(GET/POST/DELETE);模型目录:src/app/api/models/route.ts(GET)
  • 代理配置:src/app/api/settings/proxy(GET/PUT/DELETE)+ src/app/api/settings/proxy/test(POST)
  • OAuth:src/app/api/oauth/*
  • Keys/aliases/combos/pricing:src/app/api/keys*src/app/api/models/aliassrc/app/api/combos*src/app/api/pricing
  • 用量:src/app/api/usage/*;同步/云:src/app/api/sync/*src/app/api/cloud/*
  • CLI 工具助手:src/app/api/cli-tools/*
  • IP 过滤:src/app/api/settings/ip-filter(GET/PUT)
  • Thinking budget:src/app/api/settings/thinking-budget(GET/PUT)
  • 系统提示:src/app/api/settings/system-prompt(GET/PUT)
  • 会话:src/app/api/sessions(GET);限流:src/app/api/rate-limits(GET)
  • 弹性:src/app/api/resilience(GET/PATCH)— 请求队列、连接冷却、提供方熔断、等待冷却配置;src/app/api/resilience/reset(POST)
  • 缓存统计:src/app/api/cache/stats(GET/DELETE);遥测:src/app/api/telemetry/summary(GET)
  • 预算:src/app/api/usage/budget(GET/POST);回退链:src/app/api/fallback/chains(GET/POST/DELETE)
  • 合规审计:src/app/api/compliance/audit-log(GET,分页 + 结构化元数据)
  • Evals:src/app/api/evals(GET/POST)、src/app/api/evals/[suiteId](GET)
  • 策略:src/app/api/policies(GET/POST)
  • 同步令牌:src/app/api/sync/tokens(GET/POST)、src/app/api/sync/tokens/[id](GET/DELETE)
  • 配置包:src/app/api/sync/bundle(GET,ETag 版本化快照)
  • WebSocket:src/app/api/v1/ws/route.ts — OpenAI 兼容 WS 客户端的 Upgrade 处理器

2)SSE + 翻译核心

主流程模块(均已验证存在于仓库):

  • 入口:src/sse/handlers/chat.ts
  • 核心编排:open-sse/handlers/chatCore.ts
  • 提供方执行适配器:open-sse/executors/*
  • 格式检测/提供方配置:open-sse/services/provider.ts
  • 模型解析/解析:src/sse/services/model.tsopen-sse/services/model.ts
  • 账户回退逻辑:open-sse/services/accountFallback.ts
  • 翻译注册表:open-sse/translator/index.ts
  • 流转换:open-sse/utils/stream.tsopen-sse/utils/streamHandler.ts
  • 用量提取/归一化:open-sse/utils/usageTracking.ts
  • Think 标签解析:open-sse/utils/thinkTagParser.ts
  • Embedding 处理器:open-sse/handlers/embeddings.ts;Embedding 注册表:open-sse/config/embeddingRegistry.ts
  • 图像生成处理器:open-sse/handlers/imageGeneration.ts;注册表:open-sse/config/imageRegistry.ts
  • 响应净化:open-sse/handlers/responseSanitizer.ts;角色归一化:open-sse/services/roleNormalizer.ts

服务层(业务逻辑)关键模块:

  • 账户选择/评分:open-sse/services/accountSelector.ts
  • 上下文生命周期:open-sse/services/contextManager.ts
  • IP 过滤执行:open-sse/services/ipFilter.ts;会话追踪:open-sse/services/sessionManager.ts
  • 请求去重:open-sse/services/signatureCache.ts;系统提示注入:open-sse/services/systemPrompt.ts
  • Thinking budget:open-sse/services/thinkingBudget.ts;通配符模型路由:open-sse/services/wildcardRouter.ts
  • 限流管理:open-sse/services/rateLimitManager.ts;熔断器:open-sse/services/circuitBreaker.ts
  • 上下文交接:open-sse/services/contextHandoff.ts(context-relay 策略的交接摘要生成与注入)
  • Codex 配额抓取:open-sse/services/codexQuotaFetcher.ts(为 context-relay 交接决策抓取 Codex 配额)
  • 冷却感知重试:src/sse/services/cooldownAwareRetry.ts(按模型冷却重试,可配置 requestRetry / maxRetryIntervalSec
  • 安全出站请求:src/shared/network/safeOutboundFetch.ts(SSRF 防护 + 私网 URL 拦截 + 重试 + 超时)
  • 出站 URL 守卫:src/shared/network/outboundUrlGuard.ts(校验提供方 URL 的 CIDR 范围)
  • 提供方请求默认值:open-sse/services/providerRequestDefaults.ts(provider 级 maxTokenstemperaturethinkingBudgetTokens
  • GLM 常量:open-sse/config/glmProvider.ts;Antigravity 上游:open-sse/config/antigravityUpstream.ts;Codex 客户端常量:open-sse/config/codexClient.ts
  • 模型别名播种:src/lib/modelAliasSeed.ts(启动时播种 30+ 跨代理方言别名)

域层模块:

  • 成本规则/预算:src/lib/domain/costRules.ts;回退策略:src/lib/domain/fallbackPolicy.ts
  • Combo 解析:src/lib/domain/comboResolver.ts;锁定策略:src/lib/domain/lockoutPolicy.ts
  • 策略引擎:src/domain/policyEngine.ts(集中式 lockout → budget → fallback 评估)
  • 错误码目录:src/lib/domain/errorCodes.ts;请求 ID:src/lib/domain/requestId.ts;抓取超时:src/lib/domain/fetchTimeout.ts
  • 请求遥测:src/lib/domain/requestTelemetry.ts;合规/审计:src/lib/domain/compliance/index.ts
  • Eval 运行器:src/lib/domain/evalRunner.ts
  • 域状态持久化:src/lib/db/domainState.ts(SQLite CRUD:回退链、预算、成本历史、锁定状态、熔断器)

OAuth 提供方模块(21 个实现模块,位于 src/lib/oauth/providers/):

  • 注册表索引:src/lib/oauth/providers/index.ts
  • 各提供方:claude.tscodex.tsgemini.tsantigravity.tsqoder.tsqwen.tskimi-coding.tsgithub.tskiro.tscursor.tskilocode.tscline.ts
  • 薄封装:src/lib/oauth/providers.ts

3)持久化层

主状态库(SQLite)

  • 核心基础设施:src/lib/db/core.ts(better-sqlite3、迁移、WAL)
  • 再导出门面:src/lib/localDb.ts(调用方的薄兼容层)
  • 文件位置:${DATA_DIR}/storage.sqlite(设置 $XDG_CONFIG_HOME/omniroute/storage.sqlite 时用该路径,否则默认 ~/.omniroute/storage.sqlite
  • 实体(表 + KV 命名空间):providerConnections、providerNodes、modelAliases、combos、apiKeys、settings、pricing、customModelsproxyConfigipFilterthinkingBudgetsystemPrompt

用量持久化

  • 门面:src/lib/usageDb.ts(拆分为 src/lib/usage/* 模块)
  • storage.sqlite 中的 SQLite 表:usage_historycall_logsproxy_logs
  • 保留可选文件工件用于兼容/调试:${DATA_DIR}/log.txt${DATA_DIR}/call_logs/<repo>/logs/...
  • 启动迁移时会把遗留 JSON 文件迁移到 SQLite

域状态库(SQLite)

  • src/lib/db/domainState.ts — 域状态 CRUD
  • 表(在 src/lib/db/core.ts 中创建):domain_fallback_chainsdomain_budgetsdomain_cost_historydomain_lockout_statedomain_circuit_breakers
  • 写穿缓存模式:内存中的 Map 在运行时拥有权威数据;变更同步写入 SQLite;冷启动时从 DB 恢复状态

4)认证与安全面

  • 仪表盘 Cookie 认证:src/proxy.tssrc/app/api/auth/login/route.ts
  • API Key 生成/校验:src/shared/utils/apiKey.ts
  • 提供方密钥保存在 providerConnections 条目中
  • 出站代理支持:open-sse/utils/proxyFetch.ts(env vars)、open-sse/utils/networkProxy.ts(按提供方或全局可配置)
  • SSRF/出站 URL 守卫:src/shared/network/outboundUrlGuard.ts(对全部提供方调用拦截私有/回环/链路本地网段)
  • 运行时环境校验:src/lib/env/runtimeEnv.ts(Zod schema,启动时输出错误/警告)
  • 同步令牌:src/lib/db/syncTokens.ts(配置包下载端点的 scoped 令牌;由 sync_tokens SQLite 表支撑,迁移 024_create_sync_tokens.sql
  • WebSocket 握手认证:src/lib/ws/handshake.ts(通过 API Key 或会话 Cookie 校验 WS Upgrade 请求)

5)云同步

  • 调度器初始化:src/lib/initCloudSync.tssrc/shared/services/initializeCloudSync.tssrc/shared/services/modelSyncScheduler.ts
  • 周期任务:src/shared/services/cloudSyncScheduler.tssrc/shared/services/modelSyncScheduler.ts
  • 控制路由:src/app/api/sync/cloud/route.ts

请求生命周期(/v1/chat/completions

关联文档给出了完整的时序图,这是理解整个系统如何工作的核心:

sequenceDiagram
    autonumber
    participant Client as CLI/SDK Client
    participant Route as /api/v1/chat/completions
    participant Chat as src/sse/handlers/chat
    participant Core as open-sse/handlers/chatCore
    participant Model as Model Resolver
    participant Auth as Credential Selector
    participant Exec as Provider Executor
    participant Prov as Upstream Provider
    participant Stream as Stream Translator
    participant Usage as usageDb

    Client->>Route: POST /v1/chat/completions
    Route->>Chat: handleChat(request)
    Chat->>Model: parse/resolve model or combo

    alt Combo model
        Chat->>Chat: iterate combo models (handleComboChat)
    end

    Chat->>Auth: getProviderCredentials(provider)
    Auth-->>Chat: active account + tokens/api key

    Chat->>Core: handleChatCore(body, modelInfo, credentials)
    Core->>Core: detect source format
    Core->>Core: translate request to target format
    Core->>Exec: execute(provider, transformedBody)
    Exec->>Prov: upstream API call
    Prov-->>Exec: SSE/JSON response
    Exec-->>Core: response + metadata

    alt 401/403
        Core->>Exec: refreshCredentials()
        Exec-->>Core: updated tokens
        Core->>Exec: retry request
    end

    Core->>Stream: translate/normalize stream to client format
    Stream-->>Client: SSE chunks / JSON response

    Stream->>Usage: extract usage + persist history/log

关键环节拆解:

  1. 客户端 POST /v1/chat/completions,路由转发到 handleChat(request)
  2. 模型解析:解析模型名或 Combo 名;若是 Combo 模型,进入 handleComboChat 迭代 Combo 模型序列;
  3. 凭据选择getProviderCredentials(provider) 返回活动账户与令牌/API Key;
  4. 核心编排handleChatCore 先检测源格式,再把请求翻译为目标格式,随后调用执行器 execute(provider, transformedBody) 发起上游调用;
  5. 令牌刷新分支:遇到 401/403 时调用 refreshCredentials() 刷新令牌后重试;
  6. 流回传:翻译/归一化流回客户端(SSE chunks 或 JSON);
  7. 用量落库:提取用量并持久化历史/日志。

Combo + 账户回退流程

flowchart TD
    A[Incoming model string] --> B{Is combo name?}
    B -- Yes --> C[Load combo models sequence]
    B -- No --> D[Single model path]

    C --> E[Try model N]
    E --> F[Resolve provider/model]
    D --> F

    F --> G[Select account credentials]
    G --> H{Credentials available?}
    H -- No --> I[Return provider unavailable]
    H -- Yes --> J[Execute request]

    J --> K{Success?}
    K -- Yes --> L[Return response]
    K -- No --> M{Fallback-eligible error?}

    M -- No --> N[Return error]
    M -- Yes --> O[Mark account unavailable cooldown]
    O --> P{Another account for provider?}
    P -- Yes --> G
    P -- No --> Q{In combo with next model?}
    Q -- Yes --> E
    Q -- No --> R[Return all unavailable]

回退决策由 open-sse/services/accountFallback.ts 驱动,依据状态码与错误消息启发式判断。Combo 路由额外增加一层保护:提供方范围的 400 错误(如上游内容屏蔽、角色校验失败)被视为模型局部失败,从而让后续 Combo 目标仍可继续执行——这是保证 Combo 策略可用性的关键设计。

OAuth 接入与令牌刷新生命周期

sequenceDiagram
    autonumber
    participant UI as Dashboard UI
    participant OAuth as /api/oauth/[provider]/[action]
    participant ProvAuth as Provider Auth Server
    participant DB as localDb
    participant Test as /api/providers/[id]/test
    participant Exec as Provider Executor

    UI->>OAuth: GET authorize or device-code
    OAuth->>ProvAuth: create auth/device flow
    ProvAuth-->>OAuth: auth URL or device code payload
    OAuth-->>UI: flow data

    UI->>OAuth: POST exchange or poll
    OAuth->>ProvAuth: token exchange/poll
    ProvAuth-->>OAuth: access/refresh tokens
    OAuth->>DB: createProviderConnection(oauth data)
    OAuth-->>UI: success + connection id

    UI->>Test: POST /api/providers/[id]/test
    Test->>Exec: validate credentials / optional refresh
    Exec-->>Test: valid or refreshed token info
    Test->>DB: update status/tokens/errors
    Test-->>UI: validation result

实时流量中的令牌刷新在 open-sse/handlers/chatCore.ts 内通过执行器的 refreshCredentials() 完成,与上文的请求生命周期相互印证。

云同步生命周期(启用 / 同步 / 禁用)

sequenceDiagram
    autonumber
    participant UI as Endpoint Page UI
    participant Sync as /api/sync/cloud
    participant DB as localDb
    participant Cloud as External Cloud Sync
    participant Claude as ~/.claude/settings.json

    UI->>Sync: POST action=enable
    Sync->>DB: set cloudEnabled=true
    Sync->>DB: ensure API key exists
    Sync->>Cloud: POST /sync/{machineId} (providers/aliases/combos/keys)
    Cloud-->>Sync: sync result
    Sync->>Cloud: GET /{machineId}/v1/verify
    Sync-->>UI: enabled + verification status

    UI->>Sync: POST action=sync
    Sync->>Cloud: POST /sync/{machineId}
    Cloud-->>Sync: remote data
    Sync->>DB: update newer local tokens/status
    Sync-->>UI: synced

    UI->>Sync: POST action=disable
    Sync->>DB: set cloudEnabled=false
    Sync->>Cloud: DELETE /sync/{machineId}
    Sync->>Claude: switch ANTHROPIC_BASE_URL back to local (if needed)
    Sync-->>UI: disabled

启用云同步后,周期同步由 CloudSyncScheduler 触发。

数据模型与存储映射

关联文档用 ER 图完整描述了核心实体及其关系:

erDiagram
    SETTINGS ||--o{ PROVIDER_CONNECTION : controls
    PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider
    PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage

    SETTINGS {
      boolean cloudEnabled
      number stickyRoundRobinLimit
      boolean requireLogin
      string password_hash
      string fallbackStrategy
      json rateLimitDefaults
      json providerProfiles
    }

    PROVIDER_CONNECTION {
      string id
      string provider
      string authType
      string name
      number priority
      boolean isActive
      string apiKey
      string accessToken
      string refreshToken
      string expiresAt
      string testStatus
      string lastError
      string rateLimitedUntil
      json providerSpecificData
    }

    PROVIDER_NODE {
      string id
      string type
      string name
      string prefix
      string apiType
      string baseUrl
    }

    MODEL_ALIAS {
      string alias
      string targetModel
    }

    COMBO {
      string id
      string name
      string[] models
    }

    API_KEY {
      string id
      string name
      string key
      string machineId
    }

    USAGE_ENTRY {
      string provider
      string model
      number prompt_tokens
      number completion_tokens
      string connectionId
      string timestamp
    }

    CUSTOM_MODEL {
      string id
      string name
      string providerId
    }

    PROXY_CONFIG {
      string global
      json providers
    }

    IP_FILTER {
      string mode
      string[] allowlist
      string[] blocklist
    }

    THINKING_BUDGET {
      string mode
      number customBudget
      string effortLevel
    }

    SYSTEM_PROMPT {
      boolean enabled
      string prompt
      string position
    }

几个值得注意的设计点:

  • SETTINGS 承载全局开关(cloudEnabledrequireLogin)、轮询策略(stickyRoundRobinLimit)、fallbackStrategy 与限流配置(rateLimitDefaultsproviderProfiles);
  • PROVIDER_CONNECTION 是账户级实体,同时支持 apiKeyaccessToken/refreshToken 两类凭据,priorityisActiverateLimitedUntil 直接服务于账户选择与回退;
  • PROVIDER_NODE 支持自定义兼容节点(apiType + baseUrl),与 providerConnection 形成"节点支撑连接"的关系;
  • COMBOname + models[] 表达多模型回退序列;MODEL_ALIAS 提供跨代理方言别名。

物理存储文件:

  • 主运行时 DB:${DATA_DIR}/storage.sqlite
  • 请求日志行:${DATA_DIR}/log.txt(兼容/调试工件)
  • 结构化调用载荷归档:${DATA_DIR}/call_logs/
  • 可选的翻译器/请求调试会话:<repo>/logs/...

部署拓扑

flowchart LR
    subgraph LocalHost[Developer Host]
        CLI[CLI Tools]
        Browser[Dashboard Browser]
    end

    subgraph ContainerOrProcess[OmniRoute Runtime]
        Next[Next.js Server\nPORT=20128]
        Core[SSE Core + Executors]
        MainDB[(storage.sqlite)]
        UsageDB[(usage tables + log artifacts)]
    end

    subgraph External[External Services]
        Providers[AI Providers]
        SyncCloud[Cloud Sync Service]
    end

    CLI --> Next
    Browser --> Next
    Next --> Core
    Next --> MainDB
    Core --> MainDB
    Core --> UsageDB
    Core --> Providers
    Next --> SyncCloud

典型部署形态是开发者本机运行(或容器化),Next.js 服务默认监听 PORT=20128。CLI 工具与浏览器仪表盘都访问本地运行时,运行时再向外部 AI 提供方与云同步服务发起请求。

模块映射(决策关键)

路由与 API 模块

  • src/app/api/v1/*src/app/api/v1beta/*:兼容 API
  • src/app/api/v1/providers/[provider]/*:每提供方专属路由(chat、embeddings、images)
  • src/app/api/providers*:提供方 CRUD、校验、测试
  • src/app/api/provider-nodes*:自定义兼容节点管理
  • src/app/api/provider-models:自定义模型管理(CRUD)
  • src/app/api/models/route.ts:模型目录 API(别名 + 自定义模型)
  • src/app/api/oauth/*:OAuth/设备码流程
  • src/app/api/keys*:本地 API Key 生命周期;src/app/api/models/alias:别名管理
  • src/app/api/combos*:回退 Combo 管理;src/app/api/pricing:成本计算的定价覆盖
  • src/app/api/settings/proxy:代理配置;src/app/api/settings/proxy/test:出站代理连通性测试
  • src/app/api/usage/*:用量与日志 API
  • src/app/api/sync/* + src/app/api/cloud/*:云同步与云向助手
  • src/app/api/cli-tools/*:本地 CLI 配置写入器/检查器
  • src/app/api/settings/ip-filtersrc/app/api/settings/thinking-budgetsrc/app/api/settings/system-prompt
  • src/app/api/sessions:活动会话列表(GET)
  • src/app/api/rate-limits:按账户限流状态(GET)
  • src/app/api/sync/tokenssrc/app/api/sync/tokens/[id]src/app/api/sync/bundle(ETag 版本化)
  • src/app/api/v1/ws:OpenAI 兼容 WS 客户端的 Upgrade 处理器

路由与执行核心

  • src/sse/handlers/chat.ts:请求解析、Combo 处理、账户选择循环
  • open-sse/handlers/chatCore.ts:翻译、执行器分发、重试/刷新处理、流建立
  • open-sse/executors/*:提供方专属的网络与格式行为

翻译注册表与格式转换器

  • open-sse/translator/index.ts:翻译器注册表与编排
  • 请求翻译器:open-sse/translator/request/*
  • 响应翻译器:open-sse/translator/response/*
  • 格式常量:open-sse/translator/formats.ts

持久化

  • src/lib/db/*:SQLite 上的持久配置/状态与域持久化
  • src/lib/localDb.ts:DB 模块的兼容再导出
  • src/lib/usageDb.ts:SQLite 表之上的用量历史/调用日志门面

Provider Executor 覆盖(策略模式)

每个提供方都有一个继承 BaseExecutor(位于 open-sse/executors/base.ts)的特化执行器。BaseExecutor 提供了 URL 构建、请求头构造、带指数退避的重试、凭据刷新钩子,以及 execute() 编排方法。

Executor Provider(s) 特殊处理
DefaultExecutor OpenAI、Claude、Gemini、Qwen、OpenRouter、GLM、Kimi、MiniMax、DeepSeek、Groq、xAI、Mistral、Perplexity、Together、Fireworks、Cerebras、Cohere、NVIDIA 等 按提供方动态 URL/请求头配置
AntigravityExecutor Google Antigravity 自定义 project/session ID、Retry-After 解析
CliProxyApiExecutor CLIProxyAPI 兼容提供方 自定义认证与协议处理
CloudflareAiExecutor Cloudflare Workers AI Account ID 注入、基于 Neurons 的用量追踪
CodexExecutor OpenAI Codex 注入系统指令、强制 reasoning effort
CursorExecutor Cursor IDE ConnectRPC 协议、Protobuf 编码、checksum 请求签名
GithubExecutor GitHub Copilot Copilot 令牌刷新、VSCode 模拟请求头
KiroExecutor AWS CodeWhisperer/Kiro AWS EventStream 二进制格式 → SSE 转换
OpenCodeExecutor OpenCode AI SDK 兼容的提供方设置
PollinationsExecutor Pollinations AI 无需 API Key、受限速请求
QoderExecutor Qoder AI PAT 与 OAuth 支持、多模型免费层
VertexExecutor Google Vertex AI 服务账号认证、区域化端点

其余所有提供方(包括自定义兼容节点)均使用 DefaultExecutor。仓库中 open-sse/executors/ 目录实际包含远超表格所列的执行器实现(含大量 web 会话型执行器,如 claude-web、grok-web、kimi-web、perplexity-web 等),它们遵循同样的 BaseExecutor 扩展约定。

Provider 兼容性矩阵

关联文档给出了代表性提供方的兼容性矩阵(format / auth / stream / non-stream / token refresh / usage API):

Provider 格式 认证 流式 非流式 令牌刷新 用量 API
Claude claude API Key / OAuth ⚠️ 仅管理员
Gemini gemini API Key / OAuth ⚠️ Cloud Console
Antigravity antigravity OAuth ✅ 完整配额 API
OpenAI openai API Key
Codex openai-responses OAuth ✅ 强制 ✅ 限流
GitHub Copilot openai OAuth + Copilot Token ✅ 配额快照
Cursor cursor 自定义 checksum
Kiro kiro AWS SSO OIDC ✅ (EventStream) ✅ 用量上限
Qwen openai OAuth ⚠️ 按请求
Qoder openai OAuth / PAT ⚠️ 按请求
Kilo Code openai OAuth
Cline openai OAuth
Kimi Coding openai OAuth
OpenRouter openai API Key
GLM/Kimi/MiniMax claude API Key
DeepSeek openai API Key
Groq openai API Key
xAI (Grok) openai API Key
Mistral openai API Key
Perplexity openai API Key
Together AI openai API Key
Fireworks AI openai API Key
Cerebras openai API Key
Cohere openai API Key
NVIDIA NIM openai API Key
Cloudflare AI openai API Token + Acct ID
Pollinations openai 无(免 Key)
Scaleway AI openai API Key
LongCat openai API Key
Ollama Cloud openai API Key(可选)
HuggingFace openai API Key
Nebius openai API Key
SiliconFlow openai API Key
Hyperbolic openai API Key
Vertex AI gemini Service Account ⚠️ Cloud Console

矩阵要点:API Key 类提供方普遍不支持令牌刷新与用量 API;OAuth 类(Claude、Gemini、Antigravity、GitHub Copilot、Kiro、Qwen、Qoder 等)支持令牌刷新,其中 Antigravity 提供完整的配额 API;Codex 强制流式响应。

格式翻译覆盖

检测到的源格式:

  • openai
  • openai-responses
  • claude
  • gemini

目标格式:

  • OpenAI chat/Responses
  • Claude
  • Gemini/Antigravity envelope
  • Kiro
  • Cursor

翻译采用 OpenAI 作为枢纽格式——所有转换都以 OpenAI 作为中间格式:

Source Format → OpenAI (hub) → Target Format

翻译根据源载荷形状与提供方目标格式动态选择。翻译管线的附加处理层:

  • 响应净化:剥离 OpenAI 格式响应(流式与非流式)中的非标准字段,确保严格 SDK 兼容
  • 角色归一化:对非 OpenAI 目标将 developersystem;对拒绝 system 角色的模型(GLM、ERNIE)将 systemuser
  • Think 标签提取:从内容中解析 <think>...</think> 块到 reasoning_content 字段
  • 结构化输出:将 OpenAI response_format.json_schema 转换为 Gemini 的 responseMimeType + responseSchema

支持的 API 端点

端点 格式 处理器
POST /v1/chat/completions OpenAI Chat src/sse/handlers/chat.ts
POST /v1/messages Claude Messages 同一处理器(自动检测)
POST /v1/responses OpenAI Responses open-sse/handlers/responsesHandler.ts
POST /v1/embeddings OpenAI Embeddings open-sse/handlers/embeddings.ts
GET /v1/embeddings 模型列表 API route
POST /v1/images/generations OpenAI Images open-sse/handlers/imageGeneration.ts
GET /v1/images/generations 模型列表 API route
POST /v1/providers/{provider}/chat/completions OpenAI Chat 每提供方专属 + 模型校验
POST /v1/providers/{provider}/embeddings OpenAI Embeddings 每提供方专属 + 模型校验
POST /v1/providers/{provider}/images/generations OpenAI Images 每提供方专属 + 模型校验
POST /v1/messages/count_tokens Claude Token Count API route
GET /v1/models OpenAI Models list API route(chat + embedding + image + 自定义模型)
GET /api/models/catalog 目录 按提供方 + 类型分组的全部模型
POST /v1beta/models/*:streamGenerateContent Gemini 原生 API route
GET/PUT/DELETE /api/settings/proxy 代理配置 网络代理配置
POST /api/settings/proxy/test 代理连通性 代理健康/连通性测试
GET/POST/DELETE /api/provider-models Provider Models 支撑自定义与托管可用模型的提供方模型元数据

Bypass Handler(旁路处理器)

旁路处理器(open-sse/utils/bypassHandler.ts)拦截 Claude CLI 发出的已知"一次性"请求——预热 ping、标题提取、token 计数——并返回伪造响应,不消耗上游提供方令牌。该行为仅在 User-Agent 包含 claude-cli 时触发。这是节省成本、避免无意义上游调用的精巧设计。

请求日志与工件

旧的文件型请求日志器(open-sse/utils/requestLogger.ts)仅为遗留兼容而保留。当前运行时契约:

  • APP_LOG_TO_FILE=true:应用与审计日志写入 <repo>/logs/
  • SQLite 支持的调用日志记录:call_logs
  • ${DATA_DIR}/call_logs/YYYY-MM-DD/...:启用调用日志管线时的工件

失败模式与弹性

1)账户/提供方可用性

  • 可重试上游失败时对连接施加冷却(cooldown)
  • 请求失败前先进行账户回退
  • 当前模型/提供方路径耗尽时进行 Combo 模型回退

2)令牌过期

  • 对可刷新的提供方进行预检 + 带重试的刷新
  • 核心路径中刷新尝试后的 401/403 重试

3)流安全

  • 感知断开的流控制器
  • 带流结束 flush 与 [DONE] 处理的翻译流
  • 提供方用量元数据缺失时的用量估算回退

4)云同步降级

  • 同步错误被暴露,但本地运行时继续工作
  • 调度器具备可重试逻辑,但周期执行默认调用单次尝试同步

5)数据完整性

  • SQLite schema 迁移与启动时的自动升级钩子
  • 遗留 JSON → SQLite 迁移兼容路径

6)SSRF / 出站 URL 守卫

  • src/shared/network/outboundUrlGuard.ts 在到达提供方执行器前拦截所有私有/回环/链路本地目标 URL
  • 提供方模型发现与校验路由使用 src/shared/network/safeOutboundFetch.ts,每次出站请求前都应用守卫
  • 守卫错误以 URL_GUARD_BLOCKED + HTTP 422 暴露,并通过 providerAudit.ts 写入合规审计轨迹

可观测性与运维信号

运行时可见性来源:

  • src/sse/utils/logger.ts 的控制台日志
  • SQLite 中的按请求用量聚合(usage_historycall_logsproxy_logs
  • settings.detailed_logs_enabled=true 时 SQLite 中的四阶段详细载荷捕获(request_detail_logs
  • log.txt 中的文本化请求状态日志(可选/兼容)
  • APP_LOG_TO_FILE=truelogs/ 下的可选应用日志文件
  • 启用调用日志管线时 ${DATA_DIR}/call_logs/ 下的可选请求工件
  • 供 UI 消费的仪表盘用量端点(/api/usage/*

详细请求载荷捕获为每次路由调用存储最多四个 JSON 阶段:

  1. 从客户端收到的原始请求
  2. 实际发送给上游的翻译后请求
  3. 重建为 JSON 的提供方响应(流式响应压缩为最终摘要 + 流元数据)
  4. OmniRoute 返回给客户端的最终响应(流式响应以相同压缩摘要形式存储)

安全敏感边界

  • JWT_SECRET:保护仪表盘会话 Cookie 的校验/签名
  • INITIAL_PASSWORD:首次运行的初始密码引导,应显式配置
  • API_KEY_SECRET:保护生成的本地 API Key 格式(HMAC)
  • 提供方密钥(API Key/令牌)持久化在本地 DB 中,应在文件系统层面加以保护
  • 云同步端点依赖 API Key 认证 + machine id 语义

环境与运行时矩阵

代码中实际使用的环境变量:

  • 应用/认证:JWT_SECRETINITIAL_PASSWORD
  • 存储:DATA_DIR
  • 兼容节点行为:ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE
  • 可选存储基础路径覆盖(Linux/macOS 且未设 DATA_DIR 时):XDG_CONFIG_HOME
  • 安全哈希:API_KEY_SECRETMACHINE_ID_SALT
  • 日志:APP_LOG_TO_FILEAPP_LOG_RETENTION_DAYSCALL_LOG_RETENTION_DAYS
  • 同步/云 URL:NEXT_PUBLIC_BASE_URLNEXT_PUBLIC_CLOUD_URL
  • 出站代理:HTTP_PROXYHTTPS_PROXYALL_PROXYNO_PROXY 及小写变体
  • SOCKS5 功能开关:ENABLE_SOCKS5_PROXYNEXT_PUBLIC_ENABLE_SOCKS5_PROXY
  • 平台/运行时辅助(非应用级配置):APPDATANODE_ENVPORTHOSTNAME

已知架构说明

  1. usageDblocalDb 共享同一基础目录策略(DATA_DIRXDG_CONFIG_HOME/omniroute~/.omniroute),并带遗留文件迁移。
  2. /api/v1/route.ts 委托给与 /api/v1/models 相同的统一目录构建器(src/app/api/v1/models/catalog.ts),避免语义漂移。
  3. 请求日志器启用时会写完整请求头/请求体,应把日志目录视为敏感数据。
  4. 云行为依赖正确的 NEXT_PUBLIC_BASE_URL 与云端点可达性。
  5. open-sse/ 目录以 @omniroute/open-sse npm workspace 包发布;源码通过 @omniroute/open-sse/... 导入(由 Next.js transpilePackages 解析)。文档中的路径为一致性保留目录名 open-sse/
  6. 仪表盘图表使用 Recharts(SVG 基础),提供可访问、可交互的分析可视化(模型用量柱状图、带成功率的提供方分解表)。
  7. E2E 测试使用 Playwrighttests/e2e/),通过 npm run test:e2e 运行;单元测试使用 Node.js test runnertests/unit/),通过 npm run test:unit 运行。src/ 下源码为 TypeScript(.ts/.tsx);open-sse/ workspace 仍为 JavaScript(.js)。
  8. 设置页分为 7 个标签页:General、Appearance、AI、Security、Routing、Resilience、Advanced。Resilience 页只配置请求队列、连接冷却、提供方熔断与等待冷却行为;实时熔断运行时状态显示在 Health 页。
  9. Context Relay 策略(context-relay)分两层实现:combo.ts 决定是否生成交接,chat.ts 在账户解析后注入交接。交接数据存放在 context_handoffs SQLite 表中。这种拆分是有意的,因为只有 chat.ts 知道实际账户是否发生了变化。
  10. 代理强制已全面化:tokenHealthCheck.ts 按连接解析代理,/api/providers/validate 使用 runWithProxyContextproxyFetch.ts 使用 undici.fetch() 以在 Node 22 上保持 dispatcher 兼容。
  11. Node.js 运行时策略检测/api/settings/require-login 返回 nodeVersionnodeCompatible 字段。当运行时落在受支持的 Node.js 安全版本线之外时,登录页会渲染警告横幅。

操作验证清单

  • 从源码构建:npm run build
  • 构建 Docker 镜像:docker build -t omniroute .
  • 启动服务并验证:
    • GET /api/settings
    • GET /api/v1/models
  • CLI 目标 base URL:当 PORT=20128 时应为 http://<host>:20128/v1

结语

从架构上看,OmniRoute 的成功在于"统一入口 + 分层解耦":Next.js 路由层负责协议入口,src/sse + open-sse 负责格式翻译与执行,SQLite 负责状态与用量持久化,域层策略引擎负责决策。执行器策略模式让新增提供方只需继承 BaseExecutor,翻译枢纽格式(OpenAI)让格式转换可组合,写穿缓存与冷启动恢复让域状态既快又稳。理解这张架构图,就等于理解了为什么一个本地进程能够把 Claude Code、Codex、Cursor 等工具与上百家上游提供方安全、可靠地衔接在一起。

要继续深入,可以阅读仓库中的相关文档:docs/architecture/RESILIENCE_GUIDE.mddocs/architecture/AUTHZ_GUIDE.mddocs/architecture/REPOSITORY_MAP.md,以及同源更新的英文版 docs/architecture/ARCHITECTURE.md

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391