정책, 캐시 친화성 및 지출 제어를 위한 단일 Rust 바이너리 형태의 자체 호스팅 LLM 라우터.
Millwright는 사용자의 AI 애플리케이션과 선택한 모델 제공자 사이에 실행되는 오픈 소스, 자체 호스팅 LLM 라우터입니다. OpenAI Chat Completions와 Anthropic Messages를 수신하여 각 요청을 OpenAI와 호환되는 API, Anthropic 또는 Amazon Bedrock으로 라우팅합니다.
사용자는 어떤 모델이 cheap, mid, 그리고 frontier 역할에 속하는지 정의합니다. Millwright는 해결된 역할이 허용하는 가장 낮은 추정 비용의 정상 경로를 선택하며, 세션 ID가 제공되면 프롬프트 캐시 재사용을 위해 제공자/모델 친화성(affinity)을 유지합니다.
Millwright는 라우터이며 에이전트 오케스트레이터가 아닙니다. 에이전트를 생성하거나, 작업을 스케줄링하거나, 프롬프트를 검사하거나, 컨텍스트를 재작성하지 않습니다.
모든 요청이 가장 비싼 모델에 도달하고 제공자 변경으로 인해 프롬프트 캐시 재사용이 깨질 때 LLM 비용은 빠르게 증가합니다. Millwright는 더 낮은 비용의 경로를 명확하게 만듭니다:
모델 지출 제어: 정책이 필요하다고 말하는 작업에만 frontier 모델을 예약할 수 있습니다.
프롬프트 캐시 보호: 역할별 친화성(role-scoped affinity)은 각 세션을 확인된 제공자와 모델에 유지하여 캐시 창이 따뜻하게 유지되도록 합니다.
동시 에이전트 구동 유지: 하나의 세션에서 요청을 직렬화하지 않고 독립적인 cheap, mid, 그리고 frontier 레인을 유지할 수 있습니다.
애플리케이션 코드 변경 없이 제공자 변경: 단일 엔드포인트 뒤에서 호환되는 트래픽을 여러 제공자로 라우팅합니다.
라우팅 검사 가능하게 유지: 응답 헤더가 선택된 경로를 식별하며, 영속성이 가능한 경우 추적(traces) 및 원장 항목(ledger entries)이 증거를 보존합니다.
데이터 플레인 자체 실행: 제공자 자격 증명은 사용자의 인프라에 남아 있으며, 필수적인 호스팅 제어 평면(hosted control plane)이 없습니다.
소스에서 빌드할 때는 Rust 1.97 이상이 필요합니다.
git clone https://github.com/Northwood-Systems/millwright.git
cd millwright
cargo install --path . --locked
...
millwright init
제공자(provider) 엔드포인트, 모델 역할(model roles), 가격 책정 방식(pricing), 그리고 분리된 워크로드 키와 운영자 키에 대해 설명합니다. 이 시스템은 제공자의 자격 증명 자체를 저장하는 것이 아니라, 제공자 비밀 환경 변수(provider-secret environment variables)에 대한 참조만 저장합니다.
Claude Code, Codex, OpenCode, Pi 또는 다른 호환 클라이언트를 연결하세요. 저렴한(cheap), 중간(mid), 또는 최첨단(frontier) 역할을 요청하려면 millwright-fast, millwright-code, 또는 millwright-plan을 선택합니다.
포함된 Docker Compose 설정은 Mock 제공자와 로컬 데모 키를 사용하여 Millwright를 시작합니다:
make compose-up
다른 터미널에서:
curl http://localhost:8080/v1/chat/completions \
-H 'Authorization: Bearer sk-millwright-local-demo' \
-H 'Content-Type: application/json' \
...
아키텍처 · 라우터 API · 정책 및 카탈로그 · 배포 · 비용 분석 · 보안
명시적인 작업(task) 및 위험(risk) 헤더, 클라이언트의 모델 선택 또는 문서화된 기본값을 사용하여 요청을 분류합니다. Millwright는 cheap, mid, 또는 frontier 역할을 해결한 다음, 정책이 허용하는 가장 낮은 추정 비용의 정상 작동 모델을 선택합니다. 고위험 및 계획 요청은 항상 최첨단(frontier) 역할을 사용합니다.
모든 결정에는 선택된 모델, 제공자, 경로 이유(route reason), 그리고 거부된 대안들이 포함됩니다. 결정을 내리기 위해 메시지 내용은 절대 검사되지 않습니다.
순진한(Naive) 요청별 라우팅은 세션 중간에 모델을 전환함으로써 제공자의 프롬프트 캐시 절약 효과를 지울 수 있습니다. Millwright는 독립적인 cheap, mid, 및 frontier 친화성 레인(affinity lanes)들을 하나의 불투명한 세션 ID 아래 유지하며, 각 레인은 자체 캐시 TTL(Time To Live)을 가집니다.
다른 역할로 해결된 트래픽은 더 이상 하나의 따뜻한 경로를 놓고 경쟁하지 않습니다. 동일한 역할을 가진 호출들은 마지막으로 확인된 제공자/모델에 수렴하는 반면, 모든 요청은 동시적으로 유지됩니다—Millwright는 에이전트 트래픽을 직렬화하거나 에이전트 라이프사이클을 오케스트레이션(orchestrate)하지 않습니다.
완료된 요청들은 일반적으로 사용 증거(usage evidence), 비용 출처(cost provenance), 제공자 시도, 그리고 라우팅 증거를 원장(ledger)에 기록합니다. 로컬 기본값은 SQLite이며, PostgreSQL은 프로덕션 배포에 사용할 수 있습니다.
| 명령어 | 표시 내용 |
|---|
millwright spend | 총 지출액(Total spend), 캐시 읽기율(cache read rate), 팀별 세부 내역 |
millwright models | 모델 및 제공업체 구성(Model and provider mix) |
millwright trace <id> | 거부된 대안을 포함한 단일 라우팅 결정 |
millwright top | 터미널에서 실시간 지출액 및 모델 활동 |
동일한 데이터는 인증된 /v1/millwright/* 관리 API를 통해 JSON 출력으로 spend, models, trace가 대시보드 및 자동화에 사용 가능합니다.
millwright analyze는 실시간 Millwright 원장(ledger) 또는 로컬 Millwright, OpenAI 호환, Anthropic JSONL을 읽습니다. 이는 자체 포함된 HTML 또는 Markdown 보고서와 스키마 버전이 지정된 JSON을 생성합니다.
millwright analyze \
--url http://127.0.0.1:8080 \
--key "$MILLWRIGHT_OPERATOR_KEY" \
...
보고서는 측정된(measured) 비용 증거와 모델링된(modeled) 후보 경제성을 분리합니다. 전체 교체 비용과 가격 하한선(price-floor) 경제 시나리오를 비교하려면 명시적인 카탈로그 및 후보 허용 목록(allowlist)을 추가하십시오. 후보 결과는 품질 결과나 프로덕션 라우팅 권장 사항이 아닌 비용 가설입니다. 비용 분석(Cost Analysis)을 참조하십시오.
OpenAI Chat Completions와 Anthropic Messages를 지원하며, OpenAI 호환 API, 네이티브 Anthropic, Amazon Bedrock을 통해 제공됩니다. 동일 프로토콜 경로(Same-protocol routes)는 Millwright가 모델링하지 않는 필드를 보존합니다. 교차 프로토콜 경로(Cross-protocol routes)는 지원되는 텍스트 및 도구 하위 집합(subset)으로 번역하고, 데이터를 조용히 삭제하는 대신 지원되지 않는 형태(shapes)를 거부합니다.
재시도 가능한 전송 실패, 시간 초과(timeouts), HTTP 408/429, 그리고 HTTP 5xx 응답은 하나의 제한된 장애 복구 시도(bounded failover attempt)를 유발할 수 있습니다. 서킷 브레이커(Circuit breakers)는 건강하지 않은 경로가 모든 요청을 받는 것을 막습니다.
Millwright는 Docker 및 Docker Compose 지원과 함께 단일 Rust 바이너리로 배포됩니다. 제공업체 자격 증명은 환경 변수에 유지되며, 별도의 워크로드 키와 운영자 키(operator keys)가 추론(inference) 및 관리 액세스를 제어합니다. 구조화된 로그는 API 키와 프롬프트 페이로드를 생략하며; 요청 본문(request bodies), 동시성(concurrency), 시간 초과, 상위 스트림 버퍼(upstream buffers)는 제한됩니다.
Millwright를 자체 인프라에 배포하거나, 특정 제공업체를 통합하거나, 워크로드 라우팅 정책을 설계하는 데 도움이 필요하신가요?
버그 수정, 기능 추가, 테스트, 문서 개선 등 모든 기여를 환영합니다. 풀 리퀘스트(pull request)를 열기 전에 CONTRIBUTING.md 파일을 읽어주세요.
The Rust 툴체인은 rust-toolchain.toml에 고정되어 있습니다.
git clone https://github.com/Northwood-Systems/millwright.git
cd millwright
make build
...
풀 리퀘스트를 열기 전에 다음을 실행하세요:
make fmt
make lint
make test
...
이 검사들은 Rustfmt, 경고가 거부된 Clippy, 모든 Rust 테스트 대상(test targets), 종속성 권고 사항(dependency advisories), 승인된 라이선스, 그리고 종속성 출처를 포함합니다. make audit는 cargo-deny를 필요로 합니다. CI는 또한 릴리스 바이너리 및 Docker 이미지를 빌드합니다.
Apache-2.0