news 2026/8/30 7:29:13

LiteLLM 自定义提供商扩展开发快速上手:一篇文章接入新 LLM

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LiteLLM 自定义提供商扩展开发快速上手:一篇文章接入新 LLM

LiteLLM 自定义提供商扩展开发快速上手:一篇文章接入新 LLM

【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm

每接一个新模型,就要重写一遍客户端适配吗?参数名不一样、响应结构不一样、流式分片的格式还不一样,接入工作全在重复劳动。litellm 的设计目标,就是用一套 OpenAI 风格的调用覆盖 100+ 家 LLM 服务——而做一次 litellm 自定义提供商扩展开发,成本比想象低得多:写一个转换类,注册一个名字,就接进来了。下面围绕「把一个新 LLM 服务接进 litellm」这条主线,带你走通一个最小可用的自定义 provider。

心智模型:从模型名到响应的三段链路

动代码之前,先建立方向感。一个 litellm 自定义 provider 不是黑盒,而是一条三段链路:模型名myprovider/quick-1b先经过注册表,由get_llm_provider把斜杠前的前缀拆出来、对照litellm.provider_list定位到你的转换类;转换类是「海关」——请求出境时把 OpenAI 格式盖戳成目标 API 的入参,响应入境时再把厂商的原始 JSON 翻译成统一的ModelResponse;BaseLLM 基类则提供 httpx 会话、响应处理钩子这些公共基础设施,你的转换类只管「翻译」,不管「物流」。

所以 litellm 扩展开发的全部工作量,就是补上链路里「海关」这一环:一个转换类,加一次注册。

动手前的三件准备:环境与三个关键文件

动手前的准备可以压缩成一张清单:

  • 环境:拿到代码仓库后,在项目根目录执行pip install -e .装成可编辑模式——这既是开发依赖的安装方式,也是后续本地调试最快的路径,改完代码立刻生效。
  • litellm BaseLLM 基类:litellm/llms/base.py 是官方注释里写明「用于通过 API 调用添加新 LLM provider」的模板基类,提供客户端会话创建和process_response钩子。
  • 自定义 LLM 模板:litellm/llms/base_llm/chat/transformation.py 里的BaseConfig是转换类的抽象基类,同文件还定义了BaseLLMException,是后面要统一抛出的异常类型。
  • 参数转换参考:别从零发明,直接读 litellm/llms/ollama/chat/transformation.py,OllamaChatConfig展示了从参数翻译、响应转换到流式解析的完整链路,是照着抄最省事的样板。

最小 Provider:四方法骨架

最小可用的 provider 只需要承诺四个方法,同步/异步各一对、补全与流式各一对:

# litellm/llms/myprovider/chat/transformation.py:最小四方法骨架 class MyProviderConfig: # 继承 BaseConfig,骨架先让请求跑通 def completion(self, model, messages, api_base, api_key, **kwargs): ... # 同步补全:发出请求,返回统一的 ModelResponse async def acompletion(self, model, messages, api_base, api_key, **kwargs): ... # 异步补全:用异步客户端,返回结构相同 def completion_streaming(self, model, messages, api_base, api_key, **kwargs): ... # 同步流式:逐块 yield,返回 GenericStreamingChunk 迭代器 async def acompletion_streaming(self, model, messages, api_base, api_key, **kwargs): ... # 异步流式:返回异步迭代器

四个方法就位,litellm.completion(model="myprovider/quick-1b", ...)就能端到端走通。这就是 litellm 接入新 LLM 的及格线。

翻译层:OpenAI 格式与目标 API 的双向转换

转换类的核心是双向工作:请求侧把messages和采样参数翻译成目标服务认识的字段,响应侧再把厂商输出映射回统一结构。以假想的 myprovider 为例:

# MyProviderConfig 内部:请求与响应两道"海关" def transform_request(self, model, messages, optional_params): return { # 把 OpenAI 风格参数打包成目标 API 的请求体 "model": model, "input": messages, # 该厂商把消息列表叫 input,litellm 叫 messages "max_tokens": optional_params.get("max_tokens", 100), } def transform_response(self, raw, model): # 把原始响应反译回 ModelResponse return ModelResponse( id=raw.get("id"), choices=[{"message": {"role": "assistant", "content": raw["output"]}}], model=model, )

在 litellm 参数转换这条链路里,这一层是唯一需要随厂商 API 演进维护的地方:字段改名、新增参数、接口废弃,全部被它吸收,上游业务代码无感。

注册与本地验证:从写完到调通

litellm 怎么知道该用你的转换类?答案在 litellm/litellm_core_utils/get_llm_provider_logic.py:get_llm_providermodel="myprovider/quick-1b"拆出前缀,去litellm.provider_list里匹配。注册要做的事就是让前缀进这张表——把 provider 加入列表并保证转换类可按名导入,或者直接走litellm/llms/openai_like/下的 JSON 注册表声明式接入。

验证脚本控制在一屏以内:

# scripts/verify_myprovider.py:端到端冒烟,跑通即证明接线正确 import litellm litellm.api_base = "https://api.myprovider.com/v1" resp = litellm.completion( model="myprovider/quick-1b", api_key="sk-test-xxx", messages=[{"role": "user", "content": "用一句话打个招呼"}], ) print(resp.choices[0].message.content)

首次调用报 404 时,九成是api_base的路径前缀或注册缺失,而不是转换逻辑。开发模式下改完重跑即可,不需要重装。

进阶与避坑:四个真实硬问题

工具调用:厂商支持 function calling 时,转换层要再当一次「海关」——把tools翻译成对方原生 schema,响应再把它的 tool_calls 翻回 OpenAI 结构,字段对照可直接参考 ollama 转换类里的工具处理写法。

成本计算:花费统计从 litellm/model_prices_and_context_window.json 读取模型单价。新模型接入后在这里补一条每 token 定价,proxy 的 spend 看板才会自动核算,不用另写计费代码。

⚠️流式解析:最容易翻车的一环。漏掉终止事件(最后那个[DONE]或带finish_reason的分片),客户端会一直等下去,表现为流挂起、日志无报错。写流式方法时把「处理最后一个 chunk」当必选项,SSE 分块处理可对照OllamaChatConfig的实现。

异常处理:别裸抛Exception,统一抛BaseLLMException(与BaseConfig同文件定义),它携带status_codeheadersbody,外层异常映射会转成标准 litellm 错误,限流重试、超时回退等机制才能生效:

# 转换层收到非 2xx 响应时抛标准异常,映射层接手转换 raise BaseLLMException(status_code=resp.status_code, message=resp.text, headers=resp.headers)

继续探索:多模态、路由与社区

最小 provider 只是入场券。litellm/llms/base_llm/下已把图像生成、语音转录、embedding 各自切出独立目录,多模态能力就是再实现对应 endpoint 的转换类;想让同一模型名下挂多家服务做负载均衡或故障切换,走 Router 与 proxy 的路由配置,本文写的转换类可以原样复用。这个 provider 若有通用价值,提个 PR 进社区,是让别人帮你维护的最划算方式。

【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

ASP.NET MVC 与 DotNetCasClient 集成的场景

这是一个非常经典的 ASP.NET MVC 与 DotNetCasClient 集成 的场景。你遇到的问题核心在于:DotNetCasClient 的 CasAuthenticationModule 是在 Application_AuthenticateRequest 阶段自动运行的,它会直接拦截请求并处理票据,而不是让你在 CasController 里手动去“拿”票据。…

作者头像 李华
网站建设 2026/8/30 7:28:07

如何通过node.js来实现项目的登录和注册功能

通过node.js可以实现中小型项目的后端搭建,基于js的语法达到全栈开发的效果。1.创建项目在文件夹中自定义命名一个文件,在终端打开,初始化包管理配置文件:npm init -y安装新版本的express:npm i express在项目根目录下创建app.js文…

作者头像 李华
网站建设 2026/8/30 7:27:49

CVPRW 2026 | 动态场景下多曝光图像融合

题目: NTIRE 2026 The 3rd Restore Any Image Model (RAIM) Challenge: Multi-Exposure Image Fusion in Dynamic Scenes (Track 2) 作者: Lishen Qu; Yao Liu; Jie Liang; Hui Zeng; Wen Dai; Guanyi Qin; Ya-nan Guan; Shihao Zhou; Jufeng Yang; L…

作者头像 李华
网站建设 2026/8/30 7:27:16

MATLAB实现PINN求解二维泊松方程:完整源码与实战指南

简介:本资源是一套基于MATLAB实现的物理信息神经网络(PINN)求解二维泊松方程的完整教学与实践代码,面向计算数学、科学计算及AI for Science方向的本科生、研究生与科研初学者,解决传统数值方法在复杂边界或无网格场景…

作者头像 李华
网站建设 2026/8/30 7:23:36

三极管放大电路详解:直流偏置与静态工作点计算调试

三极管放大是模拟电路里最典型的一道分水岭。很多人能背出 Ic βIb,但一看到实际电路就开始迷糊:为什么基极要接一个电阻到 VCC?为什么不能直接把信号源怼到三极管基极?为什么放大电路一定要用直流电源供电?还有人把“…

作者头像 李华
网站建设 2026/8/30 7:23:32

AMD锐龙7 9800X3D+RX 9070 XT,1.6万游戏主机配置方案

这次我们来看一套 1.6 万元预算的游戏主机配置方案。标题里的“AMD 980X3D”,正确型号是 AMD 锐龙7 9800X3D,它属于 AMD 9000 系列游戏处理器,最核心的优势是 3D V-Cache 缓存技术,对网游和吃 CPU 的游戏帧率提升非常明显&#xf…

作者头像 李华