# OmniRoute

> 41,856★ 게이트웨이를 안 쓴 이유는 성능이 아니다. 이 도구의 1티어가 내 구독 계정을 위장해 태워 보내는 구조라서다.

- 수치: 수확 7종 → 0
- 사람이 보는 화면: https://aitryed.com/ko/teardowns/harness/omniroute/
- 반대 언어: https://aitryed.com/en/teardowns/harness/omniroute/index.md
- 저장소: https://github.com/diegosouzapw/OmniRoute
- 이 사이트 안내(AI용): https://aitryed.com/ko/llms.txt

---

**AI 서비스 291개를 하나의 창구로 묶어 주는 도구입니다. 잘 만들었고, 배울 게 일곱 가지 있었고, 일곱 가지 다 안 쓰기로 했습니다. 이유는 성능이 아니라 «무엇을 태워 보내는가»였습니다.**

> **[도판]** 티어를 순서대로 내려가는 구조 자체는 깔끔하다. 문제는 그 순서의 첫 칸이 무엇인가에 있다.
>
> 요청 하나가 내려가는 경로. IDE 33종이 로컬 프록시 하나만 바라보고, 프록시가 압축 엔진 12개를 거쳐 티어 1부터 4까지 순서대로 시도한다. 티어 1이 구독 계정이고 여기가 이 도구를 못 쓰는 이유다.

## 이 도구가 하는 일

AI 서비스는 회사마다 **부르는 방법이 다릅니다.** 여러 개를 쓰려면 그만큼 다르게 짜야 합니다.

이 도구는 그 사이에 끼어 앉아 **전부 같은 방법으로 부를 수 있게** 해 줍니다. 그리고 한 곳이 안 되면 **자동으로 다음 곳으로 넘깁니다.**

「좋아요」 41,856개, 한 달 설치 21만 회. 규모도 큽니다.

| | 개수 |
|---|---|
| 소스 파일 | **11,091** |
| 테스트 파일 | 4,240 |
| 문서 | 1,460 — 다만 **1,215개가 43개 언어 번역본**이라 원문은 약 245개 |

문서 줄을 따로 적어 둔 이유가 있습니다. **「문서 1,460개」는 실제보다 여섯 배 커 보입니다.** 번역본을 빼고 세어야 실제 규모가 나옵니다.

## 잘 만든 부분 — 「고장을 한 덩어리로 안 본다」

기술적으로 정말 잘 만든 부분이 있습니다. **실패를 세 층으로 쪼갭니다.**

| 층 | 무엇을 끊나 | 비유하면 |
|---|---|---|
| 1층 | **회사 전체**를 잠시 끊음 | 그 가게 전체가 문 닫음 |
| 2층 | **열쇠 하나**만 재움 | 그 직원 하나만 쉼 |
| 3층 | **모델 하나**만 잠금 | 그 메뉴 하나만 품절 |

왜 이게 좋냐면 — 「오류가 났다」고 다 같은 오류가 아니기 때문입니다. **회사 서버가 죽은 것**과 **내 열쇠 하나가 한도 초과된 것**은 완전히 다른데, 층을 안 나누면 **둘 다 「실패」로 뭉뚱그려져서** 멀쩡한 나머지까지 같이 끊깁니다.

그리고 다시 여는 방식도 좋습니다. 한 번에 확 열지 않고 **60초 → 30초 → 15초로 줄이면서 절반만 먼저 보내 봅니다.** 살았나 확인하고 나머지를 보냅니다.

## 그런데 간판 숫자 셋이 전부 안 버텼습니다

<strong>「평균 89.2% 절감」</strong>이 대표 숫자입니다. 계산식을 보니 이랬습니다.

```
1 − (1−0.80) × (1−0.46) = 0.892
```

곱셈 한 줄입니다. 그리고 이 계산이 성립하려면 **전제가 하나** 필요합니다 — **두 압축 장치가 서로 «다른» 군더더기를 먹어야** 합니다.

실제로는 겹칩니다. 앞엣것은 반복되는 구조를 줄이고, 뒤엣것은 문장의 군더더기를 줄이는데, **같은 자리를 두 번 줄이는 부분이 있습니다.**

그리고 **그 독립성을 실제로 잰 데이터가 창고에 없습니다.**

→ 배운 것: **두 개선을 곱해서 합치는 계산은 「둘이 안 겹친다」는 전제 위에서만 참입니다.** 그 전제를 안 재고 곱하면 숫자가 부풀려집니다.

## 그래서 왜 일곱 개를 전부 기각했나

여기가 본론입니다. **성능이 아니라 구조 때문**입니다.

이 도구는 요청을 보낼 때 **순서대로 여러 곳을 시도**합니다. 그 **첫 번째 칸이 제 유료 구독 계정**이었습니다.

그 자체는 이상하지 않습니다. 문제는 **어떻게 태워 보내는가**입니다.

구독 계정은 **원래 그 회사가 만든 프로그램으로 쓰라고 준 것**입니다. 다른 프로그램이 그걸 쓰면 막힙니다. 이 도구는 그걸 **정식 프로그램인 것처럼 위장**해서 통과시킵니다.

그리고 결정적인 게 있습니다. **이 창고 자신이 「계정 영구 정지」를 «사고»가 아니라 «일상적으로 일어나는 일»로 모델링**해 두고 있었습니다. 정지당했는지 감지하는 화면을 **제품 기능으로** 팔고 있었습니다.

즉 **정지가 예외가 아니라 전제**입니다.

## 조각만 빼 오는 것도 안 합니다

「그럼 좋은 부분만 가져오면 되지 않나」 싶은데, 그것도 안 했습니다.

경계를 **조각이 아니라 창고 단위**로 그었습니다.

이유는 이렇습니다. 조각을 가져오려면 **그 조각을 읽고 이해하고 옮겨야** 합니다. 그 과정에서 **어디까지가 안전한 조각인지를 매번 판단**해야 합니다. 그리고 그 판단이 틀렸을 때 **대가가 계정 정지**입니다.

**판단 비용이 얻는 것보다 크면, 선은 조각이 아니라 통째로 긋는 게 맞습니다.**

그래서 **재제안 금지**로 적어 뒀습니다. 나중에 제가 이 문서를 근거로 다시 꺼내지 않도록.

## 공정하게 덧붙일 것

깎아내리기만 하면 틀립니다. **이 창고는 위험한 일을 하면서 그 위험을 문서로 드러내 놓는 쪽**입니다.

보안 문서만 **15편**이고, 정보 반출 정책·오류 정보 처리·공급망·사고 대응이 전부 따로 있습니다. **숨기는 쪽보다 훨씬 낫습니다.**

다만 하나만 분명히 해 둡니다.

> **드러내 놓았다는 사실이 도입해도 된다는 뜻은 아닙니다. 위험을 알고 있는 것과 위험이 사라지는 것은 다른 일입니다.**

## 여기부터는 자세한 기록입니다

**설계에서 배울 게 일곱 가지 있었고, 일곱 가지 다 안 쓰기로 했습니다.** OmniRoute는 AI 프로바이더 291개를 로컬 엔드포인트 하나로 묶어 주는 게이트웨이입니다. 별 41,856개, npm 월 다운로드 21만. 그런데 이 게이트웨이가 요청을 제일 먼저 태워 보내는 **1티어가 제 Claude Code·Codex 구독 계정**이고, 그걸 태우는 방법이 **TLS 지문 위장과 클라이언트 이름 난독화**입니다. 레포 자신이 「계정 영구 정지」를 예외가 아니라 **상시 운영 상태로 모델링**해 두고 밴 감지 UI를 제품 기능으로 팔고 있었습니다.

## 무엇을 하는 물건인가

**로컬에 뜨는 OpenAI 호환 프록시입니다.** `npm i -g omniroute` 로 깔면 `localhost:20128/v1` 이 열리고, IDE와 CLI는 그 주소 하나만 바라봅니다. 뒤에서 라우터가 프로바이더를 고르고, 앞이 실패하면 다음 칸으로 내려갑니다. 파는 것은 세 가지입니다 — **4티어 자동 폴백 · 12엔진 토큰 압축 · 3계층 복원력.**

규모는 실물입니다. 카탈로그만 채운 레포가 아닙니다.

| 구성 | 실측 |
|---|---|
| 소스 | 전체 11,091 파일 중 `.ts` 7,133 · `.tsx` 1,023 |
| 테스트 | 4,240 파일 — unit 3,991 / integration 124 / e2e 42 |
| 문서 | 1,460 파일. 다만 그중 **1,215가 43개 언어 번역본**이라 원문은 약 245개 |
| 배포 | npm 전역 · Docker · Electron · Termux · PWA |
| 기계 인터페이스 | MCP 104 tool / 31 scope · A2A · REST · 웹훅 · CLI 80+ 명령 |

npm 월 다운로드 21만 1,769건, 6개월에 288 버전. **유령 레포가 아니라 실제로 도는 물건**입니다.

## 대표 기법 — 여기는 진짜 잘 만들었다

**실패를 한 덩어리로 안 봅니다.** 같은 "에러"를 세 단위로 쪼갭니다. **L1 서킷브레이커**는 프로바이더 전체를 끊고(408·5xx 에만 발동, 60/30/15초 뒤 절반만 열어 탐침), **L2 쿨다운**은 키 하나만 재웁니다(기저 5초에 지수 백오프, 429는 Retry-After 준수), **L3 락아웃**은 모델 하나만 잠급니다. 한 군데 터졌을 때 **무엇이 죽은 것인지를 층으로 구분**합니다.

**그리고 재시도하면 안 되는 실패를 따로 둡니다.** 문서 원문이 이렇습니다 — *"terminal state(banned·expired·credits exhausted)는 운영자를 위한 것이지 쿨다운 대상이 아니다."* 되살아날 수 없는 실패를 재시도 큐에 넣지 않고 사람에게 올립니다.

나머지 다섯은 이렇습니다. **changelog 파편** — PR마다 `changelog.d/<이슈번호>-<슬러그>.md` 를 새로 하나 만들고 릴리스 때 합칩니다. 같은 파일을 여럿이 안 고치니 **병합 충돌이 구조적으로 0**입니다. **야간 CI 다섯 종** — 변이 테스트·속성 기반·OpenAPI 스키마 퍼징·복원력·LLM 보안. **숫자에 산정 방법을 붙이는 규율** — 헤드라인 옆에 중복 제거 방식과 재감사 주기와 *"숫자는 양방향으로 움직인다"* 를 같이 적습니다. **스킬 45개로 도구 자신을 감싸기.** **보존 엔진** — 압축 엔진 12개 앞에 코드·URL·JSON을 바이트 단위로 지키는 층을 따로 둡니다.

## 깨본 결과 — 간판 숫자 셋이 전부 안 버텼다

**「평균 89.2% 토큰 절감」은 곱셈 한 줄입니다.** 산식이 `1 − (1−0.80) × (1−0.46)` 인데, 이건 **두 압축기가 서로 다른 잉여를 먹는다는 가정** 위에서만 참입니다. 실제로 앞 엔진은 툴 출력의 구조적 반복을, 뒤 엔진은 산문의 어휘 잉여를 줄입니다 — 겹칩니다. **레포에 그 독립성을 잰 데이터가 없습니다.**

**「291 프로바이더 · 테스트 25,000+」는 산술적으로 성립하지 않습니다.** 테스트 파일을 직접 세면 왕복 검증에 해당하는 건 e2e 42 · integration 124 뿐입니다. 291개를 실제로 왕복해 본 테스트는 존재할 수 없습니다. 대부분은 **카탈로그 항목이지 검증된 경로가 아닙니다.**

**「기여자 500+」는 전수 페이징으로 368명이었습니다.** API 상한은 500이니 상한에 막힌 것도 아닙니다. 게다가 커밋 6,225건 중 **3,822건(61%)이 한 사람**이고 2위가 216건입니다. 기여자 10위에 `Antigravity Assistant`(45커밋)가 있고 주간 최대 572커밋(하루 80건)이 찍힙니다 — **커밋 상당수가 AI 생성**으로 봐야 합니다.

> **[도판]** 숫자 검증과 도입 판정은 다른 축이다. 이 레포는 두 축에서 각각 다른 이유로 걸렸다.
>
> 레포가 내건 숫자 셋을 다시 센 결과. 89.2퍼센트 절감은 독립성 가정 위에서만 참이고, 291 프로바이더 검증은 왕복 테스트가 166건뿐이며, 기여자 500명 이상은 전수 페이징으로 368명이었다.

## 그래서 왜 전부 기각했나

**차단 사유는 성능이 아니라 구조입니다.** 네 가지가 겹쳤습니다.

- **구독 계정 우회가 1티어입니다.** 클라이언트 이름의 첫 글자 뒤에 제로폭 결합자(U+200D)를 끼워 넣습니다. 문서가 밝힌 목적이 *"상류 필터가 grep 하지 못하도록"* 입니다. 별도 모듈은 Firefox TLS 지문을 그대로 흉내 내고, 또 다른 모듈은 요청을 *"공식 CLI 트래픽과 구별 불가능하게"* 재구성합니다. **같은 문서 서두에는 「ToS 위반용이 아니다」라고 적혀 있습니다** — 부인 문구와 코드가 하는 일이 어긋납니다.
- **밴을 상수로 취급합니다.** 상류 응답에서 `suspended`·`deactivated` 신호를 잡아 그 연결을 영구 차단 상태로 내리는 기능이 있고, 대시보드에 설정 카드까지 있습니다. **밴 감지가 제품 기능이라는 건 밴이 예외가 아니라는 뜻입니다.**
- **루트 CA를 OS 신뢰 저장소에 심습니다.** 로컬 HTTPS 복호화 모듈이 60여 파일. 기본 비활성이고 레포도 위험하다고 경고하지만, **개인 판단으로 할 일이 아니라 보안 승인 사안**입니다.
- **안전장치 둘이 모두 조용히 실패합니다.** 개인정보 마스킹은 *"fail-open이며 예외는 절대 트래픽을 막지 않는다"* — 마스커가 터지면 원문이 그대로 나갑니다. 감사 로그는 *"실패하면 조용히 삼킨다"* — **결손을 알 수 없는 로그는 근거로 쓸 수 없습니다.**

**그리고 수확 기법 7종까지 같이 기각했습니다.** 이게 이 페이지에서 제일 값을 치른 판단입니다. 3계층 실패 격리도 terminal state 분리도 제 야간 QA 루프에 그대로 맞는 설계였는데, **좋은 설계 조각을 뽑아 오는 일 자체가 이 레포를 계속 열어 보게 만든다**는 게 문제였습니다. 조각을 가져오려면 원본을 계속 참조해야 하고, 참조하다 보면 "이 정도는 개인 PC에서" 로 미끄러집니다. **경계는 조각 단위가 아니라 레포 단위로 긋는 게 맞았습니다.**

## 판정

| 항목 | 판정 |
|---|---|
| 도구 도입 | **차단.** 재론 불필요 |
| 설계 수확 7종 | **전량 기각.** 조각만 빼 오는 것도 안 함 |
| 재제안 | **금지.** 이 문서를 근거로 다시 제안하지 않는다 |
| 다시 여는 조건 | 제가 명시적으로 이 레포를 다시 꺼낼 때만 |

**공정하게 덧붙이면, 이 레포는 위험한 일을 하면서 그 위험을 문서로 드러내 놓는 쪽입니다.** 보안 문서만 15편이고 반출 정책·에러 살균·공급망·사고 대응이 전부 따로 있습니다. 숨기는 쪽보다 낫습니다. 다만 **드러내 놓았다는 사실이 도입 가능하다는 뜻은 아닙니다** — 위험을 알고 있다는 것과 위험이 사라지는 것은 다른 일입니다.

건강도에서 하나만 더. 커밋 61%가 한 사람, npm 메인테이너 한 명 — **버스 팩터 1**입니다. 6개월에 288 버전이면 이틀에 1.5회 릴리스이고, 회귀 위험이 구조적으로 높습니다. 별 41,856개는 이 둘을 가려 주지 않습니다.
