news 2026/10/13 7:59:58

LiteLLM:多模型统一调用的轻量抽象层实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LiteLLM:多模型统一调用的轻量抽象层实战指南

1. 项目概述:LiteLLM 是什么,它解决的不是“能不能用”,而是“怎么用得稳、用得省、用得快”

LiteLLM 这个名字一出来,很多人第一反应是:“又一个 LLM 工具库?”——但如果你真把它当成普通封装库来用,大概率会在第三天凌晨两点对着报错日志抓头发。我最早在某高校实验室做多模型对比实验时接触它,当时团队要同时调用本地部署的 Llama 3-8B、云上托管的 Qwen2-72B,还有几个小众开源模型(比如某个基于 MoE 架构的轻量推理模型),每个 API 接口格式、鉴权方式、流式响应结构、token 计数逻辑、超时策略全都不一样。我们写了三套 client 代码,维护成本高到连测试用例都懒得更新。直到把 LiteLLM 引入 pipeline,才真正把“调模型”这件事从工程负担降维成配置动作。

LiteLLM 的核心定位非常清晰:它不是模型,不是训练框架,也不是推理加速器;它是一个统一抽象层(Unified Abstraction Layer),专为“多模型协同调度”而生。关键词就三个:兼容性、一致性、可观测性。它不改变底层模型能力,但彻底重构了你和模型交互的方式——就像给所有不同品牌、不同接口、不同电压的电器,统一装上标准插座和智能电表。你不用再记 OpenAI 的messages字段怎么嵌套、Anthropic 的system放哪、Google 的contents是数组还是对象、Ollama 的/api/chat返回体里done字段是布尔还是字符串……LiteLLM 全部给你标准化成一套输入/输出契约。

它适合谁?不是只适合大厂算法工程师,恰恰相反,最适合三类人:

  • 中小团队后端开发者:需要快速接入多个模型服务,但没人力长期维护各厂商 SDK;
  • MLOps 工程师:负责模型网关、AB 测试、灰度发布、fallback 策略,需要统一埋点与熔断;
  • 研究型开发者:做 prompt 工程、RAG 对比、Agent 编排,需要屏蔽底层差异,专注上层逻辑。

它不能做什么?别指望它帮你训模型、压缩权重、做量化推理或 GPU 显存优化。它也不提供模型本身——你得自己准备模型服务地址、API Key 或本地运行环境。它的价值不在“新增能力”,而在“消除摩擦”。实测下来,一个原本需要 5 天对接 4 个模型的项目,用 LiteLLM 后,首版联调压缩到 8 小时内完成,且后续增删模型只需改两行配置。

2. 核心设计思路拆解:为什么是“轻量级抽象”,而不是“重封装 SDK”?

2.1 不造轮子,只搭桥:LiteLLM 的哲学底色

很多同类工具试图“统一一切”,结果越统越重——加中间件、启独立服务、强依赖特定部署模式。LiteLLM 反其道而行之:它选择做最薄的一层胶水代码。整个包安装后仅 3MB,无 C 扩展,纯 Python 实现,零 runtime 依赖(除 requests、httpx 等基础网络库)。这不是技术妥协,而是刻意为之的设计取舍。

为什么必须“轻”?因为它的使用场景决定了它必须能无缝嵌入任何已有系统:

  • 它可能被塞进 FastAPI 的 middleware 里做统一鉴权路由;
  • 可能被 import 到 LangChain 的 Tool 类中作为底层 call 方法;
  • 也可能直接跑在边缘设备上,调用本地 Ollama 或 llama.cpp;
  • 甚至被写进 Jupyter Notebook 做快速原型验证。

一旦引入重量级依赖(比如强制要求 Redis 做缓存、要求 Kafka 做事件总线),它就失去了“即插即用”的灵魂。我见过有团队强行给 LiteLLM 加一层 gRPC 封装,结果调试链路拉长三倍,出问题根本分不清是模型挂了、网关崩了,还是 gRPC 序列化错了——这完全违背了 LiteLLM “降低复杂度”的初衷。

2.2 统一接口背后的三重契约:Input / Output / Metadata

LiteLLM 的统一性不是靠“假装大家都一样”,而是通过三套明确契约实现的:

第一层:输入契约(Standardized Input)
无论你调哪个模型,输入都必须是标准 OpenAI 格式:

response = litellm.completion( model="gpt-4o", messages=[{"role": "user", "content": "你好"}], temperature=0.7, max_tokens=1024 )

哪怕你实际调的是 Anthropic 的 Claude,LiteLLM 也会在内部把messages转成system + content,把temperature映射为anthropic_temperature,再发请求。这个转换不是黑盒 magic,而是明确定义在litellm/model_prices_and_context_window.json和litellm/main.py的get_supported_openai_params()中——你可以随时查源码看映射规则。

第二层:输出契约(Standardized Output)
返回值永远是 OpenAI-style response 对象:

{ "id": "chatcmpl-xxx", "choices": [{"message": {"role": "assistant", "content": "你好!"}}], "usage": {"prompt_tokens": 5, "completion_tokens": 4, "total_tokens": 9}, "model": "gpt-4o" }

哪怕底层是 Ollama 返回的裸 JSON{ "response": "你好!", "model": "llama3" },LiteLLM 也会补全id、choices、usage(按字符粗略估算)、created时间戳等字段。这个“补齐”不是为了好看,而是为了让上层业务代码无需判断if "choices" in resp或elif "response" in resp——统一字段名,才能写统一逻辑。

第三层:元数据契约(Standardized Metadata)
这是最容易被忽略、却最体现工程深度的部分。LiteLLM 在 response 里注入了._response_ms(耗时毫秒)、._model_response(原始响应体)、._response_headers(原始 header),还支持通过litellm.set_verbose = True打印完整请求/响应日志。这些字段不参与业务逻辑,但对 debug、监控、计费、fallback 决策至关重要。比如 fallback 逻辑可以这样写:

try: resp = litellm.completion(model="gpt-4o", ...) except Exception as e: if getattr(e, "_response_ms", 0) > 10000: # 超过10秒 resp = litellm.completion(model="claude-3-haiku", ...)

没有这套元数据,fallback 就只能靠 try-except 捕获异常,无法做耗时维度的智能降级。

2.3 为什么支持 100+ 模型,却几乎不增加维护成本?

截至 2024 年中,LiteLLM 官方支持模型已超 120 个,涵盖 OpenAI、Azure、Anthropic、Google、Cohere、Mistral、Groq、Fireworks、Together、Ollama、llama.cpp、HuggingFace Text Generation Inference、以及国内多家大模型平台。但它的核心代码量始终控制在 5000 行以内。秘诀在于:模型适配器(Adapter)机制 + 配置驱动。

每个模型支持,本质就是一个.py文件(如litellm/llms/anthropic/anthropic.py),只做三件事:

  1. 定义completion()函数,接收标准输入,调用对应厂商 SDK 或 requests 发请求;
  2. 定义convert_messages_to_prompt()函数,把 OpenAI messages 转成本模型所需格式;
  3. 定义process_response()函数,把原始响应转成标准 OpenAI response。

新增一个模型,只需写这三个函数,其余路由、重试、缓存、日志全部复用主干逻辑。更关键的是,LiteLLM 把大量差异化逻辑外置为配置项:

  • litellm.api_base控制请求地址;
  • litellm.api_key控制鉴权;
  • litellm.custom_llm_provider指定厂商;
  • litellm.max_retries统一重试策略。

这意味着,即使某个小众模型没被官方收录,你也可以不改一行 LiteLLM 源码,仅靠配置 + 自定义 provider 就能接入。我曾用这种方式,在 2 小时内接入某实验室自研的私有模型服务,全程只写了 12 行配置和一个 30 行的custom_provider.py。

3. 核心细节解析与实操要点:从“能跑”到“跑得稳”的关键参数与陷阱

3.1 模型路由(Model Routing):不只是负载均衡,更是业务策略中枢

LiteLLM 的Router不是简单的 round-robin 轮询。它是一套可编程的流量调度引擎,核心能力有三:权重分配、健康探测、动态 fallback。

先看最常用的权重路由:

from litellm import Router router = Router( model_list=[ { "model_name": "gpt-4o", # 路由名 "litellm_params": { "model": "gpt-4o", "api_key": os.getenv("OPENAI_API_KEY"), "api_base": "https://api.openai.com/v1" }, "weight": 0.6 # 60% 流量 }, { "model_name": "claude-3-haiku", "litellm_params": { ... }, "weight": 0.4 } ], num_retries=3 )

这里weight不是静态比例,而是概率权重。Router 内部用random.choices()实现,每次请求独立采样,保证长期统计符合设定。但注意:权重只在首次路由时生效,不参与重试。如果 gpt-4o 第一次失败,Router 默认会重试同一模型(除非你显式配置fallbacks)。

真正的业务级调度藏在fallbacks和allowed_fallback_models:

router = Router( model_list=[...], fallbacks={ "gpt-4o": ["claude-3-haiku", "ollama/llama3"], "claude-3-haiku": ["gpt-3.5-turbo"] } )

这个配置意味着:当gpt-4o请求失败(HTTP 错误、超时、5xx),Router 会按顺序尝试claude-3-haiku→ollama/llama3,直到成功或耗尽列表。但这里有个致命陷阱:fallback 不自动继承原始请求参数。比如你原始请求带了max_tokens=2048,fallback 到ollama/llama3时,如果该模型 context window 只有 2048,而你的 prompt 已占 1800 tokens,就会直接报context_length_exceeded。解决方案是预计算 token 数并动态调整:

from litellm import token_counter def safe_route(messages, **kwargs): # 先估算 prompt tokens prompt_tokens = token_counter(model="gpt-4o", text=messages) if prompt_tokens > 1500: kwargs["max_tokens"] = min(kwargs.get("max_tokens", 2048), 512) return router.completion(model="gpt-4o", messages=messages, **kwargs)

这个细节,文档里不会写,但线上事故往往就出在这里。

3.2 Token 计数与预算控制:别让“免费额度”变成“账单炸弹”

LiteLLM 内置token_counter(),但它不是万能的。它基于 HuggingFace 的tiktoken(OpenAI 模型)和transformers(HuggingFace 模型)实现,对非标准 tokenizer 模型(如某些中文微调模型用的 sentencepiece)可能不准。我实测过某国产模型,token_counter(model="qwen2-72b", text="你好")返回 2,但实际 API 返回prompt_tokens: 4——差了整整一倍。

更危险的是:token 计数误差会直接导致 budget 超限。LiteLLM 支持budget参数做硬限制:

litellm.completion( model="gpt-4o", messages=[...], budget=1000, # 总 token 预算 max_tokens=512 )

但这个budget是按 LiteLLM 自己算的 token 数扣减的。如果它少算了 30%,你设 1000 实际可能消耗 1300,budget 提前耗尽,后续请求直接被拒。所以生产环境必须:

  1. 对关键模型,用真实 API 调用校准 token 计数偏差(写个脚本批量测 100 条样本,算平均误差率);
  2. budget值按预估 * (1 + 误差率)设置,留足 buffer;
  3. 开启litellm.set_verbose = True,定期抽样检查response._response_ms和response.usage是否匹配预期。

提示:LiteLLM 的usage字段中prompt_tokens和completion_tokens是模型实际返回的,绝对可信;而token_counter()返回的是预估,仅用于预算控制和日志记录,不可用于 billing 结算。

3.3 流式响应(Streaming)的坑:别让“实时”变成“卡顿”

流式响应是 LiteLLM 最易用错的功能。表面看只要加stream=True:

response = litellm.completion( model="gpt-4o", messages=[...], stream=True ) for chunk in response: print(chunk.choices[0].delta.content or "")

但问题在于:不同模型的流式 chunk 结构天差地别。OpenAI 返回delta对象,Anthropic 返回delta.text,Ollama 返回response字段,Google 返回candidates[0].content.parts[0].text。LiteLLM 的统一输出契约在此刻失效——它只保证最终聚合后的response.choices[0].message.content正确,但对chunk的结构不做标准化。

这意味着:上面那段代码在 OpenAI 上跑得好好的,切到 Claude 就报AttributeError: 'dict' object has no attribute 'choices'。正确做法是:永远用litellm.stream_chunk_builder()辅助解析:

from litellm import stream_chunk_builder response = litellm.completion(..., stream=True) full_response = "" for chunk in response: # 将原始 chunk 转为标准 OpenAI chunk 格式 standard_chunk = stream_chunk_builder(chunk, model="claude-3-haiku") full_response += standard_chunk.choices[0].delta.content or "" yield standard_chunk.choices[0].delta.content or ""

这个函数内部做了模型特异性解析,把各种 raw chunk 映射到统一delta结构。不调用它,流式就是定时炸弹。

3.4 本地模型接入:Ollama 与 llama.cpp 的实操差异

LiteLLM 对本地模型支持极好,但 Ollama 和 llama.cpp 的接入姿势完全不同,新手极易混淆。

Ollama 接入:

# 必须指定 custom_llm_provider litellm.completion( model="ollama/llama3", # 注意前缀 ollama/ messages=[...], api_base="http://localhost:11434", # Ollama 默认端口 custom_llm_provider="ollama" )

关键点:model参数必须带ollama/前缀,custom_llm_provider必须显式设为"ollama",否则 LiteLLM 会当成 OpenAI 模型去https://api.openai.com/v1请求,直接 404。

llama.cpp 接入:

# llama.cpp 需要启动 server 模式 # ./server -m models/llama-3-8b.Q4_K_M.gguf -c 2048 --port 8080 litellm.completion( model="llama-3-8b", # 任意名,但需与 server -m 的模型名一致 messages=[...], api_base="http://localhost:8080/v1", # 注意 /v1 后缀 custom_llm_provider="llama_cpp" )

关键点:custom_llm_provider必须是"llama_cpp",且api_base必须带/v1(这是 llama.cpp server 的固定路径)。漏掉/v1,请求会 404;写成llama-cpp(带横线)会报Provider not supported。

实操心得:本地模型调试时,务必先用 curl 直接调通底层服务:
curl http://localhost:11434/api/chat -d '{"model":"llama3","messages":[{"role":"user","content":"hi"}]}'
确保底层 OK 后,再让 LiteLLM 调。否则你会在 LiteLLM 日志里看到一堆Connection refused,误以为是 LiteLLM 配置错,其实是 Ollama 没起来。

4. 实操过程与核心环节实现:从零搭建一个高可用多模型网关

4.1 环境准备与最小可行配置

我们以一个典型场景为例:构建一个面向内部员工的 AI 助手 Web API,需同时支持 GPT-4o(高精度)、Claude-3-Haiku(低成本)、Ollama-llama3(离线兜底),并具备自动 fallback 和耗时监控。

第一步:安装与基础验证

pip install litellm # 验证是否能调通 OpenAI(需提前设置环境变量) export OPENAI_API_KEY="sk-..." python -c "import litellm; print(litellm.completion(model='gpt-3.5-turbo', messages=[{'role':'user','content':'hi'}]).choices[0].message.content)"

如果报AuthenticationError,检查 key 是否正确;如果报ConnectionError,检查网络是否能访问api.openai.com。

第二步:Router 初始化(带健康检查)

from litellm import Router import os # 模型列表,含健康检查配置 model_list = [ { "model_name": "gpt-4o", "litellm_params": { "model": "gpt-4o", "api_key": os.getenv("OPENAI_API_KEY"), "api_base": "https://api.openai.com/v1" }, "health_check_interval": 30, # 每30秒探测一次 "num_retries": 2 }, { "model_name": "claude-3-haiku", "litellm_params": { "model": "claude-3-haiku-20240307", "api_key": os.getenv("ANTHROPIC_API_KEY"), "api_base": "https://api.anthropic.com/v1" }, "health_check_interval": 30, "num_retries": 2 }, { "model_name": "ollama-llama3", "litellm_params": { "model": "ollama/llama3", "api_base": "http://localhost:11434", "custom_llm_provider": "ollama" }, "health_check_interval": 10, # 本地服务更脆弱,探测更勤 "num_retries": 3 } ] # 初始化 Router,启用健康检查和 fallback router = Router( model_list=model_list, fallbacks={ "gpt-4o": ["claude-3-haiku", "ollama-llama3"], "claude-3-haiku": ["gpt-4o", "ollama-llama3"], "ollama-llama3": ["gpt-4o"] # 离线模型失败,必须上云 }, set_verbose=True, # 生产环境建议关掉,用日志系统替代 num_retries=1 # Router 层重试,避免模型层重试叠加 )

注意health_check_interval:对云服务设 30 秒合理,对本地 Ollama 设 10 秒,因为本地进程可能被 OOM kill,需要更快感知。LiteLLM 的健康检查是同步 HTTP GET/health(Ollama 支持,OpenAI 不支持,所以对云模型是 pinghttps://api.openai.com/v1/models)。

4.2 构建带熔断与预算的 Completion 封装

直接暴露router.completion()给业务层风险极高。我们需要封装一层,加入熔断、预算、超时控制:

import time from litellm import BudgetManager from litellm.integrations.custom_logger import CustomLogger class SafeLLMClient: def __init__(self, router, max_budget=10000): self.router = router self.budget_manager = BudgetManager(max_budget=max_budget) self.request_count = 0 def completion(self, model, messages, **kwargs): self.request_count += 1 start_time = time.time() # 1. 预算检查 if self.budget_manager.get_current_cost() > self.budget_manager.max_budget * 0.95: raise Exception("Budget almost exhausted") # 2. 设置超时(防止某个模型 hang 住) timeout = kwargs.pop("timeout", 30) try: # 3. 调用 Router response = self.router.completion( model=model, messages=messages, timeout=timeout, **kwargs ) # 4. 更新预算(按 usage 计费) cost = self._calculate_cost(response) self.budget_manager.update_cost(cost) # 5. 记录耗时 duration = time.time() - start_time print(f"[{self.request_count}] {model} | {duration:.2f}s | {cost:.4f} USD") return response except Exception as e: duration = time.time() - start_time print(f"[{self.request_count}] {model} | FAILED | {duration:.2f}s | {str(e)[:50]}") raise e def _calculate_cost(self, response): # 简化版:按 token 数和模型单价算 usage = response.usage model = response.model # 价格表(实际应从数据库或配置中心读) prices = { "gpt-4o": {"prompt": 0.000005, "completion": 0.000015}, "claude-3-haiku-20240307": {"prompt": 0.00000025, "completion": 0.00000125}, "ollama/llama3": {"prompt": 0, "completion": 0} # 本地免费 } price = prices.get(model, prices["gpt-4o"]) return (usage.prompt_tokens * price["prompt"] + usage.completion_tokens * price["completion"]) # 使用 client = SafeLLMClient(router, max_budget=5000) resp = client.completion( model="gpt-4o", messages=[{"role": "user", "content": "写一首关于春天的五言绝句"}], temperature=0.3 ) print(resp.choices[0].message.content)

这个封装实现了:

  • 预算硬控制:超 95% 预警,100% 拒绝;
  • 超时熔断:单次请求最长 30 秒,避免线程阻塞;
  • 成本透明:每条请求打印耗时和预估费用;
  • 错误归因:失败时打印具体模型和错误摘要,便于排查。

注意:BudgetManager是 LiteLLM 内置类,但它的update_cost()是内存计数,不持久化。生产环境需替换为 Redis 或数据库存储,否则重启进程预算清零。

4.3 FastAPI 集成:暴露标准 OpenAI 兼容 API

很多前端或现有工具(如 LangChain)期望调用标准 OpenAI endpoint。LiteLLM 支持一键启动兼容服务:

# 启动 LiteLLM 代理服务 litellm --model gpt-4o --api-key sk-xxx --drop-in

但这种方式缺乏定制性。更推荐用 FastAPI 自定义:

from fastapi import FastAPI, Request, HTTPException from fastapi.responses import StreamingResponse import json app = FastAPI() @app.post("/v1/chat/completions") async def chat_completions(request: Request): try: body = await request.json() # 提取标准字段 model = body.get("model", "gpt-4o") messages = body.get("messages", []) stream = body.get("stream", False) temperature = body.get("temperature", 1.0) max_tokens = body.get("max_tokens", 2048) # 调用封装好的 client if stream: # 流式处理 async def stream_generator(): response = client.completion( model=model, messages=messages, stream=True, temperature=temperature, max_tokens=max_tokens ) for chunk in response: # 转为 SSE 格式 yield f"data: {json.dumps(chunk.dict(), ensure_ascii=False)}\n\n" yield "data: [DONE]\n\n" return StreamingResponse(stream_generator(), media_type="text/event-stream") else: # 非流式 response = client.completion( model=model, messages=messages, temperature=temperature, max_tokens=max_tokens ) return response except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # 启动:uvicorn main:app --reload

这个 API 完全兼容 OpenAI SDK:

from openai import OpenAI client = OpenAI(base_url="http://localhost:8000/v1", api_key="anything") resp = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "hi"}] )

前端无需改一行代码,就能享受 LiteLLM 的多模型路由和 fallback 能力。

4.4 监控与可观测性:用 Prometheus + Grafana 看清模型健康度

LiteLLM 内置litellm.monitoring模块,支持上报指标到 Prometheus:

from litellm.monitoring import PrometheusLogger prometheus_logger = PrometheusLogger() # 注册到 Router router = Router( model_list=[...], callbacks=[prometheus_logger] # 自动上报 metrics ) # 启动 Prometheus HTTP server from prometheus_client import start_http_server start_http_server(8001) # 指标暴露在 :8001/metrics

它会上报以下关键指标:

  • litellm_request_total{model="gpt-4o",status="success"}:请求总数
  • litellm_request_duration_seconds_bucket{model="gpt-4o",le="10"}:耗时分布
  • litellm_token_usage_total{model="gpt-4o",type="prompt"}:token 消耗
  • litellm_health_check_status{model="ollama-llama3"}:健康状态(1=healthy, 0=unhealthy)

在 Grafana 中,你可以创建看板监控:

  • 各模型成功率趋势(rate(litellm_request_total{status="success"}[1h]) / rate(litellm_request_total[1h]))
  • P95 耗时 Top3(histogram_quantile(0.95, sum(rate(litellm_request_duration_seconds_bucket[1h])) by (le, model)))
  • 本地模型健康状态(litellm_health_check_status == 0告警)

实操心得:Prometheus 指标默认是内存存储,重启丢失。生产环境务必配置--storage.tsdb.path持久化,或用 VictoriaMetrics 替代。

5. 常见问题与排查技巧实录:那些文档里不会写的血泪教训

5.1 典型问题速查表

问题现象可能原因排查命令/方法解决方案
AuthenticationError: Invalid API keyAPI Key 格式错误或过期echo $OPENAI_API_KEY | wc -c检查长度;curl -H "Authorization: Bearer $KEY" https://api.openai.com/v1/models重新生成 Key,确保无空格换行;用export OPENAI_API_KEY="sk-..."设置
TimeoutError: Request timed out模型服务响应慢或网络延迟高time curl -X POST https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $KEY" -d '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"hi"}]}'增加timeout参数;检查litellm.num_retries;对慢模型单独设max_retries=1避免重试雪崩
ContextWindowExceededErrorPrompt + max_tokens 超模型 context windowlitellm.token_counter(model="gpt-4o", text=prompt)计算实际 prompt tokens动态截断 prompt;或用litellm.get_max_tokens("gpt-4o")获取模型最大值,预留 200 tokens 给 response
Provider not supportedcustom_llm_provider拼写错误print(litellm.supported_litellm_providers)查看支持列表严格按文档拼写:"ollama"、"llama_cpp"、"anthropic"(无下划线)
Stream response is empty流式 chunk 解析失败litellm.set_verbose=True,看日志中raw streaming response必须用stream_chunk_builder()解析,不可直接遍历response

5.2 那些踩过的坑:只有亲手调过才知道

坑一:环境变量污染导致模型路由错乱
LiteLLM 会自动读取OPENAI_API_KEY、ANTHROPIC_API_KEY等环境变量。如果你在.env文件里同时写了OPENAI_API_KEY和ANTHROPIC_API_KEY,但 Router 只配置了gpt-4o,那么当gpt-4ofallback 到claude-3-haiku时,LiteLLM 会自动用ANTHROPIC_API_KEY,即使你没在litellm_params里显式传。这导致:你以为只配了一个模型,实际悄悄用了两个 Key。
避坑:生产环境禁用全局环境变量,所有 Key 必须显式传入litellm_params:

{ "model_name": "gpt-4o", "litellm_params": { "model": "gpt-4o", "api_key": "sk-xxx-gpt", # 显式传 "api_base": "https://api.openai.com/v1" } }

坑二:Ollama 模型名大小写敏感,但 LiteLLM 不报错
Ollama 的ollama list显示模型名为llama3,但你ollama run llama3成功,litellm.completion(model="ollama/llama3", ...)却报model not found。原因是:Ollama 实际注册的模型名是llama3:latest,而 LiteLLM 默认用llama3去查。
避坑:始终用ollama list看全名,或在 LiteLLM 中显式指定 tag:

litellm.completion(model="ollama/llama3:latest", ...) # 加 :latest

坑三:llama.cpp server 的--port和--host必须匹配
启动 llama.cpp server 时,如果只写./server -m model.gguf --port 8080,它默认绑定127.0.0.1:8080。但 LiteLLM 的api_base如果写http://localhost:8080/v1,在 Docker 环境中localhost指向容器自身,而非宿主机。
避坑:启动 server 时加--host 0.0.0.0:

./server -m model.gguf --port 8080 --host 0.0.0.0

然后 LiteLLM 用http://host.docker.internal:8080/v1(Mac/Windows)或http://宿主机IP:8080/v1(Linux)。

坑四:Fallback 不重试,但 Router 会重试,导致重复计费
假设你配置fallbacks={"gpt-4o": ["claude"]},且gpt-4o因超时失败。Router 会先重试gpt-4o(num_retries=2),两次都失败后,才 fallback 到 `claude

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 7:59:18

综合能源系统双层优化调度策略复现与Matlab实现解析

1. 项目概述与选题背景1.1 为什么"核心期刊复现"这么让人头大先说结论:复现一篇综合能源系统方向的核心期刊论文,很多时候比自己在原有框架上加一个新目标函数更痛苦。原因很简单,期刊正文里给出的公式是从定稿模型中截取的"高…

作者头像 李华
网站建设 2026/10/13 7:59:03

基于Hough变换的答题卡识别:从直线检测到透视校正的工程实践

简介:这份资源围绕基于Hough变换的答题卡识别技术展开,面向计算机视觉入门者、图像处理课程学习者及需要自动阅卷方案的开发者,帮助解决答题卡选项定位、填涂识别与答案映射等实际问题。压缩包共14个文件,以13个m脚本文件和1个jpg…

作者头像 李华
网站建设 2026/10/13 7:58:46

MySQL存储引擎选型指南:InnoDB与MyISAM对比及运维实战

我之前处理过一个比较典型的线上排查:一张业务表行数不到一千万,服务器负载也不高,可每天高峰时段的查询耗时总在慢慢爬升,从几十毫秒一路涨到两三秒。索引看了,执行计划也看了,慢查询日志里照样没什么明显…

作者头像 李华
网站建设 2026/10/13 7:57:38

整数各位数字分解:取模运算原理与工程鲁棒实现

1. 这不是数学作业,而是一道藏在编程面试里的“思维体操”“整数的分解(逆序输出与正序输出)”——光看标题,很多人第一反应是小学奥数题:把123拆成1、2、3,再倒过来写成321。但如果你真这么做了&#xff0…

作者头像 李华
网站建设 2026/10/13 7:57:29

2026年技术交叉风口:AI智能体、6G、量子计算与碳纤维

1. 为什么我说2026年的风口藏在"技术交叉处"2026年如果只用一个词概括科技圈的状态,我会用"格式化"。过去两年AI赛道的热度已经把概念炒得很高了,但一个明显的信号是,越来越多人开始意识到,真正的赢家不再比拼…

作者头像 李华