Claude国内使用和中转站系列第 24 / 24 篇

同一组测试跑两遍:直连 Claude 官方接口和通过中转站,到底差在哪

同一个脚本,对着 Claude 官方接口和一家中转站各跑两遍,三十多项逐条对照:官方会拒绝的写法里有八种中转站放行,几样功能中转站用不了或悄悄忽略,数 token、缓存、响应头和报错格式也不一样。附脚本,能对着你自己的那一家跑。

发布 · 约 17 分钟读完 · 经人工审核()· 本站的内容怎么来的

本站已实测,测试日期:2026-10-15。

本页目录(12 节)
  1. 先说结论
  2. 一、总表
  3. 二、官方会拒绝的写法:在中转站上测不出来
  4. 三、中转站用不了或者悄悄忽略的
  5. 四、数字对不上的
  6. 五、报错长得不一样
  7. 六、中转站自己也在变
  8. 七、对照脚本
  9. 八、写程序时的几条习惯
  10. 和 Claude Code 的关系
  11. 花费
  12. 这次实测没有覆盖到的

这篇教程解决一个问题:我的代码通过中转站跑得好好的,换一家、或者换成直连官方,会不会出问题?反过来,官方文档里写的功能,在中转站上是不是都能用?

本站的 Claude API 系列,大部分是通过酷站AI 中转站实测的。《通过中转站用 Claude API》那篇已经汇总过出入,但当时没有官方的 key,“官方”那一栏只能写文档怎么说。这周用 Max 套餐每月赠送的 API 额度拿到了官方的 key,于是把同一个脚本对着两边各跑了两遍,逐条对照。

实测环境
日期 2026-10-15
官方 api.anthropic.com,一把 Console 里建的 API key,用的是 Max 套餐每月赠送的额度
中转站 酷站AI,一把有额度上限的 key
模型 Sonnet 5.5
方式 同一个只用 Python 标准库的脚本(文末附全文),两边各跑两遍,两遍的结论一致

先说结论

  • 官方文档说会被拒绝的九种写法,官方确实全部返回 400,中转站放行了其中八种。 在中转站上能跑通的代码,换到官方可能直接报错。这是最该注意的一条,见第二节。
  • 有几样功能中转站用不了,或者返回 200 却没有生效。 抓取网页、代码执行、按需压缩、停止序列、文件和批量接口、Agent Skills、托管智能体,官方都正常。
  • 数字也不一样。 数 token 的接口在官方一个不差,在中转站差了一倍多;不带 metadata.user_id 时中转站的缓存不命中,官方照常命中。
  • 报错和响应头的格式不一样,依赖这些写的代码要留意。
  • 日常的请求两边一致:发消息、流式、工具调用、结构化输出、base64 的图片、联网搜索。

一、总表

“官方”和“中转站”两栏都是这次实测看到的。

基本的请求和响应

项目 官方 中转站
发消息 200 200
流式 正常,以 message_stop 结束 一样
三次请求的耗时中位数 约 1.1 秒 约 2.8 到 3.2 秒
request-id 响应头 有 没有,有一个中转站自己的 x-request-id
限流的响应头 12 个 一个也没有
模型列表 14 个,每条有 11 个字段:能力、上下文上限、下线时间等 16 个,每条只有 ID 等 4 个字段
查单个模型 200 404

耗时和测试机所在的网络位置关系很大,这里只说明在本站这台服务器上是这样,不能拿来比两家的快慢。

官方文档说会被拒绝的写法

写法 官方 中转站
不带 max_tokens 400 400(10 月 13 日测时是 503,见第六节)
预填:最后一条消息是 assistant 400 200
Sonnet 5.5 把 thinking 设成 disabled 400 200
temperature 设成 0.5 400 200
工具名带点号 400 200
工具名用中文 400 200
工具结果前面放一段文字 400 200
工具调用之后,下一条消息没有回结果 400 200,模型又调了一次工具
旧参数 output_format 400 200,返回普通文字

常用功能

项目 官方 中转站
工具调用 200,tool_use 一样
结构化输出(output_config.format) 拿到合规的 JSON 一样
图片,base64 200 200
图片,网址 200 400
停止序列 生效 不生效,照常输出完
一道要动脑的题,开自适应思考 有思考块,带签名 也有思考块,带签名
按需压缩 返回一个压缩块,stop_reason 是 compaction 参数被忽略,照常回答
到阈值自动压缩的策略 被接受 400

数字

项目 官方 中转站
同一句话,数 token 的接口说 23 21
同一句话,真实请求计的输入 23 51
不标 cache_control 的普通请求 不写缓存,不读缓存 一样
同一段系统提示连发 4 次,不带 metadata.user_id 第 1 次写,后 3 次都读到 4 次都在写,一次也没读到
同上,带固定的 user_id 和不带一样 后 3 次读到,每次还多写 19 个 token 的缓存

在 Anthropic 那边执行的工具

工具 官方 中转站
联网搜索 200,有搜索的内容块 一样
抓取网页 200,有抓取的内容块 400
代码执行 200,有代码执行的结果块 200,但没有任何工具的内容块:被忽略了

消息接口以外

接口 官方 中转站
文件 200 404
批量 200 404
skills 200 404
托管智能体(列环境) 200 404

这几样在官方上怎么用,这周都补测过,写进了各自的文章:文件和批量、Agent Skills、托管智能体的入门、环境和数据、多智能体。另外两处这周查到的差别也在别的文章里:浏览器工具集的结果里带一个 browser_state 块,中转站不认,见《用 SDK 的工具集类让 Claude 操作浏览器》;Claude Code 的 advisor 用令牌接中转站时打不开,用官方的 key 能用,见《advisor 工具》。

二、官方会拒绝的写法:在中转站上测不出来

上面第二张表是这次最有用的结果。这些写法大多在文档里有明确的出处:Sonnet 5.5 的迁移指南列了五种会返回 400 的设置(思考预算、采样参数、预填、强制选工具、关掉思考),工具名有一条正则(只能是字母、数字、下划线和连字符),工具结果必须紧跟在工具调用后面、并且放在消息的最前面。

官方确实一条条都拒绝了。中转站除了“不带 max_tokens”,其余八种都放行,返回 200,有的还给出了一段看起来正常的回答。

这意味着:

  • 在中转站上测试全过,不等于代码写对了。 哪天换成直连官方,或者换一家校验严格的中转站,同一份代码会直接报 400。
  • 升级模型的时候最容易踩。 迁移指南里“这一代开始拒绝”的那些写法,通过这家中转站一个也测不出来,见《升级到 5.5 的清单》。
  • 按官方的规则写代码。 每个工具调用都回结果,结果放在消息最前面,工具名只用字母、数字、下划线和连字符,不用预填,Sonnet 5.5 和 Opus 5.5 不设采样参数。

三、中转站用不了或者悄悄忽略的

直接报错的(400、404)好办,第一次跑就知道。要小心的是返回 200、功能却没发生的那几样:

请求里带了什么 中转站上实际发生的 怎么发现
代码执行工具 没有任何工具的内容块 检查响应里有没有代码执行的结果块
按需压缩 照常回答,没有压缩块 检查 stop_reason 是不是 compaction
停止序列 没在序列处停 检查 stop_reason 是不是 stop_sequence
旧参数 output_format 返回普通文字 解析 JSON 失败时查一下参数名

这几样在官方上都按文档工作。所以在中转站上写程序,不要只看状态码,要看响应里有没有你期望的那个东西。这条习惯在官方上也该有,换接口时更是必须。

四、数字对不上的

数 token 的接口。 官方文档说它给的是估算,可能差一点。实测官方一个不差:接口说 23,真实请求计了 23。中转站接口说 21,真实请求计了 51,多出来的这一截本站分不清来源。所以通过中转站,估算花费要看真实响应里的 usage,别看这个接口。

提示缓存。 官方不带 metadata.user_id 也照常命中:第一次写,之后每次都读。中转站不带的话一次都读不到,每次都按写缓存的价付钱;带上固定的 user_id 才命中,而且每次还多写 19 个 token 的缓存。通过这家中转站写程序,一场对话里的请求要带同一个 user_id,提示缓存那一篇里有更多测试。

响应头。 官方每个响应都有 request-id 和 12 个限流的响应头,可以读着它们主动放慢;中转站一个也没有,只能等 429 来了再退避。要找中转站查某一次请求,记下它的 x-request-id。

五、报错长得不一样

模型名写错时,两边都是 404,SDK 抛的异常类不会分错。细节不同:

官方 中转站
error.type not_found_error 中转站自己起的类型名
消息 英文 中文
响应体里的 request_id 有 没有
路径写错时 404,JSON 404,不是 JSON

判断出了什么错,看 HTTP 状态码或者 SDK 的异常类,不要匹配 error.type 的字符串。 不然换个接口,判断就失效了。

六、中转站自己也在变

“不带 max_tokens”这一项,10 月 13 日测这家中转站时返回的是 503,这次是 400,和官方一致了。中转站的行为会随它的版本变,今天的这张表过一阵就不一定准。换中转站、升级模型、或者隔一段时间,把下面的脚本再跑一遍。

七、对照脚本

这个脚本在《通过中转站用 Claude API》那个自测脚本的基础上,加了官方会拒绝的那几种写法、报错的样子、缓存每次的读写数字和消息接口以外的几个接口。只用 Python 标准库,不打印 key 和请求头。不设 ANTHROPIC_BASE_URL 时请求发到官方;设了就发到那个地址。

"""官方和中转站对照:同一组请求对着一个接口地址跑一遍。只用标准库,不打印 key 和请求头。
不设 ANTHROPIC_BASE_URL 时发到官方。"""
import base64, json, os, statistics, struct, time, urllib.error, urllib.request, zlib

BASE = (os.environ.get("ANTHROPIC_BASE_URL") or "https://api.anthropic.com").rstrip("/")
KEY = os.environ.get("ANTHROPIC_API_KEY") or os.environ["ANTHROPIC_AUTH_TOKEN"]
MODEL = "claude-sonnet-5-5"
HDR = {"x-api-key": KEY, "anthropic-version": "2023-06-01", "content-type": "application/json", "user-agent": "compare/1"}

def call(path, body=None, beta=None, method=None):
    h = dict(HDR)
    if beta:
        h["anthropic-beta"] = beta
    req = urllib.request.Request(BASE + path, data=json.dumps(body).encode() if body is not None else None, headers=h, method=method)
    t0 = time.time()
    try:
        with urllib.request.urlopen(req, timeout=180) as r:
            code, text, hd = r.status, r.read().decode("utf-8", "replace"), dict(r.headers)
    except urllib.error.HTTPError as e:
        code, text, hd = e.code, e.read().decode("utf-8", "replace"), dict(e.headers)
    try:
        parsed = json.loads(text)
    except ValueError:
        parsed = {"_raw": text[:80]}
    return code, parsed if isinstance(parsed, dict) else {}, {k.lower(): v for k, v in hd.items()}, time.time() - t0

def msg(content, beta=None, **f):
    return call("/v1/messages", {"model": MODEL, "max_tokens": 200, "messages": [{"role": "user", "content": content}], **f}, beta)

def brief(code, body):
    if code != 200:
        e = body.get("error") if isinstance(body.get("error"), dict) else {}
        return f"HTTP {code}({e.get('type') or '不是官方的报错格式'})"
    return f"HTTP 200,stop_reason={body.get('stop_reason')}"

def text_of(body):
    return "".join(b.get("text", "") for b in body.get("content", []) if b.get("type") == "text")

def row(name, result):
    print(f"{name}:{result}", flush=True)

def png(size=64):
    def chunk(tag, data):
        return struct.pack(">I", len(data)) + tag + data + struct.pack(">I", zlib.crc32(tag + data))
    px = b"".join(b"\x00" + b"\xff\x00\x00" * size for _ in range(size))
    return b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", size, size, 8, 2, 0, 0, 0)) + chunk(b"IDAT", zlib.compress(px)) + chunk(b"IEND", b"")

print("接口:", "官方" if "anthropic.com" in BASE else "中转站", flush=True)

# 一、基本
times = []
for _ in range(3):
    code, body, hd, dt = msg("只回答两个字:你好", max_tokens=30)
    times.append(dt)
row("基本请求", brief(code, body))
row("三次的耗时中位数", f"{statistics.median(times):.2f} 秒")
row("响应头", f"request-id {'有' if 'request-id' in hd else '没有'};限流头 {sum(1 for k in hd if k.startswith('anthropic-ratelimit-'))} 个;"
    f"组织 ID {'有' if 'anthropic-organization-id' in hd else '没有'};x-request-id {'有' if 'x-request-id' in hd else '没有'}")
code, body, _, _ = call("/v1/models?limit=100")
data = body.get("data") or []
row("模型列表", f"HTTP {code},{len(data)} 个;每条的字段:{sorted(data[0].keys()) if data else '—'}")
code, body, _, _ = call(f"/v1/models/{MODEL}")
row("查单个模型", f"HTTP {code}" + (f",字段 {sorted(body.keys())}" if code == 200 else ""))
req = urllib.request.Request(BASE + "/v1/messages", data=json.dumps({"model": MODEL, "max_tokens": 30, "stream": True,
      "messages": [{"role": "user", "content": "只回答两个字:你好"}]}).encode(), headers=HDR)
try:
    with urllib.request.urlopen(req, timeout=180) as r:
        events = [line.decode().split(":", 1)[1].strip() for line in r if line.startswith(b"event:")]
    row("流式", "正常,以 message_stop 结束" if events[-1:] == ["message_stop"] else f"最后几个事件 {events[-3:]}")
except urllib.error.HTTPError as e:
    row("流式", f"HTTP {e.code}")

# 二、报错的样子
code, body, hd, _ = msg("hi", model="claude-no-such-model", max_tokens=10)
e = body.get("error") if isinstance(body.get("error"), dict) else {}
row("模型名写错", f"HTTP {code},type={e.get('type')};顶层 type={body.get('type')};有 request_id={'request_id' in body};消息是中文={any(ord(c) > 0x4e00 for c in str(e.get('message', '')))}")
code, body, _, _ = call("/v1/no-such-path", {"x": 1})
row("路径写错", f"HTTP {code},{'JSON' if '_raw' not in body else '不是 JSON'}")

# 三、官方文档说会拒绝的写法
code, body, _, _ = call("/v1/messages", {"model": MODEL, "messages": [{"role": "user", "content": "你好"}]})
row("不带 max_tokens", brief(code, body))
code, body, _, _ = call("/v1/messages", {"model": MODEL, "max_tokens": 30, "messages": [{"role": "user", "content": "你好"}, {"role": "assistant", "content": "你好,"}]})
row("预填(最后一条是 assistant)", brief(code, body))
row("thinking 设成 disabled", brief(*msg("你好", max_tokens=30, thinking={"type": "disabled"})[:2]))
row("temperature=0.5", brief(*msg("你好", max_tokens=30, temperature=0.5)[:2]))
weather = {"name": "get_weather", "description": "查某个城市现在的天气",
           "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}
row("工具名带点号", brief(*msg("上海天气?", max_tokens=50, tools=[{**weather, "name": "get.weather"}])[:2]))
row("工具名用中文", brief(*msg("上海天气?", max_tokens=50, tools=[{**weather, "name": "查天气"}])[:2]))
hist = [{"role": "user", "content": "上海天气?"},
        {"role": "assistant", "content": [{"type": "tool_use", "id": "toolu_compare01", "name": "get_weather", "input": {"city": "上海"}}]},
        {"role": "user", "content": [{"type": "text", "text": "结果如下:"}, {"type": "tool_result", "tool_use_id": "toolu_compare01", "content": "晴,20 度"}]}]
code, body, _, _ = call("/v1/messages", {"model": MODEL, "max_tokens": 60, "tools": [weather], "messages": hist})
row("工具结果前面放一段文字", brief(code, body))
hist2 = [hist[0], hist[1], {"role": "user", "content": [{"type": "text", "text": "继续"}]}]
code, body, _, _ = call("/v1/messages", {"model": MODEL, "max_tokens": 60, "tools": [weather], "messages": hist2})
row("工具调用没有回结果", brief(code, body))
row("旧参数 output_format", brief(*msg("中国的首都是哪里?", output_format={"type": "json_schema", "schema": {"type": "object", "properties": {"city": {"type": "string"}}}})[:2]))
code, body, _, _ = msg("从 1 数到 5,用逗号隔开,只输出数字。", max_tokens=40, stop_sequences=["3"])
row("停止序列", "生效" if body.get("stop_reason") == "stop_sequence" else f"没有生效({brief(code, body)})")

# 四、常用功能
row("工具调用", brief(*msg("上海现在天气怎么样?", tools=[weather])[:2]))
schema = {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], "additionalProperties": False}
code, body, _, _ = msg("中国的首都是哪里?", output_config={"format": {"type": "json_schema", "schema": schema}})
try:
    ok = "city" in json.loads(text_of(body))
except ValueError:
    ok = False
row("结构化输出", "拿到了合规的 JSON" if ok else brief(code, body))
row("图片,base64", brief(*msg([{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": base64.b64encode(png()).decode()}}, {"type": "text", "text": "什么颜色?"}])[:2]))
row("图片,网址", brief(*msg([{"type": "image", "source": {"type": "url", "url": "https://www.python.org/static/img/python-logo.png"}}, {"type": "text", "text": "什么颜色?"}])[:2]))
code, body, _, _ = msg("17 乘以 23 等于多少?只给数字。", max_tokens=2000, thinking={"type": "adaptive", "display": "summarized"}, output_config={"effort": "high"})
th = [b for b in body.get("content", []) if b.get("type") == "thinking"]
row("思考块和签名", f"{brief(code, body)};thinking 块 {len(th)} 个;签名长度 {[len(b.get('signature') or '') for b in th]}")

# 五、数字
q = "用一句话解释什么是提示缓存。"
c1, counted, _, _ = call("/v1/messages/count_tokens", {"model": MODEL, "messages": [{"role": "user", "content": q}]})
c2, real, _, _ = msg(q, max_tokens=60)
u = real.get("usage") or {}
billed = sum(u.get(k) or 0 for k in ("input_tokens", "cache_read_input_tokens", "cache_creation_input_tokens"))
row("数 token 的接口", f"接口说 {counted.get('input_tokens')},真实请求计了 {billed}(input {u.get('input_tokens')},缓存写 {u.get('cache_creation_input_tokens')},缓存读 {u.get('cache_read_input_tokens')})")
code, body, _, _ = msg(q, max_tokens=60)
u = body.get("usage") or {}
row("不标 cache_control 的普通请求", f"缓存写 {u.get('cache_creation_input_tokens')},缓存读 {u.get('cache_read_input_tokens')}")
RULES = "".join(f"第 {i} 条:回答 {1000 + i} 号仓库的问题时,先确认仓库编号和日期,再给库存数字,数字后面写单位,不确定的要说明来源。\n" for i in range(1, 41))
def cache(extra):
    tag = os.urandom(4).hex()
    system = [{"type": "text", "text": f"会话 {tag}。你是仓库助手,遵守下面的守则:\n{RULES}", "cache_control": {"type": "ephemeral"}}]
    out = []
    for i in range(4):
        _, b, _, _ = msg(f"{1001 + i} 号仓库有多少库存?一句话。", max_tokens=40, system=system, **extra)
        uu = b.get("usage") or {}
        out.append((uu.get("cache_creation_input_tokens") or 0, uu.get("cache_read_input_tokens") or 0))
        time.sleep(2)
    return f"后 3 次读到缓存 {sum(1 for w, r in out[1:] if r > 0)} 次;每次(写, 读)={out}"
row("提示缓存,不带 metadata", cache({}))
row("提示缓存,带固定的 user_id", cache({"metadata": {"user_id": "compare-" + os.urandom(4).hex()}}))

# 六、在 Anthropic 那边执行的工具
def server_tool(tool, question):
    code, body, _, _ = msg(question, max_tokens=800, tools=[tool])
    if code != 200:
        return brief(code, body)
    blocks = sorted({b["type"] for b in body.get("content", []) if b.get("type") not in ("text", "thinking")})
    return f"HTTP 200,内容块 {blocks}" if blocks else "HTTP 200,但没有工具的内容块:被忽略了"
row("联网搜索", server_tool({"type": "web_search_20250305", "name": "web_search", "max_uses": 1}, "搜索 Python 最新的稳定版本号,一句话回答。"))
row("抓取网页", server_tool({"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 1}, "抓取 https://example.com 并用一句话说它是什么。"))
row("代码执行", server_tool({"type": "code_execution_20250825", "name": "code_execution"}, "用代码执行工具算 2 的 100 次方的各位数字之和。"))

# 七、消息接口以外
for name, path in (("文件接口", "/v1/files"), ("批量接口", "/v1/messages/batches"), ("skills 接口", "/v1/skills"), ("托管智能体(列环境)", "/v1/environments")):
    beta = "managed-agents-2026-04-01" if "environments" in path else None
    row(name, f"HTTP {call(path, beta=beta)[0]}")

用法:

# 对着官方跑:只设官方的 key
export ANTHROPIC_API_KEY="你在 Console 里建的 key"
python3 compare.py

# 对着中转站跑:再设上中转站的地址,key 换成中转站的
export ANTHROPIC_BASE_URL="中转站的接口地址"
export ANTHROPIC_API_KEY="中转站的 key"
python3 compare.py

一遍有四十个左右的请求,大多很短,大头是缓存那两组和三个服务器端工具。官方那边跑一遍,按 Sonnet 5.5 的标价是几美分。

没有官方的 key 怎么办? Max 和 Team 套餐每月送一笔 API 额度,可以在 Console 里建 key,见那篇快讯。拿来跑这样一个对照,看看你常用的那家中转站和官方差在哪,很值。

八、写程序时的几条习惯

  1. 地址和 key 从环境变量读。 换中转站、换成直连,代码都不用改。
  2. 按官方的规则写请求。 第二节那九种写法都不要用,哪怕在你的中转站上能过。
  3. 看结果,不只看状态码。 工具有没有被调用、有没有在该停的地方停、JSON 能不能解析,都检查。
  4. 一场对话带同一个 metadata.user_id。 官方上不需要,但不影响;中转站上缓存靠它。
  5. 判断报错看状态码或异常类。
  6. 估花费看 usage,实际扣费看账单。

和 Claude Code 的关系

用 Claude Code 时,上面这些大多碰不到:它自己按官方的规则组织请求、自己带 user_id、自己管上下文。Claude Code 通过中转站有它自己的一组注意事项,见《通过中转站用 Claude Code》。

花费

两边各跑两遍,加上补充的几项,官方那边按 Sonnet 5.5 的标价估计合计约 0.2 美元,用的是 Max 套餐赠送的额度。中转站那边花的是测试用的那把 key 的额度。

这次实测没有覆盖到的

  • 只对照了一家中转站、一天。 别家的表现要自己跑;这一家以后也可能改,第六节就是例子。
  • 只用了 Sonnet 5.5。 别的模型上,官方会拒绝的写法不完全一样,以迁移指南为准。
  • 耗时只说明本站这台服务器上的情况,不能拿来比两家的快慢。
  • 限流没有触发过,两边 429 时的样子没有对照。
  • 扣费没有对照,中转站实际怎么计费,以它的账单为准。
  • 快速模式、MCP 连接器、工具搜索、程序化调用工具没有放进这次的对照,中转站上的情况见《通过中转站用 Claude API》。
  • 脚本只看“请求能不能过、功能有没有发生”,不看模型是不是它声称的那个。 那是另一件事,见《thinking signature 是什么》。

来源

通过 API 中转站使用这些模型?到 Veridrop 免费检测中转站给你的是不是它声称的模型,或者看看中转站排行榜前 100 名。

相关文章

  • 通过中转站用 Claude API:哪些功能能用,哪些不能,附一个自测脚本教程 · Claude Code · 约 20 分钟

    自己写程序调 Claude 的接口,走中转站时哪些功能和官方一样、哪些用不了、哪些看着成功其实没生效。本站把这个系列在一家中转站上实测到的出入汇成一张表,分成四类讲怎么应对,并给出一个 25 个请求的自测脚本,换成你的地址和 key 就能照着测一遍。

  • Claude Code 的网络和数据:代理怎么配,它实际连了哪些地方,你的代码和对话去了哪教程 · Claude Code · 约 10 分钟

    本站在代理后面跑 Claude Code,记下它实际连的主机:即使模型请求走中转站,一句话的工夫它还连了五次 api.anthropic.com;设一个环境变量后只剩中转站。附代理配错的三种表现(非交互模式下会一声不吭地卡两分钟以上)、证书和防火墙要放行的地址,以及对话和代码存在哪、存多久、哪些会被发出去。

  • Claude Code 常见报错怎么查:连不上、401、模型不可用、配置不生效教程 · Claude Code · 约 15 分钟

    报错分三类:装不上、请求报错、配置不生效。本站用假地址和假 key 把常见的请求报错逐个复现,记下原文和原因。两个容易误判的:接口地址多写一级 /v1,报的是“模型有问题”;settings.json 写坏了,claude -p 照常运行、没有提示。附 claude doctor、--debug 的用法。

  • 通过中转站用 Claude Code:哪些功能和直连一样,哪些不一样,出了问题怎么判断是谁的教程 · Claude Code · 约 12 分钟

    Claude Code 官方有一份写给网关的兼容性说明:哪些请求头和字段必须原样转发,漏了会坏什么。本站对照这份说明,在一家中转站上把十几项功能实测了一遍:大部分正常,遇到过三处不一样的地方,其中子代理换模型后主会话报 400 的一处,中转站已经修好。附判断问题出在哪一方的办法。