1. 多模型 Key 分散的真实痛点与 LiteLLM + OpenClaw 的定位
如果你同时用 OpenAI、Anthropic、DeepSeek、通义千问这几家的模型,大概率经历过这种场景:LiteLLM 的config.yaml里塞了四五个api_key,OpenClaw 那边又要单独配一套环境变量,换一个模型就得改两处配置、重启一次服务,Key 一旦轮换还得满项目搜sk-开头的字符串。这不是配置能力问题,而是多供应商 Key 天然分散导致的维护成本。
LiteLLM 本身是一个统一的多模型调用网关,它把不同厂商的 API 抽象成 OpenAI 兼容格式,你写一份 config 就能路由到几十种模型。OpenClaw 则偏向 Agent 侧的模型调度与工具编排,它需要频繁切换底层模型来匹配不同任务。两者组合时,Key 管理就成了最容易被忽视、又最容易出事的环节。
这篇要解决的就是这件事:用 TaoToken 作为统一 Key 通道,让 LiteLLM 只认一个base_url和一个api_key,OpenClaw 侧同样只配这一组凭据,模型切换通过改model字段完成,不再碰任何厂商原始 Key。适合已经在用 LiteLLM 做路由、或者准备把 OpenClaw 接入多模型的开发者,跟着配置骨架走一遍就能落地。
2. TaoToken 统一 Key 通道的前置准备
TaoToken 在这里扮演的角色是「Key 聚合层」:你只在它这里持有一把 Key,LiteLLM 和 OpenClaw 都指向它的 API 端点,由它去完成对上游各模型的转发。对 LiteLLM 来说,TaoToken 就是一个 OpenAI 兼容的 provider,配置方式和接官方 OpenAI 没有区别。
前置动作只有三步。第一,注册并登录控制台,地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,登录后进入控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。第二,在 API Keys 页面创建一把 Key,页面地址 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ,创建后立刻复制保存,页面刷新后不再完整显示。第三,确认你要用的模型名,TaoToken 的模型列表和文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,模型名要和 LiteLLM config 里写的model字段一致。
API 基础地址统一用 https://taotoken.net/api ,注意这个地址不带任何查询参数,LiteLLM 的api_base和 OpenClaw 的base_url都填它。Key 的形态是标准的 Bearer Token,放在Authorization: Bearer <你的Key>头里。
注意:不要把 Key 硬编码进会提交到 Git 的 config 文件。下面所有配置都用环境变量占位,运行时注入。
如果你还没决定用哪些模型,可以先到模型对话页 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 手动试几个,确认响应正常再写进 config,能省掉后面排查「模型名写错」的时间。
3. LiteLLM 可复制 config 骨架与 OpenClaw 接入配置
先给 LiteLLM 的完整 config 骨架。核心思路是:所有模型都走同一个openaiprovider 类型,api_base全部指向 TaoToken,api_key全部读同一个环境变量。这样新增模型只是复制一段model_list条目,不涉及任何新凭据。
# litellm_config.yaml 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: openai/claude-sonnet-4-20250514 api_base: https://taotoken.net/api api_key: os.environ/TAOTOKEN_API_KEY - model_name: deepseek-chat litellm_params: model: openai/deepseek-chat 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 litellm_settings: drop_params: true request_timeout: 120几个参数值得单独说。model_name是你对外暴露的别名,OpenClaw 和业务代码调用的就是它;litellm_params.model里的openai/前缀是告诉 LiteLLM 用 OpenAI 兼容协议发请求,后面跟的才是 TaoToken 侧的真实模型名。drop_params: true建议打开,因为不同上游对参数支持不一致,比如某些模型不接受temperature,开启后 LiteLLM 会自动丢弃不支持的字段,避免 400 报错。request_timeout设 120 秒,长文本生成不容易被掐断。
启动 LiteLLM 代理:
export TAOTOKEN_API_KEY="你的TaoToken Key" export LITELLM_MASTER_KEY="sk-litellm-local-1234" export DATABASE_URL="postgresql://user:pass@localhost:5432/litellm" litellm --config litellm_config.yaml --port 4000LITELLM_MASTER_KEY是 LiteLLM 自己的管理密钥,和 TaoToken Key 是两回事,别混。它用于访问 LiteLLM 的管理接口和作为调用代理时的鉴权。
再看 OpenClaw 侧。OpenClaw 的模型配置通常放在它的 provider 配置里,让它指向本地 LiteLLM 代理,而不是直连 TaoToken。这样 OpenClaw 的模型切换完全由 LiteLLM 的model_name决定,职责更清晰。
# openclaw provider 配置片段 providers: - name: litellm-gateway type: openai base_url: http://127.0.0.1:4000/v1 api_key: sk-litellm-local-1234 models: - gpt-4o - claude-sonnet - deepseek-chat default_model: claude-sonnet这里api_key填的是 LiteLLM 的 master key,base_url指向本地 LiteLLM 的/v1端点。OpenClaw 完全不知道 TaoToken 的存在,它只和 LiteLLM 对话。这种分层的好处是:以后换 Key 通道、加模型、改路由策略,都只动 LiteLLM 一处,OpenClaw 配置零改动。
如果你希望 OpenClaw 直连 TaoToken 而不经过 LiteLLM,把base_url改成 https://taotoken.net/api ,api_key换成 TaoToken Key 即可,但这样就失去了 LiteLLM 的路由和降级能力,按需选择。
4. 连通性验证与模型切换实测
配置写完必须验证,否则问题会拖到业务调用时才暴露。分三层验证:先验 LiteLLM 到 TaoToken 通不通,再验 OpenClaw 到 LiteLLM 通不通,最后验模型切换是否生效。
第一层,直接 curl LiteLLM 代理,确认它能转发到 TaoToken:
curl -s http://127.0.0.1:4000/v1/chat/completions \ -H "Authorization: Bearer sk-litellm-local-1234" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet", "messages": [{"role": "user", "content": "只回复两个字:通了"}], "max_tokens": 20 }'预期返回里choices[0].message.content包含「通了」,model字段会显示 LiteLLM 记录的模型标识。如果返回 401,检查LITELLM_MASTER_KEY是否和请求头一致;如果返回 500 且日志里出现上游鉴权失败,检查TAOTOKEN_API_KEY是否注入成功。
第二层,绕过 LiteLLM 直接测 TaoToken,用来区分是 LiteLLM 配置问题还是 Key 通道问题:
curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 10 }'这一步通了但第一层不通,问题一定在 LiteLLM 的 config 或环境变量。两步都不通,问题在 Key 或模型名。
第三层,验证模型切换。把上面第一层 curl 的model字段依次换成gpt-4o、deepseek-chat,观察返回是否正常。更省事的做法是写个小脚本批量跑:
import os, requests BASE = "http://127.0.0.1:4000/v1/chat/completions" HEADERS = { "Authorization": f"Bearer {os.environ['LITELLM_MASTER_KEY']}", "Content-Type": "application/json", } for m in ["gpt-4o", "claude-sonnet", "deepseek-chat"]: r = requests.post(BASE, headers=HEADERS, json={ "model": m, "messages": [{"role": "user", "content": "回复OK"}], "max_tokens": 10, }, timeout=60) print(m, r.status_code, r.json().get("choices", [{}])[0].get("message", {}).get("content"))三个模型都返回 200 且内容正常,说明统一 Key 通道和模型切换链路完全打通。实测下来,从改 config 到验证通过,新增一个模型大约两分钟。
OpenClaw 侧的验证,触发一次 Agent 调用,在日志里确认它请求的是http://127.0.0.1:4000/v1,并且model字段是你配置的别名。如果 OpenClaw 报模型不存在,多半是它的models列表里没加对应别名。
5. 本篇常见报错与排查清单
401 Unauthorized(LiteLLM 返回):请求头里的 Bearer 和LITELLM_MASTER_KEY不一致。注意 LiteLLM 的 master key 和 TaoToken Key 是两个独立凭据,别把 TaoToken Key 填到 OpenClaw 的api_key里。
401 或 403(TaoToken 返回):TAOTOKEN_API_KEY没注入到 LiteLLM 进程,或者 Key 已被删除/轮换。用echo $TAOTOKEN_API_KEY确认环境变量在当前 shell 可见,注意export只在当前会话有效,用 systemd 或 Docker 启动时要单独配。
404 model not found:litellm_params.model里的模型名和 TaoToken 侧不一致。去文档页核对准确名称,注意大小写和版本后缀,比如claude-sonnet-4-20250514这种带日期的别写错。
400 参数不支持:某个上游不接受你传的字段。确认drop_params: true已开启,或者手动精简请求体。
连接超时:api_base写成了带路径的地址。正确值是 https://taotoken.net/api ,LiteLLM 会自动拼/v1/chat/completions,你不需要手动加/v1。
OpenClaw 侧模型切换不生效:OpenClaw 有缓存或会话粘性,切换default_model后需要新开会话。另外确认 OpenClaw 的models列表包含目标别名,否则它会在本地就拒绝请求。
Key 泄露风险:config 文件里出现明文 Key。全部改用os.environ/引用,并把 config 加入.gitignore。TaoToken 控制台可以随时吊销旧 Key 重新生成,轮换成本很低。
6. 后续接入与长期编码场景的分流建议
配置跑通之后,日常维护基本就是「加模型改一段 YAML」。如果你主要在排障和接入阶段,建议把 API Keys 页面和接入文档存成书签:Key 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ,接入细节在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,遇到模型名或参数问题先查文档再改 config。
如果你还在选模型阶段,不确定哪个模型适合当前任务,直接去模型对话页 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 手动对比几轮,比在 config 里反复试错快得多。
而如果你的场景是长期编码、Agent 持续运行、需要稳定的模型调度和额度管理,那更适合用 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它在计费和调度上针对高频编码做了优化,配合 LiteLLM 做本地路由,能把多模型切换的成本压到最低。Claude Code 相关的接入参考在 https://taotoken.net/claudecode-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claudecode&utm_campaign=rewrite ,需要的话可以对照配置。
最后留一个我踩过的坑:LiteLLM 的model_name别名不要和真实模型名完全一样,否则以后想换上游模型时,业务代码里的模型名也得跟着改。用claude-sonnet这种语义别名,底层换哪个版本都不影响调用方。