litellm 自定义 LLM 提供商接入指南:把私有模型服务变成一行调用
2026/8/30 8:43:55 网站建设 项目流程

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 内置列表里的模型厂商,每次换服务就要改一套 SDK 调用,维护成本会迅速失控。litellm 的核心价值在于用统一的 OpenAI 风格接口调用各家 LLM,同时提供成本统计、负载均衡和日志能力。这篇教程面向第一次给 litellm 写扩展的开发者:读完之后,你能判断自己的服务要不要写自定义处理器(handler),写的话代码放在哪、怎么注册、如何验证它真的被路由命中。

先判断:你的服务到底要不要写处理器

接入方式取决于对端协议,先分两类:

  • 对端兼容 OpenAI 协议(请求体是messages数组,响应是choices结构):不需要写任何新代码,只需把api_base指到对端地址即可。这是最短路径。
  • 对端是私有协议(自定义的请求字段、响应结构、鉴权头):需要继承 litellm 的自定义处理器基类,把 OpenAI 风格的入参翻译成对端格式,再把响应翻译回来。

仓库里已经内置了上百个厂商实现,它们都集中在 litellm/llms/ 目录下,按厂商分文件夹组织。写新代码前,建议先看一眼 litellm/llms/base_llm/ 里的目录划分——completion、streaming、embedding 等能力各自有独立的基础模块,这决定了你的处理器只需实现自己关心的部分。

最短路径:零代码接入 OpenAI 兼容端点

如果服务说的是 OpenAI 协议,一次completion调用就能跑通:

import litellm response = litellm.completion( model="openai/my-internal-model", # 前缀仅用于路由标识 api_base="https://your-gateway.example.com/v1", api_key="sk-xxxx", messages=[{"role": "user", "content": "你好"}], ) print(response.choices[0].message.content)

如果你用的是 litellm 的代理模式(Proxy),更推荐把端点写进配置文件而不是代码里。根目录的 proxy_server_config.yaml 就是标准示例:在model_list中登记model_namelitellm_providerapi_base,客户端调用时只写统一的模型名,端点细节全部收敛在网关侧。

需要写处理器时:代码应该落在哪里

三个关键文件:

  • litellm/llms/base.py:BaseLLM模板基类,定义了响应处理、HTTP 会话等公共辅助方法。
  • litellm/llms/custom_llm.py:CustomLLM类,是官方给扩展者的模板,completion/acompletion/streaming/astreaming四个方法都已留好签名;同文件还提供了CustomLLMError异常类。
  • litellm/proxy/example_config_yaml/custom_handler.py:一个可直接运行的最小样例,展示了继承和实例化的完整形态。

继承 CustomLLM,实现最少的四个方法

同步和异步、流式与非流式各一个方法,签名较长但参数都是框架透传进来的,你主要关心messagesapi_baseapi_keyoptional_params这几项:

import litellm from litellm import CustomLLM, CustomLLMError from litellm.types.utils import ModelResponse, GenericStreamingChunk class AcmeLLM(CustomLLM): def completion(self, model, messages, api_base, api_key, optional_params, **kwargs) -> ModelResponse: # 1. 把 messages 翻译成对端的 prompt 格式 # 2. 用 httpx 请求对端 API(api_key 由框架传入,别自己读环境变量) # 3. 把响应组装成 ModelResponse 返回 raise CustomLLMError(status_code=500, message="Not implemented") # acompletion / streaming / astreaming 按同样思路补齐

写响应时对齐ModelResponse的既有字段:choices里放messagefinish_reasonusage里放 token 数。这两项分别影响下游取值和成本统计,缺一个后面都会出幺蛾子。

用 custom_provider_map 注册并路由

litellm 用一张全局映射表把"模型名前缀"绑定到处理器实例上,定义在 litellm/types/llms/custom_llm.py:

litellm.custom_provider_map.append({ "custom_id": "acme", "litellm_provider": "acme", "custom_handler": AcmeLLM(), }) response = litellm.completion( model="acme/acme-chat-v1", messages=[{"role": "user", "content": "你好"}], )

请求进来后,litellm/litellm_core_utils/get_llm_provider_logic.py 里的get_llm_provider负责解析模型名前缀、确定走哪个处理器;litellm/main.py 在构造调用时会遍历custom_provider_map找到匹配的custom_id,再把请求交给你的completion。也就是说:前缀命名要和custom_id对得上,这是路由生效的前提。

代理场景下也可以把custom_provider_map写进配置的litellm_settings中,由 Proxy 启动时加载——不过处理器实例必须是本地 Python 对象,不能通过远程 URL 加载。

怎么验证接入真的生效

按这个顺序排查,能定位绝大多数问题:

  1. 非流式冒烟:调用一次completion,确认返回内容来自对端,且response.modelresponse.usage有值。如果抛出的异常类型是 litellm 的统一异常族而不是你抛的原始错误,说明请求确实走了处理器链路(异常归一化逻辑在 litellm/litellm_core_utils/exception_mapping_utils.py)。
  2. 流式路径:加stream=True,逐块消费GenericStreamingChunk,重点确认最后一块携带finish_reason,否则客户端会认为流未正常结束。
  3. 日志侧观察:给 litellm 挂上 Langfuse 等日志后端后,每次调用的输入、输出、token 消耗都能在面板里看到,适合验证 usage 字段是否被正确解析。
  4. 沉淀测试:参考 tests/llm_translation/ 下按厂商组织的测试文件,为你的处理器补一组 pytest 用例,把请求构造和响应解析的关键断言固化下来。

容易踩的坑

  • 自己读环境变量拿密钥api_keyapi_base是框架按调用参数传进来的,硬编码读os.environ会让代理模式下动态配置的密钥失效。确需外部密钥存储时,再看 litellm/secret_managers/ 的集成方式。
  • 异常不带状态码:处理器内部请统一抛CustomLLMError(status_code, message),否则上游无法区分是鉴权失败、限流还是服务不可用,重试与 fallback 策略会失灵。
  • usage 不填:litellm 的成本跟踪依赖响应里的 token 统计;模型定价维护在根目录的 model_prices_and_context_window.json,你的模型不在表里时,至少要保证 usage 真实,再自行补充定价条目,否则代理面板的花费统计是空的。
  • 流式和非流式行为不一致:两个路径的响应解析代码经常只测了一个,建议两者各写一条断言,尤其留意流式结束标志。
  • 模型前缀与 custom_id 不一致:调用时写acme/xxx,注册却用了别的custom_id,请求会落回默认路由或直接报无法解析提供商——这是注册类问题里最高频的一种。

后续可以扩展的方向

处理器跑通之后,能力边界才真正打开:如果你的服务支持工具调用,在参数翻译层把 OpenAI 的tools数组映射成对端格式即可;如果要在网关层面做多模型调度,把自定义端点登记进 litellm/proxy/ 的模型列表后,Router 的负载均衡、超时和 fallback 配置就都能直接复用。另外仓库提供 Docker 与 Helm 两套部署资产(docker/ 与 helm/),把扩展后的 litellm 打进镜像上线时可以直接参照。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询