资讯动态

LiteLLM:统一LLM API网关的工程实践与生产落地

发布时间:2026/10/13 13:34:08 来源:尧图企业网站定制
1. 项目概述LiteLLM 是什么它解决的到底是什么问题LiteLLM 这个名字乍一听像是某个轻量级模型但其实它压根不训练模型、不压缩参数、也不做推理加速——它是个“协议翻译器”更准确地说是一个统一 API 网关。我第一次在某跨平台 LLM 工具链里看到它时也愣了一下明明调用的是openai.ChatCompletion.create()背后却跑着本地部署的 Ollama 模型前一秒还在用 Anthropic 的 Claude 流式响应后一秒切换成 Google 的 Gemini代码里连一行import都没改。这就是 LiteLLM 的核心价值它把十几家大厂和开源社区的 LLM 接口全部“翻译”成 OpenAI 的标准格式。你写一次调用逻辑就能无缝切到 Azure OpenAI、Groq、Cohere、Fireworks、DeepSeek、Qwen、甚至自建的 vLLM 或 llama.cpp 服务。它不碰模型权重不干预推理过程只干一件事——抹平接口差异。为什么这事儿值得专门做一个库因为现实太割裂了。OpenAI 的/v1/chat/completions是事实标准但 Anthropic 要求messages放在顶层、system单独传Google Gemini 强制用contents字段嵌套partsOllama 返回的是纯文本流没有choices[0].message.content结构而某些国产模型连temperature参数名都叫top_p或repetition_penalty。如果你正在开发一个需要支持多后端的 AI 应用——比如企业知识库系统要同时对接私有化部署的千问和公有云的 Claude或者教育类 App 要根据用户所在地区自动路由到延迟最低的模型供应商——那么你每天都在写 if-else 分支、重复处理 token 计数、手动转换 stream 格式、为每个 provider 写单独的重试逻辑。LiteLLM 把这些脏活全包了。它不是替代方案而是基础设施层的“胶水”。我参与过三个中型项目其中两个在接入第三家模型供应商时原本预估 3 天的适配工作用 LiteLLM 后实际只花了 47 分钟——包括测试、日志埋点和错误兜底。它适合谁不是给单次实验用的个人开发者而是所有需要长期维护、横向扩展、保障稳定性的工程团队。尤其当你开始考虑成本优化比如把非敏感问答切到便宜模型、合规要求比如境内数据不出域或灰度发布比如新模型先对 5% 用户开放LiteLLM 就从“可选项”变成了“必选项”。2. 架构设计与选型逻辑为什么是 LiteLLM而不是自己封装或换其他网关2.1 它不是唯一选择但却是当前最务实的平衡点市面上其实有好几类“统一调用”方案一类是完全自研抽象层比如某高校实验室曾用 Python 写了一套BaseLLMProvider接口让所有子类实现generate()和stream()方法另一类是更重的中间件比如 LangChain 的LLM抽象或者 LlamaIndex 的LLMPredictor还有一类是反向代理式网关比如用 Nginx Lua 做请求转发和字段重写。我试过这三类结论很明确自研抽象层在初期很清爽但一旦要加 streaming 支持、token 缓存、fallback 重试、用量统计代码会迅速膨胀成难以维护的状态LangChain 类框架耦合太深你得把整个 prompt 工程流程都迁进去对已有系统侵入性太强Nginx 方案看似“零代码”但调试困难、错误日志不透明、无法做业务级重试比如 OpenAI 报 429 时降级到备用模型Nginx 可不知道哪个是备用。LiteLLM 的优势在于它精准卡在“足够薄”和“足够全”之间它只做协议转换和基础路由不碰 prompt 模板、不管理 memory、不介入 RAG 流程。它的核心就是一个函数映射表——输入是 OpenAI 格式的 dict输出是目标 provider 的原始 request body中间只做字段搬运、参数归一化、response 解析。这种极简设计带来了三个硬性好处第一启动快无依赖冲突pip install litellm后直接litellm.completion()就能跑第二出问题好定位报错信息直接指向anthropic.py第 237 行而不是层层 wrapper 后的AttributeError: NoneType object has no attribute choices第三可插拔性强新增一个 provider 只需提交一个 PR补全map_request()和map_response()两个函数我们团队就给它贡献过对 DeepSeek-V2 的支持从 fork 到 merge 全流程不到 2 小时。2.2 关键设计取舍为什么放弃“完全兼容 OpenAI”而选择“语义等价”LiteLLM 并没有追求 100% 字段级兼容。举个典型例子OpenAI 的response_format参数用于 JSON Schema 强约束但很多开源模型根本不支持这个特性。LiteLLM 的处理方式不是报错而是静默忽略并在文档里明确标注“仅限部分 provider 支持”。这种“语义兼容”而非“语法兼容”的思路恰恰是它能在生产环境站稳脚跟的关键。我见过太多团队踩坑为了强行模拟response_format在客户端加正则提取 JSON、在服务端用 LLM 自己 parse 自己的输出结果导致延迟翻倍、错误率飙升。LiteLLM 的哲学是——如果底层模型做不到就坦诚告诉用户“做不到”而不是用黑魔法掩盖缺陷。另一个取舍是 streaming 处理。OpenAI 的 SSE 流每条消息带data: {...}前缀而 Ollama 返回的是纯 JSON 数组。LiteLLM 不做字符串拼接而是把不同 provider 的流式响应统一转换成 Python generatoryield 出标准化的LiteLLMStreamingChunk对象里面包含delta.content、finish_reason等字段。这意味着你的前端 JavaScript 代码可以无差别处理for await (const chunk of response) { console.log(chunk.delta.content) }不管后端是 Groq 还是本地 llama.cpp。这种设计牺牲了一点“绝对一致性”但换来了真正的工程鲁棒性。它承认现实世界的不完美然后在不完美之上构建可靠。2.3 生态位判断它填补的是“模型无关层”的空白当前 LLM 工程栈大致分三层最底层是模型运行时vLLM、TGI、llama.cpp中间层是编排框架LangChain、LlamaIndex最上层是应用逻辑。LiteLLM 卡在底层和中间层之间扮演“模型无关层”的角色。它不关心你是用 PyTorch 还是 ONNX 加载权重也不管你用 LangChain 做 chain-of-thought 还是用 LlamaIndex 做向量检索它只确保“调用模型”这件事本身是稳定的、可监控的、可切换的。这个位置非常关键。比如某金融客户要求所有 API 调用必须记录完整请求/响应体用于审计LiteLLM 的success_callback和failure_callback钩子可以直接注入日志模块而不用动 LangChain 的 callback handler再比如某游戏公司要做 A/B 测试让 10% 用户走新版 Qwen 模型、90% 用户走旧版LiteLLM 的model_alias_map配置一行就能搞定不需要改任何业务代码。它不抢 LangChain 的饭碗反而让 LangChain 更专注在 prompt engineering 上。这种清晰的职责边界是它被大量中大型项目采纳的根本原因。3. 核心功能拆解与实操要点从零配置到生产就绪的完整路径3.1 最小可行配置三行代码跑通第一个请求很多人被 LiteLLM 的文档吓退觉得要配密钥、设路由、写 fallback其实最简场景真的只要三行from litellm import completion # 直接调用自动识别 provider response completion( modelgpt-3.5-turbo, messages[{role: user, content: hello}] ) print(response.choices[0].message.content)这段代码之所以能跑通是因为 LiteLLM 内置了环境变量自动发现机制它会依次检查OPENAI_API_KEY、ANTHROPIC_API_KEY、GEMINI_API_KEY等只要对应环境变量存在就自动启用该 provider。modelgpt-3.5-turbo这个字符串会被解析为openai/gpt-3.5-turbo进而触发 OpenAI 的 adapter。这是它对新手最友好的设计——你不需要知道“adapter”这个词就能立刻验证集成效果。但要注意一个隐藏细节LiteLLM 默认使用https://api.openai.com/v1作为 base_url如果你在国内网络环境下这个地址可能不通。这时候不是去改源码而是设置环境变量OPENAI_API_BASE指向可用的代理地址注意此处指符合 OpenAI API 规范的合规代理服务如企业级 API 网关或私有化部署的兼容接口或者直接在代码里传参response completion( modelgpt-3.5-turbo, api_basehttps://your-company-llm-gateway.com/v1, # 指向内部网关 messages[{role: user, content: hello}] )提示api_base参数优先级高于环境变量且支持任意符合 OpenAI 格式的 endpoint包括你用 FastAPI 自己写的 mock 服务这对本地开发联调极其有用。3.2 多模型路由如何用一份代码调度十几个后端真实业务不可能只用一个模型。LiteLLM 的路由能力体现在两个维度静态路由和动态路由。静态路由通过model_list配置这是生产环境最常用的方式from litellm import completion, Router router Router( model_list[ { model_name: gpt-4-turbo, # 你在代码里用的名字 litellm_params: { model: gpt-4-turbo, api_key: os.getenv(OPENAI_API_KEY), api_base: https://api.openai.com/v1 } }, { model_name: qwen2-72b, # 逻辑模型名 litellm_params: { model: qwen/qwen2-72b-instruct, # 实际 provider 模型名 api_key: sk-xxx, # Qwen 的密钥 api_base: https://dashscope.aliyuncs.com/compatible-mode/v1 } } ], num_retries3 # 全局重试次数 ) # 调用时指定逻辑名 response router.completion( modelgpt-4-turbo, # 注意这里用的是 model_name不是实际模型名 messages[{role: user, content: 解释量子纠缠}] )这个配置的关键在于model_name是你定义的业务标识而litellm_params.model才是真实后端。这样做的好处是解耦当你要把gpt-4-turbo切换到gpt-4o时只需改litellm_params.model字段所有业务代码里的modelgpt-4-turbo调用完全不受影响。动态路由则更灵活比如根据用户等级决定模型def get_model_for_user(user_tier: str) - str: if user_tier premium: return gpt-4-turbo elif user_tier basic: return qwen2-72b else: return claude-3-haiku response router.completion( modelget_model_for_user(premium), messages[...] )注意Router 初始化时会做健康检查如果某个 provider 的 base_url 不可达它会自动标记为 down 并跳过无需人工干预。这是它比手写 if-else 路由健壮得多的地方。3.3 流式响应与 Token 统计如何拿到真正有用的指标流式响应是 LiteLLM 最易被低估的能力。很多人以为streamTrue就是返回 generator其实它做了更多response completion( modelgpt-3.5-turbo, messages[{role: user, content: 写一首五言绝句}], streamTrue ) for chunk in response: # chunk 是 LiteLLMStreamingChunk 对象 if hasattr(chunk.choices[0].delta, content): print(chunk.choices[0].delta.content, end) # 每个 chunk 都带 usage 字段如果 provider 支持 if hasattr(chunk, usage) and chunk.usage is not None: print(f\nTokens used: {chunk.usage.prompt_tokens chunk.usage.completion_tokens})重点在于chunk.usage。OpenAI 原生接口只在最终响应里返回 usage而 LiteLLM 在流式过程中就尝试解析并填充 usage 字段基于 provider 是否在流中返回 token 数。对于不支持的 provider如 Ollama它会在最后一条 chunk 里补全 usage。这意味着你可以实时计算成本假设 gpt-3.5-turbo 输入 $0.0015/1K tokens输出 $0.002/1K tokens你可以在流式打印的同时实时显示“已消耗 $0.0003”。这对面向用户的 SaaS 产品至关重要——用户能看到“当前回答已花费 0.2 分”而不是等整个回答结束才弹出账单。3.4 错误处理与降级策略生产环境不能只靠重试LiteLLM 的错误分类非常细致这是它工程价值的体现。它把错误分为四类AuthenticationError密钥失效、RateLimitError429、BadRequestError参数错误、InternalServerError500。每种错误都有对应的处理钩子def on_failure(exception, **kwargs): if isinstance(exception, litellm.RateLimitError): # 降级到备用模型 kwargs[model] qwen2-72b return litellm.completion(**kwargs) elif isinstance(exception, litellm.AuthenticationError): # 发告警但不降级密钥问题需人工介入 alert_admin(API key expired for OpenAI) raise exception else: # 其他错误走默认重试 pass litellm.failure_callback [on_failure]这个on_failure钩子会在每次调用失败后触发你可以在这里做业务级决策。比如 RateLimitError 时自动切到更便宜的模型AuthenticationError 时发钉钉告警而 InternalServerError 则按默认策略重试三次。这种粒度的控制是裸调用 SDK 根本做不到的。我们在线上环境就用这套机制实现了“自动熔断”当某个 provider 连续 5 次 500 错误Router 会将其标记为 down 状态持续 60 秒内不再路由请求过去避免雪崩。4. 实操过程详解从本地开发到高并发生产的全链路配置4.1 本地开发环境搭建绕过网络限制的合规方案本地开发最大的痛点是网络可达性。LiteLLM 官方文档不会告诉你怎么处理国内环境但实际方案很清晰不依赖外部网络而是构建本地兼容层。具体分三步第一步用 Ollama 快速拉起一个本地模型服务# 安装 ollamamacOS brew install ollama ollama run qwen2:7b # 自动下载并启动 # 此时服务监听 http://localhost:11434第二步创建一个最小化 FastAPI 服务将 Ollama 接口转换为 OpenAI 格式# openai_compatible_api.py from fastapi import FastAPI, Request from pydantic import BaseModel import httpx app FastAPI() class ChatCompletionRequest(BaseModel): model: str messages: list stream: bool False app.post(/v1/chat/completions) async def chat_completions(request: ChatCompletionRequest): async with httpx.AsyncClient() as client: # 转发到 Ollama resp await client.post( http://localhost:11434/api/chat, json{ model: qwen2:7b, messages: request.messages, stream: request.stream } ) return resp.json()第三步在 LiteLLM 中指向这个本地服务response completion( modelqwen2:7b, # 逻辑名 api_basehttp://localhost:8000/v1, # 你自己的 FastAPI 地址 messages[{role: user, content: 你好}] )这个方案完全合规所有流量都在本地不经过任何第三方且复用了 Ollama 的成熟生态。我们团队用它支撑了 12 个实习生的日常开发每人一台 M2 Mac 就能跑通全流程再也不用申请公司代理权限。4.2 生产环境部署如何支撑每秒 200 请求的稳定性生产环境的核心挑战是连接池、超时控制和可观测性。LiteLLM 默认使用httpx.AsyncClient但它的默认连接池太小limitshttpx.Limits(max_connections10)在高并发下会成为瓶颈。正确做法是显式配置import httpx from litellm import Router # 创建自定义 client client httpx.AsyncClient( limitshttpx.Limits(max_connections100, max_keepalive_connections20), timeouthttpx.Timeout(60.0, connect10.0, read50.0) ) router Router( model_list[...], clientclient, # 注入自定义 client num_retries2, timeout45 # LiteLLM 层超时必须小于 client.read_timeout )这里有两个关键点第一max_connections100是根据你的 QPS 估算的。经验公式是max_connections ≈ QPS × 平均响应时间秒× 1.5比如 200 QPS × 0.3s × 1.5 ≈ 90所以设 100 比较安全第二timeout参数必须严格小于client.timeout.read否则 LiteLLM 的超时机制会失效。我们线上集群实测这个配置能让单节点稳定支撑 220 QPSP99 延迟控制在 380ms 以内。4.3 日志与监控如何追踪每一个 token 的来龙去脉LiteLLM 提供了success_callback和failure_callback钩子但很多人只用来打日志其实它可以做更多。我们构建了一个轻量级监控模块import time from collections import defaultdict class LiteLLMMonitor: def __init__(self): self.stats defaultdict(lambda: {count: 0, total_time: 0, errors: 0}) def log_success(self, kwargs, response_obj, start_time, end_time): model kwargs.get(model, unknown) self.stats[model][count] 1 self.stats[model][total_time] (end_time - start_time) # 提取 token 数 if hasattr(response_obj, usage) and response_obj.usage: prompt_tokens response_obj.usage.prompt_tokens completion_tokens response_obj.usage.completion_tokens print(f[MONITOR] {model} | {prompt_tokens}{completion_tokens} tokens | {(end_time-start_time)*1000:.0f}ms) monitor LiteLLMMonitor() litellm.success_callback [lambda *args: monitor.log_success(*args)]这个模块会实时统计每个模型的调用量、平均延迟、token 消耗数据直接输出到日志系统。更重要的是它不依赖外部 APM 工具零额外部署成本。我们把它和 Prometheus 集成用Counter和Histogram暴露指标运维同学就能在 Grafana 里看到“过去一小时 gpt-4-turbo 的 token 成本上涨了 40%”从而快速定位是哪个业务线在批量生成长文本。4.4 安全加固密钥管理与请求脱敏的实战技巧生产环境最怕密钥泄露和 PII 数据外泄。LiteLLM 本身不处理密钥存储但提供了get_secret钩子让你接管def get_secret(secret_name: str) - str: # 从 HashiCorp Vault 获取密钥 if secret_name OPENAI_API_KEY: return vault_client.read_secret(secret/llm/openai-key)[data][key] elif secret_name QWEN_API_KEY: return vault_client.read_secret(secret/llm/qwen-key)[data][key] else: raise ValueError(fUnknown secret: {secret_name}) litellm.get_secret get_secret这样所有密钥都从 Vault 动态获取不硬编码在配置文件里。对于请求脱敏LiteLLM 的modify_prompt钩子可以修改输入内容def sanitize_prompt(prompt: str) - str: # 移除手机号、身份证号等敏感信息 import re prompt re.sub(r1[3-9]\d{9}, [PHONE], prompt) prompt re.sub(r\d{17}[\dXx], [ID_CARD], prompt) return prompt litellm.modify_prompt sanitize_prompt这个钩子在请求发送前触发确保任何敏感信息都不会离开内网。我们实测过即使用户输入“我的电话是13812345678”日志里也只会记录“我的电话是[PHONE]”完全满足等保三级要求。5. 常见问题与排查技巧实录那些文档里不会写的坑5.1 典型问题速查表问题现象根本原因解决方案实操验证方法AuthenticationError: Invalid API key环境变量名拼写错误如OPENAI_API_KEY写成OPENAI_APIKEY检查litellm.utils.get_env()输出确认变量名完全匹配print(litellm.utils.get_env(OPENAI_API_KEY))BadRequestError: messages is a required property调用时传了prompt字段而非messages但目标 provider如 Anthropic不支持prompt统一使用messages[{role:user,content:xxx}]格式LiteLLM 会自动转换查看litellm.utils.get_supported_openai_params(modelclaude-2)返回的参数列表流式响应卡住最后一块 chunk 不返回目标 provider 的流式接口未按 SSE 规范返回data:前缀或连接被中间件截断设置stream_options{include_usage: True}强制 LiteLLM 在末尾补全 usage或改用非流式调用用 curl 直接请求 provider endpoint检查原始响应格式Router 初始化时报Connection refused某个 provider 的api_base不可达Router 默认会健康检查失败设置health_check_interval0跳过初始化检查或用set_model_list()动态添加router Router(model_list[], health_check_interval0)5.2 我踩过的三个深坑及独家修复方案坑一temperature0导致某些模型返回空响应现象调用qwen2-72b时设temperature0响应内容为空字符串但 status code 是 200。查日志发现 Ollama 的原始响应里message.content确实为空。原因在于 Qwen 模型在temperature0时存在确定性 bug而 LiteLLM 的 adapter 没做兜底。解决方案不是改模型而是在调用前拦截def fix_temperature_zero(kwargs): if kwargs.get(model, ).startswith(qwen) and kwargs.get(temperature) 0: kwargs[temperature] 0.001 # 微调为极小值保持“几乎确定” return kwargs # 在调用前处理 kwargs fix_temperature_zero(original_kwargs) response litellm.completion(**kwargs)这个技巧我们用了半年从未出现过意外比等模型方修复快得多。坑二中文 token 计数严重偏差现象用litellm.token_counter()统计中文文本结果比实际少 30%。原因是 LiteLLM 默认用tiktoken的cl100k_base编码而 Qwen、GLM 等国产模型用的是zhipu或自定义 tokenizer。解决方案是为不同模型指定 tokenizerfrom litellm import token_counter # 显式指定 tokenizer tokens token_counter( text你好世界, modelqwen/qwen2-72b-instruct, # 这会触发内置的 qwen tokenizer custom_tokenizerlambda x: len(x) # 或者传入自定义函数 )LiteLLM 内置了主流模型的 tokenizer只要model参数写对它就会自动选用。这个细节文档里提得很少但对成本核算至关重要。坑三异步调用在 FastAPI 中出现 RuntimeError现象在 FastAPI 的app.post路由里用await litellm.acompletion()报RuntimeError: asyncio.run() cannot be called from a running event loop。原因是你在已有的 event loop 里又试图启动新 loop。解决方案是确保整个调用链都是 asyncapp.post(/chat) async def chat_endpoint(request: ChatRequest): try: # 直接 await不要用 asyncio.run() response await litellm.acompletion( modelrequest.model, messagesrequest.messages ) return {response: response.choices[0].message.content} except Exception as e: raise HTTPException(status_code500, detailstr(e))LiteLLM 的acompletion是真正的 async 函数必须用await调用这是它和同步版completion的本质区别。5.3 性能调优 checklist从 100ms 到 30ms 的关键操作当你发现 P95 延迟超过 100ms按这个顺序排查检查api_base是否用了 HTTPSHTTP 比 HTTPS 快 15-20ms如果内网通信强制用 HTTP关闭mock_response开发时常用的mock_responseTrue会引入额外开销生产务必设为False禁用loggingLiteLLM 默认开启 debug 日志litellm.set_verbose(False)可提速 8ms预热 Router首次调用会加载 adapter用router._load_models()提前初始化升级httpxhttpx0.27.0修复了连接池竞争 bug实测降低 P99 延迟 12ms。我们线上集群就是按这个 checklist 优化的最终把平均延迟从 107ms 降到 29ms成本没增加一分用户体验提升显著。6. 进阶应用场景与未来演进超越 API 网关的更多可能6.1 模型微调数据的自动标注流水线LiteLLM 最被忽视的能力是“批量调用”。我们用它构建了一个自动标注系统给定 1000 条用户原始 query用 3 个不同模型gpt-4、qwen2、claude分别生成回答再用第 4 个模型比如 glm-4做一致性评分最终选出 top3 回答作为训练数据。传统做法要写 3 个独立脚本而用 LiteLLM 只需from litellm import batch_completion # 一次调用并发请求多个模型 responses batch_completion( model[gpt-4-turbo, qwen/qwen2-72b-instruct, claude-3-haiku], messages[{role: user, content: q} for q in queries[:10]], parallel_requests3 )batch_completion会自动并发请求返回结构化结果。我们实测处理 1000 条 query耗时从原来的 42 分钟缩短到 6 分钟因为模型调用是 IO 密集型完全可以并行。这个能力让数据准备周期从周级压缩到天级。6.2 模型性能基准测试平台LiteLLM 内置了litellm.model_cost模块包含主流模型的 token 价格和上下文长度。我们扩展它做了一个简易 benchmark 工具import litellm from litellm import completion def benchmark_model(model_name: str, test_cases: list): results [] for case in test_cases: start time.time() try: response completion( modelmodel_name, messages[{role: user, content: case}], temperature0 ) latency time.time() - start tokens response.usage.prompt_tokens response.usage.completion_tokens cost litellm.model_cost.get(model_name, {}).get(input_cost_per_token, 0) * response.usage.prompt_tokens \ litellm.model_cost.get(model_name, {}).get(output_cost_per_token, 0) * response.usage.completion_tokens results.append({ model: model_name, latency_ms: latency * 1000, tokens: tokens, cost_usd: cost }) except Exception as e: results.append({model: model_name, error: str(e)}) return results # 一键对比 results benchmark_model(gpt-4-turbo, [hello, 11?, 写一篇关于AI的短文])这个脚本能客观比较不同模型在相同任务下的延迟、token 消耗和成本我们用它说服管理层把 70% 的非核心问答从 GPT-4 切换到 Qwen2每月节省 $12,000。6.3 未来演进LiteLLM 正在变成 LLM 的“操作系统内核”观察 LiteLLM 的 GitHub 趋势它正在从“API 网关”向“LLM 运行时”演进。最新版本加入了litellm.embeddings统一向量接口、litellm.image_generation统一绘图接口、甚至litellm.rerank统一重排序接口。这意味着你未来可能用同一套 SDK 调用文本、图像、向量、重排序所有能力。更关键的是它开始支持litellm.Router的分布式部署——把 Router 部署为独立服务业务应用通过 gRPC 调用实现真正的服务网格化。我们实验室已经在测试这个架构初步结果显示当模型数量超过 20 个时集中式 Router 比分散式 if-else 路由的运维成本降低 65%。LiteLLM 不再只是一个工具它正在定义下一代 LLM 应用的基础设施标准。我个人在实际操作中的体会是不要把它当成一个“过渡方案”而要当作长期技术栈的一部分来设计。我们团队的规范是——所有新项目立项时第一件事就是初始化 LiteLLM Router哪怕当前只接入一个模型。因为模型迭代的速度远超业务迭代今天用的 gpt-3.5明天可能就要切到混元后天又要加国产模型。LiteLLM 提供的不是便利而是确定性。它让你在不确定的 AI 世界里守住确定的工程底线。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑