1. 从红队评估脚本的 401 与 base_url 冲突切入
最近关于前沿模型公司引入驻场第三方安全评估的讨论很多,METR、Redwood Research 这类独立评估方会拿到系统访问权,红队脚本自然也要直接调模型 API。对评估脚本/API 调用方来说,真正卡住复现的不是观点,而是调用凭据从哪来、Base URL 怎么配、调用记录怎么对照。我在新建调用凭据时统一去 TaoToken 官网(https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=openai_log_entry)拿 Key,Base URL 固定写成 https://taotoken.net/api。下面从一段 OpenAI API 调用记录出发,把 TaoToken 入口、curl 命令、Claude Code settings.json、Codex config.toml、CC Switch 三件套和调用日志对照讲清楚。所有命令都在本地终端执行,不连接生产库。
先看一个最常见的事故:评估脚本昨天还能跑,今天换了一台机器,只把OPENAI_API_KEY改成了新 Key,却忘了清掉旧的OPENAI_BASE_URL。结果调用记录里显示的是官方域名,返回 401 或 404,排查半天以为是 Key 失效。实际上 OpenAI SDK 会自己在 Base URL 后面拼接/v1/chat/completions,如果你手动写成https://taotoken.net/api/v1,最终请求路径会变成/api/v1/v1/chat/completions,这不是配置错误,而是路径重复。
# 错误:把 /v1 写进 Base URL,SDK 会再拼一次 export OPENAI_BASE_URL="https://taotoken.net/api/v1" export OPENAI_API_KEY="YOUR_API_KEY" # 正确:Base URL 只写到 /api export OPENAI_BASE_URL="https://taotoken.net/api" export OPENAI_API_KEY="YOUR_API_KEY"判断入口是否切换成功,最直接的方法是看请求日志。OpenAI Python SDK 在 debug 日志里会打印实际请求 URL。如果看到:
POST https://taotoken.net/api/v1/chat/completions说明 TaoToken 入口已经生效。如果看到的是其他域名,或者出现/api/v1/v1/,就要回到环境变量和客户端初始化处排查。调用记录是评估脚本可复现的第一手证据,不要把 Key 写进代码,也不要把真实 Key 提交到仓库。
2. OpenAI SDK 接入 TaoToken:最小改动与 curl 对照
评估脚本通常用 OpenAI 兼容接口,改动量很小:只换base_url和api_key。推荐从环境变量读取,避免硬编码。下面这段 Python 可以直接在本地运行,调用一次聊天补全,并打印request_id、模型名和 token 用量。
import os from openai import OpenAI client = OpenAI( api_key=os.environ["OPENAI_API_KEY"], base_url=os.environ.get("OPENAI_BASE_URL", "https://taotoken.net/api"), ) resp = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "ping"}], temperature=0, ) print("request_id:", resp.id) print("model:", resp.model) print("usage:", resp.usage)运行前先导出变量:
export OPENAI_BASE_URL="https://taotoken.net/api" export OPENAI_API_KEY="YOUR_API_KEY" python openai_ping.py如果你更喜欢用 curl 做最小验证,可以用下面命令。注意 curl 需要显式写全路径,因为 curl 不会像 SDK 那样帮你拼接。
curl -sS https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "ping"}], "temperature": 0 }' | jq .返回体里通常包含这些字段:
{ "id": "chatcmpl-xxxxxxxx", "object": "chat.completion", "model": "gpt-4o-mini", "usage": { "prompt_tokens": 8, "completion_tokens": 1, "total_tokens": 9 } }调用日志对照时,重点看三件事:请求 URL 是否指向https://taotoken.net/api,Authorization是否使用Bearer YOUR_API_KEY,返回的id是否能和本地记录一一对应。Key 建议在 TaoToken 控制台新建,入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=get_api_key ,创建后立即复制保存,不要复用官方 Key,也不要把 Key 贴在聊天记录或 issue 里。
3. Claude Code 的 settings.json 与 ANTHROPIC_* 三件套
Claude Code 的配置体系和 OpenAI SDK 不同,它读的是ANTHROPIC_*环境变量。很多人把 OpenAI 的OPENAI_BASE_URL套到 Claude Code 上,结果怎么都不生效。正确做法是在settings.json里写清楚三件套:ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL。如果客户端版本同时识别ANTHROPIC_API_KEY,也可以一起保留,但不要只写 OpenAI 那套。
用户级配置可以放在~/.claude/settings.json,项目级配置可以放在项目根目录.claude/settings.json。项目级优先级更高,适合评估脚本这种需要固定端点的场景。
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_API_KEY": "YOUR_API_KEY", "ANTHROPIC_MODEL": "claude-3-5-sonnet-latest" } }这里有一个细节:ANTHROPIC_BASE_URL不要带/v1。Claude Code 内部会按 Anthropic 接口规范拼接路径。如果你写成https://taotoken.net/api/v1,容易出现 404 或路径重复。配置完成后,用下面的命令验证启动环境:
claude --version claude进入交互界面后,可以用/status查看当前 API 端点。如果状态里显示的 Base URL 不是https://taotoken.net/api,优先检查 shell 里有没有旧的ANTHROPIC_BASE_URL覆盖了配置文件。环境变量优先级通常高于部分配置文件,建议在启动 Claude Code 的终端里执行env | grep ANTHROPIC确认。
如果你用 CC Switch 管理多套配置,建议维护成三组:TaoToken 远程配置、本地默认配置、离线测试配置。每组只改三个值:Base URL、API Key、模型别名。切换后不要只重启终端,最好新开一个 shell,避免旧环境变量残留。CC Switch 三件套的本质不是某个插件魔法,而是把ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL分离管理,减少手改配置文件带来的串环境问题。
再用 curl 直接验证 Anthropic 风格接口:
curl -sS https://taotoken.net/api/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-3-5-sonnet-latest", "max_tokens": 64, "messages": [{"role": "user", "content": "ping"}] }' | jq .如果返回 401,先确认x-api-key使用的是YOUR_API_KEY对应的真实 Key;如果返回 404,检查 Base URL 是否误写成https://taotoken.net/api/v1;如果返回模型不存在,去模型对话页确认可用模型名。Claude Code 的完整配置可以对照文末的官方文档入口,一步一步核对。
4. Codex 的 config.toml:为什么不能套 ANTHROPIC_*
Codex 使用config.toml,不是settings.json,也不能把ANTHROPIC_*环境变量套过来。Codex 的模型供应商配置通常放在~/.codex/config.toml,通过model_provider指定当前使用哪个 provider。下面是一个最小可复制示例,把 TaoToken 配成一个自定义 provider。
model = "gpt-4o-mini" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat"然后在 shell 里导出 Codex 使用的 Key。注意变量名要和env_key一致,不要写成ANTHROPIC_API_KEY。
export TAOTOKEN_API_KEY="YOUR_API_KEY" codex --config ~/.codex/config.toml如果 Codex 启动后报provider not found,检查model_provider的值是否和[model_providers.taotoken]一致,大小写和连字符都要对齐。如果报 401,检查env_key对应的环境变量是否真的导出成功:
printenv TAOTOKEN_API_KEY如果报路径错误,检查base_url是否写成了https://taotoken.net/api/v1。Codex 和 Claude Code 的配置体系不同,混用ANTHROPIC_*只会让排查更乱。评估脚本里如果同时跑 OpenAI SDK、Claude Code、Codex,建议按工具分文件:OpenAI 用.env,Claude Code 用settings.json,Codex 用config.toml,每个文件只放自己那套变量。
5. 调用日志对照:request_id、usage 与本地 JSONL
评估脚本的价值在于可复现,而可复现的前提是调用日志完整。不要只把结果打印到屏幕,建议每次调用都追加写入本地call_log.jsonl。下面脚本在调用成功后记录时间、延迟、request_id、模型名、token 用量和实际 Base URL。
import json import os import time from openai import OpenAI client = OpenAI( api_key=os.environ["OPENAI_API_KEY"], base_url=os.environ.get("OPENAI_BASE_URL", "https://taotoken.net/api"), ) def call_once(prompt: str): t0 = time.time() resp = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], temperature=0, ) usage = resp.usage.model_dump() if hasattr(resp.usage, "model_dump") else dict(resp.usage) record = { "ts": time.time(), "latency_ms": int((time.time() - t0) * 1000), "request_id": resp.id, "model": resp.model, "usage": usage, "base_url": str(client.base_url), } with open("call_log.jsonl", "a", encoding="utf-8") as f: f.write(json.dumps(record, ensure_ascii=False) + "\n") return record if __name__ == "__main__": print(call_once("ping"))运行后可以用 jq 快速查看:
jq -c '{ts, latency_ms, request_id, model, usage}' call_log.jsonl对照 OpenAI API 调用记录时,重点比对request_id是否连续、base_url是否稳定指向https://taotoken.net/api、usage是否和账单或控制台统计一致。如果base_url字段显示的是其他地址,说明客户端初始化时被旧环境变量污染。评估脚本并发跑任务时,建议给每条日志加上run_id,这样即使多个脚本同时写同一个 JSONL,也能按批次过滤。
record["run_id"] = os.environ.get("RUN_ID", "local-dev")本地日志不要记录完整 Key,也不要记录用户隐私数据。只保留request_id、模型、延迟、token 数就足够做入口核对和成本估算。
6. 评估脚本可复现:环境变量、并发与错误分支
红队评估脚本往往需要批量调用,常见错误分支包括 401、403、404、429 和 5xx。不要把所有异常都当成网络问题,按状态码分类处理更高效。
import os import time from openai import OpenAI, APIStatusError, APIConnectionError, RateLimitError client = OpenAI( api_key=os.environ["OPENAI_API_KEY"], base_url=os.environ.get("OPENAI_BASE_URL", "https://taotoken.net/api"), ) def safe_call(prompt: str, retries: int = 3): for i in range(retries): try: return client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], temperature=0, ) except RateLimitError: time.sleep(2 ** i) except APIStatusError as e: if e.status_code in (401, 403): raise RuntimeError("检查 API Key 是否来自 TaoToken 控制台,且未混用官方 Key") from e if e.status_code == 404: raise RuntimeError("检查 Base URL 是否为 https://taotoken.net/api,且模型名可用") from e if e.status_code >= 500: time.sleep(1 + i) else: raise except APIConnectionError: time.sleep(1 + i) raise RuntimeError("重试耗尽")并发方面,评估脚本不要一上来就开几百个线程。先用 2 到 4 个并发跑通,再根据 429 情况调整。每个任务记录开始时间、结束时间和状态码,输出到本地 CSV 或 JSONL。所有命令都在本地执行,不连接生产库,也不要把脚本挂到数据库上直连。如果评估对象包含 SQL 或系统命令,只生成待执行文本,由读者在隔离环境手动执行。
7. 常见报错排查清单:401、404、429 与配置优先级
下面这张清单可以直接贴在排查笔记里。遇到问题时按顺序检查,比反复重启更有效。
- 401 invalid api key:
YOUR_API_KEY没有替换成真实 Key,或者混用了官方 Key。去 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=cta_api_keys 重新创建。 - 404 not found:Base URL 多写了
/v1,或者模型名不存在。Base URL 应为https://taotoken.net/api,模型名去模型对话页确认。 - 400 bad request:请求体字段不合法,或者路径重复导致服务端无法解析。
- 429 rate limit:并发过高或短时间请求过多。降低并发,增加指数退避。
- Claude Code 不生效:检查
~/.claude/settings.json和项目级.claude/settings.json的优先级,检查终端里是否残留旧的ANTHROPIC_BASE_URL。 - Codex 不生效:检查
~/.codex/config.toml里的model_provider、env_key、base_url三处是否一致,不要套ANTHROPIC_*。 - 调用记录里 base_url 不对:在代码里打印
str(client.base_url),确认没有默认值覆盖环境变量。 - Key 泄露风险:不要把真实 Key 写入脚本、提交到 Git、粘贴到公开渠道。使用环境变量或本地密钥管理。
配置优先级可以用一句话记住:命令行临时变量 > 项目级配置 > 用户级配置 > 默认值。排查时先看当前 shell 里有哪些相关变量:
env | grep -E "OPENAI|ANTHROPIC|TAOTOKEN|CODEX"如果输出里同时出现多套 Base URL,优先清理旧变量,再新开终端复现。评估脚本的入口问题,九成以上都出在环境变量混用和 Base URL 路径重复上。
8. 文末路径:模型对话 → Coding Plan → 创建 Key → Claude Code 文档
如果你已经能把 OpenAI SDK、Claude Code、Codex 的调用记录跑通,下一步就是按实际用量选择入口。建议顺序如下:
- 先到模型对话页确认可用模型和响应效果:https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=cta_chat
- 如果需要长期跑评估脚本或 Coding 任务,查看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=cta_coding_plan
- 在控制台创建新的 API Key,替换本文中的
YOUR_API_KEY:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=cta_api_keys - Claude Code 用户对照官方文档检查
settings.json和ANTHROPIC_*三件套:https://taotoken.net/doc/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=cta_claude_code_doc
所有配置的 Base URL 都保持为https://taotoken.net/api,不要在末尾追加/v1。Key 统一使用YOUR_API_KEY占位符,复制后只放在本地环境变量或未提交的配置文件中。官网入口再放一次,方便新建凭据时直接进入:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=final_cta 。把调用记录、curl 命令和本地 JSONL 对照起来,TaoToken 入口是否生效就不再靠猜,评估脚本也能稳定复现。