
1. 供应链投毒之后pip install litellm 还能不能继续用LiteLLM 是一个把几十家模型厂商 API 统一成一套 OpenAI 风格接口的 Python 库你写litellm.completion(model...)就能在 GPT、Claude、Gemini 之间切换不用为每家单独写 SDK。它常被当成 AI 应用里的“网关层”Agent 框架、评测脚本、内部工具都会依赖它。也正因为下载量大、又天然要接触各种 API Key它成了供应链投毒的高价值目标。这次事件的核心不是 LiteLLM 功能有漏洞而是 PyPI 上出现了两个非正常发布的版本其中.pth文件会在 Python 解释器启动时自动执行不需要你import litellm也会触发。这意味着只要恶意版本进过你的环境任何 Python 脚本启动都可能被牵连。所以“重建安全配置”要解决两件事一是把依赖版本钉死并做哈希校验二是把散落在各处的厂商 Key 收拢成一条可控通道降低单点泄露后的爆炸半径。我试过在本地把 LiteLLM 的 Key 管理从“每个项目一份环境变量”改成统一网关最直接的收益不是省事而是出事时只需要轮换一个地方。下面按“先锁依赖、再统一通道、最后验证”的顺序走一遍你可以直接照着改。2. 前置准备TaoToken 统一 Key 通道与 LiteLLM 的角色分工在讲配置之前先把分工说清楚不然后面 config.yaml 容易写乱。LiteLLM 在你的项目里扮演两个角色作为 Python 库被业务代码调用或者作为 proxy 服务对外暴露一个/v1/chat/completions兼容端点。无论哪种它都需要知道“请求发给谁、用什么 Key”。传统做法是把OPENAI_API_KEY、ANTHROPIC_API_KEY等直接写进环境变量Key 分散、轮换麻烦、日志里还容易漏。TaoToken 在这里的作用是提供一条统一的 API 通道你只需要持有 TaoToken 的 Key由它去对接后端模型业务侧不再直接持有各厂商原始 Key。这样 LiteLLM 的配置里只出现一个 base_url 和一个 Key供应链投毒即使偷到了环境变量拿到的也是可快速吊销的通道凭证而不是你所有厂商的长期密钥。需要提前准备的东西一个 TaoToken 账号用来生成 API Key。入口在控制台的 API Keys 页面https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite确认你要用的模型名TaoToken 的模型对话页可以直接试https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite接入文档放在手边配置字段对不上时查它https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite如果你打算长期跑编码类 Agent可以了解 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite注意不要把厂商原始 Key 和 TaoToken Key 混写在同一个.env里。统一通道的意义就是让业务侧只认一个 Key混写等于白做。3. 可复制配置锁定 litellm 版本 config.yaml 骨架3.1 先锁版本再谈安装事件之后第一件事不是升级而是把版本钉死。LiteLLM 官方建议回退到安全版本我们用精确锁定并配合哈希校验避免 pip 拉到被替换过的包。# 1. 查看当前环境里装了什么版本 pip show litellm 2/dev/null | grep -i version # 2. 卸载可能存在的异常版本 pip uninstall -y litellm # 3. 安装锁定版本示例用 1.82.6以官方公告的安全版本为准 pip install litellm1.82.6如果你要更严格用 requirements 文件加哈希。先生成带哈希的锁定文件pip install pip-tools # 在 requirements.in 里写一行litellm1.82.6 pip-compile --generate-hashes requirements.in -o requirements.txt生成的requirements.txt会长这样每行带--hashlitellm1.82.6 \ --hashsha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ --hashsha256:yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy安装时强制校验pip install --require-hashes -r requirements.txt--require-hashes的作用是只要下载到的包哈希对不上pip 直接报错退出不会静默安装。这一步是防投毒的关键动作比单纯锁版本更硬。3.2 config.yaml 骨架LiteLLM proxy 模式用config.yaml描述模型列表。下面这份骨架把上游统一指向 TaoToken 通道你只需要替换 Key 和模型名。model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_base: https://taotoken.net/api api_key: os.environ/TAOTOKEN_API_KEY - model_name: claude-sonnet litellm_params: model: anthropic/claude-sonnet-4-20250514 api_base: https://taotoken.net/api api_key: os.environ/TAOTOKEN_API_KEY general_settings: master_key: os.environ/LITELLM_MASTER_KEY database_url: os.environ/DATABASE_URL几个字段说明字段作用注意点model_name业务侧调用的别名自定义建议语义化model上游真实模型标识前缀决定走哪家适配器api_base统一通道地址固定为https://taotoken.net/apiapi_key通道凭证用os.environ/引用不写明文master_keyproxy 自身的访问密钥和上游 Key 分开管理环境变量这样设export TAOTOKEN_API_KEY你的TaoToken Key export LITELLM_MASTER_KEY给proxy用的随机串提示api_key写成os.environ/TAOTOKEN_API_KEY而不是直接填值是为了让配置文件可以进 Git而密钥留在运行环境里。这是供应链安全里最基本的一条隔离。3.3 启动 proxylitellm --config config.yaml --port 8000启动后 LiteLLM 会在本地 8000 端口暴露 OpenAI 兼容接口业务代码把 base_url 指向http://127.0.0.1:8000即可不再直接接触任何厂商 Key。4. 验证请求确认通道打通且版本干净配置写完必须验证两件事通道能通、环境里没有恶意残留。4.1 检查恶意 .pth 文件# 找到 site-packages 路径 python3 -c import site; print(site.getsitepackages()[0]) # 在该目录下查找可疑的 .pth find $(python3 -c import site; print(site.getsitepackages()[0])) -name litellm_init.pth如果这条命令有输出说明环境里存在异常文件先删掉再继续。同时检查一下持久化痕迹ls -la ~/.config/sysmon/sysmon.py 2/dev/null systemctl --user status sysmon.service 2/dev/null4.2 发一个真实请求用 curl 打 proxy 的兼容端点curl http://127.0.0.1:8000/v1/chat/completions \ -H Authorization: Bearer $LITELLM_MASTER_KEY \ -H Content-Type: application/json \ -d { model: gpt-4o, messages: [{role: user, content: 只回复两个字通了}] }预期返回结构里choices[0].message.content有内容model字段回显你配置的别名。如果返回 401检查LITELLM_MASTER_KEY是否和启动时一致如果返回上游错误检查TAOTOKEN_API_KEY和api_base。4.3 用 Python 库方式验证如果你不用 proxy而是直接import litellm可以这样指定通道import os import litellm os.environ[TAOTOKEN_API_KEY] 你的TaoToken Key resp litellm.completion( modelopenai/gpt-4o, api_basehttps://taotoken.net/api, api_keyos.environ[TAOTOKEN_API_KEY], messages[{role: user, content: ping}], ) print(resp.choices[0].message.content)跑通说明库本身工作正常且请求确实走了统一通道。想快速对比不同模型输出可以直接在模型对话页试https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite5. 本篇常见错排查5.1 pip install 报哈希不匹配--require-hashes模式下报THESE PACKAGES DO NOT MATCH THE HASHES通常是你本地缓存的 wheel 和 requirements 里的哈希对不上。先清缓存再装pip cache purge pip install --require-hashes -r requirements.txt如果清了还报说明 requirements.txt 里的哈希是旧版本生成的重新pip-compile --generate-hashes一次。5.2 启动 proxy 报 model 找不到litellm.BadRequestError: model not found多半是model字段前缀写错。走统一通道时前缀要和适配器匹配比如openai/gpt-4o、anthropic/claude-sonnet-4-20250514。前缀不对LiteLLM 会按错误的适配器去拼请求。5.3 401 但 Key 明明是对的分两种proxy 返回 401是master_key不匹配上游返回 401是TAOTOKEN_API_KEY无效或没被读到。用echo $TAOTOKEN_API_KEY确认环境变量在当前 shell 里真的存在os.environ/引用的是进程启动时的环境不是配置文件里的值。5.4 装完还是担心有残留跑一遍完整自查pip show litellm | grep -i version find $(python3 -c import site; print(site.getsitepackages()[0])) -name *.pth | xargs grep -l litellm 2/dev/null kubectl get pods -A 2/dev/null | grep node-setup第三条只在你有 K8s 环境时才有意义。任何一条有异常输出先隔离机器再处理。5.5 依赖树里间接引入 litellmpip install dspy这类框架可能把 litellm 作为传递依赖拉进来。用这条命令看谁引入了它pip show litellm | grep -i required-by如果required-by里有你不认识的项目去它的依赖声明里确认 litellm 的版本约束必要时用pip install litellm1.82.6覆盖再跑一次哈希校验。6. 把 Key 通道收拢之后长期怎么维护供应链投毒这件事真正改变的不是某一次安装动作而是“Key 放在哪、依赖怎么锁”这两个习惯。统一通道的价值在于业务代码里不再出现厂商原始 KeyLiteLLM 的配置只认一个api_base和一个可吊销凭证。这样即使某天又出现类似的包污染你能做的响应从“轮换所有厂商 Key”变成“吊销一个通道 Key 再换一个”。如果你在跑编码类 Agent 或长期任务建议把通道 Key 和 proxy 的 master key 分开管理前者管上游访问后者管本地服务入口。Coding Plan 页面有这类长期场景的说明https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite最后留一个我踩过的坑config.yaml里用os.environ/引用变量时如果你用 systemd 或容器启动 proxy环境变量要在 service 文件或 compose 里显式传入光在.bashrc里 export 是不生效的。启动前先env | grep TAOTOKEN确认一遍能省掉很多“配置明明对却 401”的排查时间。