1. litellm 适配 claude code 的 api_base 与 Anthropic 兼容层踩坑记录
litellm 是一个把多家大模型 API 统一成 OpenAI 或 Anthropic 格式的网关,claude code 是 Anthropic 官方的命令行编码工具,两者组合起来能让 claude code 用上非 Anthropic 的模型。听起来很美好,但我在把 litellm 作为统一网关接入 claude code 的过程中,被 api_base、Anthropic 消息格式和 Vertex AI 后端之间的兼容性问题折腾了整整两天。这篇记录面向已经在用 litellm 的开发者,把请求路由和鉴权配置里最常见的失败模式拆开讲清楚,每一步都给出可复制的配置和验证动作,包括 curl 探活和日志比对,帮你快速定位报错到底出在哪一层。
核心检索词先摆出来:litellm 接入 claude code 时,api_base 指向哪里、Anthropic 兼容层走哪个后缀、Vertex AI 后端为什么会被意外触发,这三个问题决定了你的请求最终打到哪个端点。适合谁看?已经在本地跑起 litellm、想让 claude code 复用这套网关、但被 401 或 RESOURCE_EXHAUSTED 卡住的开发者。如果你还没搭 litellm,也能跟着走,因为我会把最小可用的 config.yaml 完整贴出来。
我踩的第一个坑就是以为只要把 ANTHROPIC_BASE_URL 指向 litellm 就万事大吉,结果 claude code 抛出的错误里赫然写着 Vertex AI 和 limit=0,而我根本没配过 Vertex AI。这个现象背后是 claude code 的路由逻辑:它默认走 Anthropic 的 /v1/messages 格式,但也内置了对 /anthropic、/vertex_ai/v1、/bedrock 这几个后缀的识别,一旦你的 base_url 或环境变量里带了相关线索,它就会切到对应后端,而 litellm 那边如果没有对应的 key,请求就会以奇怪的方式失败。下面按顺序把每个坑拆开。
2. TaoToken 前置准备:统一网关的 Key 与 Base URL 怎么拿
在讲 litellm 的配置之前,先把上游凭据准备好。我这次用的是 TaoToken 作为上游统一入口,它的好处是同一个 Key 能覆盖多种模型,省得在 litellm 里为每个后端单独配 key。你需要先拿到两样东西:API Key 和 Base URL。
访问 https://taotoken.net/api 可以看到接口说明,Key 的申请在控制台完成,地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=。拿到 Key 之后,Base URL 统一用 https://taotoken.net/api,注意这个地址不带任何路径后缀,litellm 的 api_base 就填它。
这里有个容易混淆的点:TaoToken 的 Base URL 是给 litellm 用的,而 claude code 的 ANTHROPIC_BASE_URL 要指向你本地的 litellm 服务,比如 http://127.0.0.1:4000。两层地址不要搞反,否则 claude code 会直接把请求打到上游,绕过 litellm 的格式转换,Anthropic 消息格式对不上就会报错。
如果你只是想先验证模型能不能通,可以直接用模型对话页面测一下,地址是 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=。确认 Key 有效之后,再回到 litellm 的配置。对于长期做编码或 Agent 的场景,可以考虑 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=,它的额度策略更适合高频调用。
需要提醒的是,litellm 的 master_key 这个配置项坑了很多人。如果你只是自用,本地测试时 litellm 不填 master_key 也能跑,claude code 那边只填 base_url 就能调通。但一旦你在 litellm 里设了 master_key,claude code 的 ANTHROPIC_AUTH_TOKEN 就必须和它一致,否则会报 401。我当初就是本地 apifox 测试通过,放到 claude code 里死活 401,排查半天才发现是 master_key 和 auth token 不匹配。自用场景建议先不设 master_key,减少一层鉴权变量。
3. 可复制的 litellm config.yaml 与 claude code settings 配置
这一节给出完整的配置文件,路径和字段都按实际能跑通的版本来写。litellm 的配置文件默认放在项目根目录或 ~/.litellm/config.yaml,启动时用litellm --config ./config.yaml --port 4000。
先看 litellm 的 config.yaml:
model_list: - model_name: claude-sonnet-4-20250514 litellm_params: model: anthropic/claude-sonnet-4-20250514 api_base: https://taotoken.net/api api_key: os.environ/TAOTOKEN_API_KEY - model_name: gemini-2.5-pro litellm_params: model: gemini/gemini-2.5-pro api_base: https://taotoken.net/api api_key: os.environ/TAOTOKEN_API_KEY litellm_settings: drop_params: true set_verbose: true general_settings: master_key: sk-litellm-local几个关键点。第一,model字段里的前缀anthropic/和gemini/决定了 litellm 用哪个 provider 的适配器,这个前缀不能省,否则 litellm 不知道该怎么转换消息格式。第二,api_base统一指向 TaoToken 的 https://taotoken.net/api,不要在后面加 /v1 或 /anthropic,加了反而会 404。第三,api_key用环境变量引用,启动前先export TAOTOKEN_API_KEY=你的key,避免把 Key 写死在文件里。第四,master_key我设了一个本地值,claude code 那边必须对应填上。
然后是 claude code 的 settings 文件,路径在 ~/.claude/settings.json:
{ "env": { "ANTHROPIC_MODEL": "claude-sonnet-4-20250514", "ANTHROPIC_BASE_URL": "http://127.0.0.1:4000", "ANTHROPIC_AUTH_TOKEN": "sk-litellm-local" } }注意 ANTHROPIC_BASE_URL 填的是本地 litellm 地址,不带任何后缀。ANTHROPIC_AUTH_TOKEN 和 litellm 的 master_key 保持一致。ANTHROPIC_MODEL 填 litellm config 里定义的 model_name,不是上游的真实模型名。
如果你用的是 Codex 或 Cline 这类工具,配置思路一样,只是文件位置不同。Codex 的 auth.json 里填 base_url 和 api_key,Cline 的 MCP 配置里填 Base URL、Key、Model ID 三件套。三件套缺一不可,尤其是 Model ID 要和 litellm 的 model_name 对上。
启动 litellm 之后,先别急着开 claude code,用 curl 探活确认 litellm 本身是通的:
curl -X POST http://127.0.0.1:4000/v1/messages \ -H "Content-Type: application/json" \ -H "x-api-key: sk-litellm-local" \ -H "anthropic-version: 2023-06-01" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 64, "messages": [{"role": "user", "content": "ping"}] }'如果这一步返回正常的 Anthropic 格式响应,说明 litellm 到上游的链路是通的。如果返回 401,检查 master_key 和 x-api-key 是否一致。如果返回 404,检查 api_base 是不是多加了后缀。
4. 验证请求与成功结果:从 curl 到 claude code 的完整链路
curl 探活通过之后,下一步是验证 claude code 能不能真正走通。先启动 litellm 并打开 verbose 日志,这样每个请求的路由和转换过程都能看到:
export TAOTOKEN_API_KEY=你的key litellm --config ./config.yaml --port 4000 --detailed_debug日志里会打印每个请求命中的 provider、转换后的上游请求体、以及上游返回的状态码。这一步非常关键,因为 claude code 报的错往往是它自己抛的,真正的失败原因藏在 litellm 的日志里。
然后开一个终端跑 claude code:
claude进去之后随便问一句,比如「读一下当前目录的 README」。如果一切正常,你会看到 claude code 正常调用工具、读取文件、返回结果。同时 litellm 的日志里会显示请求命中了anthropic/claude-sonnet-4-20250514这个 provider,上游返回 200。
成功的关键标志有三个。第一,litellm 日志里 provider 是 anthropic 而不是 vertex_ai。第二,请求路径是 /v1/messages 而不是 /vertex_ai/v1/messages。第三,claude code 没有抛出 RESOURCE_EXHAUSTED 或 limit=0 这类错误。
我实测下来,只要 config.yaml 里 model 前缀写对、api_base 不带后缀、master_key 和 auth token 一致,这条链路是能稳定跑通的。之前卡住的原因就是 claude code 意外走了 Vertex AI 后端,而 litellm 那边没有 Vertex AI 的 key,导致请求在格式转换阶段就失败了。
如果你想让 claude code 用上 Gemini 模型,把 ANTHROPIC_MODEL 改成 gemini-2.5-pro 即可,litellm 会自动用 gemini 适配器转换消息格式。但要注意,Gemini 对 Anthropic 的 tool use 格式支持不完整,claude code 调用工具时可能会报格式错误,这个后面排障章节会讲。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
这一节把我在适配过程中遇到的真实报错逐个拆开,给出定位方法和解决动作。
第一个是 401 Unauthorized。这个最常见,原因通常是 master_key 和 ANTHROPIC_AUTH_TOKEN 不一致。排查方法:在 litellm 日志里搜Authentication Error,如果看到Invalid proxy server token passed,就是 token 对不上。解决动作:把两边改成同一个值,或者干脆去掉 master_key 自用。还有一种 401 是上游返回的,说明 TaoToken 的 Key 无效或过期,去控制台重新生成一个。
第二个是 local proxy failed。这个报错说明 claude code 连不上本地的 litellm 服务。排查方法:先curl http://127.0.0.1:4000/health看 litellm 是否在跑,如果连不上就是端口没起或防火墙拦了。解决动作:确认 litellm 启动时 --port 4000 和 settings.json 里的端口一致,确认没有其他进程占用 4000。
第三个是 reading choices 相关报错。这个通常出现在 litellm 把 Anthropic 格式转成 OpenAI 格式再转回来的时候,字段丢失导致解析失败。排查方法:在 litellm 日志里找reading 'choices'或undefined,看是哪个字段为空。解决动作:在 litellm_settings 里加drop_params: true,让 litellm 丢弃上游不支持的参数,减少转换失败的概率。
第四个是 OAuth 相关报错。如果你用的是 Claude Code 的 OAuth 登录模式,它会尝试走 Anthropic 官方端点,而不是你配的 base_url。排查方法:看报错里有没有oauth或console.anthropic.com。解决动作:确保用的是 ANTHROPIC_AUTH_TOKEN 而不是 OAuth token,或者在 settings.json 里显式设置"apiKeyHelper"指向你的 token。
第五个是 RESOURCE_EXHAUSTED 和 limit=0。这个是我踩得最深的坑。报错里出现 Vertex AI 和 limit=0,说明 claude code 没走你配的 litellm,而是切到了 Vertex AI 后端。原因是 claude code 识别到了某些环境变量或 base_url 里的线索,误判成了 Vertex AI 模式。排查方法:检查 ANTHROPIC_BASE_URL 是不是带了 /vertex_ai 后缀,检查环境里有没有 GOOGLE_APPLICATION_CREDENTIALS 之类的变量。解决动作:把 base_url 改成纯本地地址,清掉所有 Vertex AI 相关的环境变量。
第六个是工具调用格式错误。claude code 调用工具时,如果上游模型对 Anthropic 的 tool use 格式支持不好,会报tool_use或input_schema相关错误。排查方法:在 litellm 日志里看转换后的请求体,对比 Anthropic 官方格式。解决动作:换一个对 tool use 支持更好的模型,或者在 litellm 里加自定义转换逻辑。
6. 语义一致的 CTA 与后续接入建议
排障和接入相关的文档都在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=,里面有完整的接口说明和示例。Key 的管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=,可以随时生成和吊销。如果你主要做编码或 Agent 场景,Coding Plan 的额度策略更划算,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=。
最后说一个实用技巧。litellm 的日志级别调到 detailed_debug 之后,每个请求的完整链路都能看到,包括 claude code 发来的原始请求、litellm 转换后的上游请求、上游返回的原始响应、以及转换回 Anthropic 格式的最终响应。排障时把这四段日志对照着看,基本能定位到问题出在哪个环节。我后来养成习惯,每次改配置先跑一遍 curl 探活,再看 litellm 日志确认 provider 正确,最后才开 claude code,这样能把问题范围缩小到最小。