1. 从 Mozilla 报告和 OpenRouter token 榜切入:TaoToken 先拿 Key、Base URL 锁到 /api
如果你正在用 OpenRouter、DeepSeek 做应用开发或模型评测,最近 Mozilla 报告和 OpenRouter 的 token 消耗榜把开源权重模型再次推到台前;不过本文不展开行业讨论,直接从可复现的接入动作开始。接入 TaoToken 时,先到 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=blog_intro 获取 Key,再把 Base URL 填为https://taotoken.net/api。很多人在这一步会踩到两个典型报错:一是请求头里仍然写着旧平台的 Key,结果返回401 invalid api key;二是 Base URL 多写了/v1或少了/api,客户端拼接后变成404 path not found。本文按“拿 Key → 填 Base URL → 配请求头 → 记 token 用量 → 排障”的顺序走一遍,目标不是只跑通一次对话,而是让 DeepSeek、OpenRouter 风格的评测调用能够留下可对账的 token 记录。
先把本文的变量统一下:
- Key:从 TaoToken 控制台获取,正文统一写
YOUR_API_KEY。 - Base URL:
https://taotoken.net/api,不要带 UTM,不要随意补路径。 - 模型名:以 TaoToken 控制台或文档中展示的模型名为准,下面用
deepseek-chat作为占位示例。 - 记账字段:至少记录
model、request_id、prompt_tokens、completion_tokens、total_tokens、时间戳。 - 调用方式:可以用
curl、OpenAI 兼容 SDK、Claude Code、Codex,但每个工具的配置项不要混用。
如果你还没有 Key,建议先打开官网完成创建和复制。为了后续排障方便,Key 不要直接写进公开仓库,也不要发到聊天记录里;本地先用环境变量或.env文件管理。下面这个入口用于第一次拿 Key 和确认控制台位置:
https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=key_console
拿到 Key 后,不要急着改 Claude Code、Codex 或 CC Switch。先用一条最小请求验证 Key、Base URL、模型名三者是否匹配。最小请求能返回usage,后面的客户端配置才有意义。
2. 请求头、Base URL 与模型名:用 curl 和 Python SDK 复现 DeepSeek 调用记账
先看最小curl样例。注意这里把 Base URL 写成https://taotoken.net/api,请求路径按客户端或文档约定拼接。下面示例中完整地址使用https://taotoken.net/api/chat/completions,如果你的控制台文档给出的是/v1/chat/completions,以控制台为准,但 Base URL 仍然保持https://taotoken.net/api。不要同时写两个域名,也不要加额外反向代理地址。
curl https://taotoken.net/api/chat/completions \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-chat", "messages": [ {"role": "user", "content": "只回答:pong"} ], "stream": false }'如果返回401,优先检查Authorization是否写成Bearer YOUR_API_KEY,而不是Bearer sk-xxx或只写 Key。如果返回404,优先检查 Base URL 是否被误写成https://taotoken.net/api/v1,导致 SDK 再拼一次版本号。模型名也要从控制台复制,不要凭记忆写deepseek、deepseek-ai、deepseek/deepseek-chat这类可能不存在的别名。
Python 侧建议用 OpenAI 兼容 SDK,这样可以把usage直接拿来做记账。下面的代码把 Base URL 固定为https://taotoken.net/api,Key 从环境变量读取,避免明文散落。
import os from openai import OpenAI client = OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url="https://taotoken.net/api", ) resp = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": "你是一个简洁的评测助手。"}, {"role": "user", "content": "用一句话说明当前请求使用的是哪个模型。"}, ], stream=False, ) print("request_id:", resp.id) print("model:", resp.model) print("prompt_tokens:", resp.usage.prompt_tokens) print("completion_tokens:", resp.usage.completion_tokens) print("total_tokens:", resp.usage.total_tokens)运行前设置环境变量:
export TAOTOKEN_API_KEY="YOUR_API_KEY" python deepseek_usage_check.py如果是流式调用,很多 OpenAI 兼容接口默认不会在最后一段返回完整usage,需要显式打开stream_options。否则你会看到文本正常输出,但 token 字段为空,后续记账就会断档。
stream = client.chat.completions.create( model="deepseek-chat", messages=[{"role": "user", "content": "输出三个短句。"}], stream=True, stream_options={"include_usage": True}, ) for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="") if chunk.usage: print("\nusage:", chunk.usage)到这里,你已经完成了最核心的三件事:请求头写对、Base URL 写对、模型名从控制台确认。接下来才是把同一套信息迁移到 Claude Code、Codex 和 CC Switch。迁移时最容易犯的错,是把 Claude Code 的ANTHROPIC_*变量复制到 Codex 的config.toml里,或者反过来把 Codex 的model_provider写法塞进 Claude Code。工具不同,配置项就不同。
3. Claude Code settings.json 接入:ANTHROPIC_* 只服务 Claude Code,不服务 Codex
Claude Code 的配置重点是settings.json和环境变量。常见做法是在用户级或项目级settings.json中配置env,把 Base URL 指向https://taotoken.net/api,认证变量使用 Key 占位符。下面是一个可复制骨架,模型名和控制台展示保持一致,不要直接照抄不存在的模型。
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "claude-3-5-sonnet-latest", "ANTHROPIC_SMALL_FAST_MODEL": "claude-3-5-haiku-latest" } }如果你的 Claude Code 版本读取的是ANTHROPIC_API_KEY,也可以在本地环境变量中补充:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" export ANTHROPIC_API_KEY="YOUR_API_KEY"注意两点。第一,ANTHROPIC_BASE_URL应精确写成https://taotoken.net/api,不要加/v1。第二,改完settings.json或环境变量后要重启 Claude Code 进程,否则旧会话可能仍在使用启动时读到的变量。若你使用 CC Switch 管理多个供应商,建议把“供应商名称、Base URL、API Key”当作三件套固定下来:
- 供应商名称:
TaoToken - Base URL:
https://taotoken.net/api - API Key:
YOUR_API_KEY
CC Switch 不同版本的字段名可能不同,但本质映射不变。不要只改显示名称而忘记改 Base URL,也不要只改 Key 而保留旧供应商地址。切换后先用 Claude Code 发起一个短对话,再查看本地日志或 usage 记录,确认请求确实走了https://taotoken.net/api。如果你需要对照 Claude Code 的更多细节,可以从官网入口进入文档区:
https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=claude_env
排障时可以用“变量优先级”思路:项目级.env、用户级settings.json、启动命令前导环境变量、CC Switch 写入的配置,可能同时存在。出现401或仍然走旧模型时,先确认最终生效的是哪一组。最稳妥的方式是临时清掉其他供应商变量,只保留 TaoToken 的 Base URL 和 Key 做一次最小验证。
4. Codex config.toml 接入:wire_api、model_provider 与 TAOTOKEN_API_KEY
Codex 的配置和 Claude Code 完全不同。不要把ANTHROPIC_*写进config.toml,也不要在 Codex 里期待ANTHROPIC_BASE_URL生效。Codex 通常通过model_provider指定供应商标识,再在[model_providers.xxx]里配置base_url、env_key、wire_api。下面是一个可复制的 TOML 示例,把base_url指向https://taotoken.net/api,Key 通过环境变量TAOTOKEN_API_KEY读取。
model = "gpt-4.1" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat"然后在本地设置环境变量:
export TAOTOKEN_API_KEY="YOUR_API_KEY" codex这里有几个容易忽略的点。第一,env_key填的是环境变量名,不是 Key 本身,所以写TAOTOKEN_API_KEY,不要写YOUR_API_KEY。第二,wire_api要根据 TaoToken 控制台或文档给出的兼容方式选择;如果文档说明使用 Chat Completions 兼容,就填chat,如果说明使用 Responses API,再改成对应值。第三,模型名要和控制台一致,不要因为 Claude Code 里写了claude-*,就以为 Codex 也必须是同一个模型名。Codex 配置文件中的模型字段只影响 Codex 自己。
如果你在 Codex 里看到model not found或provider not found,优先检查三处:
model_provider的值是否和[model_providers.taotoken]的taotoken一致。base_url是否写成https://taotoken.net/api,而不是带 UTM 的官网链接。- 环境变量是否真的在当前 shell 里生效,可以用
printenv TAOTOKEN_API_KEY查看,不要把 Key 打印到公开 CI 日志。
当 Codex 跑通后,再用同一套 Key 去配 Claude Code 或 CC Switch。此时不要共享配置文件,而是按工具分开维护。建议本地目录结构如下:
~/.config/taotoken/ claude-settings.json codex-config.toml cc-switch-profiles.json usage.jsonl这样做的目的不是形式主义,而是排障时能快速定位是“Key 错”“Base URL 错”还是“模型名错”。尤其在做 DeepSeek 与开源权重模型评测时,你会频繁切换模型,如果配置混在一起,token 记录很难归因。
5. 用量记账与对账:从 request_id 到 token 字段,本地 JSONL 可复现
TaoToken 帮 DeepSeek 调用记账的关键,不是只看控制台总消耗,而是在每次请求后把响应里的usage落到本地。这样你可以按项目、按模型、按评测批次做对账。最轻量的方式是写 JSONL,每行一个请求记录,便于追加、grep 和后续导入。
import json import os import time from openai import OpenAI client = OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url="https://taotoken.net/api", ) def record_usage(model: str, resp, tag: str = "default"): row = { "ts": time.strftime("%Y-%m-%dT%H:%M:%S%z"), "provider": "taotoken", "tag": tag, "model": model, "request_id": getattr(resp, "id", None), "prompt_tokens": getattr(resp.usage, "prompt_tokens", 0), "completion_tokens": getattr(resp.usage, "completion_tokens", 0), "total_tokens": getattr(resp.usage, "total_tokens", 0), } with open("usage.jsonl", "a", encoding="utf-8") as f: f.write(json.dumps(row, ensure_ascii=False) + "\n") model = "deepseek-chat" resp = client.chat.completions.create( model=model, messages=[{"role": "user", "content": "输出一句评测样本。"}], ) record_usage(model, resp, tag="report_repro") print(resp.choices[0].message.content) print(resp.usage)如果要做批量评测,建议给每次运行加一个tag,例如mozilla_report_repro、openrouter_compare、deepseek_weekly_check。这样即使模型名相同,也能区分不同批次的 token 消耗。若需要本地查询,可以用 SQLite,把 JSONL 导入后按模型聚合。SQL 由读者本地执行,不要连接生产库。
CREATE TABLE IF NOT EXISTS llm_usage ( id INTEGER PRIMARY KEY AUTOINCREMENT, ts TEXT NOT NULL, provider TEXT NOT NULL, tag TEXT NOT NULL, model TEXT NOT NULL, request_id TEXT, prompt_tokens INTEGER NOT NULL, completion_tokens INTEGER NOT NULL, total_tokens INTEGER NOT NULL ); INSERT INTO llm_usage (ts, provider, tag, model, request_id, prompt_tokens, completion_tokens, total_tokens) VALUES ('2025-01-01T00:00:00+0800', 'taotoken', 'report_repro', 'deepseek-chat', 'req_xxx', 120, 80, 200);聚合查询示例:
SELECT model, tag, COUNT(*) AS calls, SUM(prompt_tokens) AS input_tokens, SUM(completion_tokens) AS output_tokens, SUM(total_tokens) AS all_tokens FROM llm_usage GROUP BY model, tag ORDER BY all_tokens DESC;注意流式请求的 usage 记录。前面提过,流式响应要打开stream_options={"include_usage": True},否则最后一段可能没有 usage。另一个常见问题是流式拼接后只保存了文本,没有保存request_id和 token 字段,导致无法和 TaoToken 控制台对账。建议在流式循环结束后,把最后一次chunk.usage和chunk.id写入同一行 JSONL。
如果是多模型评测,还要固定采样参数。比如同一批提示词,temperature、top_p、max_tokens尽量保持一致,否则 token 消耗差异既可能来自模型输出,也可能来自参数变化。记账表里可以额外加temperature、max_tokens、prompt_version字段,方便后续解释差异。开源权重模型与前沿模型的对比,只有把调用口径固定下来,token 记录才有复现意义。
6. 排障清单:401、404、429、流式 usage 为空、CC Switch 不生效
下面按报错或现象整理一份排障清单。遇到问题时不要先改模型,先按顺序检查 Key、Base URL、请求头、模型名、环境变量。
现象一:401 invalid api key
Authorization请求头是否写成Bearer YOUR_API_KEY。- 是否把官网链接或控制台地址误当成 Key。
- 环境变量是否在当前终端生效,例如
printenv TAOTOKEN_API_KEY。 - Claude Code 里是否同时存在旧供应商的
ANTHROPIC_AUTH_TOKEN。 - Codex 里
env_key是否指向了正确变量名。
现象二:404 path not found或404 model not found
- Base URL 是否精确为
https://taotoken.net/api。 - 客户端是否自动拼接
/v1,导致出现双/v1。 - 手写
curl时完整路径是否与控制台文档一致。 - 模型名是否从控制台复制,而不是凭记忆写别名。
- Codex 的
wire_api是否与 TaoToken 实际兼容方式一致。
现象三:429 too many requests
- 降低并发,不要用无限线程池压测。
- 为批处理任务加队列和重试。
- 检查是否多个工具共用同一个 Key 导致瞬时并发叠加。
- 将重试日志写入本地 usage 表,记录失败原因。
现象四:流式输出正常,但 usage 为空
- 请求体是否加上
stream_options: {"include_usage": true}。 - 是否只读取了
delta.content,没有读取最后的chunk.usage。 - 记录脚本是否在异常退出时丢失最后一行。
- 是否把非流式与流式记录混在同一张表却没有加
mode字段。
现象五:Claude Code 仍走旧供应商
- 检查
settings.json的env是否生效。 - 检查项目级配置、用户级配置、CC Switch 配置是否冲突。
- 重启 Claude Code,不要只开新会话。
- 确认
ANTHROPIC_BASE_URL是https://taotoken.net/api。
现象六:Codex 报 provider 相关错误
- 检查
model_provider与[model_providers.taotoken]名称是否一致。 - 检查
config.toml是否误写了ANTHROPIC_*,Codex 不读这些。 - 检查
env_key是否写成环境变量名。 - 检查模型名是否属于 Codex 可用的模型列表。
现象七:CC Switch 三件套不一致
- 供应商名称、Base URL、API Key 三项是否同时切换。
- 是否只改了 Key,Base URL 仍保留旧地址。
- 切换后是否重启对应 CLI。
- 是否在不同 shell 中残留旧环境变量。
遇到配置问题时,可以先回到官网确认当前 Key 状态、模型列表和文档入口:
https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=troubleshoot
如果只是模型名或 Base URL 写错,通常几分钟就能恢复。真正影响复现实验的是 token 记录缺失,所以每次排障后,建议用一条最小请求重新打印request_id和usage,确认记账链路没有断。
7. 把热点变成可复现评测:固定模型名、固定提示词、固定记账口径
Mozilla 报告、OpenRouter token 榜、DeepSeek 请求趋势这些外部热点,对工程师真正有用的启发是:选型不能只看一次对话体验,而要看同一套任务下的调用成本、延迟和 token 记录。你可以用 TaoToken 做三件事:第一,把 Base URL 固定为https://taotoken.net/api;第二,把 Key 收口到环境变量;第三,把每次请求的model、request_id、usage落到本地 JSONL 或 SQLite。这样当你要对比deepseek-chat、其他开源权重模型或前沿模型时,至少记账口径是一致的。
一个可复现的小流程如下:
- 从官网获取 Key,本地设置为
TAOTOKEN_API_KEY。 - 用
curl或 Python SDK 发一条最小请求,确认https://taotoken.net/api可用。 - 准备固定提示词集合,例如 20 条评测样本,每条保存
prompt_version。 - 对每个模型跑相同参数,记录
prompt_tokens、completion_tokens、total_tokens。 - 把结果写入本地 JSONL,再导入 SQLite 做聚合。
- 对比不同模型的 token 消耗和输出质量,不用把 Key 或完整响应贴到公开仓库。
- 若使用 Claude Code 或 Codex,分别维护
settings.json和config.toml,不要把变量互相套用。 - 用 CC Switch 切换供应商时,只改三件套,并重启 CLI。
- 每次新增模型,先用最小请求验证模型名,再进入批量评测。
- 定期核对 TaoToken 控制台用量与本地
usage.jsonl,发现差异先查流式 usage 和失败重试记录。
这套流程不依赖特定插件,也不要求连接外部数据库。你只需要本地执行命令,把配置和用量文件放在自己的项目目录里。对于用 OpenRouter/DeepSeek 做应用开发或模型评测的工程师来说,先把 Key、Base URL、请求头、模型名和 token 记录跑通,再谈模型对比,效率会高很多。
如果你准备把上面的配置落到项目里,建议按这个顺序走:先在模型对话页验证模型输出,再选 Coding Plan,然后去 API Keys 创建或轮换 Key,最后照着 Claude Code 文档把settings.json对齐。对应入口如下:
- 模型对话:https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=cta_chat
- Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=cta_coding
- 创建 Key:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=cta_keys
- Claude Code 文档:https://taotoken.net/doc/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=cta_claudecode
最后再强调一次配置边界:Claude Code 使用settings.json和ANTHROPIC_*;Codex 使用config.toml、model_provider、wire_api;CC Switch 只维护供应商名称、Base URL、API Key 三件套。Base URL 统一写https://taotoken.net/api,Key 占位符统一用YOUR_API_KEY。把这些边界守住,再用usage字段做记账,DeepSeek 调用和开源权重模型评测就不会变成一笔糊涂账。