llm-localfirst
llm-localfirst
本地优先的 LLM 路由 — 让敏感数据和批量文本处理留在你自己的模型上,只在真正困难时才调用云端。
大多数 LLM 路由器优化的是调用哪家云提供商以降低成本或实现故障转移。llm-localfirst 则反转了这个默认设定:它首先在你的本地模型(Ollama / vLLM / LM Studio)上运行,只有工作确实需要时才会触达云端。它额外提供了主流路由器没有的两项能力:
🔒 失败即关闭的隐私路由。 你标记为
sensitive=True的调用会固定到本地模型,绝不允许回退到云端。如果本地模型不可用,该调用会抛出异常——它不会悄悄把你的提示词发送给第三方 API。🤝 Manager-worker 委派。 为云端“director”代理提供一个即插即用的工具,把 token 密集、低风险的文本处理(摘要 / 起草 / 翻译 / 重排版 / 提取 / 分类)卸载给快速的本地 worker——从而削减云端开销并把批量数据留在你的硬件上。(提炼自一个生产环境 Pydantic AI 代理。)
此外还有一个模型允许列表保护(拒绝任意模型字符串——这是 SSRF/成本爆炸半径的控制)、可达性探测缓存、一个 MCP server 包装器,以及 CLI。
隐私保证,五行说明
from llm_localfirst import Router, LocalUnavailable
router = Router.from_env()
try:
out = router.complete("Redact all PII from this record.",
source=customer_record, sensitive=True)
except LocalUnavailable:
# Local model is down. We did NOT send the record to the cloud. You decide.
...sensitive=True 意味着这些数据不得离开这台机器。路由器宁可失败也不泄露。这种不对称性——敏感调用失败即关闭,普通批量调用回退到云端——正是这个产品的核心。
Related MCP server: OpenAI-Compatible MCP Gateway
安装
pip install llm-localfirst # the routing brain — zero provider SDKs
pip install "llm-localfirst[openai]" # + talk to local Ollama/vLLM/LM Studio (and cloud OpenAI)
pip install "llm-localfirst[anthropic]" # + Claude (the default cloud fallback / reason model)
pip install "llm-localfirst[all]" # everything (also: mcp, pydantic-ai)Extra | Adds | Needed for |
无 |
|
|
|
| 在本地 OpenAI 兼容服务器(或云端 OpenAI)上执行调用 |
|
| 默认云端回退 / |
|
|
|
|
| manager-worker |
决策路径(decide())不导入任何提供商 SDK,因此你只需安装核心包即可检查路由——并运行整个测试套件。
60 秒快速上手(Ollama)
ollama pull qwen2.5:7b # any OpenAI-compatible local server works
pip install "llm-localfirst[openai,anthropic]"
export ANTHROPIC_API_KEY=sk-ant-... # only needed for the cloud fallback / reason pathfrom llm_localfirst import Router, Kind
router = Router.from_env()
# 1) Inspect routing WITHOUT spending a token.
print(router.decide(kind=Kind.BULK)) # -> local (cheap + private)
print(router.decide(kind="reason")) # -> cloud (the hard part)
print(router.decide(sensitive=True)) # -> local (pinned; never cloud)
# 2) Actually run it. Bulk work prefers local, and falls back to cloud only if local is down.
print(router.complete("Summarize this in one sentence.",
source=long_text, kind=Kind.BULK).text)或者从 shell 中:
llm-localfirst doctor # show config, the allowlist, and local up/down
llm-localfirst route "summarize this" --kind bulk
llm-localfirst route "redact this" --sensitive # exits non-zero if local is down (fail-closed)路由如何决策
decide() 会探测你的本地模型是否可达(带缓存),然后按顺序应用以下规则:
调用 | 本地可用 | 本地不可用 |
| 本地 | 抛出 |
显式指定 | — | 抛出 |
| 云端 | 云端 |
| 本地 | 云端回退( |
显式指定 | 该允许列表中的模型(仅敏感调用时阻止云端) |
任何显式的 model 必须是允许列表中的名称;任意字符串(或一个游离 URL)会抛出 ModelNotAllowed。该允许列表就是 SSRF / 成本守卫——调用方永远无法让路由器指向一个未配置的新端点或昂贵模型。
Manager-worker 委派(Pydantic AI)
让云端 director 保留规划和工具调用,把繁重的文本工作转交给本地 worker:
from pydantic_ai import Agent
from llm_localfirst import Router
from llm_localfirst.integrations.pydantic_ai import attach_worker
router = Router.from_env()
director = Agent("anthropic:claude-haiku-4-5", system_prompt="...")
# Adds a `delegate_to_worker(task, source)` tool that routes to your LOCAL model.
# attach_worker REFUSES a non-local worker, so delegated source text can't leak.
attach_worker(director, router, worker_model="local",
on_delegate=lambda task, result: ...) # optional observability hookdirector 调用 delegate_to_worker 来处理摘要、起草、翻译、重排版和提取;这些任务在你的 GPU 上运行,而不是消耗云端 token。参见 examples/manager_worker.py。
原生 MCP
将路由器以三个工具的形式暴露给任何 MCP 客户端(Claude Desktop、IDE、代理)——route(只做决策)、complete 和 usage(本次会话已花费):
pip install "llm-localfirst[mcp]"
llm-localfirst mcp # serves over stdio云端费用上限
隐私保证回答的是这次调用可以离开机器吗?。本地优先设置还必须回答另一个问题:离开机器已经花了多少钱?
每次 completion 都会自动记账——无需配置,无需标志:
router = Router.from_env()
router.complete("summarise this", source=long_document)
router.ledger.calls("cloud") # 1
router.ledger.tokens("local") # Usage(input_tokens=..., output_tokens=...)
router.ledger.snapshot() # JSON-safe, for logs给它一个上限,它就会停止而不是超支——与隐私固定相同的失败即关闭姿态,现在应用于金钱:
from llm_localfirst import Budget, Router
router = Router(..., budget=Budget(max_cloud_tokens=200_000))
...
llm_localfirst.BudgetExceeded: cloud token budget spent: 203_400/200_000 tokens本地调用永远不会被设限。 对它们设限会违背本地运行的意义——云端预算耗尽只是意味着云端被关闭,而批量工作会继续流动。
或者按费用限制,这需要价格:
export LF_PRICES='{"haiku": [0.8, 4.0], "sonnet": [3.0, 15.0], "opus": [15.0, 75.0]}'
export LF_MAX_CLOUD_COST=5.00它刻意不做两件事:
它不内置价格表。 价格会变化,而一份过期的硬编码数字比没有数字更糟。价格由你提供——并且如果任何一个允许列表中的云端模型缺少价格,费用上限拒绝启动,而不是默默停在
$0.00并且永远不会触发。max_cloud_tokens和max_cloud_calls是精确的,完全不需要配置。它不限制单次调用。 Token 计数只有在提供商响应之后才存在,因此上限是在被突破后阻止下一次云端调用。它把超支限制在一次调用以内;它无法限制某一次调用。
账本保存在内存中,作用域为 Router。它是进程的护栏,而不是计费系统——如果你需要跨进程强制费用,请将 ledger.snapshot() 持久化到你自己的存储中。
llm-localfirst complete "..." --usage # tally on stderr, completion on stdout
llm-localfirst doctor # shows the budget and which models are priced同类对比
llm-localfirst 并不是一个通用的多云网关,也没打算成为这样的网关。说得清楚且公正:LiteLLM 和 Bifrost 已经可以路由到本地模型(Ollama、vLLM)——本地能力并不是差异点。差异在于失败即关闭的隐私固定、manager-worker 委派工具,以及本地优先的默认姿态。
能力 | llm-localfirst | LiteLLM | OpenRouter | llmrouter-lib |
路由到本地模型(Ollama/vLLM) | ✅ | ✅ | ❌ | ➖ |
默认姿态为本地优先 | ✅ | ❌(云代理) | ❌ | ➖ |
敏感调用失败即关闭——绝不回退到云端 | ✅ | ❌ | ❌ | ❌ |
Manager-worker 委派工具(云端→本地) | ✅ | ❌ | ❌ | ❌ |
允许列表保护(拒绝任意模型字符串) | ✅ | ➖ | ➖ | ➖ |
多云供应商 / 负载均衡 / 缓存 | ➖(设计使然) | ✅ | ✅ | ➖ |
如果你想要一个拥有数十个提供商的大规模云网关,请使用 LiteLLM。如果你想让私有数据在结构上就留在本地,让批量工作在自有的硬件上运行,那么这个库就是为你准备的。
这不是什么
不是多云网关。 它自带一个本地后端 + Claude(+ 可选的 OpenAI)。更多后端可通过在允许列表上注册来添加;它不会长出上百个提供商 shim。
不是内容分类器。 你将调用标记为
sensitive=True(或选择一个kind)。它不会猜测你的文本是否私密——它只执行你所声明的内容。不是负载均衡或语义缓存。 那些是网关功能;这是一个带有隐私保证的路由策略。
不是成本分析或计费。 费用上限 是进程内的护栏,而不是仪表盘:进程结束时计数归零,并且它报告的是提供商报告的数字。要真实数字,请阅读你的提供商账单。
不是提示词防火墙。 它控制的是调用在哪里运行,而不是调用里包含什么。
配置
所有设置都从环境变量(前缀 LF_)或 .env 文件读取。参见 .env.example。要点如下:
变量 | 默认值 | 含义 |
|
| 本地 OpenAI 兼容端点 |
|
| 本地模型 ID |
|
| 非敏感回退使用的云端模型 |
|
|
|
|
| 确保敏感调用永不泄露 |
|
| 可达性探测的缓存秒数 |
|
| 每百万 token 的 |
| 未设置 | 每进程云端调用次数的上限 |
| 未设置 | 每进程云端 token 数的上限 |
| 未设置 | 云端花费上限(需要 |
开发
uv venv && uv pip install -e '.[dev]'
ruff check . && pytest路由核心(策略、注册表、路由器、可达性)实现了 100% 离线覆盖——无需网络,也无需提供商 SDK。欢迎贡献;参见 CONTRIBUTING.md。
许可证
MIT © Shaxzodbek Qambaraliyev / Blaze。见 LICENSE。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseCqualityDmaintenanceAn MCP server that routes LLM requests across multiple providers and orchestrates other MCP servers, with a focus on local privacy for embeddings and memory.283
- FlicenseNot gradedqualityDmaintenanceLocal MCP server that exposes fixed tools for GPT, Claude, and Gemini while routing to any OpenAI-compatible chat completions backend with independent configuration per target.1
- AlicenseNot gradedqualityBmaintenanceA self-hostable MCP server that routes prompts to multiple LLM providers using declarative policies, with multi-role orchestration for independence and verification.MIT
- AlicenseNot gradedqualityCmaintenancePrivacy-first local MCP hub for coordinating multiple AI providers from Claude Code, supporting local Ollama seats and cloud providers with safety routing.MIT
Related MCP Connectors
Hosted MCP server for LLM cost estimation, model comparison, and budget-aware routing.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/shaxzodbek-uzb/llm-localfirst'
If you have feedback or need assistance with the MCP directory API, please join our Discord server