ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

调用 Qwen 的 Key 由 TaoToken 出,OpenRouter token 谁消耗

调用 Qwen 的 Key 由 TaoToken 出,OpenRouter token 谁消耗 1. 从一次 Qwen 调用日志说起Key、Base URL 和 token 归属为什么容易搞混在应用开发里Key 和 Base URL 被环境变量悄悄改写的排障现场比模型答错更常见。今天从 TaoToken 官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentqwen_key_intro拿 KeyBase URL 填 https://taotoken.net/api然后回答一个很具体的问题Qwen 的调用 Key 由 TaoToken 出之后OpenRouter 的 token 到底是谁消耗的。近期 Mozilla 报告解读引发了对中国开源模型分发优势的讨论Qwen 成为不少团队第一个接入的模型这也让“Key 从哪来、请求打到哪、token 记在谁头上”变成必须写进工程规范的问题。很多开发者第一次遇到这个困惑是在日志里同时看到两个 provider 的计数一边是自己刚接好的 TaoToken另一边是历史项目里残留的 OpenRouter。于是直觉上会问“我明明用 TaoToken 的 Key 调 Qwen为什么 OpenRouter 还有 token 消耗”答案通常不在模型本身而在调用链的出口。一个请求的 token 归属只由两件事决定最终请求发到了哪个 Base URL以及请求头里带了谁的 API Key。谁提供服务token 就记在谁那里。中间件、SDK、CC Switch、Claude Code、Codex、环境变量加载顺序都可能让你以为自己在调 Qwen实际请求却打到了另一个网关。本文按应用开发者视角从最小可验证调用、日志埋点、Claude Code 配置、Codex 配置、CC Switch 三件套到本地 token 统计一步步把归属链路拆开。你不需要改动生产数据库也不需要把 Agent 直连到任何数据库所有 SQL 和命令都在你本地终端执行。目标很明确让 Qwen 调用固定走 TaoToken产出调用方日志与 token 统计并能用数据回答“OpenRouter token 是谁消耗的”。2. TaoToken 拿 Key 与 Base URL先用最小请求确认出口第一步不是改业务代码而是做一个最小可验证调用。先去 TaoToken 控制台创建 API Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentqwen_key_create 。拿到 Key 后不要直接写进业务代码先放环境变量并用一个独立脚本请求一次 Qwen。Base URL 按产品配置填 https://taotoken.net/apiKey 占位符用 YOUR_API_KEY。export TAOTOKEN_API_KEYYOUR_API_KEY export TAOTOKEN_BASE_URLhttps://taotoken.net/api用 curl 发一个非流式请求确认服务端返回的 usage 字段curl -sS $TAOTOKEN_BASE_URL/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: qwen-plus, messages: [ {role: user, content: 只输出一行 JSON{\ok\:true,\provider\:\taotoken\}} ], stream: false, temperature: 0.1 }如果你更习惯 Python可以用 OpenAI SDK 做同样的验证。注意 base_url 仍然填 https://taotoken.net/api模型 ID 以 TaoToken 控制台模型页为准下面用 qwen-plus 作为示例import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlhttps://taotoken.net/api, ) resp client.chat.completions.create( modelqwen-plus, messages[ {role: user, content: 输出一行 JSON包含 ok 和 provider 字段} ], temperature0.1, ) print(resp.model_dump_json(indent2))这次调用如果成功重点观察三样东西返回体里的model、id、usage。usage.prompt_tokens、usage.completion_tokens、usage.total_tokens就是这次 Qwen 调用的 token 消耗。只要 Base URL 是 https://taotoken.net/apiKey 来自 TaoToken这次消耗就记在 TaoToken 侧不会记到 OpenRouter。你可以把这一步理解为“归零实验”在没有任何 OpenRouter 配置的干净终端里发一次请求看 TaoToken 的用量是否增加OpenRouter 是否不动。如果这一步就失败了常见原因不是 Qwen 模型不可用而是环境变量串线。先检查当前 shell 是否还残留旧的OPENAI_BASE_URLenv | grep -E OPENAI|OPENROUTER|ANTHROPIC|TAOTOKEN | sort如果看到OPENAI_BASE_URL指向别的网关或者OPENAI_API_KEY是旧项目的 Key就先清理再重试。不要把多个供应商的 Key 混在同一个 shell 会话里做验证那样日志无法归因。3. OpenRouter token 谁消耗按“最终出口”拆归属链路先把结论说清楚Qwen 调用 Key 由 TaoToken 出Base URL 填 https://taotoken.net/api那么这次 Qwen 调用的 token 消耗记在 TaoToken。OpenRouter token 被消耗只可能因为你的应用里还存在另一条请求路径它使用了 OpenRouter 的 Base URL 和 OpenRouter 的 Key。换句话说不是 Qwen 消耗了 OpenRouter token而是你的某个调用方把请求发给了 OpenRouter。可以用一张判定表来理解实际发出的 Base URL实际使用的 Key 来源token 记在谁那里https://taotoken.net/apiTaoToken 控制台创建的 KeyTaoTokenOpenRouter 的接口地址OpenRouter 的 KeyOpenRouter其他自建或第三方网关对应网关的 Key对应网关所以排查顺序应该是先抓“最终出口”再抓“Key 来源”最后看“usage 归属”。很多项目会在代码里写一个provider变量但真正发请求时用的是 SDK 默认配置。比如全局设置了OPENAI_BASE_URL业务代码只传model和messages这时你以为自己在调 QwenSDK 却可能把请求发到了旧网关。还有一种情况是多个.env文件按顺序加载后面的文件覆盖了前面的OPENAI_API_KEY导致 Key 和 Base URL 不匹配。在调用方加一段配置快照日志是最低成本的定位方式import os def snapshot_provider_config(): return { openai_base_url: os.getenv(OPENAI_BASE_URL), openai_api_key_prefix: (os.getenv(OPENAI_API_KEY) or )[:8], taotoken_api_key_prefix: (os.getenv(TAOTOKEN_API_KEY) or )[:8], openrouter_api_key_prefix: (os.getenv(OPENROUTER_API_KEY) or )[:8], anthropic_base_url: os.getenv(ANTHROPIC_BASE_URL), default_model: os.getenv(DEFAULT_MODEL), } print(snapshot_provider_config())如果快照里openai_base_url不是 https://taotoken.net/api而是 OpenRouter 的地址那就说明 Qwen 调用并没有走 TaoToken。此时 OpenRouter 的 token 增长是合理的因为请求确实发给了 OpenRouter。修正方式不是去 OpenRouter 后台找原因而是回到调用方把 Base URL 和 Key 统一到 TaoToken。如果你使用框架或中间件还可以在请求前后记录更完整的上下文。不要只记录模型名因为模型名可能被多个 provider 支持。至少记录base_url、api_key_prefix、model、request_id、usage、latency_ms、status_code。这些字段后面会进入本地 token 统计表用来区分 TaoToken 消耗和 OpenRouter 消耗。4. 在 Claude Code 中把 Qwen 接到 TaoTokensettings.json 与 ANTHROPIC_*Claude Code 走的是 Anthropic 协议变量不要把它和 Codex 的配置混在一起。你可以在用户级或项目级 settings.json 中设置环境变量。下面是一个可复制的示例Base URL 仍然使用 https://taotoken.net/apiKey 使用 TaoToken 控制台创建的 YOUR_API_KEY{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_API_KEY: YOUR_API_KEY, ANTHROPIC_MODEL: qwen-plus, ANTHROPIC_SMALL_FAST_MODEL: qwen-turbo } }放置位置可以是~/.claude/settings.json也可以是项目内的.claude/settings.json。改完后重启 Claude Code让配置重新加载。然后在一个只读场景里发一条简单请求例如让它解释一段本地函数观察返回是否正常。如果返回 401优先检查ANTHROPIC_AUTH_TOKEN是否和ANTHROPIC_API_KEY同时被旧值覆盖如果返回 404检查 Base URL 是否被写成了其他路径。Claude Code 的 token 统计要结合调用方日志看。你可以在启动 Claude Code 前先运行一次配置快照确认当前 shell 没有把ANTHROPIC_BASE_URL指向 OpenRouter。如果 Claude Code 的日志里出现了非 TaoToken 的请求 ID或者你的 OpenRouter 用量在 Claude Code 使用期间增长那说明当前 profile 并没有真正切到 TaoToken。此时不要继续调模型参数先把配置源找出来是用户级 settings.json、项目级 settings.json还是 shell 里的环境变量优先级更高。另外要强调ANTHROPIC_*只用于 Claude Code 这类 Anthropic 协议工具不要把这些变量复制到 Codex 的配置里。Codex 不读ANTHROPIC_BASE_URL也不会因为你在 shell 里导出了ANTHROPIC_AUTH_TOKEN就改用 TaoToken。把两套配置混用是“Qwen 走 TaoToken、OpenRouter 仍在消耗”的常见原因之一。5. 在 Codex 中配置 Qwen 走 TaoTokenconfig.toml 独立配置Codex 使用自己的 config.toml通常是~/.codex/config.toml。这里要单独配置 provider不要套用 Claude Code 的ANTHROPIC_*变量。下面是一个面向 TaoToken 的配置示例model qwen-plus model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY然后在 shell 里只注入 TaoToken 的 Keyexport TAOTOKEN_API_KEYYOUR_API_KEY如果你的 Codex 版本还要求声明传输方式请按当前版本文档补充对应字段核心不变的是 provider 的base_url必须指向 https://taotoken.net/apienv_key必须指向 TaoToken 的 Key。配置完成后启动 Codex在会话里询问一个简单问题再回到本地日志查看这次请求实际使用的 base_url。如果日志里仍然是 OpenRouter 的地址说明 Codex 还在使用旧 provider可能因为model_provider没有改或者用户级配置被项目级配置覆盖。Codex 场景下最容易出现的问题是开发者把 Claude Code 的 settings.json 复制到了 Codex 项目里然后以为 Codex 会读取ANTHROPIC_BASE_URL。实际上 Codex 只认自己的 config.toml 和对应环境变量。结果就是 Claude Code 已经走 TaoTokenCodex 却还在走 OpenRouter于是你看到 OpenRouter token 继续增长误以为是 Qwen 调用导致的。把两套配置分开管理是解决这个问题的关键。建议为 Codex 单独建一个启动脚本#!/usr/bin/env bash set -euo pipefail export TAOTOKEN_API_KEYYOUR_API_KEY export TAOTOKEN_BASE_URLhttps://taotoken.net/api # 清理可能干扰 Codex 的旧变量 unset OPENAI_BASE_URL OPENAI_API_KEY OPENROUTER_API_KEY ANTHROPIC_BASE_URL ANTHROPIC_AUTH_TOKEN codex这样每次启动 Codex 时环境是干净的只有 TaoToken 的 Key 和 Base URL 生效。Qwen 调用产生的 token 会记在 TaoToken 侧OpenRouter 不会因为 Codex 而增加消耗。6. CC Switch 三件套多供应商切换时不串 token如果你使用 CC Switch 管理多个供应商建议把“三件套”对齐后再切换Base URL、API Key、默认模型。对 TaoToken Qwen 这条链路来说三件套就是Base URLhttps://taotoken.net/apiAPI KeyYOUR_API_KEY来自 TaoToken 控制台默认模型qwen-plus以 TaoToken 控制台模型页为准在 CC Switch 中为 TaoToken 建一个独立 profile不要把 OpenRouter 的 Key 填进同一个 profile。如果你同时保留 OpenRouter profile至少在切换后确认当前生效的是哪一套。可以用下面的命令快速检查python - PY import os keys [ OPENAI_BASE_URL, OPENAI_API_KEY, OPENROUTER_API_KEY, ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, TAOTOKEN_API_KEY, ] for k in keys: v os.getenv(k) if v and k.endswith(KEY): v v[:8] ... print(f{k}{v}) PY如果OPENAI_BASE_URL和OPENROUTER_API_KEY同时存在而你的目标是用 TaoToken 调 Qwen就先把 OpenRouter 相关变量清理掉。更规范的做法是拆成两个 env 文件启动时只加载一个# .env.taotoken OPENAI_BASE_URLhttps://taotoken.net/api OPENAI_API_KEYYOUR_API_KEY DEFAULT_MODELqwen-plus# .env.openrouter OPENAI_BASE_URLhttps://openrouter.ai/api/v1 OPENAI_API_KEYYOUR_OPENROUTER_KEY DEFAULT_MODEL你的模型启动脚本里只 source 其中一个set -a source .env.taotoken set a python your_app.pyCC Switch 只负责切换配置不负责 token 归属。归属永远由最终请求的 Base URL 和 Key 决定。切换完成后最好立刻发一次最小请求并记录 usage确认这次 token 记到了预期的 provider。如果 CC Switch 切换后 OpenRouter 用量还在涨就去看当前 profile 是否真的被应用读取以及是否有另一个进程仍在使用旧环境。7. 调用方日志与 token 统计把“谁消耗”变成可查询的数据要彻底回答“OpenRouter token 谁消耗”不能只看控制台总额必须在调用方落日志。建议设计一张本地表字段包括时间、请求 ID、provider、base_url、model、prompt_tokens、completion_tokens、total_tokens、latency_ms、status_code。下面用 SQLite 做示例所有命令都在你本地执行。import sqlite3 import time from datetime import datetime, timezone from openai import OpenAI DB llm_usage.db def init_db(): conn sqlite3.connect(DB) conn.execute( CREATE TABLE IF NOT EXISTS llm_calls ( id INTEGER PRIMARY KEY AUTOINCREMENT, ts TEXT NOT NULL, request_id TEXT, provider TEXT NOT NULL, base_url TEXT NOT NULL, model TEXT NOT NULL, prompt_tokens INTEGER DEFAULT 0, completion_tokens INTEGER DEFAULT 0, total_tokens INTEGER DEFAULT 0, latency_ms INTEGER, status_code INTEGER ) ) conn.commit() conn.close() def record_call(provider, base_url, model, usage, latency_ms, status_code, request_idNone): conn sqlite3.connect(DB) conn.execute( INSERT INTO llm_calls ( ts, request_id, provider, base_url, model, prompt_tokens, completion_tokens, total_tokens, latency_ms, status_code ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) , ( datetime.now(timezone.utc).isoformat(), request_id, provider, base_url, model, getattr(usage, prompt_tokens, 0), getattr(usage, completion_tokens, 0), getattr(usage, total_tokens, 0), latency_ms, status_code, ), ) conn.commit() conn.close() init_db() client OpenAI( api_keyYOUR_API_KEY, base_urlhttps://taotoken.net/api, ) start time.time() resp client.chat.completions.create( modelqwen-plus, messages[{role: user, content: 统计这次调用的 token}], ) latency_ms int((time.time() - start) * 1000) record_call( providertaotoken, base_urlhttps://taotoken.net/api, modelresp.model, usageresp.usage, latency_mslatency_ms, status_code200, request_idresp.id, ) print(recorded:, resp.id, resp.usage)之后就可以用本地 SQL 做聚合。先看按 provider 分组的 token 总量SELECT provider, model, SUM(total_tokens) AS tokens, COUNT(*) AS calls FROM llm_calls GROUP BY provider, model ORDER BY tokens DESC;再看按 base_url 分组的明细SELECT base_url, model, SUM(total_tokens) AS tokens, COUNT(*) AS calls FROM llm_calls GROUP BY base_url, model ORDER BY tokens DESC;如果第一张表里provideropenrouter的记录还在增长就去第二张表看对应的base_url是什么。只要 base_url 不是 https://taotoken.net/api那就不是 Qwen 走 TaoToken 产生的消耗而是另一个调用路径。你可以继续按request_id、model、时间窗口定位到具体服务或脚本。比如某个定时任务仍在用旧配置或者某个本地脚本加载了.env.openrouter。还可以做一个小型日报查询把 TaoToken 和 OpenRouter 分开统计SELECT date(ts) AS day, provider, SUM(total_tokens) AS tokens, COUNT(*) AS calls FROM llm_calls GROUP BY day, provider ORDER BY day DESC, tokens DESC;当这份数据稳定后你就能明确回答Qwen 调用由 TaoToken 提供 KeyBase URL 是 https://taotoken.net/apitoken 记在 TaoTokenOpenRouter 的 token 如果仍有消耗来源一定是指向 OpenRouter 的那部分请求。把日志和统计留在调用方而不是依赖记忆或控制台猜测是多供应商环境下最可靠的做法。8. 把 Qwen 调用固定到 TaoToken检查清单与下一步最后给出一份可执行的检查清单。每次接入新环境或切换配置后按顺序过一遍Base URL 是否为 https://taotoken.net/apiAPI Key 是否来自 TaoToken 控制台创建的 YOUR_API_KEY模型 ID 是否在 TaoToken 模型页可查且与调用方日志一致调用方日志中的 provider 是否为 taotokenOpenRouter 的 token 消耗是否来自另一个独立任务或旧配置Claude Code 是否只使用ANTHROPIC_*Codex 是否只使用 config.tomlCC Switch 当前 profile 是否只启用了一套三件套Base URL、Key、默认模型如果这七项都确认无误Qwen 调用就不会再把 token 记到 OpenRouter 上。需要创建或更换 Key可以从 TaoToken 控制台开始https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentqwen_key_console 。如果你想先验证模型对话再决定是否接入 Coding Plan可以按下面路径操作模型对话https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentqwen_key_chatCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentqwen_key_plan创建 Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentqwen_key_consoleClaude Code 文档https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentqwen_key_claude_code回到官网入口可以随时查看最新模型与配置说明https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentqwen_key_cta 。把 Base URL 固定为 https://taotoken.net/api把 Key 统一为 TaoToken 出把调用方日志和 token 统计落到本地表里你就不会再被“OpenRouter token 谁消耗”这个问题困住。
返回列表