浏览器能打开 API 主机,官方 SDK 仍可能超时,因为它们不读同一处代理设置。2026-10-27 核对的是 openai 3.39.0、anthropic 2.3.0、google-genai 2.33.0 和 Node 上的 openai 7.45.0。下面只写文档和源码里能对上的字段。
OpenAI、Anthropic 和 Google 都没有把中国大陆列为这些 API 的支持地。2026-10-27,ChatGPT 支持国家页的可见名单里有 Taiwan,没有看到 China、Hong Kong、Macau;页面写明名单外访问或提供访问可能导致封锁或暂停。Anthropic 支持地区政策页的生效日仍是 2026-11-12,当天名单同样没有中国大陆。Gemini API 的 available regions 当天能搜到 Taiwan,搜不到 Mainland China、Hong Kong、Macau、Macao 或 China 这几个字符串;这不是对整页名单的逐项校对。名单外调用可能违反条款并导致密钥被停用。把 base_url 改到非官方主机,请求就不再发往原厂,也不能取得地区资格,不在本文范围内。不要使用他人的密钥或支付卡。
先看变量有没有被进程读到
下面只打印「有没有设置」,避免把带口令的代理地址打出来:
python3 - <<'PY'
import os
names = [
"http_proxy", "https_proxy", "all_proxy", "no_proxy",
"HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "NO_PROXY",
]
for name in names:
print(f"{name}={'set' if os.environ.get(name) else 'unset'}")
PY
发布日期来自当天的 GitHub Releases:openai 3.39.0 与 npm 上的 openai 7.45.0 是 2026-10-26,anthropic 2.3.0 是 2026-10-23,google-genai 2.33.0 是 2026-10-22。本文没有用密钥发起生成请求,也没有在大陆宽带上复测。
| 客户端 | 2026-10-27 核对到的读法 | 超时单位 |
|---|---|---|
| curl | 手册:小写优先;http_proxy 只有小写。NO_PROXY 即使写了 --proxy 也会绕过名单内主机 | 秒,--max-time |
| OpenAI Python 3.39.0 | 默认 HTTP 层是 HTTPX2。环境变量页列出大写的 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY、NO_PROXY。默认客户端没有把 trust_env 设成 False | 秒。默认 10 分钟,连接 5 秒 |
| OpenAI Node 7.45.0 | README 没有写自动读取 HTTPS_PROXY,而是传入 undici 的 ProxyAgent | 毫秒。默认 10 分钟 |
| Anthropic Python 2.3.0 | 默认客户端用 urllib.request.getproxies()。Python 文档:先大小写不敏感地扫描 *_proxy,没有再看 macOS 系统配置和 Windows 注册表 | 秒。默认 10 分钟,连接 5 秒 |
| google-genai 2.33.0 | README 写在创建客户端前设置 HTTPS_PROXY。默认依赖是 httpx,httpx2 是可选额外项 | HttpOptions.timeout 的文档单位是毫秒 |
端口 8080 只代表你本机已经在听的那个入站,不是某一种产品的固定端口。下面的地址都写成 http://127.0.0.1:8080,请换成你自己的端口。不要把用户名和口令写进仓库。
curl 的小写和 SDK 的大写不是同一套
2026-10-27 打开的 curl 手册 写明:环境变量大小写都可以,小写优先;http_proxy 是例外,只有小写。用环境变量指定代理,效果与 --proxy 相同。NO_PROXY 里的主机会直接连接,即使命令行写了 --proxy。手册页眉没有给出一个 curl 版本号,你机器上的行为以 curl --version 为准。
不带密钥、并显式指定代理时,可以看主机有没有返回 HTTP 状态。2026-10-27 没有重放这条命令。2026-10-26 的 支付排查 在起草环境里对无密钥的模型列表看到过 HTTP 401。那是认证失败,不是「代理没连上」。你这边若是超时或重置,先记成没有到达;若已经有 401 或 403,按那篇文章对照,不要再改端口。
curl -sS -D - -o /dev/null --max-time 20 \
--proxy "http://127.0.0.1:8080" \
https://api.openai.com/v1/models
--proxy 只作用于这一条命令。它不能证明稍后启动的 Python 进程读到了同名变量。
OpenAI Python:默认十分钟,read 是两块数据之间
v3.39.0 的 README 写默认请求在 10 分钟后超时,并给出:
import httpx2
from openai import OpenAI
client = OpenAI(
timeout=httpx2.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
)
源码里的 DEFAULT_TIMEOUT 是 httpx2.Timeout(timeout=600, connect=5.0)。同一 README 写明,超时抛出 APITimeoutError,请求超时默认再重试 2 次。流式消费是例外:读取超时抛 APITimeoutError,其它 HTTPX 失败抛 APIConnectionError,而且流式消费不会自动重试,因为重放可能把已经输出的内容再生成一次。
HTTPX2 超时说明 把 read 定义成等待下一块数据的最长时间,例如响应体的一块。上面示例里的 read=5.0 意味着两块数据之间如果超过 5 秒,客户端会自己中断。这看起来像「回复写到一半停了」,异常类型却是超时,不是地区拒绝。默认的 10 分钟更宽松。把 read 改短只适合你确认上游会在这个间隔内持续送出数据的时候。
显式代理写在 README 的自定义客户端里:
from openai import OpenAI, DefaultHttpx2Client
client = OpenAI(
http_client=DefaultHttpx2Client(
proxy="http://127.0.0.1:8080",
),
)
DefaultHttpx2Client 的源码只补了超时、连接数和 follow_redirects,没有把 trust_env 设成 False。HTTPX2 环境变量页写:默认使用环境变量,要忽略就设 trust_env=False。因此未传入自定义客户端时,应按那一页的大写变量理解。本文没有在 Linux 上试验小写 https_proxy 能否被这份 SDK 读到。环境变量页也没有写 Windows 注册表。
密钥放在环境变量里,不要写进命令行。连接失败时没有 HTTP 状态码;有状态码时,401 与 403 的差别见 支付排查。
Node 官方包要自己传入代理
openai@7.45.0 的 README 把默认超时写成 10 分钟,示例是 timeout: 20 * 1000,单位是毫秒。超时抛 APIConnectionTimeoutError,请求超时默认重试 2 次。同一篇的代理示例是:
import OpenAI from 'openai';
import { fetch, ProxyAgent } from 'undici';
const proxyAgent = new ProxyAgent('http://127.0.0.1:8080');
const client = new OpenAI({
fetch,
fetchOptions: {
dispatcher: proxyAgent,
},
});
README 写明:dispatcher 这类 undici 选项必须配上同一套 fetch。只导出 HTTPS_PROXY、仍使用 Node 自带的 fetch,不在这段示例里。
Node.js CLI 文档 写:NODE_USE_ENV_PROXY=1 自 v22.21.0 和 v24.0.0 加入,稳定性为 1.1(仍在开发)。打开后,Node 在启动时解析 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY。同一页写明,这是给受信任的代理使用的,例如防火墙要求经过某台代理;不是用来隐藏流量或规避网络政策。本文没有用 openai@7.45.0 实际发出请求,因此不能断定打开这个开关后,SDK 内部的 fetch 就一定走该代理。可复现的写法仍是 README 里的 ProxyAgent。
@anthropic-ai/sdk@1.3.0 的 README 在 2026-10-27 只有安装、入门和 OpenTelemetry 等节,没有代理示例。它把完整文档指到 TypeScript SDK 文档。本文没有从那一页摘出代理参数,发布前若要写 Node 上的 Anthropic 客户端,应打开该页核对,不要把 OpenAI 的 fetchOptions 原样套过去。
Anthropic Python 会在没有变量时看系统代理
v2.3.0 的默认客户端在未传入 transport 时,用 urllib.request.getproxies() 组装代理,再挂到自己的 HTTPTransport 上。源码注释写:这样设置默认 transport 后,HTTPX 不会再自动配置代理。因此你再传入自己的 http_client 或 transport 时,走的是那个客户端的设置,不再是这段环境变量逻辑。
Python 文档 对 getproxies() 的说明是:对所有操作系统都先大小写不敏感地查找 <scheme>_proxy;找不到,再在 macOS 上读系统配置,在 Windows 上读注册表里的 Internet Settings。大小写同时存在且不一致时,优先小写。若环境里有 REQUEST_METHOD,大写的 HTTP_PROXY 会被忽略。这能解释一种分叉:Windows 上浏览器走系统代理时,Anthropic 的默认客户端可能跟着走,OpenAI 的 HTTPX2 环境变量页却没有写注册表。
SDK 自己的辅助函数里,no 代理名单包含 * 时直接返回空映射,也就是不使用代理。NO_PROXY 如果宽到盖住 api.anthropic.com,调用会直连。先看上一节脚本里的 no_proxy 有没有被设置。
默认超时同样是 10 分钟、连接 5 秒。非流式调用在预计超过 10 分钟时,源码抛出 ValueError,原文是 “Streaming is required for operations that may take longer than 10 minutes.”,并指向 Python SDK 文档的 long requests 一节。这是客户端在发请求前就拒绝,不是 HTTP 504。流式写法见 Claude API 流式文档。地区资格仍以 支持地区 为准,改成流式不能改变名单。
默认客户端还会在平台提供相应常量时打开 SO_KEEPALIVE,并把 TCP_KEEPINTVL、TCP_KEEPIDLE 设为 60、TCP_KEEPCNT 设为 5。这些数字来自 v2.3.0 源码,只说明套接字保活如何设置,不能让中间网络保留它已经丢掉的连接。空闲断开的查法见 VPN 保活与掉线重连。
Gemini:文档里的超时是毫秒
google-genai 2.33.0 的 pyproject 默认依赖 httpx,httpx2 放在可选额外项里。源码里的 GOOGLE_GENAI_HTTP_CLIENT:设为 httpx 或 httpx2 时用对应实现;auto 或未设置时,安装了 httpx 就用 httpx,否则才用 httpx2。README 仍把默认实现写成 httpx,并写明在 SDK 里把 trust_env 配成 True。源码里 aiohttp 会话显式写了 trust_env=True。本文没有看到把 httpx 的 trust_env 设成 False 的那一行。
README 的代理步骤是在创建客户端之前:
export HTTPS_PROXY='http://127.0.0.1:8080'
HttpOptions.timeout 的字段说明是「请求超时,单位毫秒」。源码里的换算是除以 1000 再交给 httpx。没有设置 HttpOptions.timeout 时,换算结果是 None;构造客户端时,若 client_args 里没有 timeout,源码会放上 None。已核对的 HTTPX2 超时页把 timeout=None 写成关闭超时。这份 SDK 的默认安装是 httpx,不是 httpx2,httpx 同一参数的页面本文没有另开核对,所以不能把 HTTPX2 那一句直接写成 httpx 的行为。你自己写成 timeout=10000 时,按字段说明是 10 秒,不是 10 分钟。和 OpenAI Python 的「秒」放在一起时最容易设错。
README 还写了用 client_args={'proxy': 'socks5://...'} 配 SOCKS,并让读者安装 httpx[socks]。那是在说明 httpx 的参数,不是推荐某个 SOCKS 服务。地区字符串的检索结果见开头;网页和 API 不是同一份名单,见 地区报错和注册。
公开文件里的法律范围
《关于清理规范互联网网络接入服务市场的通知》(工信部信管函〔2017〕32号)写明,未经电信主管部门批准,不得自行建立或租用专线(含 VPN)等其他信道开展跨境经营活动。2017 年 1 月 24 日的答记者问说明,对象是无国际通信业务经营资质而开展跨境电信业务经营的企业或个人。本文不判断某种个人使用是否违法,也不写规避执法的做法。2026-10-27 没有重新打开部委网页。
一次超时至少留下这三项
- 包名和版本:例如
openai==3.39.0。Node 还要记下process.version,因为NODE_USE_ENV_PROXY与版本有关。 - 异常类名:
APITimeoutError、APIConnectionError、APIConnectionTimeoutError,或 Anthropic 那句要求改用流式的ValueError。有 HTTP 状态码就记下状态码和请求 ID。 - 上一节脚本里哪些变量是 set。值里若有口令,不要把值写进问题记录。然后用同一出口上的 curl 看主机是否返回 HTTP 状态,把进程没读到代理,和代理读到了但主机拒绝,分成两行记下。