OmniRoute 开发者实战指南:从架构分层、三层弹性机制到代码规范的源码级解读

发布时间:2026/9/10 12:29:53
OmniRoute 开发者实战指南:从架构分层、三层弹性机制到代码规范的源码级解读 OmniRoute 开发者实战指南从架构分层、三层弹性机制到代码规范的源码级解读【免费下载链接】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, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute本指南以仓库内开发者向导 docs/i18n/gu/CLAUDE.md古吉拉特语版CLAUDE.md为核心骨架并结合当前仓库源码src/、open-sse/、tests/逐条核实展开。读者读完后可以快速掌握 OmniRoute 的代码库分层与请求管线、三类熔断/冷却运行时弹性机制的设计与排查方法以及新 Provider、新 API 路由、新 MCP 工具等常见开发场景的标准操作流程与硬性工程纪律。OmniRoute 是一个统一的 AI 代理/路由器一个入口端点聚合数百家 LLM 提供商内置自动回退auto-fallback与配额感知路由。对开发者而言真正重要的是理解代码放哪里、请求怎么走、失败如何分级处理、改了代码必须遵守哪些规则。本文把CLAUDE.md中零散的工程约定还原成一份可以照着上手的开发地图。快速开始环境与基础命令仓库使用 npm 作为包管理器开发服务器默认监听http://localhost:20128API 与 Dashboard 共用同一端口。按以下顺序完成首次启动npm install # 安装依赖自动从 .env.example 生成 .env npm run dev # 启动开发服务器地址 http://localhost:20128 npm run build # 生产构建Next.js 16 standalone npm run lint # ESLint期望 0 错误警告为既有存量 npm run typecheck:core # TypeScript 检查必须通过 npm run typecheck:noimplicit:core # 更严格的检查不允许任何 noImplicitAny 逸出 npm run test:coverage # 单元测试 覆盖率门槛75/75/75/70 — 语句/行/函数/分支 npm run check # lint 测试 组合 npm run check:cycles # 循环依赖检测运行测试项目测试以 Node.js 原生测试运行器为主Vitest 仅用于 MCP 服务端、autoCombo、缓存等特定子集# 单文件测试Node.js 原生测试运行器 — 覆盖大多数测试 node --import tsx/esm --test tests/unit/your-file.test.ts # VitestMCP server、autoCombo、缓存 npm run test:vitest # 全部测试套件 npm run test:all完整测试矩阵见 CONTRIBUTING.md 的运行测试章节深入架构说明见 AGENTS.md。代码库分层一份地图式总览OmniRoute 采用 monorepo 结构核心目录职责如下原文表格补充了实际路径层级位置职责API 路由src/app/api/v1/Next.js 应用路由 — 请求入口Handlersopen-sse/handlers/请求处理chat、embeddings 等Executorsopen-sse/executors/Provider 专属 HTTP 派发Translatorsopen-sse/translator/格式转换OpenAI ↔ Claude ↔ GeminiTransformeropen-sse/transformer/响应 API ↔ Chat CompletionsServicesopen-sse/services/Combo 路由、限流、缓存等Databasesrc/lib/db/110 个顶层 SQLite 领域模块130 个迁移Domain/Policysrc/domain/策略引擎、成本规则、回退逻辑MCP Serveropen-sse/mcp-server/107 个唯一工具3 种传输stdio / SSE / Streamable HTTP32 个作用域A2A Serversrc/lib/a2a/JSON-RPC 2.0 智能体协议Skillssrc/lib/skills/可扩展的技能框架Memorysrc/lib/memory/持续对话记忆Monorepo 组成src/Next.js 16 应用、open-sse/流式引擎工作区、electron/桌面应用、tests/、bin/CLI 入口。说明文档记录时点提供商数量为 329 家项目 README 当前宣传口径为 352 家数字随版本持续增长属正常演进。请求管线一次/v1/chat/completions的完整旅程原文给出了端到端管线这是理解为什么每个模块放在哪里的关键Client → /v1/chat/completions (Next.js 路由) → CORS → Zod 校验 → auth? → 策略检查 → Prompt 注入防护 → handleChatCore() [open-sse/handlers/chatCore.ts] → 缓存检查 → 限流 → Combo 路由? → resolveComboTargets() → 每个目标调用 handleSingleModel() → translateRequest() → getExecutor() → executor.execute() → fetch() upstream → 带退避的重试 → 响应翻译 → SSE 流或 JSON → 若为 Responses API: responsesTransformer.ts TransformStream所有 API 路由遵循一套统一模式Route → CORS preflight → Zod body 校验 → 可选 authextractApiKey/isValidApiKey→ API 密钥策略执行 → Handler 委托open-sse。项目没有全局 Next.js 中间件——横切关注点按路由隔离。Combo 路由open-sse/services/combo.ts提供 19 种公开策略priority、weighted、fill-first、round-robin、p2c、random、least-used、cost-optimized、reset-aware、reset-window、headroom、strict-random、auto、lkgp、context-optimized、cache-optimized、context-relay、fusion、pipeline。每个目标调用handleSingleModel()它用按目标隔离的错误处理与熔断检查包装handleChatCore()。Auto-Combo 的 13 因子评分见 docs/routing/AUTO-COMBO.md三层弹性详见 docs/architecture/RESILIENCE_GUIDE.md。三层弹性机制Provider 熔断 / 连接冷却 / 模型锁定OmniRoute 拥有三个相互关联但范围不同的即时失败机制。调试路由行为时必须分清它们的作用域——用错层级排查会得出错误结论。官方三层弹性示意图见 resilience-3layers.svg源文件resilience-3layers.mmd。第一层Provider 电路熔断器范围整个 Provider如glm、openai、anthropic目标阻止向在 upstream/service 层反复失败的 Provider 继续发送流量避免一个不健康的 Provider 拖慢每一次请求。实现落点核心类circuitBreaker.tsChat 网关/执行接线src/sse/handlers/chatHelpers.ts、src/sse/handlers/chat.ts运行时状态 APIsrc/app/api/monitoring/health/route.ts共享包装器open-sse/services/accountFallback.ts持久化状态表domain_circuit_breakers状态机源码在 circuitBreaker.ts 中由canExecute()/getStatus()驱动CLOSED允许正常流量。OPENProvider 被即时封禁调用方收到 provider-circuit-open 响应或 Combo 路由转向其他目标。HALF_OPEN重置超时已过放行一个探针请求。成功则关闭熔断器失败则重新打开。默认值演进原文记录了经典默认值——OAuth Provider 阈值3、重置超时60sAPI-Key Provider 阈值5、重置30s本地 Provider 阈值2、重置15s。需要特别指出的是随着连接规模扩大当前已扩展至 500 连接量级open-sse/config/constants.ts 中的默认值已经上调并且全部可以通过环境变量覆盖OMNIROUTE_CIRCUIT_BREAKER_OAUTH_THRESHOLD默认 8与OMNIROUTE_CIRCUIT_BREAKER_OAUTH_RESET_MS默认 60000OMNIROUTE_CIRCUIT_BREAKER_API_KEY_THRESHOLD默认 12与OMNIROUTE_CIRCUIT_BREAKER_API_KEY_RESET_MS默认 30000OMNIROUTE_CIRCUIT_BREAKER_LOCAL_THRESHOLD默认 2与OMNIROUTE_CIRCUIT_BREAKER_LOCAL_RESET_MS默认 15000另有 Provider 级冷却OMNIROUTE_PROVIDER_BREAKER_*_FAILURE_THRESHOLD/_COOLDOWN_MS以及自适应熔断参数DEGRADATION_THRESHOLD、MAX_BACKOFF_MULTIPLIER只有 Provider 级失败状态才应触发 Provider 熔断(408, 500, 502, 503, 504);不要因为常见账号/密钥/模型错误如大多数401、403、429场景触发整个 Provider 熔断——这些通常应落入连接冷却或模型锁定。一个普通的 API-Key Provider403只要不被归类为终端 Provider/账号错误就应当是可恢复的。懒恢复lazy recovery熔断器不使用后台定时器。当OPEN到期后getStatus()、canExecute()、getRetryAfterMs()等读操作会在读取时将状态刷新为HALF_OPEN源码中对应_refreshOpenState()这样 Dashboard 与 Combo 候选构建器不会把已过期的 Provider 永久排除在外。同时状态支持写入domain_circuit_breakers表并在进程重启后恢复_restoreFromDb()/_persistToDb()多次OPEN → HALF_OPEN → OPEN循环会触发重置超时的指数级升级_effectiveResetTimeout()上限为resetTimeout * maxBackoffMultiplier。第二层连接冷却范围单个 Provider 连接/账号/密钥目标立刻放弃一个坏密钥/坏账号同时允许同一 Provider 的其他连接继续服务请求。实现落点写入/更新路径src/sse/services/auth.ts::markAccountUnavailable账号选择/过滤src/sse/services/auth.ts::getProviderCredentials...冷却计算open-sse/services/accountFallback.ts::checkFallbackError设置src/lib/resilience/settings.tsProvider 连接上的关键字段rateLimitedUntil; testStatus: unavailable; lastError; lastErrorType; errorCode; backoffLevel;账号选择期间当满足以下条件时该连接被跳过new Date(rateLimitedUntil).getTime() Date.now();冷却同样是懒性的当rateLimitedUntil已过连接自动重新合格。成功使用后clearAccountError()会清空testStatus、rateLimitedUntil、错误字段与backoffLevel。默认连接冷却行为OAuth 基础冷却5sAPI-Key 基础冷却3sAPI-Key 的429应优先采纳 upstream 的重试建议Retry-After、reset 头、或可解析的 reset 文本反复的可恢复失败使用指数退避baseCooldownMs * 2 ** failureIndex;源码中markAccountUnavailable()还内置了防惊群Anti-Thundering Herd互斥锁src/sse/services/auth.ts中按连接维护的 mutex如果同一连接已被并发请求标记为不可用则跳过重复标记避免重置冷却计时器或重复递增backoffLevel。同时终端状态不能被冷却状态覆盖——banned、expired、credits_exhausted必须保持可用状态直至凭证/设置被修改或操作员手动重置。第三层模型锁定范围Provider 连接 模型目标当只有某个模型不可用或受配额限制时避免封禁整条连接。典型触发场景按模型计配额的 Provider 返回429本地 Provider 对缺失模型返回404Provider 特定的模式/模型权限失败如所选 Grok 模式模型锁定位于open-sse/services/accountFallback.ts内部使用modelLockoutsMap 与recordModelLockoutFailure()允许同一连接继续服务其他模型。锁定同样采用懒清理约 15 秒一次过期清理并区分rate_limit、quota_exhausted、transient等失败类别。排查指南原文实操要点若某 Provider 的所有密钥都被跳过检查 Provider 熔断器状态与每条连接的rateLimitedUntil/testStatus。若某 Provider 在重置窗口后仍永久被排除检查代码是否直接读原始state而非使用getStatus()/canExecute()直接读原始状态会绕过懒恢复。若某个 Provider 密钥失败但其他应正常工作优先排查连接冷却而不是 Provider 熔断。若只有单个模型失败优先排查模型锁定而不是连接冷却。若某状态应自我恢复它必须带有未来时间戳/重置超时以及能刷新过期状态的读路径永久状态则需要手动凭证或配置变更。核心工程规范代码风格2 空格缩进、分号、双引号、100 字符宽度、es5 尾随逗号由 lint-staged 执行 Prettier。导入顺序外部 → 内部/、omniroute/open-sse→ 相对路径。命名文件 camelCase/kebab组件 PascalCase常量 UPPER_SNAKE。ESLintno-eval、no-implied-eval、no-new-func全局视为错误no-explicit-any在open-sse/与tests/中为警告。TypeScriptstrict: false目标 ES2022模块 esnext解析 bundler优先显式类型。数据库始终通过src/lib/db/领域模块访问数据——绝不在路由或 handler 中写裸 SQL。绝不向src/lib/localDb.ts添加逻辑它只是重新导出层。绝不在localDb.ts中使用 barrel 导入——应导入具体的db/模块。DB 单例getDbInstance()来自src/lib/db/core.tsWAL 日志模式。迁移src/lib/db/migrations/——带版本号的 SQL 文件幂等在事务中执行。错误处理使用 try/catch 配合具体错误类型用 pino 上下文记录日志。永远不要在 SSE 流中静默吞掉错误——使用 abort 信号做清理。返回正确的 HTTP 状态码4xx/5xx。安全基线绝不使用eval()、new Function()或 IMPLIED eval。所有输入用 Zod schema 校验。静态凭证加密AES-256-GCM。Upstream 头拒绝清单src/shared/constants/upstreamHeaders.ts——编辑时要保持清理逻辑、Zod schema 与单元测试同步。公开 upstream 凭证Gemini/Antigravity/Windsurf 风格的 OAuth client_id/secret 与 Firebase Web 密钥从公开 CLI 提取必须通过open-sse/utils/publicCreds.ts的resolvePublicCred()嵌入——绝不写成字符串字面量。强制模式见 docs/security/PUBLIC_CREDS.md。错误响应HTTP / SSE / executor / MCP handler必须通过open-sse/utils/error.ts的buildErrorBody()或sanitizeErrorMessage()处理——绝不把原始err.stack或err.message放进响应体。详见 docs/security/ERROR_SANITIZATION.md。带变量拼装的 shell 命令调用exec()/spawn()时需要运行时值的参数通过env选项传递自动 shell 转义——绝不把不可信/外部路径字符串插值进脚本体参考src/mitm/cert/install.ts::updateNssDatabases。新增安全敏感表面时优先选择安全默认库Helmet.js、DOMPurify、ssrf-req-filter、safe-regex、Google Tink而非自定义实现。常见变更场景六条标准作业流程新增 Provider在src/shared/constants/providers.ts注册加载时 Zod 校验。如需自定义逻辑在open-sse/executors/添加执行器继承BaseExecutor。若为非 OpenAI 格式在open-sse/translator/添加翻译器。若为 OAuth 型在src/lib/oauth/constants/oauth.ts添加 OAuth 配置——若 upstream CLI 暴露公开 client_id/secret通过resolvePublicCred()嵌入见 docs/security/PUBLIC_CREDS.md绝不作为字面量。在open-sse/config/providerRegistry.ts注册模型。在tests/unit/编写测试若新增嵌入默认值须包含 publicCreds 形状断言。新增 API 路由在src/app/api/v1/your-route/下创建目录。创建带GET/POSThandler 的route.ts。遵循模式CORS → Zod body 校验 → 可选 auth → handler 委托。handler 放在open-sse/handlers/从那里导入不要内联。错误响应使用open-sse/utils/error.ts的buildErrorBody()/errorResponse()自动清理——绝不把err.stack或err.message原始放入 body。详见 docs/security/ERROR_SANITIZATION.md。添加测试——至少包含一条错误响应不泄漏堆栈的断言!body.error.message.includes(at /)。新增 DB 模块创建src/lib/db/yourModule.ts——从./core.ts导入getDbInstance。为你的领域表导出 CRUD 函数。如需新表在src/lib/db/migrations/添加迁移。在src/lib/localDb.ts重新导出只加入重新导出清单。编写测试。新增 MCP 工具在open-sse/mcp-server/tools/添加带 Zod 输入 schema async handler 的工具定义。注册进工具集经createMcpServer()接线。分配适当作用域scope。编写测试工具调用会记录到mcp_audit表。新增 A2A 技能在src/lib/a2a/skills/创建技能已有 5 个smart-routing、quota-management、provider-discovery、cost-analysis、health-report。技能接收任务上下文消息、元数据→ 返回结构化结果。在src/lib/a2a/taskExecution.ts的A2A_SKILL_HANDLERS注册。在src/app/.well-known/agent.json/route.ts暴露agent card。在tests/unit/编写测试。在 docs/frameworks/A2A-SERVER.md 的技能表中记录。新增云 Agent在src/lib/cloudAgent/agents/创建继承CloudAgentBase的 Agent 类已有 3 个codex-cloud、devin、jules。实现createTask、getStatus、approvePlan、sendMessage、listSources。在src/lib/cloudAgent/registry.ts注册。必要时处理 OAuth/凭证src/lib/oauth/providers/。编写测试并在 docs/frameworks/CLOUD_AGENT.md 记录。新增 Guardrail / Eval / Skill / Webhook 事件Guardrailsrc/lib/guardrails/→ 文档 docs/security/GUARDRAILS.mdEval 套件src/lib/evals/→ 文档 docs/frameworks/EVALS.mdSkill沙箱src/lib/skills/→ 文档 docs/frameworks/SKILLS.mdWebhook 事件src/lib/webhookDispatcher.ts→ 文档 docs/frameworks/WEBHOOKS.md测试体系与 PR 纪律内容命令单元测试npm run test:unit单文件node --import tsx/esm --test tests/unit/file.test.tsVitestMCP、autoCombonpm run test:vitestE2EPlaywrightnpm run test:e2e协议 E2EMCPA2Anpm run test:protocols:e2e生态npm run test:ecosystem覆盖率门槛npm run test:coverage75/75/75/70 — 语句/行/函数/分支覆盖率报告npm run coverage:reportPR 规则如果你改动src/、open-sse/、electron/或bin/中的生产代码必须在同一 PR 中包含或更新测试。测试层级优先级单元优先 → 集成多模块或 DB 状态→ E2E仅 UI/工作流。Bug 复现应作为自动化测试随修复一起提交。Copilot 覆盖率政策当 PR 改动生产代码且覆盖率跌破 75%语句/行/函数或 70%分支时不要只报告——添加或更新测试重新运行覆盖率门槛再请求确认。PR 报告中包含已运行的命令、变更的测试文件与最终覆盖率结果。Git 工作流与提交规范# 绝不直接向 main 提交 git checkout -b feat/your-feature git commit -m feat: 描述你的改动 git push -u origin feat/your-feature分支前缀feat/、fix/、refactor/、docs/、test/、chore/提交格式Conventional Commitsfeat(db): 添加电路熔断器—— 作用域包括db、sse、oauth、dashboard、api、cli、docker、ci、mcp、a2a、memory、skillsHusky 钩子pre-commitlint-staged check-docs-synccheck:any-budget:t11pre-pushnpm run test:unit环境与关键配置运行时Node.js ≥20.20.2 21 | ≥22.22.2 23 | ≥24 25ES Modules。TypeScript5.9目标 ES2022模块 esnext解析 bundler。路径别名/*→src/、omniroute/open-sse→open-sse/、omniroute/open-sse/*→open-sse/*。默认端口20128API Dashboard 同一端口。数据目录DATA_DIR环境变量默认~/.omniroute/。关键 env varsPORT、JWT_SECRET、API_KEY_SECRET、INITIAL_PASSWORD、REQUIRE_API_KEY、APP_LOG_LEVEL。初始化cp .env.example .env然后生成JWT_SECRETopenssl rand -base64 48与API_KEY_SECRETopenssl rand -hex 32。硬性规则清单Non-Negotiable绝不提交密钥或凭证。绝不向localDb.ts添加逻辑。绝不使用eval()/new Function()/ 隐式 eval。绝不直接向main提交。绝不在路由中写裸 SQL——使用src/lib/db/模块。绝不在 SSE 流中静默吞掉错误。始终用 Zod schema 校验输入。改动生产代码时始终包含测试。覆盖率必须保持 ≥75%语句、行、函数/ ≥70%分支当前实测约 82%。未经明确的操作员授权绝不绕过 Husky 钩子--no-verify、--no-gpg-sign。绝不将公开 upstream OAuth client_id/secret 或 Firebase Web 密钥作为字符串字面量嵌入——始终经resolvePublicCred()open-sse/utils/publicCreds.ts。见 docs/security/PUBLIC_CREDS.md。绝不在 HTTP / SSE / executor 响应中返回原始err.stack/err.message——始终经buildErrorBody()或sanitizeErrorMessage()open-sse/utils/error.ts。见 docs/security/ERROR_SANITIZATION.md。绝不将外部路径或运行时值字符串插值进传给exec()/spawn()的 shell 脚本——改用env选项传递。参考src/mitm/cert/install.ts::updateNssDatabases。绝不未经核对上述模式文档就驳回 CodeQL / Secret-Scanning 告警且驳回注释中必须写明技术理由如js/stack-trace-exposure已被sanitizeErrorMessage()处理属于已知的 CodeQL 限制可参照 docs/security/ERROR_SANITIZATION.md 判定为 false positive。绝不将启动子进程的路由/api/mcp/、/api/cli-tools/runtime/纳入未经src/server/authz/routeGuard.ts中isLocalOnlyPath()分类的集合。loopback 执行会在任何 auth 检查之前无条件发生——防止通过隧道泄漏的 JWT 被用于触发进程启动。见 docs/security/ROUTE_GUARD_TIERS.md。绝不包含将功劳归于 AI 助手、LLM 或自动化账号的Co-Authored-By尾注如名字含 Claude、GPT、Copilot、Bot邮箱位于anthropic.com/openai.com/ 机器人所有的noreply.github.com。这类尾注会把提交归属路由到 GitHub 上的机器人账号掩盖 PR 历史中的真实作者。人类协作者包括 upstream PR 作者与移植到 OmniRoute 的 issue 报告者应使用标准Co-authored-by: Name email尾注获得署名upstream 移植工作流/port-upstream-features、/port-upstream-issues依赖这一点。参考文档索引进行任何非平凡改动前先阅读对应领域的深度文档路径已统一为仓库根相对路径领域文档仓库导航docs/architecture/REPOSITORY_MAP.md架构docs/architecture/ARCHITECTURE.md工程上下文docs/architecture/CODEBASE_DOCUMENTATION.mdAuto-Combo13 因子评分19 策略docs/routing/AUTO-COMBO.md弹性3 机制docs/architecture/RESILIENCE_GUIDE.mdReasoning Replaydocs/routing/REASONING_REPLAY.mdSkills 框架docs/frameworks/SKILLS.md记忆系统FTS5 Qdrantdocs/frameworks/MEMORY.md云 Agentdocs/frameworks/CLOUD_AGENT.mdGuardrailsPII / 注入 / 视觉docs/security/GUARDRAILS.md公开 upstream 凭证Gemini 等docs/security/PUBLIC_CREDS.md错误消息清理docs/security/ERROR_SANITIZATION.mdEvalsdocs/frameworks/EVALS.md合规 / 审计docs/security/COMPLIANCE.mdWebhooksdocs/frameworks/WEBHOOKS.md授权管线docs/architecture/AUTHZ_GUIDE.mdStealthTLS / 指纹docs/security/STEALTH_GUIDE.mdAgent 协议A2A / ACP / Clouddocs/frameworks/AGENT_PROTOCOLS_GUIDE.mdMCP Serverdocs/frameworks/MCP-SERVER.mdA2A Serverdocs/frameworks/A2A-SERVER.mdAPI 参考 OpenAPIdocs/reference/API_REFERENCE.md docs/reference/openapi.yamlProvider 目录自动生成docs/reference/PROVIDER_REFERENCE.md发布流程docs/ops/RELEASE_CHECKLIST.md此外官方深度文档还有 docs/architecture/ADAPTIVE_ROUTING.md自适应路由策略与 docs/routing/ROUTER_BACKENDS.md路由器后端说明可配合阅读。小结对 OmniRoute 的开发者而言本文还原的CLAUDE.md工程约定可以浓缩为三句话请求进src/app/api/v1/逻辑进open-sse/数据一律走src/lib/db/领域模块失败先分清楚是 Provider 熔断、连接冷却还是模型锁定再决定排查方向任何生产代码改动都必须携带测试并守住 75/70 覆盖率门槛。遵循这套约定无论是接入第 330 个 Provider、新增 MCP 工具还是排查诡异的回退行为都能快速定位到正确的代码层与文档而不是在数万行代码里漫无目的地搜索。【免费下载链接】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, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考