ARTICLE DETAIL

资讯详情

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

Anthropic API 429 了?TaoToken 换 Key 后的限流排查

Anthropic API 429 了?TaoToken 换 Key 后的限流排查 1. 429 现场把“额度不够”拆成 RPM、TPM 和并发三笔账线上 Anthropic SDK 抛 429 时我第一件事不是继续加 Key而是打开 TaoToken 官网 注册并拿一张用于统一通道的 TaoToken Key。最近行业里关于 Anthropic 与 OpenAI 是否协调放缓前沿模型开发的讨论很热但这篇不评政策对服务维护者来说429 不是新闻是日志里必须定位的RateLimitError。Anthropic API 返回 429 时响应体常见type: rate_limit_error响应头里会带retry-after、request-id以及一组anthropic-ratelimit-*字段。先别把重试次数调大重试会把同一批 Token 再打一遍日志里看起来只是“更慢”实际上消耗没停。谁在消耗 Token答案通常不是“官方额度不够”这一句而是四个具体来源共享 Key 的多个服务、长上下文会话、失败重试、后台批处理。服务维护者视角下429 排查要先分三笔账第一笔是 RPM也就是单位时间请求数第二笔是 TPM也就是输入与输出 Token 速率第三笔是并发与排队很多请求并没有立即失败而是在客户端排队、重试、再排队。只看“总量”会把这三笔账混在一起最后变成一句模糊的“限流了”。更可复现的做法是把每次调用的tenant、model、input_tokens、output_tokens、cache_read_input_tokens、cache_creation_input_tokens、elapsed、request_id和retry_after打全然后再决定是换 Key、切 Base URL还是先砍上下文。下面这篇不讨论行业口水只做接入、排障和配置。你可以把 Anthropic SDK 的base_url指到https://taotoken.net/apiKey 用 TaoToken Key再按同一套日志字段对比直连和切换后的 429、耗时与调用方。这样“谁在消耗 Token”不再是猜而是能从本地日志里算出来。2. 切到 TaoToken 前拿 Key、定 Base URL、别改错环境变量在准备把 Anthropic SDK 请求切到统一通道时访问 TaoToken 官网 注册并获取 TaoToken Key。TaoToken 的 Base URL 是https://taotoken.net/api工具配置不要在这个地址后面加 UTM。Key 用占位符YOUR_API_KEY表示实际值放环境变量、本地.env或 CI secret不要提交到仓库。先把最小环境变量定清楚。Anthropic SDK 使用ANTHROPIC_*OpenAI 兼容 SDK 使用OPENAI_*Codex 这类工具有自己的配置文件字段。混用是 429 排查里最常见的“假故障”你以为切到了 TaoToken其实进程里还残留着旧的ANTHROPIC_BASE_URL或者 Codex 读的是另一个env_key。# 本地 .env 或 CI secret不要提交到 Git export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYYOUR_API_KEY export ANTHROPIC_MODELclaude-sonnet-4-5如果同一台机器上还有 OpenAI 兼容调用单独放export OPENAI_BASE_URLhttps://taotoken.net/api export OPENAI_API_KEYYOUR_API_KEY export OPENAI_MODELgpt-5-codex注意两点。第一Anthropic SDK 的base_url建议只写到https://taotoken.net/api不要自己补/v1SDK 会按路径拼接如果你写成https://taotoken.net/api/v1部分版本会出现/v1/v1/messages这类路径重复报错可能不是 429但排查会被带偏。第二Claude Code、Codex、CC Switch 这类工具常有多层配置改完要重启终端或工具进程否则旧的 Key 还在内存里。切换前先做一个 curl 健康检查确认 Key、Base URL、模型名三者能通。这个请求只打 128 输出 token不引入业务上下文适合作为基线。export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYYOUR_API_KEY export MODEL_NAMEclaude-sonnet-4-5 curl -sS -D /tmp/taotoken_headers.txt \ $ANTHROPIC_BASE_URL/v1/messages \ -H x-api-key: $ANTHROPIC_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { \model\: \$MODEL_NAME\, \max_tokens\: 128, \messages\: [{\role\: \user\, \content\: \只回复 pong\}] } \ | tee /tmp/taotoken_body.json printf \n--- headers ---\n cat /tmp/taotoken_headers.txt printf \n--- body ---\n cat /tmp/taotoken_body.json如果这个 curl 返回 200说明通道基本可用如果仍 429先看响应头里的retry-after和request-id再看是不是模型名、并发或输入 token 太大。不要在业务代码里反复重放先把基线请求跑通。3. Anthropic SDK 最小改造base_url 指向 TaoToken 与 curl 复现Python 项目里最小改造就是把base_url指向 TaoTokenKey 从环境变量读。不要硬编码 Key也不要在日志里打印完整 Key。下面这段可以直接改到你的封装层里import os from anthropic import Anthropic client Anthropic( api_keyos.environ[ANTHROPIC_API_KEY], base_urlos.environ.get(ANTHROPIC_BASE_URL, https://taotoken.net/api), ) resp client.messages.create( modelos.environ.get(ANTHROPIC_MODEL, claude-sonnet-4-5), max_tokens256, messages[{role: user, content: 只回复 pong}], ) print(request_id, resp.id) print(input_tokens, resp.usage.input_tokens) print(output_tokens, resp.usage.output_tokens)Node/TypeScript 项目的写法类似关键是baseURL和apiKey都来自环境变量import Anthropic from anthropic-ai/sdk; const client new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY!, baseURL: process.env.ANTHROPIC_BASE_URL ?? https://taotoken.net/api, }); const resp await client.messages.create({ model: process.env.ANTHROPIC_MODEL ?? claude-sonnet-4-5, max_tokens: 256, messages: [{ role: user, content: 只回复 pong }], }); console.log(resp.id, resp.usage);如果业务代码里有多个封装层建议只保留一个client单例不要在每次请求时重新构造。频繁重建客户端会带来连接池抖动排查 429 时容易把连接问题和限流问题混在一起。切换后第一轮不要直接放全量流量先拿一个内部租户或一个低频接口跑对照。curl 复现命令已经在上节给出这里再强调日志路径把响应头保存到文件把响应体保存到另一个文件。429 时不要只贴RateLimitError这一行要带request-id、retry-after和模型名。这样你才能判断是请求速率高、Token 速率高还是某个调用方在短时间内打出了大量输入 token。4. 直连与切换后对照429、耗时、日志字段怎么记下表不预设“切换后一定 429 更少”而是给你一套同口径记录法。切换前后都按这些字段记才能回答谁在消耗 Token。表格里的“示例记录法”指的是你本地日志应包含的字段不是固定数值。观察项直连 Anthropic API记录方式切到 TaoToken Base URL记录方式判读429 响应体type、message、request-id同口径记录先确认是否rate_limit_error429 响应头retry-after、anthropic-ratelimit-*同口径记录区分 RPM 与 TPMP50/P95 耗时按接口、租户、模型分桶按同一分桶计算判断是否只是重试拉长输入 tokeninput_tokensinput_tokens谁在塞长上下文输出 tokenoutput_tokensoutput_tokens谁在放大 max_tokens缓存读cache_read_input_tokens同字段缓存是否命中缓存写cache_creation_input_tokens同字段是否反复写缓存调用方tenant、service、job同标签多租户定位请求 IDrequest_idrequest_id用于对账和追踪重试次数本地计数器同计数器重试风暴最危险一个可读日志样例可以长这样数值请替换成你自己的2026-02-12T10:00:00 levelINFO msganthropic_ok tenantweb-a modelclaude-sonnet-4-5 in1820 out240 cache_read0 cache_create1024 elapsed2.31 request_idreq_xxx 2026-02-12T10:00:01 levelWARN msganthropic_429 tenantjob-b modelclaude-sonnet-4-5 in9200 out0 elapsed0.12 retry_after8 request_idreq_yyy如果日志是 JSON Lines在本地脱敏日志上执行聚合不要连生产库。下面这条命令只读本地文件jq -r select(.msganthropic_ok or .msganthropic_429) | [.tenant, .model, (.in // 0), (.out // 0), (.elapsed // 0), .msg] | tsv app.log \ | awk -F\t {key$1\t$2; n[key]; in[key]$3; out[key]$4; t[key]$5; if($6anthropic_429) r429[key]} END {for (k in n) printf %s\tcalls%d\tin%d\tout%d\tavg_elapsed%.3f\t429%d\n, k, n[k], in[k], out[k], t[k]/n[k], r429[k]0} 这一步能快速暴露三个事实哪个租户调用最多、哪个租户输入 token 最大、哪个租户 429 最多。很多“换 Key 后还限流”的案例最后都发现是某个后台任务和线上服务共用 Key或者某个编码工具在批量读文件。5. Claude Code 的 settings.jsonANTHROPIC_* 只给 Claude Code 用Claude Code 侧通常通过settings.json注入环境变量。路径可以是~/.claude/settings.json也可以是项目级.claude/settings.json以你当前版本为准。配置目标很明确让 Claude Code 请求走 TaoToken 的 Base URLKey 用 TaoToken Key。{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: YOUR_API_KEY, ANTHROPIC_MODEL: claude-sonnet-4-5 } }改完后先查当前 shell 是否还有旧的ANTHROPIC_*覆盖。不要打印完整 Key只看是否存在和尾号env | grep -E ANTHROPIC_(BASE_URL|API_KEY|MODEL) | sed s/.*/redacted/ env | awk -F /^ANTHROPIC_API_KEY/{print ANTHROPIC_API_KEY tail substr($2, length($2)-3)}Claude Code 这类工具会读目录、读文件、维护多轮上下文Token 消耗通常比普通问答高。排查时不要把它和线上服务混在同一个 Key 下。更好的做法是给 Claude Code 单独 Key在小目录里跑限制一次读取范围并观察request_id和usage。如果 Claude Code 仍 429先看是不是同一个 Key 同时在跑多个窗口再看输入 token 是否因为大仓库扫描而暴涨。6. Codex 的 config.toml不要把 ANTHROPIC_* 塞进去Codex 用的是另一套配置通常在~/.codex/config.toml。这里不要写ANTHROPIC_BASE_URL或ANTHROPIC_API_KEY那会把两个工具的配置串线。Codex 侧应该声明自己的 provider 和env_keymodel gpt-5-codex model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat然后在终端里提供对应的 Keyexport TAOTOKEN_API_KEYYOUR_API_KEY如果你的 Codex 版本字段名不完全一样以本地config.toml的示例为准但原则不变Codex 读TAOTOKEN_API_KEY或它自己的env_key不要读ANTHROPIC_API_KEY。同理Claude Code 也不要读TAOTOKEN_API_KEY除非你明确在settings.json里做了映射。排查 429 时先把两个工具的 Key 和 Base URL 分开看再谈限流。7. CC Switch 三件套核对供应商、工具配置、终端变量如果你用 CC Switch 管理多套终端 AI 工具常见“三件套”是供应商条目、Claude Code 的settings.json、Codex 的config.toml。三处配置必须同源否则你切了供应商实际请求还在旧通道上429 当然继续出现。核对清单如下供应商条目Base URL 是否为https://taotoken.net/apiKey 是否为YOUR_API_KEY模型名是否和控制台一致。Claude Codesettings.json的env是否写入ANTHROPIC_BASE_URL、ANTHROPIC_API_KEY。Codexconfig.toml的model_provider是否指向 TaoTokenenv_key是否指向TAOTOKEN_API_KEY。终端变量当前 shell 是否残留旧 Key尤其是 CI、systemd、Docker Compose 里的环境变量。进程重启改完配置后是否重启了 Claude Code、Codex 或终端。本地核对可以用这些命令输出会脱敏grep -R ANTHROPIC_BASE_URL\|ANTHROPIC_API_KEY ~/.claude 2/dev/null | sed s/\(API_KEY[:][[:space:]]*\).*/\1redacted/ grep -R base_url\|env_key\|model_provider ~/.codex 2/dev/null env | grep -E ANTHROPIC|OPENAI|TAOTOKEN | sed s/.*/redacted/如果三件套里有任何一处仍指向旧 Base URL先修正再跑流量。不要用“多切几次”来碰运气。8. 谁在消耗 Token12 个证据点与本地日志排查服务维护者最需要回答的问题不是“有没有限流”而是“哪个调用方在消耗 Token”。下面 12 个证据点基本覆盖 Anthropic/OpenAI 模型调用里的常见黑洞。共享 Key 多租户多个服务共用一个 Key429 后无法定位租户。重试风暴429 后立刻重试输入 token 被重复发送。长上下文每轮重发多轮对话把历史全量带上输入 token 线性膨胀。RAG top_k 过大检索片段太长答案只用了最后几段。system prompt 膨胀规则、示例、工具说明越加越多每次请求都重复。工具调用循环模型反复调用同一个工具上下文反复叠加。后台任务与线上同 Key夜间批处理抢占线上额度。编码工具批量读文件Claude Code、Codex 类工具扫描大仓库单次输入很大。流式中断重发客户端断开后重新请求旧请求可能已计费。缓存未命中cache_read_input_tokens很低cache_creation_input_tokens很高。max_tokens 过大输出上限设得远高于实际需要。日志未按租户打标签只能看到总 429无法拆账。把这些字段打进封装层比事后猜有效。下面是一个可复制的 Python 记录片段import logging import time import uuid from anthropic import Anthropic, RateLimitError log logging.getLogger(anthropic_usage) def call_anthropic(client: Anthropic, *, tenant: str, model: str, messages: list, max_tokens: int 512): trace_id str(uuid.uuid4()) started time.time() try: resp client.messages.create( modelmodel, max_tokensmax_tokens, messagesmessages, ) log.info( anthropic_ok trace_id%s tenant%s model%s in%s out%s cache_read%s cache_create%s elapsed%.3f request_id%s, trace_id, tenant, model, resp.usage.input_tokens, resp.usage.output_tokens, getattr(resp.usage, cache_read_input_tokens, 0), getattr(resp.usage, cache_creation_input_tokens, 0), time.time() - started, resp.id, ) return resp except RateLimitError as exc: headers getattr(getattr(exc, response, None), headers, {}) log.warning( anthropic_429 trace_id%s tenant%s model%s elapsed%.3f retry_after%s request_id%s body%s, trace_id, tenant, model, time.time() - started, headers.get(retry-after), headers.get(request-id), str(exc)[:300], ) raise这段代码不直接解决 429但它让 429 变得可解释。你可以在本地脱敏日志上按tenant聚合找出调用最多、输入 token 最大、429 最多的租户。然后再决定是限流、拆 Key、缩短上下文还是把编码工具迁到独立通道。9. 把 429 抑制到可接受退避、并发、缓存、配额分层排查完“谁在消耗 Token”下一步才是抑制 429。几个动作优先级很高。第一重试要带退避和 jitter。只对 429 和 5xx 重试4xx 参数错误不要重试。429 时优先读响应头retry-after没有就指数退避。import random import time from anthropic import RateLimitError def with_retry(fn, max_attempts5): for attempt in range(1, max_attempts 1): try: return fn() except RateLimitError as exc: if attempt max_attempts: raise headers getattr(getattr(exc, response, None), headers, {}) retry_after float(headers.get(retry-after) or 0) backoff max(retry_after, min(2 ** attempt, 20)) random.random() time.sleep(backoff)第二按租户拆 Key 或至少拆标签。线上服务、后台任务、Claude Code、Codex 不要共用一个 Key。即使暂时共用也要在日志里打tenant和service否则 429 后无法归因。第三限制输入。对多轮对话做摘要对 RAG 做重排和截断对 system prompt 做版本化和缓存。Anthropic 的缓存字段能帮你判断缓存是否命中cache_read_input_tokens高说明复用了cache_creation_input_tokens高说明反复写缓存。第四控制并发。客户端加信号量或队列不要无限开协程。429 出现时队列比重试更安全。批处理任务错峰避免和线上高峰重叠。第五记录anthropic-ratelimit-*响应头。它们能告诉你剩余请求、剩余 token、重置时间。把响应头按接口和租户落盘建立仪表盘比单看错误率更早发现异常。第六把编码工具和个人实验隔离开。Claude Code 和 Codex 的 token 消耗模式与线上 API 不同混用同一个 Key 会让排查失去边界。需要低成本试模型时可以走 TaoToken 官网 的统一入口再按工具分别配置。10. 文末路径模型对话、Coding Plan、创建 Key、Claude Code 文档如果你已经把 Anthropic SDK 的base_url改到https://taotoken.net/api下一步建议按这个顺序验证和落地先用 模型对话 验证模型名、Key 和最小请求是否正常别一上来就把全量业务切过去。如果 Claude Code、Codex 这类编码工具用量大再看 Coding Plan把编码工具和线上服务的额度边界分开。创建和管理 Key 到 API Keys线上服务、后台任务、个人工具各用独立 Key429 时才能按 Key 归因。Claude Code 的settings.json写法可以直接对照 Claude Code 文档确认ANTHROPIC_BASE_URL、ANTHROPIC_API_KEY、ANTHROPIC_MODEL没有写错位置。最后回到 TaoToken 官网 注册并获取 TaoToken Key把 Key 占位符YOUR_API_KEY替换成你的实际值然后重启终端或工具进程。429 本身不可怕可怕的是所有调用方共用一把 Key、所有日志只有一行错误。把 Base URL 切到https://taotoken.net/api只是第一步真正的排查从request_id、input_tokens、output_tokens、retry_after和tenant这些字段开始。谁在消耗 Token日志会告诉你。
返回列表