OmniRoute 开发指南:请求流水线、三层容错机制与代码修改规范全解

发布时间:2026/9/14 11:42:08
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本文基于 OmniRoute 仓库的官方 Claude Code 工作指引文档docs/i18n/pt/CLAUDE.md葡萄牙语版与英文版CLAUDE.md同源编写。读完本篇后你将掌握OmniRoute 的目录分层与请求处理流水线、提供者熔断器 / 连接级冷却 / 模型级封锁这三大容错机制的原理与源码位置、新增提供者 / API 路由 / MCP 工具 / A2A 技能的标准操作流程以及项目的测试门禁、安全红线与 Git 工作流约定。一、快速上手开发与测试命令OmniRoute 是一个统一的 AI 代理/路由器AI Gateway单一入口点接入数百个 LLM 提供者provider提供自动回退、配额感知路由、上下文压缩、MCP/A2A 协议服务与桌面/PWA 形态。日常开发命令如下摘自指引文档命令均已与package.json中的 scripts 核实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 # 严格模式检查禁止隐式 any npm run test:coverage # 单元测试 覆盖率门禁文档口径 75/75/75/70 npm run check # lint 测试组合 npm run check:cycles # 检测循环依赖测试运行方式# 单个测试文件Node.js 原生测试运行器 —— 绝大多数测试用它 node --import tsx/esm --test tests/unit/your-file.test.ts # VitestMCP 服务器、autoCombo、缓存等场景 npm run test:vitest # 全部测试套件 npm run test:all从package.json的实际 scripts 可以看到各命令的真实形态test:unit使用node --import tsx/esm --test --test-concurrency4运行tests/unit/下按目录分批的用例test:vitest使用独立的vitest.mcp.config.ts配置test:e2e走 Playwrightscripts/dev/run-playwright-tests.mjscheck:cycles对应 check-cycles.mjs。完整的测试矩阵参见 CONTRIBUTING.md 的测试运行章节深度架构参见 AGENTS.md。版本提示指引文档写作时 Node 要求为≥20.20.2 21 | ≥22.22.2 23 | ≥24 25当前仓库package.json的engines字段实际为22.22.2 23 || 24.0.0 27请以当前仓库实际声明为准。二、项目分层总览层位置职责API 路由src/app/api/v1/Next.js App Router 入口处理器handlersopen-sse/handlers/请求处理chat、embeddings 等执行器executorsopen-sse/executors/提供者特定的 HTTP 派发翻译器translatorsopen-sse/translator/格式转换OpenAI ↔ Claude ↔ Gemini转换器transformeropen-sse/transformer/Responses API ↔ Chat Completions服务层open-sse/services/组合路由、限流、缓存等数据库src/lib/db/SQLite 领域模块与版本化迁移领域/策略src/domain/策略引擎、成本规则、回退逻辑MCP 服务器open-sse/mcp-server/大量工具、3 种传输stdio / SSE / Streamable HTTP、细粒度 scopeA2A 服务器src/lib/a2a/JSON-RPC 2.0 智能体协议技能src/lib/skills/可扩展的技能结构记忆src/lib/memory/持久化会话记忆从源码结构看整个仓库是 monoreposrc/Next.js 应用、open-sse/流式引擎工作区独立 npm 包、electron/桌面端、tests/分层测试、bin/CLI 入口。这种路由壳 引擎核的切分使得 open-sse 引擎可以脱离 Next.js 上下文独立测试Vitest 套件即针对它。三、请求流水线一个典型的/v1/chat/completions请求经过如下链路客户端 → /v1/chat/completionsNext.js 路由 → CORS → Zod 校验 → 认证可选→ 策略检查 → 提示词注入防护 → handleChatCore() [open-sse/handlers/chatCore.ts] → 缓存检查 → 限流 → 组合路由判定 → resolveComboTargets() → 每个目标调用 handleSingleModel() → translateRequest() → getExecutor() → executor.execute() → fetch() 上游 → 带退避的重试 → 响应翻译 → SSE 流式或 JSON → 若为 Responses APIresponsesTransformer.ts 的 TransformStreamAPI 路由遵循一致的模式路由 → CORS 预检 → Zod 请求体校验 → 可选认证extractApiKey/isValidApiKey→ API Key 策略应用 → 委托 open-sse 处理器。值得注意的设计决策是不存在全局 Next.js middleware拦截全部发生在路由层内——这使得各路由的认证/授权策略可以独立控制也对应了安全分层见下文严格规则中的 loopback 守卫。组合路由Combo routing位于 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()它以 per-target 的错误处理和熔断检查包裹handleChatCore()。13 因子 Auto-Combo 评分见 AUTO-COMBO.md三层容错体系见 RESILIENCE_GUIDE.md。四、三层容错机制熔断器、连接冷却、模型封锁这是本指引中技术含量最高的部分。OmniRoute 有三个相关但必须保持作用域分离的临时故障机制调试路由异常时务必先判断故障属于哪一层4.1 提供者熔断器Circuit Breaker作用域整个提供者如glm、openai、anthropic。目的对上游/服务层面持续失败的提供者停止发送流量避免不健康的提供者拖慢所有请求。关键实现核心类circuitBreaker.ts聊天门控接线src/sse/handlers/chatHelpers.ts、src/sse/handlers/chat.ts运行时状态 APIsrc/app/api/monitoring/health/route.ts共享 wrapperaccountFallback.ts持久化状态表domain_circuit_breakers三态模型CLOSED正常放行流量OPEN提供者被临时封禁调用方收到电路打开响应或组合路由直接跳到下一个目标HALF_OPEN重置超时到期放行一个探测请求——成功则关闭熔断失败则重新打开。阈值配置参数集中定义在 constants.ts 的PROVIDER_PROFILES约 L252-L302按提供者类型区分且全部支持环境变量覆盖类型熔断阈值默认重置窗口对应环境变量OAuth860sOMNIROUTE_CIRCUIT_BREAKER_OAUTH_THRESHOLD/..._OAUTH_RESET_MSAPI Key1230sOMNIROUTE_CIRCUIT_BREAKER_API_KEY_THRESHOLD/..._API_KEY_RESET_MS本地215sOMNIROUTE_CIRCUIT_BREAKER_LOCAL_THRESHOLD/..._LOCAL_RESET_MS事实核对指引文档中写的是OAuth 阈值 3 / API Key 阈值 5 / 本地阈值 2而当前源码默认值已演进为 8 / 12 / 2注释标明是为 500 连接规模重新标定且注释中保留了旧的 3/5 值供参考。此外PROVIDER_PROFILES还包含一组自适应熔断 v2 参数degradationThreshold、maxBackoffMultiplier、backoffEscalationCount及providerFailureThreshold/WindowMs/CooldownMs同样可用OMNIROUTE_PROVIDER_BREAKER_*环境变量调节说明熔断器已从简单三态演进为带降级DEGRADED与退避升级的自适应实现。触发边界这是文档反复强调的行为契约只有提供者级别的故障状态码应触发熔断(408, 500, 502, 503, 504);普通账户/Key/模型层面的错误——大多数401、403、429——不应触发整个提供者的熔断它们属于连接级冷却或模型封锁的范畴。通用的 API Key403应当可恢复除非被归类为提供者/账户的终态错误。懒恢复lazy recovery熔断器不使用后台定时器。当OPEN到期后getStatus()、canExecute()、getRetryAfterMs()等读操作会把状态惰性推进到HALF_OPEN——这保证监控面板和组合路由候选生成器不会把已过期的提供者永远排除在外。已核实这三个方法均存在于 circuitBreaker.ts。4.2 连接级冷却Connection Cooldown作用域单条提供者/账户/Key 连接。目的临时跳过一条坏 Key/账户同时让同一提供者的其他连接继续服务。关键实现写入/更新路径src/sse/services/auth.ts::markAccountUnavailable()账户选择/过滤src/sse/services/auth.ts::getProviderCredentials...冷却计算accountFallback.ts 中的checkFallbackError()配置settings.ts提供者连接上的关键字段rateLimitedUntil; testStatus: unavailable; lastError; lastErrorType; errorCode; backoffLevel;账户选择阶段满足以下条件的连接会被跳过new Date(rateLimitedUntil).getTime() Date.now();冷却同样是懒评估rateLimitedUntil过期后连接自动重新获得资格成功使用后clearAccountError()会清理testStatus、rateLimitedUntil、错误字段和backoffLevel。默认冷却行为与PROVIDER_PROFILES一致OAuth 基础冷却5stransientCooldown: 5000API Key 基础冷却3stransientCooldown: 3000且rateLimitCooldown: 0表示优先遵循上游retry-afterAPI Key 收到429时应优先采用上游的 retry 提示Retry-After头、reset 头或可解析的 reset 文本可恢复故障反复出现时使用指数退避baseCooldownMs * 2 ** failureIndex;2 ** failureIndex的退避计算已核实存在于 accountFallback.ts。一个防惊群anti-thundering-herd守卫防止对同一连接的并发故障反复延长冷却或使backoffLevel翻倍。终态不是冷却banned、expired、credits_exhausted应持续保持不可用直到凭据/配置变更或运维人员手动重置——切勿用瞬态冷却状态覆盖终态。4.3 模型级封锁Model Lockout作用域提供者 连接 模型三元组。目的避免在只有一个模型不可用或该连接上某模型配额受限的情况下把整条连接打瘫。典型场景按模型配额计费的提供者返回429本地提供者对不存在的模型返回404特定于提供者的模式/权限故障如 Grok 的特定 mode。模型封锁实现位于 accountFallback.ts允许同一连接继续服务其他模型——这是三层机制中粒度最细的一层。4.4 调试决策树文档给出的排查顺序非常实用某提供者的所有 Key 都被跳过→ 同时检查提供者熔断器状态和每条连接的rateLimitedUntil/testStatus提供者似乎在重置窗口后仍被永久排除→ 检查代码是否直接读了原始state字段而没有走getStatus()/canExecute()懒恢复的入口单条 Key 失败但其他应正常→ 优先用连接冷却而非提供者熔断仅单个模型失败→ 优先用模型封锁而非连接冷却某状态需要自动恢复→ 它必须携带未来时间戳/重置超时且存在会把过期状态推进的读路径永久状态则必须依靠人工变更凭据或配置。五、关键代码约定5.1 代码风格2 空格缩进、分号、双引号、100 字符行宽、ES5 尾逗号lint-staged 经 Prettier 强制导入顺序外部包 → 内部/、omniroute/open-sse→ 相对路径命名文件用 camelCase/kebab-case组件 PascalCase常量 UPPER_SNAKEESLintno-eval、no-implied-eval、no-new-func全局为 errorno-explicit-any在open-sse/与tests/中为 warningTypeScriptstrict: false、目标 ES2022、模块 esnext、bundler 解析优先显式类型。路径别名/*→src/omniroute/open-sse→open-sse/。5.2 数据库永远通过src/lib/db/下的领域模块访问数据库——绝不在路由或处理器里写裸 SQL绝不往 localDb.ts 里加逻辑它只是 re-export 层也绝不从它的桶导入barrel import应直接导入db/下的具体模块数据库单例src/lib/db/core.ts的getDbInstance()WAL 日志模式迁移src/lib/db/migrations/下为版本化、幂等的 SQL 文件在事务中执行。5.3 错误处理与安全try/catch 使用具体错误类型用 pino 记录上下文绝不静默吞掉 SSE 流中的错误——用 abort signal 做清理返回恰当的 HTTP 状态码4xx/5xx全局禁用eval()/new Function()/ 隐式 eval所有输入必须过 Zod 校验凭据静态存储使用 AES-256-GCM 加密上游请求头黑名单upstreamHeaders.ts——修改时必须同步保持头净化逻辑、Zod 方案与单元测试一致公开上游凭据Gemini/Antigravity/Windsurf 风格的 OAuth client_id/secret、从公开 CLI 提取的 Firebase Web Key必须经 publicCreds.ts 的resolvePublicCred()注入严禁写成字符串字面量——强制模式见 PUBLIC_CREDS.mdresolvePublicCred位于该文件 L201错误响应HTTP / SSE / 执行器 / MCP 处理器必须经 error.ts 的buildErrorBody()L363或sanitizeErrorMessage()errorSanitization.ts L709处理——绝不把裸的err.stack/err.message放进响应体规范见 ERROR_SANITIZATION.md由变量拼接 shell 命令调用exec()/spawn()且脚本需要运行时取值时一律通过env选项传入自动转义严禁把不可信的外部路径字符串插值进脚本体。参考实现src/mitm/cert/install.ts::updateNssDatabases新增安全敏感面时优先选用安全默认库Helmet.js、DOMPurify、ssrf-req-filter、safe-regex、Google Tink而不是自研实现。六、常见修改场景标准操作流程6.1 新增提供者Provider在 providers.ts 注册加载时经 Zod 校验若需要定制逻辑在open-sse/executors/添加执行器继承BaseExecutor若上游格式非 OpenAI 风格在open-sse/translator/添加翻译器若基于 OAuth在src/lib/oauth/constants/oauth.ts添加配置——如果上游 CLI 携带公开 client_id/secret必须走resolvePublicCred()绝不写字面量在open-sse/config/providerRegistry.ts注册模型在tests/unit/写测试如引入了新的内嵌凭据模式需包含 publicCreds 断言。6.2 新增 API 路由建目录src/app/api/v1/your-route/写route.ts实现GET/POST处理器遵循统一模式CORS → Zod 校验 → 可选认证 → 委托处理器处理器放在open-sse/handlers/从那里导入不要内联错误响应使用buildErrorBody()/errorResponse()自动净化绝不裸传堆栈补测试——至少包含一条断言错误响应不泄漏堆栈!body.error.message.includes(at /)。6.3 新增数据库模块创建src/lib/db/yourModule.ts从./core.ts导入getDbInstance导出领域表的 CRUD 函数需要新表时在src/lib/db/migrations/加迁移在 localDb.ts 中追加 re-export仅导出列表写测试。6.4 新增 MCP 工具在open-sse/mcp-server/tools/添加工具定义Zod 输入 schema 异步处理器注册到工具集由createMcpServer()连接分配合适的 scope写测试工具调用会记录到mcp_audit表。6.5 新增 A2A 技能 / 云智能体 / Guardrail / Eval / WebhookA2A 技能在src/lib/a2a/skills/创建已有 smart-routing、quota-management、provider-discovery、cost-analysis、health-report 五个技能接收任务上下文消息、元数据返回结构化结果在 taskExecution.ts 的A2A_SKILL_HANDLERS注册在src/app/.well-known/agent.json/route.tsAgent Card暴露测试 更新 A2A-SERVER.md 技能表云智能体在src/lib/cloudAgent/agents/继承CloudAgentBase已有 codex-cloud、devin、jules 三个实现createTask、getStatus、approvePlan、sendMessage、listSources在src/lib/cloudAgent/registry.ts注册需要时补 OAuthsrc/lib/oauth/providers/文档更新 CLOUD_AGENT.mdGuardrailsrc/lib/guardrails/→ GUARDRAILS.mdEval 集src/lib/evals/→ EVALS.md沙箱技能src/lib/skills/→ SKILLS.mdWebhook 事件src/lib/webhookDispatcher.ts→ WEBHOOKS.md。七、测试策略与覆盖率门禁场景命令单元测试npm run test:unit单文件node --import tsx/esm --test tests/unit/file.test.tsVitestMCP、autoCombonpm run test:vitestE2EPlaywrightnpm run test:e2e协议 E2EMCP A2Anpm run test:protocols:e2e生态测试npm run test:ecosystem覆盖率门禁npm run test:coverage覆盖率报告npm run coverage:report三条政策值得强调PR 规则改动src/、open-sse/、electron/、bin/下任何生产代码同一 PR 必须包含或更新测试分层偏好单元测试优先 → 集成测试跨模块或涉及 DB 状态→ E2E仅限 UI/工作流bug 复现脚本必须先于或随修复一起固化为自动化测试覆盖率政策目标是声明/行/函数 ≥75%、分支 ≥70%文档口径当前实测约 82%。注意从package.json看test:coverage中 c8 的--check-coverage参数目前设置为 60/60/60/60即 CI 硬性门禁低于文档目标值——文档目标与 CI 门禁之间留了缓冲空间。当 PR 覆盖率不达标时不是只报告而是必须补测试、重跑门禁并在 PR 报告中附上执行的命令、改动的测试文件与最终覆盖率数字。八、Git 工作流与环境# 绝不直接提交到 main git checkout -b feat/your-feature git commit -m feat: descreva a sua alteração # 实际提交信息应为描述性文本 git push -u origin feat/your-feature分支前缀feat/、fix/、refactor/、docs/、test/、chore/提交格式Conventional Commitsfeat(db): 添加熔断器—— 可用 scopedb、sse、oauth、dashboard、api、cli、docker、ci、mcp、a2a、memory、skillsHusky 钩子pre-commit 跑 lint-staged check-docs-synccheck:any-budget:t11pre-push 跑npm run test:unit。环境要点Node.js 以当前package.json的engines为准22.22.2 23 || 24.0.0 27ESM 模块TypeScript 5.9ES2022 目标bundler 解析默认端口20128API 与 dashboard 同端口数据目录由环境变量DATA_DIR控制默认~/.omniroute/关键环境变量PORT、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。九、严格红线Never List指引文档最后以 16 条硬性规则收束浓缩为几条最关键的不提交任何秘密/凭据不直接提交main不绕过 Husky 钩子--no-verify等不往localDb.ts加逻辑不在路由里写裸 SQL——一律走src/lib/db/模块不使用eval()/new Function()不静默吞掉 SSE 流错误生产代码变更必须带测试覆盖率保持 ≥75%声明/行/函数/ ≥70%分支公开 OAuth client_id/secret 与 Firebase Web Key 一律经resolvePublicCred()绝不写字面量错误响应一律经buildErrorBody()/sanitizeErrorMessage()不裸传err.stack/err.message不把外部/运行时值插值进exec()/spawn()脚本用env选项传参不忽略 CodeQL / Secret-Scanning 告警而不核查——例如经sanitizeErrorMessage()净化的调用点触发js/stack-trace-exposure属已知工具限制不识别自研净化器可标注误报但须引用 ERROR_SANITIZATION.md 说明不暴露会生成子进程的路由/api/mcp/、/api/cli-tools/runtime/而不做 routeGuard.ts 中isLocalOnlyPath()的 loopback 分级——loopback 强制在一切认证检查之前无条件执行保证经隧道泄漏的 JWT 无法触发进程派生分级模型见 ROUTE_GUARD_TIERS.md提交信息中不写把作者导向 AI/自动化账号的Co-Authored-Bytrailer含 Claude、GPT、Copilot 等字样或noreply.github.com机器人邮箱否则会掩盖真实作者归属人类协作者含 upstream PR 作者与 issue 报告者则应当以标准Co-authored-by: Name email署名。十、参考文档索引对任何非平凡的改动文档建议先读对应的设计文档。下表已将原文档中的相对链接统一转换为仓库根目录起点领域文档仓库导航REPOSITORY_MAP.md架构ARCHITECTURE.md工程参考CODEBASE_DOCUMENTATION.mdAuto-Combo13 因子评分、19 策略AUTO-COMBO.md容错3 机制RESILIENCE_GUIDE.md推理重放REASONING_REPLAY.md技能结构SKILLS.md记忆系统FTS5 QdrantMEMORY.md云智能体CLOUD_AGENT.mdGuardrailsPII / 注入 / 视觉GUARDRAILS.md公开上游凭据PUBLIC_CREDS.md错误净化ERROR_SANITIZATION.md评估EVALS.md合规 / 审计COMPLIANCE.mdWebhooksWEBHOOKS.md授权流水线AUTHZ_GUIDE.mdStealthTLS / 指纹STEALTH_GUIDE.md智能体协议A2A / ACP / 云AGENT_PROTOCOLS_GUIDE.mdMCP 服务器MCP-SERVER.mdA2A 服务器A2A-SERVER.mdAPI 参考 OpenAPIAPI_REFERENCE.md openapi.yaml提供者目录自动生成PROVIDER_REFERENCE.md发布流程RELEASE_CHECKLIST.md三层容错示意图源文件为 resilience-3layers.mmd渲染图位于docs/diagrams/exported/resilience-3layers.svg。一句话总结OmniRoute 的工程纪律可以浓缩为三件事——请求链路上路由壳只做薄、逻辑沉到 open-sse 引擎故障处理上熔断器管提供者、冷却管连接、封锁管模型三者作用域永不混用安全上凭据不落地字面量、错误不落地堆栈、子进程不落地公网。掌握这三条主线就能在这个 550 贡献者协作的大型 monorepo 中做出符合规范的改动。【免费下载链接】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),仅供参考