개요
9Router는 Claude Code, Cursor, Copilot 등 AI 코딩 도구를 40개 이상의 AI 제공업체에 연결하며, 자동 폴백과 RTK token 압축을 지원하여 token을 20-40% 절약하고 코딩이 중단되지 않도록 보장합니다.
README 미리보기
\n \n \n # 9Router - FREE AI Router & Token Saver\n \n **Never stop coding. Save 20-40% tokens with RTK + auto-fallback to FREE & cheap AI models.**\n \n **Connect All AI Code Tools (Claude Code, Cursor, Antigravity, Copilot, Codex, Gemini, OpenCode, Cline, OpenClaw...) to 40+ AI Providers & 100+ Models.**\n \n [](https://www.npmjs.com/package/9router)\n [](https://www.npmjs.com/package/9router)\n [](https://github.com/decolua/9router/blob/main/LICENSE)\n\n \n \n [🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Setup](#-setup-guide) • [🌐 Website](https://9router.com)\n\n [🇻🇳 Tiếng Việt](./i18n/README.vi.md) • [🇨🇳 中文](./i18n/README.zh-CN.md) • [🇯🇵 日本語](./i18n/README.ja-JP.md)\n\n\n---\n\n## 🤔 Why 9Router?\n\n**Stop wasting money, tokens and hitting limits:**\n\n- ❌ Subscription quota expires unused every month\n- ❌ Rate limits stop you mid-coding\n- ❌ Tool outputs (git diff, grep, ls...) burn tokens fast\n- ❌ Expensive APIs ($20-50/month per provider)\n- ❌ Manual switching between providers\n\n**9Router solves this:**\n\n- ✅ **RTK Token Saver** - Auto-compress tool_result content, save 20-40% tokens per request\n- ✅ **Maximize subscriptions** - Track quota, use every bit before reset\n- ✅ **Auto fallback** - Subscription → Cheap → Free, zero downtime\n- ✅ **Multi-account** - Round-robin between accounts per provider\n- ✅ **Universal** - Works with Claude Code, Codex, Cursor, Cline, any CLI tool\n\n---\n\n## 🔄 How It Works\n\n```\n┌─────────────┐\n│ Your CLI │ (Claude Code, Codex, OpenClaw, Cursor, Cline...)\n│ Tool │\n└──────┬──────┘\n │ http://localhost:20128/v1\n ↓\n┌─────────────────────────────────────────────┐\n│ 9Router (Smart Router) │\n│ • RTK Token Saver (cut tool_result tokens) │\n│ • Format translation (OpenAI ↔ Claude) │\n│ • Quota tracking │\n│ • Auto token refresh │\n└──────┬────────────────────────────────────
FAQ (5)
문제 해결opencode-go 또는 xiaomi-tokenplan 공급자를 테스트할 때 'Provider test not supported'가 반환되는 이유는 무엇인가요?
/api/providers/[id]/test 라우트에서 프로바이더 switch 문에 opencode-go 및 xiaomi-tokenplan에 대한 명시적 case가 누락되어 있었습니다. 이는 필요한 테스트 로직을 추가하여 수정되었습니다(PR #1576). 서버를 최신 커밋으로 업데이트하거나, app/src/app/api/providers/[id]/test/route.js에 유효성 검사 라우트를 참조하여 수동으로 case를 추가한 후 npm run build로 다시 빌드하세요.
문제 해결9Router가 콤보의 다음 모델로 폴백하지 않고 HTTP 408/499 오류를 반환하는 이유는 무엇인가요?
이것은 open-sse/services/accountFallback.js에 있는 복원력(resilience) 버그입니다. 43번째 줄에서 폴백 로직이 모든 4xx 상태(401/402/403/429 제외)를 재시도 불가능한 클라이언트 오류로 처리하면서, 일시적인 프록시 타임아웃까지 의도치 않게 포함하게 됩니다: HTTP 408 (AWS ALB/Cloudflare/HAProxy의 Request Timeout), 499 (Nginx의 Client Closed Request), 그리고 425 (TLS 0-RTT의 Too Early). 수정 방법: 이러한 일시적 코드를 명시적으로 제외하여 콤보 폴백이 트리거되도록 합니다:
// Exclude transient timeout / transport codes from client-error non-fallback
const NON_FALLBACK_CLIENT_STATUSES = new Set([
401, 402, 403, 429, // Account / quota scoped
408, 425, 499 // Transient gateway / timeout errors that MUST trigger fallback
]);
if (status >= 400 && status < 500 && !NON_FALLBACK_CLIENT_STATUSES.has(status)) {
return { shouldFallback: false, cooldownMs: 0 };
}
이 변경을 통해 업스트림 노드가 멈추고 게이트웨이가 408/499를 반환할 때, 9Router는 클라이언트 요청을 종료하는 대신 다음 콤보 멤버로 페일오버합니다.
문제 해결ds/deepseek-v4.1-flash 사용 시 9router DeepSeek 오류 "HTTP 400: you passed deepseek-v4.1-flash"를 해결하는 방법은?
9router의 내장 ds/deepseek-v4.1-flash 항목이 업스트림으로 잘못된 모델 이름을 전달합니다 — DeepSeek API는 deepseek-flash(또는 deepseek-v4-pro)만 허용하므로 요청이 HTTP 400 오류로 실패합니다. 해결 방법: 9router에서 "Add Model"을 사용하여 DeepSeek 제공업체 아래에 정확히 deepseek-flash라는 이름의 사용자 지정 모델을 생성하세요. 이렇게 하면 모델 테스트(녹색 체크)를 통과하고 채팅이 정상적으로 작동합니다. 영구적인 수정을 위해서는 9router가 V4.1 Flash 항목을 업스트림 이름 deepseek-flash에 매핑해야 합니다(issue #4939에서 추적 중).
문제 해결9router를 curl, Claude Code 또는 기타 non-OpenCode 클라이언트와 함께 사용할 때 발생하는 '403 FreeTierError: OpenCode's free tier can only be used from within OpenCode' 오류를 해결하는 방법
원인: 9router의 resolveOpencodeSession()(open-sse/executors/opencode.js에 위치)이 ses_ 세션 ID를 합성하는데, 이 ID의 12자리 16진수 접두사가 유효한 역전 타임스탬프가 아닌 SHA-256 다이제스트입니다. OpenCode Zen의 무료 티어(oc/* 모델)는 이 접두사를 검증하여 요청을 'OpenCode 클라이언트가 아님'으로 분류하고 403 FreeTierError로 거부합니다. 무료 티어만 영향을 받으며, OpenCode CLI는 실제 세션 헤더를 전송하기 때문에 정상 작동합니다.
우회 방법(코드 변경 없음): 모든 요청에 유효한 OpenCode 세션 ID 헤더를 전송하세요. 두 헤더 모두 작동합니다:
curl -H "x-session-id: ses_ecc985076ffe3FWJqsz05vQbUW" ...
curl -H "x-opencode-session: ses_ecc985076ffe3FWJqsz05vQbUW" ...
ID는 실제로 인코딩된 OpenCode ID여야 합니다(실제 ID는 접두사가 ~(Date.now()*0x1000 + counter)의 16진수 표현이므로 ses_ecc…ffe 형태로 나타남). 다이제스트에서 파생된 가짜 ses_ ID는 여전히 403을 반환합니다. 세션 경과 시간은 중요하지 않습니다 — 올바르게 인코딩된 ID는 30일 전 타임스탬프라도 여전히 200을 반환합니다. 요청 본문의 tools는 무관하며, 헤더가 유일한 판별 기준입니다.
영구 수정: resolveOpencodeSession()을 패치하여 일반 리졸버의 UUID를 translateSessionId()로 재래핑하는 대신 executor의 실제 생성기(stableSessionId, OpenCode와 동일한 generateSessionId() 사용)로 폴백하도록 합니다:
if (viaManager) {
if (OPENCODE_SESSION_RE.test(viaManager)) return viaManager;
return stableSessionId(credentials);
}
이렇게 하면 세션별 할당량 친화성(업스트림은 세션별로 무료 티어 사용량을 집계함)을 유지하면서 시간적으로 유효한 ses_ ID를 생성합니다.
문제 해결Why does 9Router /v1/models report a stale 272k context window for the top-gpt, high-gpt, and hermes-advisor presets, and how do I fix premature auto-compaction?
On 9Router v0.5.104 the Codex-backed combo presets top-gpt, high-gpt, and hermes-advisor advertised context_length: 272000 via GET /v1/models. The cause: top-gpt/high-gpt included the base cx/gpt-6-astra seat whose static Codex capability entry was 272000, and the combo cap was derived from the weakest seat, so clients deriving auto-compaction thresholds from model metadata compacted far too early (routable seats actually support 1M+). Fix (implemented and deployed on the patched fork): 1) Persist an optional per-combo context cap via an additive, backward-compatible SQLite migration. 2) Clamp the advertised cap to the resolved minimum capacity of the combo's seats. 3) Point top-gpt and high-gpt at the extended-context Astra seat so the old 272k seat can no longer lower the safe floor. 4) Treat empty SQLite context values as unset (not a zero-token cap). After deploying via blue-green rebuild, verify: GET /v1/models should return context_length and capabilities.contextWindow of 400000 for all three presets. Regression coverage: tests/unit/v1-models-combo-context.test.js and tests/unit/v1-models-route-codex.test.js.