Millwright: Rust-based, self-hosted LLM router
Score
69提供了一种新型自托管路由方案,对多模型管理场景有明确信息增量。
项目文档和架构描述清晰,但尚未经过大规模生产验证。
对需要成本控制和隐私保护的团队有直接实用价值,开源且易于集成。
发布于 Hacker News 热门当日,与当前 LLM 部署痛点高度契合。
来自 Hacker News 热门话题,GitHub 项目内容公开可查,可信度较高。
Base 76.5 × T2 Source weight ×0.9 = 69
Curation line 70Below curation line
Why selected
This project addresses the practical pain point of switching among multiple model backends, and its open-source implementation holds significant reference value.
AI commentary
「If you're struggling with orchestrating multiple LLM APIs and controlling costs, Millwright's deterministic routing approach is worth a try. Its Rust implementation and self-hosted nature make it especially suitable for teams with strict latency and security requirements.」
Quick overview
Millwright is a self-hosted LLM router written in Rust, emphasizing cost-effectiveness, deterministic routing, and high performance. It is secure and private by default, supporting multi-model load balancing and fallback, making it suitable for AI applications that require local deployment, low latency, and high reliability. The project is open-sourced on GitHub and can be flexibly integrated into existing inference backends.
- Built with Rust for high performance and memory safety
- Self-hosted with security and privacy by default
- Deterministic routing and cost control mechanisms
- Multi-model fallback and load balancing support
Full text
Millwright
The self-hosted LLM router for policy, cache affinity, and spend control in one Rust Binary.
What is Millwright
Millwright is an open-source, self hosted LLM router that runs between your AI applications and the model providers you choose. It accepts OpenAI Chat Completions and Anthropic Messages, then routes each request to an OpenAI-compatible API, Anthropic, or Amazon Bedrock.
You define which models belong in the cheap, mid, and frontier roles. Millwright selects the lowest estimated-cost healthy route the resolved role permits and, when given a session ID, preserves provider/model affinity for prompt-cache reuse.
Millwright is a router, not an agent orchestrator. It does not spawn agents, schedule work, inspect prompts, or rewrite context.
Why Millwright
LLM costs rise quickly when every request reaches the most expensive model and provider changes break prompt-cache reuse. Millwright makes the lower-cost path explicit:
- Control model spend — reserve frontier models for the work your policy says needs them.
- Protect prompt caches — role-scoped affinity keeps each session on a confirmed provider and model while its cache window is warm.
- Keep concurrent agents moving — one session can maintain independent
cheap,mid, andfrontierlanes without serializing requests. - Change providers without changing application code — route compatible traffic across providers behind one endpoint.
- Keep routing inspectable — response headers identify the chosen route; traces and ledger entries retain the evidence when persistence is available.
- Run the data plane yourself — provider credentials stay on your infrastructure, with no required hosted control plane.
Get Started
Quick Start
Rust 1.97+ is required when building from source.
git clone https://github.com/Northwood-Systems/millwright.git cd millwright cargo install --path . --locked millwright init millwright serve
millwright init walks through provider endpoints, model roles, pricing, and separate workload and operator keys. It stores references to provider-secret environment variables, never the provider credentials themselves.
Connect Claude Code, Codex, OpenCode, Pi, or another compatible client. Choose millwright-fast, millwright-code, or millwright-plan to request the cheap, mid, or frontier role.
Optional Local Demo
The included Docker Compose setup starts Millwright with a mock provider and local demo key:
make compose-up
From another terminal:
curl http://localhost:8080/v1/chat/completions \
-H 'Authorization: Bearer sk-millwright-local-demo' \
-H 'Content-Type: application/json' \
-d '{"model":"millwright-fast","messages":[{"role":"user","content":"Hello from Millwright"}]}'
Architecture · Router API · Policy & Catalog · Deployment · Cost Analysis · Security
Features
Policy-controlled routing
Classify requests with explicit task and risk headers, the client's model selection, or documented defaults. Millwright resolves a cheap, mid, or frontier role, then selects the lowest estimated-cost healthy model that policy allows. High-risk and planning requests always use the frontier role.
Every decision includes the chosen model, provider, route reason, and rejected alternatives. Message content is never inspected to make the decision.
Cache-aware concurrency
Naive per-request routing can erase provider prompt-cache savings by switching models mid-session. Millwright keeps independent cheap, mid, and frontier affinity lanes under one opaque session ID, each with its own cache TTL.
Traffic resolved to different roles no longer fights over one warm route. Same-role calls converge on the last confirmed provider/model, while all requests remain concurrent—Millwright does not serialize agent traffic or orchestrate agent lifecycles.
See where the spend goes
Completed requests normally write usage evidence, cost provenance, provider attempts, and routing evidence to the ledger. SQLite is the local default; PostgreSQL is available for production deployments.
| Command | What it shows |
|---|---|
millwright spend |
Total spend, cache read rate, and per-team breakdown |
millwright models |
Model and provider mix |
millwright trace <id> |
One routing decision, including rejected alternatives |
millwright top |
Live spend and model activity in the terminal |
The same data is available through the authenticated /v1/millwright/* management APIs, with JSON output from spend, models, and trace for dashboards and automation.
Analyze cost opportunities
millwright analyze reads a live Millwright ledger or local Millwright, OpenAI-compatible, or Anthropic JSONL. It produces a self-contained HTML or Markdown report plus schema-versioned JSON.
millwright analyze \ --url http://127.0.0.1:8080 \ --key "$MILLWRIGHT_OPERATOR_KEY" \ --since 30d \ --report analysis.html \ --json-out analysis.json
Reports separate measured cost evidence from modeled candidate economics. Add an explicit catalog and candidate allowlist to compare full-swap costs and a price-floor economic scenario. Candidate results are cost hypotheses—not quality results or production routing recommendations. See Cost Analysis.
Provider and protocol support
OpenAI Chat Completions and Anthropic Messages come in; OpenAI-compatible APIs, native Anthropic, and Amazon Bedrock go out. Same-protocol routes preserve fields Millwright does not model. Cross-protocol routes translate the supported text-and-tools subset and reject unsupported shapes instead of silently dropping data.
Retryable transport failures, timeouts, HTTP 408/429, and HTTP 5xx responses can trigger one bounded failover attempt. Circuit breakers stop unhealthy routes from receiving every request.
Built for self-hosting
Millwright ships as one Rust binary with Docker and Docker Compose support. Provider credentials remain in environment variables, while separate workload and operator keys control inference and management access. Structured logs omit API keys and prompt payloads; request bodies, concurrency, timeouts, and upstream buffers are bounded.
Enterprise
Need help deploying Millwright inside your infrastructure, integrating a provider, or designing a routing policy for your workload?
Contributing
Bug fixes, features, tests, and documentation improvements are welcome. Read CONTRIBUTING.md before opening a pull request.
Quick Start for Contributors
The Rust toolchain is pinned in rust-toolchain.toml.
git clone https://github.com/Northwood-Systems/millwright.git cd millwright make build make test
Code Quality / Linting
Before opening a pull request, run:
make fmt make lint make test make audit
The checks cover Rustfmt, Clippy with warnings denied, all Rust test targets, dependency advisories, approved licenses, and dependency sources. make audit requires cargo-deny. CI also builds the release binary and Docker image.
License
Apache-2.0
Related items
92
FeaturedOpenRouter Launches Prompt Caching with Sticky Routing to Drastically Reduce Multi-Turn Costs
OpenRouter 推出提示缓存与粘性路由,大幅降低多轮对话成本
For developers making frequent AI API calls, this feature is a direct money-saver. Sticky routing guarantees cache hit rates, and session_id requires zero configuration—every OpenRouter user should try it immediately.
91
FeaturedChatGPT Work: An AI Agent That Takes Action Across Apps and Files
ChatGPT Work:可在跨应用和文件中执行操作的AI Agent
I think this is a key step for AI assistants moving from Q&A to execution. Especially noteworthy for professionals who need to automate complex workflows. ChatGPT Work could become a new paradigm for productivity tools.
90
FeaturedAnatomy of a Frontier Lab Agent Intrusion: A Technical Timeline of the July 2026 Incident
前沿实验室代理入侵事件技术时间线:2026年7月事件剖析
This technical timeline is a must-read for all AI security researchers and agent developers—it doesn't just describe one attack but sounds an alarm on the weak defense systems of agent architectures. For teams deploying autonomous agents, this is an essential disaster prevention manual.
90
FeaturedBetter Tools Made Copilot Code Review Worse? Here's How GitHub Improved It
更好的工具反而让Copilot代码审查更糟?GitHub这样改进
This blog post deserves close reading by all AI product engineers and ML practitioners—it breaks the intuition that 'more powerful tools = better AI' and instead emphasizes an engineering philosophy aligned with agent reasoning patterns. Especially important for teams optimizing code review or similar agent-based products.
88
FeaturedOpenRouter Launches Unified Multimodal API: Single Endpoint for Image, Video, Audio, Embeddings, and Transcription
OpenRouter 推出统一多模态 API:单端点支持图像、视频、音频、嵌入与转录
This news is worth attention from all developers building multimodal AI applications: OpenRouter's unified API solves the pain of model switching, especially for startups or rapid prototyping. If you're struggling with multiple API keys and SDKs, this interface could be the unified layer you need.
87
FeaturedAnthropic Launches Claude for Teachers: AI Tools Designed for Educators
Anthropic 推出 Claude for Teachers:面向教师的教育 AI 工具
This announcement is valuable for educators and AI industry watchers alike. Instead of a generic chatbot, Anthropic designed a safety-first tool specifically for teachers, demonstrating the right approach for AI vertical deployment: solving real pain points rather than showing off technology. The built-in guardrails also set a reference for other AI companies, especially when serving scenarios involving children or teenagers.
86
FeaturedOpenRouter Introduces New Auto Router: Model Routing Powered by Market Wisdom
OpenRouter发布全新Auto Router:用市场智慧优化模型路由
This update is worth attention for anyone using APIs to build AI apps. Instead of guessing or testing model selection, market data now does the heavy lifting. Though sparse on details, the direction is right, especially for teams relying on aggregated model services.
86
FeaturedClaude Code v2.1.211 Release: Multiple Fixes and Improvements
Claude Code v2.1.211 发布:多项修复与改进
As a developer who frequently uses Claude Code for automated coding, I'm particularly interested in the security fixes, especially the permission preview character bypass and auto mode overriding hook decisions—these directly affect the security boundaries during team collaboration. The improvement in background agent reporting also makes long-running tasks more reliable. I recommend all users upgrade as soon as possible.