梯子
代码里调用 OpenAI、Claude API 怎么走代理:Python、Node.js 与服务器三种场景
浏览器能打开 ChatGPT 和 Claude,Python 或 Node.js 脚本调用 API 却超时?本文给出环境变量、requests、httpx、官方 SDK 自定义 HTTP 客户端和 undici ProxyAgent 的可运行写法,说明服务器上为什么优先选支持地区部署,以及 API Key 的保管方法。
简短回答
本地开发时,Python 的 requests、httpx 默认读取 HTTPS_PROXY 环境变量,设置好即可;Node.js 内置 fetch 通常不读,需要用 undici 的 ProxyAgent 设置全局代理。线上服务优先部署在 API 支持地区的服务器上,不再依赖本地梯子。
30 秒梯子选择器
回答 4 个问题:设备、用途、预算、流量,直接得到 3 个候选和理由。
为什么浏览器能用,代码却超时
客户端的“系统代理”主要给浏览器和部分桌面 App 用,你写的 Python、Node.js 程序不一定理会它,于是请求直接发往 api.openai.com 或 api.anthropic.com,在国内网络下表现为连接超时。解决思路分三种场景:本地脚本设置环境变量或在代码里显式指定代理;Node.js 额外处理内置 fetch;线上服务器尽量部署在 API 支持地区,不走代理。下文以 127.0.0.1:7890 举例,端口以客户端设置中显示的 HTTP / 混合端口为准。
先设环境变量:最通用的一步
export HTTPS_PROXY=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
export NO_PROXY=localhost,127.0.0.1
Windows PowerShell、CMD 的写法和长期生效方法见 终端代理设置。设置后用 curl 确认网络通了,能拿到 HTTP 状态码(哪怕是 401)就说明代理生效:
curl -sS -o /dev/null -w "%{http_code}\n" https://api.anthropic.com/v1/models
| 工具 | 默认读取 HTTPS_PROXY | 说明 |
|---|---|---|
| Python requests | 是 | 也可用 proxies= 参数显式指定 |
| Python httpx | 是 | 由 trust_env 控制,默认开启 |
| Node.js 内置 fetch | 多数版本否 | 需要 undici 的 ProxyAgent |
Python:requests、httpx 与官方 SDK
环境变量对 requests 和 httpx 都有效。需要在代码里写死(比如只让这一个脚本走代理)时:
import os
import requests
proxies = {"http": "http://127.0.0.1:7890", "https": "http://127.0.0.1:7890"}
r = requests.get(
"https://api.openai.com/v1/models",
headers={"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}"},
proxies=proxies,
timeout=30,
)
print(r.status_code)
httpx 的较新版本用 proxy 参数,较旧版本是 proxies,以所用版本文档为准:
import httpx
with httpx.Client(proxy="http://127.0.0.1:7890", timeout=30) as client:
print(client.get("https://api.anthropic.com/v1/models").status_code)
OpenAI 与 Anthropic 的 Python SDK 底层使用 httpx,通常也会读取环境变量;想单独控制时,可以通过 http_client 参数传入自定义客户端:
import httpx
from openai import OpenAI
from anthropic import Anthropic
proxy_client = httpx.Client(proxy="http://127.0.0.1:7890")
openai_client = OpenAI(http_client=proxy_client) # 读取 OPENAI_API_KEY
claude_client = Anthropic(http_client=proxy_client) # 读取 ANTHROPIC_API_KEY
直接传入 httpx.Client 会替换 SDK 的默认超时等设置,SDK 一般另提供保留默认值的包装类,具体以所用 SDK 版本的文档为准。
Node.js:给 fetch 设置全局代理
Node.js 内置的 fetch 基于 undici,但在很多版本中不会自动读取 HTTPS_PROXY。用 undici 包提供的 ProxyAgent 设置全局 dispatcher:
import { ProxyAgent, setGlobalDispatcher } from 'undici';
const proxy = process.env.HTTPS_PROXY;
if (proxy) setGlobalDispatcher(new ProxyAgent(proxy));
const res = await fetch('https://api.openai.com/v1/models', {
headers: { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
});
console.log(res.status);
只在设置了环境变量时启用代理,部署到海外服务器时代码不用改。如果全局设置对内置 fetch 没有生效,改用从 undici 导入的 fetch。官方 Node SDK 底层同样基于 fetch,多数情况下全局 dispatcher 会一并生效;SDK 也支持传入自定义请求选项,参数名以所用版本文档为准。
服务器:优先部署在支持地区
线上服务不建议依赖梯子:节点切换、订阅到期都会让接口直接不可用。更稳的做法是把调用 API 的服务放在 OpenAI、Anthropic 支持地区的云服务器上(支持地区以官方页面为准),各平台的地区要求见 ChatGPT 专题 与 Claude 专题。
如果只是在自己的 Linux 开发机上临时调试,可以参考 Linux 梯子配置 运行代理内核。两个常见坑:
- systemd 服务不读 shell 配置:在 unit 文件里用
Environment=HTTPS_PROXY=...写入。 - 容器里的 127.0.0.1 指向容器自己:要填宿主机可达的地址,Linux 上可用
--add-host=host.docker.internal:host-gateway把宿主机映射进来。
API Key 怎么保管
| 做法 | 说明 |
|---|---|
放在 .env 并加入 .gitignore | 提交前用 git status 确认没被跟踪 |
| 不写进前端代码 | 浏览器端代码对所有访问者可见,应由后端转发请求 |
| 按项目分开创建 Key | 泄露时只吊销一个,影响范围小 |
| 日志里不打印请求头 | 避免 Key 出现在日志平台或报错截图中 |
常见问题
Q环境变量设置了,Python 脚本还是超时?
先确认脚本是从设置过变量的同一个终端启动的;IDE 的运行按钮、systemd 服务、计划任务都不会读取 shell 配置文件。再检查代码里是否把 trust_env 关掉了,或传入了自己的代理参数覆盖了环境变量。
Q代理地址用 http:// 还是 socks5://?
客户端的混合端口通常同时支持 HTTP 和 SOCKS5,写 http:// 最省事。要用 socks5://,requests 和 httpx 都需要额外安装 SOCKS 支持依赖,undici 的 ProxyAgent 则面向 HTTP 代理。
Q流式输出(stream)走代理会断吗?
流式响应是一条持续较久的连接,节点不稳或客户端自动切换节点时容易中断。调试时固定一个节点,并在代码里设置合理的超时与重试。
Q公司服务器在国内,也能这样配吗?
技术上可以在服务器上运行代理内核并设置环境变量,但线上服务依赖梯子既不稳定,也涉及合规问题。更推荐把调用 API 的部分部署到支持地区的云服务器。
QAPI Key 不小心提交到 GitHub 了怎么办?
立即到对应平台的控制台吊销该 Key 并生成新的,再从提交历史中清除。只删除最新提交里的文件不够,历史记录中仍然能看到。