跳到內容
OmniRoute source

Troubleshooting (中文 (繁體))

第一次使用 OmniRoute? 從這裡開始——這些方法能解決 90% 的問題:

我看到的訊息 代表的意思 處理方式
“Can’t connect” OmniRoute 尚未執行 執行 omniroute 或 docker restart omniroute
“Invalid API key” 您的金鑰錯誤或已過期 從提供者網站重新複製金鑰
“Rate limit exceeded” 您傳送了過多請求 等待 1 分鐘,或使用 model: "auto" 自動備援
“Quota exceeded” 您的免費/付費配額已用完 連接更多提供者,或使用免費提供者(Kiro、Pollinations)
“Slow responses” 提供者繁忙或距離過遠 使用 model: "auto/fast",或連接速度更快的提供者(Groq、Cerebras)
“Wrong provider used” auto 選擇了不同的提供者 這是正常的!auto 會選擇最佳提供者。使用 model: "openai/gpt-4o" 強制指定提供者
“502 Bad Gateway” 提供者服務中斷 等待後重試,或使用 model: "auto" 切換提供者
“401 Unauthorized” 您的憑證錯誤 檢查您的 API 金鑰,或使用 OAuth 重新驗證
“omniroute is not recognized” Windows PATH 缺少全域 node 模組 將 npm 全域前綴加入 Windows PATH。使用 npm config get prefix 查找它。
“429 Too Many Requests” 受到速率限制 等待 1 分鐘,或連接更多提供者

仍然無法解決? 請參閱下方的詳細疑難排解,或前往 Discord 提問。



免費提供者的速率限制(429 / 400 / 401)

Section titled “免費提供者的速率限制(429 / 400 / 401)”

症狀:使用 model: "auto" 搭配免費/不需驗證的提供者(opencode、auggie 等)時,您會間歇性收到 HTTP 429、400 或 401,而非正常回覆。片刻後以相同提示重試便會成功,但自動化流程(cron 作業、代理程式、指令碼)會在第一次失敗時中斷。

根本原因:三種互相獨立的失敗模式會疊加發生:

  1. 提供者速率限制(429):免費方案可能會施加每個時間窗的配額。突發的大量平行呼叫會耗盡配額,因此後續請求會遭到拒絕,直到時間窗重設為止。
  2. 直通模式中的失效模型(400/401):auto/* 集區可能包含來自 opencode 的直通模型;這些模型已登錄於目錄中,但沒有有效憑證(例如 oc/north-mini-code-free → 401)。自動路由器嘗試其中一個模型並失敗,而錯誤會在備援啟動前向外傳播。
  3. 並行放大效應(高負載下的 429):當多個代理程式/cron 工作階段同時存取 auto 時,總請求速率會超出免費提供者所能容許的範圍,導致正常呼叫被標記為濫用。

已驗證的修正方式(社群回報,2026-08-10):調整三個環境變數,讓輪替、並行控制與備援機制吸收免費方案的不穩定性,而不是因此終止:

Terminal window
export OMNIROUTE_ROTATE_ON_400=true # 遇到 400/401 時跳至另一個模型/提供者(略過失效的直通模型)
export OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT=4 # 明確設定重量級請求的准入上限(預設未設定:不限制請求數量,請參閱下方附註)
export OMNIROUTE_CHAT_ADMISSION_QUEUE_MS=5000 # 延長等待重量級請求容量的有限時間,而非立即回傳可重試的 503

請在 OmniRoute 程序的環境中設定這些變數(例如透過 LaunchAgent plist 或 systemctl edit 設定常駐程式),然後重新啟動 OmniRoute。輪替旗標是效果最顯著的單一調整:它能將硬性失敗轉換為透明重試,改由集區中健康的提供者處理。

附註:OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT 會限制可同時執行的重量級(長上下文)請求數量;此限制是准入閘門,而非提供者速率限制器。**#503-fanout 更新:**此變數已不再預設設定(現在僅在明確設定時才會生效,如上所示)——重量級請求的准入改由自動推導的位元組預算(OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES)進行管控;該預算會依主機的實際記憶體上限自動調整,因此全新部署即使完全不設定此變數,也應該會看到大幅減少的 503 chat_admission_busy 拒絕;在此明確設定它時,仍會完全依照文件所述運作。明確設定的位元組預算覆寫值會限制在 8 MiB–2 GiB 之間。413 body_exceeds_budget 並非暫時性問題:請提高該位元組預算、降低 OMNIROUTE_CHAT_HARD_MAX_BODY_BYTES,或提高程序的記憶體上限。inflight_bytes_budget 卸載屬於暫時性的資源競爭,仍可重試。各提供者的速率限制(open-sse/services/rateLimitManager.ts)則由 RATE_LIMIT_MAX_WAIT_MS、RATE_LIMIT_MAX_QUEUE_DEPTH 與 RATE_LIMIT_AUTO_ENABLE 分別管理——請參閱 .env.example。

如何驗證修正已生效:快速連續執行您的代理程式/cron 兩次,並確認兩次皆成功。修正前,第二次執行通常會擲出 429/401。修正後,任何失敗(若有)都會透明地重試,且呼叫會順利完成。您也可以執行 curl /monitoring/health,並觀察提供者連線上的 rateLimitedUntil 欄位,以及受影響提供者的 circuitBreakers.providerBreakers[].state;狀態會是 CLOSED、DEGRADED、OPEN 或 HALF_OPEN 其中之一(請參閱 src/shared/utils/circuitBreaker.ts)。持續失敗的提供者會先從 CLOSED → DEGRADED → OPEN,然後在重設時間窗允許探測請求通過時進入 HALF_OPEN。

如果仍然看到 429:該提供者目前使用中的帳戶確實已耗盡其_配額_(而不只是觸發速率限制)。請在 OmniRoute 儀表板的 Providers → Accounts 中,為同一提供者新增第二個帳戶,或混用另一個免費提供者(例如 routeway、auggie)。輪替只對暫時性的速率限制/400/401 有幫助;若配額已完全耗盡,則需要第二組憑證或不同的提供者。

如果在視覺模型(auto/vision、bazaarlink/*)上看到 403:已連線的帳戶缺少包含視覺功能的付費方案,或 API 金鑰的權限不足。請在提供者儀表板中確認金鑰範圍包含視覺/多模態功能,或連線至付費層級帳戶,並將其保留為視覺模型的目標。


npm install 警告(ERESOLVE / peer / deprecated)

Section titled “npm install 警告(ERESOLVE / peer / deprecated)”

執行 npm install -g omniroute 時,您可能會看到大量警告,例如 npm warn ERESOLVE、對等相依性通知及 deprecated 訊息。這些都是預期行為,不會造成影響。 如果輸出中顯示 added <N> packages,即表示安裝成功。

若要隱藏對等相依性解析警告,請使用 OmniRoute 支援的安裝方式:

Terminal window
npm install -g omniroute --legacy-peer-deps

--legacy-peer-deps 只會隱藏 ERESOLVE 與對等相依性通知。棄用通知仍會顯示,因為它們來自遞移的第三方套件;這些通知並不表示安裝失敗。

這些警告來自 OmniRoute 無法控制之第三方套件中過時的對等相依性版本範圍:

  1. marked-terminal 要求 marked >=1 <16,但找到 marked@18 — 實際運作正常;只是上游的對等相依性範圍已過時。
  2. deprecated prebuild-install@7.1.3 — 這是一個遞移的原生二進位檔擷取輔助工具。它不會 用於安裝已鎖定版本的 wreq-js 傳輸繫結,也不表示 Web Cookie 提供者的傳輸設定失敗。

無須採取任何動作 — 除非分叉上游套件,否則無法完全隱藏這些警告。


如果 Gemini Web 請求傳回 503,並顯示未安裝 Playwright Chromium 的訊息, 表示 npm 套件已存在,但缺少瀏覽器二進位檔。 Playwright 刻意將瀏覽器下載與 npm 套件 安裝分開,因此在安裝瀏覽器之前,出現此回應是預期行為。

若使用全域 npm 安裝,請從 OmniRoute 套件的 目錄安裝 Chromium,使瀏覽器快取屬於同一個 Playwright 安裝:

Terminal window
cd "$(npm root -g)/omniroute"
npx playwright install chromium

安裝後重新啟動 OmniRoute,然後再次嘗試 Gemini Web 請求。如果您 從 Docker 映像執行 OmniRoute,請使用 -web 映像(或 runner-web 建置目標),其中已包含 Chromium 及其相依套件;基礎映像則 未包含這些元件。


問題 解決方案
首次登入無法運作 在 .env 中設定 INITIAL_PASSWORD(沒有硬編碼的預設值)
儀表板在錯誤的連接埠開啟 設定 PORT=20128 和 NEXT_PUBLIC_BASE_URL=http://localhost:20128
未將日誌寫入磁碟 設定 APP_LOG_TO_FILE=true,並確認已啟用呼叫日誌擷取
EACCES:權限遭拒 設定 DATA_DIR=/path/to/writable/dir 以覆寫 ~/.omniroute
路由策略未儲存 更新至最新的 v3.x 版本(舊版已提供用於修正設定持久化問題的 Zod 結構描述修正)
登入時當機/空白頁面 檢查 Node.js 版本 — 請參閱下方的 Node.js 相容性
dlopen / slice is not valid mach-o file(macOS) 執行 cd $(npm root -g)/omniroute/app && npm rebuild better-sqlite3 && omniroute — 請參閱下方的 macOS 原生模組重建
Proxy「fetch failed」 確認 Proxy 設定是在正確的層級進行設定 — 請參閱下方的 Proxy 問題
Docker curl: (56) Recv failure: Connection reset by peer 您的 Docker 連接埠繫結可能落在 IPv6 上。使用 -p 127.0.0.1:20128:20128 強制使用 IPv4,或使用 curl -4 測試。請參閱下方的 Docker IPv6
防毒軟體隔離 README.md 誤判 — 請參閱下方的 防毒軟體誤判
Kaspersky 將桌面應用程式標記為木馬程式 對未簽署安裝程式的行為誤判 — 請參閱下方的 防毒軟體誤判

Avast/AVG 以 MD:HttpRequest-inf[Susp] 隔離 README.md

Section titled “Avast/AVG 以 MD:HttpRequest-inf[Susp] 隔離 README.md”

這是誤判。沒有任何檔案受到感染,也不需要採取任何行動。

Avast 和 AVG 會執行一項啟發式偵測,將包含大量看似 HTTP 請求連結的 純文字/Markdown 檔案標記出來。OmniRoute 的 README.md 會包含在 npm 套件中(它已 列於 package.json → files),因此在全域安裝時會出現在 node_modules/omniroute/README.md,而其中包含約 15 個 http://localhost:20128/... 範例(MCP HTTP/SSE 端點、A2A .well-known URL,以及 curl 程式碼片段)。這樣的連結密度足以觸發該啟發式偵測。

如果此問題最近才開始發生:檔案的性質並未改變。README 擴充了端點表格 (新增了 MCP HTTP + SSE + A2A)及更多 curl 範例,因而超過偵測門檻。

此檔案只是靜態文件,完全不含任何可執行內容。您可以放心地將它從隔離區還原。

處理方式:

  1. 停止通知 — 在防毒軟體中排除安裝目錄 (Avast:設定 → 例外),加入您的全域 node_modules 路徑及/或 OmniRoute 資料目錄(~/.omniroute/)。
  2. 回報誤判 — https://www.avast.com/false-positive-file-form.php, 並附上被隔離的 README.md。這才是能幫助所有人的修正方式,因為問題在於 廠商的啟發式偵測對文字檔反應過度。

**為何我們不在自身這一端「修正」此問題:**所有範例都是 http://localhost,而 localhost 若不使用會帶來不便的自簽憑證,就無法使用 https。為了規避單一廠商的 啟發式偵測而竄改文件,只會為了迎合掃描器的錯誤而損害所有讀者的使用體驗。

Kaspersky 將桌面應用程式標記為 PDM:Trojan.Win32.Generic

Section titled “Kaspersky 將桌面應用程式標記為 PDM:Trojan.Win32.Generic”

這是行為式啟發偵測造成的誤判。沒有任何檔案受到感染。 Kaspersky 的 PDM: 前綴表示判定來自其 Proactive Defense Module(System Watcher), 它是根據安裝程式的實際_行為_進行判斷,而不是比對已知惡意軟體。觸發時, Kaspersky 會「回復」整個安裝程序,刪除已寫入的檔案,因此應用程式最後會損壞或消失。

它標記的檔案是桌面應用程式所隨附、已宣告之開放原始碼相依套件的標準元件,例如:

  • resources/app/.build/next/node_modules/playwright-&lt;hash&gt;/lib/…/agentParser.js 和 workerProcessEntry.js — Playwright,用於應用程式內 服務提供者登入及瀏覽器支援聊天功能的瀏覽器自動化程式庫。
  • resources/app/.build/next/node_modules/@wreq-js/binding-win32-&lt;arch&gt;-msvc-&lt;hash&gt;/wreq-js.win32-&lt;arch&gt;-msvc.node — 已固定版本的 wreq-js 原生繫結,用於在採用網頁 Cookie 的服務提供者上執行具有 瀏覽器指紋特徵的 HTTP 請求(&lt;arch&gt; 為 x64 或 arm64)。

觸發原因:Windows 安裝程式尚未進行程式碼簽署,因此未簽署的 NSIS 安裝程式完全沒有信譽資料,行為式啟發偵測會以最嚴格的方式執行。再加上隨附的原生 DLL, 以及寫入 %LOCALAPPDATA%\Programs\OmniRoute 下的數百個 .js 檔案(包括來自 Next.js 獨立建置、名稱後綴雜湊值的套件目錄),就足以觸發該啟發式偵測。我們已規劃 進行程式碼簽署;在實作完成之前,新版本仍可能重複發生此問題。

處理方式:

  1. 先驗證您的下載檔案(排除檔案遭竄改的可能性)。每個版本都會發布 latest.yml,其中的 sha512 欄位(base64)涵蓋 OmniRoute.Setup.&lt;version&gt;.exe 安裝程式。在 PowerShell 中,從包含安裝程式的 資料夾執行:
    Terminal window
    $b = [System.Security.Cryptography.SHA512]::Create().ComputeHash(
    [System.IO.File]::ReadAllBytes("$PWD\OmniRoute.Setup.&lt;version&gt;.exe"))
    [Convert]::ToBase64String($b)
    輸出結果必須與 latest.yml → sha512 相符。如果不相符,請刪除該檔案,並且僅從 GitHub 發布頁面重新下載。
  2. 還原並排除 — 從隔離區還原遭回復的項目,並為 %LOCALAPPDATA%\Programs\OmniRoute 新增排除項目(Kaspersky → 設定 → 威脅與排除), 然後重新安裝。
  3. 回報誤判 — https://opentip.kaspersky.com/。使用者提交的誤判報告 確實能加快加入允許清單的速度。

登入頁面當機或顯示「Module self-registration」錯誤

Section titled “登入頁面當機或顯示「Module self-registration」錯誤”

原因: 您執行的 Node.js 版本不符合 OmniRoute 核准的安全執行環境最低要求。最常見的情況是執行較舊的 Node 22 或 24 修補版本,低於 OmniRoute 要求的安全修補最低版本。

症狀:

  • 登入頁面顯示空白畫面或伺服器錯誤
  • 主控台顯示 Error: Module did not self-register 或類似的原生繫結錯誤
  • 如果執行環境不符合支援的安全性政策,登入頁面會顯示包含您 Node 版本的橘色警告橫幅

修正方式:

  1. 安裝受支援的 Node.js LTS 版本(建議:Node.js 24.x):
    Terminal window
    nvm install 24
    nvm use 24
  2. 驗證您的版本:node --version 應在 24.x LTS 系列中顯示 v24.0.0 或更新版本
  3. 重新安裝 OmniRoute:npm install -g omniroute
  4. 重新啟動:omniroute

受支援的安全版本: >=22.22.2 <23 或 >=24.0.0 <27。完整支援 Node.js 24.x LTS (Krypton) 與 Node.js 26。

npm v11+:未安裝 better-sqlite3(找不到模組)

Section titled “npm v11+:未安裝 better-sqlite3(找不到模組)”

原因: npm v11(隨 Node.js 24+ 提供)預設會封鎖選用 相依套件的安裝指令碼。由於 better-sqlite3 列於 optionalDependencies 中,且需要進行原生編譯(node-gyp rebuild),npm 會在不發出提示的情況下略過它。

症狀:

  • 伺服器啟動時當機並顯示 Cannot find module 'better-sqlite3'
  • ls node_modules/better-sqlite3 顯示「No such file or directory」
  • npm ls better-sqlite3 顯示 (empty)

修正方式:

  1. 核准安裝指令碼並重新安裝:
    Terminal window
    npm approve-scripts better-sqlite3
    npm install
  2. 或手動安裝預先建置的版本:
    Terminal window
    npm pack better-sqlite3@13.0.1
    tar -xzf better-sqlite3-*.tgz -C node_modules
    mv node_modules/package node_modules/better-sqlite3
    rm better-sqlite3-*.tgz
  3. 驗證其是否正常運作:node -e "require('better-sqlite3')(':memory:').close(); console.log('OK')"

macOS:dlopen /「slice is not valid mach-o file」

Section titled “macOS:dlopen /「slice is not valid mach-o file」”

原因: 全域執行 npm install -g omniroute 後,套件內的 better-sqlite3 原生二進位檔可能是針對與本機執行環境不同的架構或 Node.js ABI 所編譯。當預先建置的二進位檔與您的環境不相符時,這種情況在 macOS(包括 Apple Silicon 與 Intel)上相當常見。

症狀:

  • 伺服器啟動時立即失敗並顯示 dlopen 錯誤
  • 錯誤中包含 slice is not valid mach-o file
  • 完整範例:
dlopen(/Users/&lt;user&gt;/.nvm/versions/node/v24.14.1/lib/node_modules/omniroute/app/node_modules/better-sqlite3/build/Release/better_sqlite3.node, 0x0001): tried: '...' (slice is not valid mach-o file)

修正方式 — 針對您的本機環境重新建置(無須降級 Node.js):

Terminal window
cd $(npm root -g)/omniroute/app
npm rebuild better-sqlite3
omniroute

注意: 這會針對您的本機 Node.js 版本與 CPU 架構重新編譯原生繫結,從而解決二進位檔不相符的問題。官方支援的執行環境範圍是 >=22.22.2 <23 或 >=24.0.0 <27(src/shared/utils/nodeRuntimeSupport.ts 中的 SUPPORTED_NODE_RANGE,與 package.json 的 engines 欄位一致)。完整支援搭配 better-sqlite3 v12.x 的 Node.js 24.x LTS (Krypton) 與 Node.js 26。


原因: API 金鑰驗證端點 (POST /api/providers/validate) 先前會略過 Proxy 設定,導致在需要透過 Proxy 路由的環境中發生失敗。

修正(v3.5.5+): 此問題現已修正。提供者驗證現在會透過 runWithProxyContext 路由,並自動遵循提供者層級和全域 Proxy 設定。

Token 健康狀態檢查因「fetch failed」而失敗

Section titled “Token 健康狀態檢查因「fetch failed」而失敗”

原因: 背景 OAuth Token 重新整理未針對每個連線解析 Proxy 設定。

修正(v3.5.5+): Token 健康狀態檢查排程器現在會在嘗試重新整理之前,針對每個連線解析 Proxy 設定。請更新至 v3.5.5+。

SOCKS5 Proxy 傳回「invalid onRequestStart method」

Section titled “SOCKS5 Proxy 傳回「invalid onRequestStart method」”

原因: 在 Node.js 22 上,undici@8 dispatcher 與 Node 內建的 fetch() 實作不相容。

修正(v3.5.5+): 當 Proxy dispatcher 啟用時,OmniRoute 現在會使用 undici 自己的 fetch() 函式,以確保行為一致。請更新至 v3.5.5+。

WSL 下的 MITM Proxy:Windows 主機上的桌面應用程式未被攔截

Section titled “WSL 下的 MITM Proxy:Windows 主機上的桌面應用程式未被攔截”

原因: MITM Proxy 及其 CA 憑證會安裝到 OmniRoute 執行所在的環境。在 WSL 下,該環境是 Linux 客體系統,而 AI 桌面應用程式(Kiro、Trae、Copilot、Zed,……)則執行於 Windows 主機。主機應用程式不信任客體系統的憑證存放區,也不會透過客體系統的系統 Proxy 路由,因此桌面攔截不會在該處生效。

建議: 請在與您要攔截的桌面應用程式相同的作業系統上原生執行 OmniRoute(Windows 應用程式使用 Windows;macOS/Linux 亦同)。若將 OmniRoute 保留在 WSL 內,同時以主機應用程式為目標,則必須在 Windows 主機上手動信任產生的 CA 憑證,並將每個主機應用程式的網路/Proxy 設定指向 WSL Proxy 端點——這是一種不受支援且不穩定的設定。


「Language model did not provide messages」

Section titled “「Language model did not provide messages」”

原因: 提供者配額已用盡。

修正:

  1. 檢查儀表板配額追蹤器
  2. 使用具有後備層級的組合
  3. 切換至較便宜/免費的層級

原因: 訂閱配額已用盡。

修正:

  • 新增後備選項:cc/claude-opus-4-6 → glm/glm-4.7 → if/qwen3.8-max-preview
  • 使用 GLM/MiniMax 作為低成本備援

OmniRoute 會自動重新整理 Token。若問題持續發生:

  1. 儀表板 → 提供者 → 重新連線
  2. 刪除提供者連線後再重新新增

Kiro 多帳戶:第二個帳戶會使第一個帳戶失效

Section titled “Kiro 多帳戶:第二個帳戶會使第一個帳戶失效”

原因: Kiro 的後端會針對每個 OIDC 用戶端註冊強制僅允許一個有效工作階段。 當兩個帳戶共用相同的已註冊用戶端(v3.8.0 之前匯入的連線)時, 重新整理其中一個帳戶的 Token 會使另一個帳戶的重新整理 Token 失效。

修正(v3.8.0+): 重新匯入受影響的連線。 自 v3.8.0 起,每個透過匯入 Token、 Google/GitHub 社群登入或自動匯入建立的新 Kiro 連線,都會自動註冊其各自 專用的 OIDC 用戶端。因此,連線會完全隔離,重新整理其中一個 帳戶不會對任何其他帳戶造成影響。

在 v3.8.0 之前 匯入的連線不具備個別連線專用的用戶端 註冊。這些連線會繼續使用共用的社群驗證重新整理端點。 若要獲得隔離效果,請從「儀表板 → 提供者」刪除舊連線,然後透過 上述三種匯入流程中的任一種重新新增。

如需完整詳細資訊,以及並列新增兩個 Kiro 帳戶的逐步操作說明, 請參閱 docs/guides/KIRO_SETUP.md。


  1. 確認 BASE_URL 指向正在執行的執行個體(例如 http://localhost:20128)
  2. 確認 CLOUD_URL 指向您的雲端端點(例如 https://omniroute.dev)
  3. 確保 NEXT_PUBLIC_* 的值與伺服器端的值一致

症狀: 對雲端端點進行非串流呼叫時出現 Unexpected token 'd'...。

原因: 上游傳回 SSE 承載資料,但用戶端預期收到 JSON。

因應措施: 對雲端進行直接呼叫時使用 stream=true。本機執行環境包含 SSE→JSON 備援機制。

雲端顯示已連線,但出現「Invalid API key」

Section titled “雲端顯示已連線,但出現「Invalid API key」”
  1. 從本機儀表板建立新金鑰(/api/keys)
  2. 執行雲端同步:啟用雲端 → 立即同步
  3. 舊金鑰或尚未同步的金鑰在雲端仍可能傳回 401

症狀: curl http://localhost:20128/v1/models 傳回 curl: (56) Recv failure: Connection reset by peer。儀表板與未經驗證的端點可正常運作,但經過驗證的端點會失敗——看起來像是驗證問題,但其實不是。

原因: docker run -p 20128:20128 會同時在 0.0.0.0(IPv4)和 ::(IPv6)上公開連接埠,但容器內的程序僅監聽 IPv4。在 localhost 優先解析為 ::1 的主機上,連線會進入已公開的 IPv6 連接埠,但其後方沒有監聽程式 → 連線遭重設。

修正方式:

  1. 快速診斷: 執行 curl -4 http://localhost:20128/v1/models。如果加上 -4 後可正常運作,但未加時失敗,表示存在 IPv6 繫結不相符的問題。
  2. 永久修正: 在 docker run 命令中使用 -p 127.0.0.1:20128:20128,明確繫結至 IPv4:
    Terminal window
    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:latest
    這會強制使用 IPv4 繫結,同時避免將代理公開於主機的所有介面。

  1. 檢查執行環境欄位:curl http://localhost:20128/api/cli-tools/runtime/codex | jq
  2. 若使用可攜模式:請使用映像檔目標 runner-cli(內含 CLI)
  3. 若使用主機掛載模式:設定 CLI_EXTRA_PATHS,並以唯讀方式掛載主機的二進位檔目錄
  4. 如果 installed=true 且 runnable=false:已找到二進位檔,但健康檢查失敗
Terminal window
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'

  1. 在儀表板 → 使用量中檢查使用統計資料
  2. 將主要模型切換為 GLM/MiniMax
  3. 將免費方案(Qoder、Kiro)用於非關鍵任務
  4. 為每個 API 金鑰設定成本預算:儀表板 → API 金鑰 → 預算

在您的 .env 檔案中設定 APP_LOG_TO_FILE=true。應用程式記錄會寫入 logs/。 當設定中已啟用呼叫記錄管線時,請求成品會儲存於 ${DATA_DIR}/call_logs/ 下。 啟用管線擷取時,請設定 CALL_LOG_PIPELINE_CAPTURE_STREAM_CHUNKS=false 以省略 串流區塊承載資料,或調整 CALL_LOG_PIPELINE_MAX_SIZE_KB 以變更成品大小上限(單位為 KB)。

Terminal window
# 健康狀態儀表板
http://localhost:20128/dashboard/health
# API 健康檢查
curl http://localhost:20128/api/monitoring/health
  • 主要狀態:${DATA_DIR}/storage.sqlite(提供者、組合、別名、金鑰、設定)
  • 使用量:storage.sqlite 中的 SQLite 資料表(usage_history、call_logs、proxy_logs)+ 選用的 ${DATA_DIR}/call_logs/
  • 應用程式記錄:&lt;repo&gt;/logs/...(當 APP_LOG_TO_FILE=true 時)
  • 呼叫記錄成品:啟用呼叫記錄管線時位於 ${DATA_DIR}/call_logs/YYYY-MM-DD/...

「請求記錄」頁面的清除歷史記錄動作會清除 call_logs、舊版 request_detail_logs,以及本機 ${DATA_DIR}/call_logs/ 成品目錄。


當提供者的斷路器處於 OPEN 狀態時,所有請求都會遭到封鎖,直到冷卻時間結束。

修正方式:

  1. 前往 Dashboard → Settings → Resilience
  2. 檢查受影響提供者的斷路器卡片
  3. 按一下 Reset All 以清除所有斷路器,或等待冷卻時間結束
  4. 重設前,請確認提供者實際上可用

如果提供者反覆進入 OPEN 狀態:

  1. 在 Dashboard → Health → Provider Health 中檢查失敗模式
  2. 前往 Settings → Resilience → Provider Profiles,並提高失敗閾值
  3. 檢查提供者是否已變更 API 限制,或是否需要重新驗證
  4. 檢視延遲遙測資料 — 高延遲可能會造成逾時型失敗

  • 使用第一個區段為您已具備憑證之提供者的模型 ID(openai/whisper-1、openrouter/deepgram/nova-3)。僅使用 deepgram/nova-3 需要原生 Deepgram 金鑰。
  • 確認提供者已在 Dashboard → Providers 中連線
  • 檢查支援的音訊格式:mp3、wav、m4a、flac、ogg、webm
  • 確認檔案大小在提供者的限制內(通常 < 25MB)
  • 在提供者卡片中檢查 API 金鑰是否有效

使用 Dashboard → Translator 對格式轉換問題進行偵錯:

模式 使用時機
Playground 並排比較輸入/輸出格式 — 貼上失敗的請求,查看其轉換結果
Chat Tester 傳送即時訊息,並檢查完整的請求/回應承載資料,包括標頭
Test Bench 針對各種格式組合執行批次測試,以找出哪些轉換已損壞
Live Monitor 監看即時請求流程,以捕捉間歇性的轉換問題
  • 未出現思考標籤 — 檢查目標提供者是否支援思考功能,以及思考預算設定
  • 工具呼叫遺失 — 某些格式轉換可能會移除不支援的欄位;請在 Playground 模式中確認
  • 系統提示缺失 — Claude 和 Gemini 對系統提示的處理方式不同;請檢查轉換輸出
  • SDK 傳回原始字串而非物件 — 已在 v1.x 中解決;回應清理器會移除導致 OpenAI SDK Pydantic 驗證失敗的非標準欄位(x_groq、usage_breakdown 等)。如果您在 v3.x+ 上仍遇到此問題,請提交 issue。
  • GLM/ERNIE 拒絕 system 角色 — 已在 v1.x 中解決;對於不相容的模型,角色正規化器會自動將系統訊息合併至使用者訊息中。如果您在 v3.x+ 上仍遇到此問題,請提交 issue。
  • 無法辨識 developer 角色 — 已在 v1.x 中解決;對於非 OpenAI 提供者,會自動轉換為 system。如果您在 v3.x+ 上仍遇到此問題,請提交 issue。
  • json_schema 無法搭配 Gemini 使用 — 已在 v1.x 中解決;response_format 現在會轉換為 Gemini 的 responseMimeType + responseSchema。如果您在 v3.x+ 上仍遇到此問題,請提交 issue。

  • 自動速率限制僅適用於 API 金鑰提供者(不適用於 OAuth/訂閱)
  • 確認 設定 → 韌性 → 提供者設定檔 已啟用自動速率限制
  • 檢查提供者是否傳回 429 狀態碼或 Retry-After 標頭

提供者設定檔支援以下設定:

  • 基礎延遲 — 第一次失敗後的初始等待時間(預設:1s)
  • 最大延遲 — 等待時間上限(預設:30s)
  • 倍數 — 每次連續失敗時增加延遲的幅度(預設:2x)

當許多並行請求送至受到速率限制的提供者時,OmniRoute 會使用互斥鎖 + 自動速率限制來序列化請求,並防止連鎖失敗。對 API 金鑰提供者而言,此機制會自動運作。

聊天請求因 503 / chat_admission_busy 而失敗

Section titled “聊天請求因 503 / chat_admission_busy 而失敗”

症狀:

  • 聊天補全端點傳回可重試的 503 回應,其錯誤代碼為 chat_admission_busy。
  • 回應包含 Retry-After。自 #12135 起,此值會根據觀察到的 佔用情況推導而得 — 取請求已等待的 OMNIROUTE_CHAT_ADMISSION_QUEUE_MS 時間範圍 與目前重量級租約已持有時間兩者之中較大的值 — 向上取整至整數 秒,並以 60 秒為上限。當閘門閒置時,會保留歷史下限:以位元組為基礎的 路徑為 2 秒,以結構為基礎的路徑為 1 秒(後者也會包含 reason: "structure_limit")。
  • 當另一個重量級聊天或長時間執行的串流回應仍在 處理中時,可能會發生此情況。

以位元組為基礎的回應主體如下:

{
"error": {
"message": "Chat admission capacity is temporarily unavailable. Retry shortly.",
"type": "server_error",
"code": "chat_admission_busy"
}
}

以結構為基礎的回應使用相同的類型與代碼,其訊息為 Local chat admission capacity is busy for this structurally heavy request; upstream provider routing was not attempted. Retry shortly. 並包含 reason: "structure_limit"。 在預設閾值下,若請求包含至少 200 則訊息、 至少 64 個工具,或至少 32,000 個估算權杖,或有界結構估算 耗盡其 10,000 個已造訪節點或深度 12 的界限,該請求即屬於結構繁重的請求。

原因: 這是 OmniRoute 內部刻意執行的負載卸除,而非上游提供者故障。 每個處理程序都會使用處理程序本機防護機制,在保留並剖析大型請求主體之前, 先保留有限的重量級容量。重量級租約會在 SSE 回應的整個生命週期內持續保持。

#503 扇出: 此修正之前,無論主機記憶體多少,防護機制都會將並行度限制為固定的請求數量 (OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT,預設為 1),因此程式設計代理程式的 扇出(多個子代理程式/CLI,主體通常 > 256 KB)會使有效 並行度降至約 1,並在完全正常的負載下傳回 503。防護機制現在會自行調整:其閘控 依據是從處理程序實際記憶體上限自動推導出的擷取位元組預算(OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES), 同時也會參考即時資源壓力訊號 — 因此只有當主機確實承受記憶體壓力時 才會卸除負載,而不會僅因同時收到多個重量級請求就這麼做。舊的數量上限 (OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT)仍會受到遵循,但前提是您明確設定它。

當容量忙碌時,重量級請求會先等待最多 OMNIROUTE_CHAT_ADMISSION_QUEUE_MS(預設為 2000,0 會停用等待),等候空位釋出, 之後才回覆可重試的 503。此有界等待機制可讓會同時扇出重量級子請求的代理程式型用戶端 (OpenCode、Claude Code、Cursor)將突發請求序列化, 而不是因立即遭到拒絕便耗盡全部重試預算,並在工作進行途中失敗。 目前的重量級租約佔用情況、已解析的位元組預算及即時壓力嚴重程度, 會顯示於 GET /api/monitoring/health → chatAdmission(inflightBytes、maxInflightBytes、 budgetSource、pressureSeverity、countCapEnabled)— 在調整任何環境變數前,請先檢查這些資訊。 設定 → 韌性 → 請求佇列 → 並行請求不會控制此機制;該設定 管理的是另一套獨立的提供者請求佇列機制。

修正方式:

  1. 先重試。用戶端應遵循 Retry-After 並使用退避,而不是立即 重複請求。
  2. 調整任何項目之前,請先檢查 /api/monitoring/health → chatAdmission。countCapEnabled: false 以及充足的 maxInflightBytes 表示自動推導的預算已經正常 運作;若 pressureSeverity 為 high/critical,則表示主機的記憶體確實不足 — 此問題無法透過准入環境變數修正,而是需要更多 RAM 或較小的工作負載。
  3. 只有當 /api/monitoring/health 顯示自動推導的預算對您的主機而言確實過小時 (這很少見 — 它已經能從容器擴展至裸機環境),才應直接使用 OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES 覆寫,而不要退回使用舊版的請求數量上限。

如需具權威性的准入設定,請參閱環境變數參考資料。


選用的 RAG / LLM 失敗分類法(16 個問題)

Section titled “選用的 RAG / LLM 失敗分類法(16 個問題)”

部分 OmniRoute 使用者會將閘道部署在 RAG 或代理堆疊前方。在這類設定中,經常會看到一種奇怪的情況:OmniRoute 看起來運作正常(提供者在線、路由設定檔正常、沒有速率限制警示),但最終答案仍然有誤。

實務上,這類事件通常源自下游的 RAG 管線,而不是閘道本身。

如果你希望使用一套共通詞彙來描述這些失敗,可以使用 WFGY ProblemMap。這是一項採用 MIT 授權條款的外部純文字資源,定義了十六種反覆出現的 RAG / LLM 失敗模式。概括而言,它涵蓋:

  • 擷取偏移與上下文邊界損壞
  • 空白或過期的索引與向量儲存庫
  • 嵌入與語意不相符
  • 提示詞組裝與上下文視窗問題
  • 邏輯崩潰與過度自信的回答
  • 長鏈與代理協調失敗
  • 多代理記憶與角色偏移
  • 部署與啟動順序問題

做法很簡單:

  1. 調查不良回應時,請記錄:
    • 使用者任務與請求
    • OmniRoute 中的路由或提供者組合
    • 下游使用的任何 RAG 上下文(擷取的文件、工具呼叫等)
  2. 將事件對應至一或兩個 WFGY ProblemMap 編號(No.1 … No.16)。
  3. 將編號連同 OmniRoute 日誌儲存在你自己的儀表板、操作手冊或事件追蹤器中。
  4. 使用對應的 WFGY 頁面,判斷是否需要變更 RAG 堆疊、擷取器或路由策略。

完整內容與具體處理方式位於此處(MIT 授權,純文字):

WFGY ProblemMap README

如果你沒有在 OmniRoute 後方執行 RAG 或代理管線,可以忽略本節。


以下是 v3.8.0 版本特有的問題及目前的因應措施。如果修正已包含在後續修補版本中,相關項目將會更新或移除。

症狀:

  • 呼叫由 Devin 支援的工具時出現「Devin CLI not found」或「auth failed」
  • CLI 執行階段檢查回報 installed=false

原因:

  • CLI_DEVIN_BIN 指向不存在的路徑
  • 主機上未安裝 Devin CLI

修正方式:

  1. 安裝適用於你平台的 Devin CLI
  2. 在 .env 中設定 CLI_DEVIN_BIN=/usr/local/bin/devin(或實際路徑)
  3. 重新啟動 OmniRoute,然後從 儀表板 → CLI 工具重新測試

模型冷卻狀態卡住(手動重設)

Section titled “模型冷卻狀態卡住(手動重設)”

症狀:

  • 即使到期時間已過,模型仍列為冷卻中
  • 儘管時間戳記已是過去時間,組合路由仍會略過該模型

手動重設:

  • 儀表板: 設定 → 模型冷卻 → 在受影響的卡片上按一下重新啟用
  • API: 使用管理驗證標頭傳送 DELETE /api/resilience/model-cooldowns

Command Code 提供者連線失敗並出現 403

Section titled “Command Code 提供者連線失敗並出現 403”

症狀:

  • 測試 Command Code 提供者連線時出現 403
  • 新增後,提供者卡片顯示「unauthorized」

原因: OAuth 流程未完成(未收到回呼或權杖未持久儲存)。

修正方式:

  • 從 CLI 執行 omniroute providers 以重新觸發 OAuth 流程,或
  • 從儀表板 → 提供者 → Command Code → 重新連線重新執行 OAuth

ModelScope 回傳過於激進的 429 冷卻時間

Section titled “ModelScope 回傳過於激進的 429 冷卻時間”

症狀:

  • 在少量突發請求後,ModelScope 出現非常短或立即生效的冷卻時間
  • 組合路由比預期更早略過 ModelScope

原因: ModelScope 會發出提供者特有的 Retry-After 標頭。v3.8.0 提供了這些標頭的專用處理方式,因此較舊版本會將其誤判為一般速率限制提示。

修正方式:

  • 確認你使用的是 v3.8.0 或更新版本
  • 確認設定 → 韌性下的 useUpstream429BreakerHints 開關已啟用

正式環境中缺少 OMNIROUTE_WS_BRIDGE_SECRET

Section titled “正式環境中缺少 OMNIROUTE_WS_BRIDGE_SECRET”

症狀:

  • 在遠端正式主機上執行時,每個 Codex/Responses WebSocket 橋接請求都回傳 401
  • WebSocket 橋接交握在連線後立即關閉

原因: 正式環境中缺少 OMNIROUTE_WS_BRIDGE_SECRET 環境變數。

修正方式:

  1. 產生隨機密鑰:openssl rand -hex 32
  2. 在正式伺服器環境中設定 OMNIROUTE_WS_BRIDGE_SECRET=&lt;random-secret&gt;(以及任何與橋接器通訊的用戶端)
  3. 重新啟動 OmniRoute

Responses API:背景模式降級為同步模式

Section titled “Responses API:背景模式降級為同步模式”

症狀:

  • 記錄警告:background mode degraded to synchronous
  • background: true 請求會回傳一般同步回應,而不是背景工作控制代碼

原因: v3.8.0 會刻意將 Responses API 上的 background: true 降級為同步執行,並同時發出警告。完整的非同步背景執行功能將於未來提供。

修正方式:

  • 調整用戶端,使其呼叫時不使用 background,或
  • 等待提供完整非同步背景模式的後續版本(請追蹤變更日誌)

如果 CLI 顯示 ⚠ Server did not respond within 60s,但伺服器實際上仍正常運作,表示就緒探測的等待時間對您的環境而言太短。

這通常發生在 Windows(防毒軟體、檔案系統監控程式)或啟動工作負載繁重的容器中。

修正方式 — 延長等待時間:

Terminal window
# 透過環境變數(在多次啟動之間持續生效):
export OMNIROUTE_READY_TIMEOUT_MS=180000 # 3 分鐘
omniroute serve
# 透過 CLI 旗標(僅限單次):
omniroute serve --ready-timeout 180000

預設值為 60 000 毫秒(60 秒)。此警告僅供參考;伺服器會繼續在背景啟動,並在啟動完成後可供存取。

如需 OMNIROUTE_READY_TIMEOUT_MS 的完整詳細資訊,請參閱 docs/reference/ENVIRONMENT.md。



OmniRoute 原始碼 (a58000c7685f)

HagiCode

HagiCode 是智慧代理程式開發工作台,結合結構化工作流程、多代理程式執行與 Hero Dungeon 介面,將想法化為交付成果。

以更聰明、更快速且更有趣的智慧代理程式工作流程,打造實用的軟體。

HagiCode 淺色主題介面畫面
  • Smart結構化流程將意圖轉化為從構想到交付的可執行步驟。
  • Efficient多代理程式工作流程讓研究、實作與審查並行進行。
  • FunHero Dungeon 讓長時間的程式協作更直覺、更有參與感。
造訪 HagiCode