ChatGPT API 国内怎么调?3 种方案实测,附完整 Python 代码

5 阅读1分钟

上个月接了个私活,甲方要做客服问答系统,指定用 GPT 模型。我寻思这不简单,openai.ChatCompletion.create 一把梭不就完了。结果到了部署环节,服务器在国内,请求直接超时,API 摸都摸不到。折腾了整整两天,把能试的方案挨个过了一遍,今天把踩坑过程和最终方案整理出来,给卡在这一步的兄弟省点时间。

先说结论

方案延迟(首 Token)稳定性上手难度适合场景
云服务器中转800-1500ms看机器有运维能力的团队
Cloudflare Worker 代理600-1200ms中等个人项目、试水
聚合 API 平台300-800ms极低生产环境、多模型切换

最终我给甲方交付用的是方案三,原因后面细说。

为什么国内直连 OpenAI API 这么难

这个不用展开,懂的都懂。api.openai.com 在国内网络环境下访问不稳定,经常超时或者直接连不上。就算偶尔能连上,生产环境也不敢赌这个概率——半夜客服系统挂了,甲方能把你电话打爆。

问题本质就一个:怎么在国内服务器上,稳定、低延迟地调到 GPT-5.4 等模型的 API?

方案一:自建云服务器中转

最「正统」的思路——海外买台云服务器跑反向代理,国内服务器请求打过去,中转机再转发给 OpenAI。

实操步骤

我用的是某云的香港轻量服务器,Ubuntu 22.04,装个 Nginx:

# /etc/nginx/conf.d/openai-proxy.conf
server {
    listen 443 ssl;
    server_name your-proxy-domain.com;

    ssl_certificate /etc/ssl/certs/your-cert.pem;
    ssl_certificate_key /etc/ssl/private/your-key.pem;

    location /v1/ {
        proxy_pass https://api.openai.com/v1/;
        proxy_set_header Host api.openai.com;
        proxy_set_header Authorization $http_authorization;
        proxy_set_header Content-Type $http_content_type;
        proxy_connect_timeout 60s;
        proxy_read_timeout 120s;
        proxy_buffering off;  # 流式输出必须关掉
    }
}

Python 端改一下 base_url 就行:

from openai import OpenAI

client = OpenAI(
    api_key="sk-xxx",
    base_url="https://your-proxy-domain.com/v1"
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "你好,介绍一下你自己"}],
    stream=True
)

for chunk in response:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

踩坑记录

流式输出卡顿:一开始忘了加 proxy_buffering off,Nginx 默认缓冲响应体,流式输出变成一坨一坨往外吐,用户体验极差。加上这行立刻丝滑了。

SSL 证书问题:用自签名证书,Python 的 httpx(openai SDK 底层用的)会报 SSL 验证错误。要么用 Let's Encrypt 搞正经证书,要么客户端加 http_client=httpx.Client(verify=False)——但生产环境别这么干。

带宽和流量:GPT-5.4 长上下文响应,一次对话来回几十 KB 很正常。轻量服务器那点带宽,并发一上来就扛不住。测了一下,10 个并发请求就开始出现明显延迟。

这个方案能用,但维护成本高。服务器要续费、证书要续期、带宽要监控,挂了还得自己修。个人玩玩可以,给甲方交付不敢赌。

方案二:Cloudflare Worker 代理

这个方案在 GitHub 上很流行,利用 Cloudflare 的边缘节点做中转,免费额度每天 10 万次请求,个人开发者用起来很顺手。

实操步骤

在 Cloudflare Dashboard 创建 Worker,贴入以下代码:

// Cloudflare Worker 代理 OpenAI API
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    
    // 简单的 token 校验,防止被扫
    const authToken = request.headers.get('X-Proxy-Token');
    if (authToken !== env.PROXY_SECRET) {
      return new Response('Unauthorized', { status: 401 });
    }

    // 转发到 OpenAI
    const targetUrl = `https://api.openai.com${url.pathname}${url.search}`;
    
    const modifiedHeaders = new Headers(request.headers);
    modifiedHeaders.delete('X-Proxy-Token');
    modifiedHeaders.set('Host', 'api.openai.com');

    const response = await fetch(targetUrl, {
      method: request.method,
      headers: modifiedHeaders,
      body: request.body,
    });

    // 保留流式响应头
    const newHeaders = new Headers(response.headers);
    newHeaders.set('Access-Control-Allow-Origin', '*');

    return new Response(response.body, {
      status: response.status,
      headers: newHeaders,
    });
  },
};

Python 端调用:

import httpx
from openai import OpenAI

client = OpenAI(
    api_key="sk-xxx",
    base_url="https://your-worker.your-domain.workers.dev/v1",
    default_headers={"X-Proxy-Token": "your-secret-token"},
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "用 Python 写一个快速排序"}],
)
print(response.choices[0].message.content)

踩坑记录

workers.dev 域名也不稳定:以为找到了银弹,结果 workers.dev 在国内部分地区同样拉跨。解决方案是绑自己的域名,走 Cloudflare CDN。

Worker 执行时间限制:免费版单次请求最多跑 10ms CPU 时间(注意是 CPU 时间不是墙钟时间),纯转发没问题,Worker 里加复杂逻辑就可能超限。

并发限流:免费版每分钟 1000 次请求。测试阶段够用,上了生产就悬——甲方那个客服系统高峰期轻松破这个数。

免费、部署快,适合个人项目和 Demo。但稳定性和限流的问题,没敢用在正式交付上。

方案三:聚合 API 平台(最终方案)

折腾一圈下来发现,不想自己运维中转服务的话,用现成的 API 聚合平台最省事。网络链路问题人家帮你解决了,你只需要改个 base_url,其他代码一行不动。

我现在用的是 ofox.ai 的聚合接口,一个 Key 能调 GPT-5.4、Claude Opus 4.6、Gemini 3 Pro,兼容 OpenAI SDK 协议,迁移成本基本为零。

实操代码

from openai import OpenAI

client = OpenAI(
    api_key="your-ofox-key",
    base_url="https://api.ofox.ai/v1"  # 聚合接口,国内直连
)

# 调 GPT
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "你是一个专业的客服助手"},
        {"role": "user", "content": "我的订单 #12345 什么时候发货?"}
    ],
    temperature=0.7,
    max_tokens=500,
)
print(response.choices[0].message.content)

# 同一个 client 切到 Claude,只需要改 model 名
response_claude = client.chat.completions.create(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "帮我重构这段代码的异常处理"}],
)
print(response_claude.choices[0].message.content)

流式输出也完全兼容:

stream = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "详细解释 Python 的 GIL"}],
    stream=True,
)

full_response = ""
for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        full_response += delta
        print(delta, end="", flush=True)

为什么最后选了这个

给甲方交付的客服系统,有几个硬性条件:国内服务器直连、支持多模型切换(甲方说不准哪天要换 Claude 或国产模型)、稳定性有保障(半夜挂了不能是我的锅)。

这三条一卡,方案一和二都不太行。聚合平台的好处是:网络链路人家维护,模型切换改个字符串,出了问题我可以甩锅(不是)。

实测下来 GPT-5.4 首 Token 延迟基本在 400-600ms,流式输出体感流畅,甲方那边也没反馈过卡顿。

补充:给 Cursor / TRAE 配 API 的场景

除了代码调用,很多兄弟是想在 AI 编程工具里用自己的 Key。以 Cursor 为例:

  1. 打开 Settings → Models → OpenAI API Key
  2. 填入你的 Key
  3. Override OpenAI Base URL 填 https://api.ofox.ai/v1
  4. 选模型,保存,完事

TRAE 和其他兼容 OpenAI 协议的工具同理,改 Base URL + 填 Key。

踩坑合集

顺便把这两天踩的其他坑也列一下:

1. openai SDK 版本问题

openai 库现在是 1.x,用法和 0.x 完全不同。看到网上教程写 openai.ChatCompletion.create(),那是旧版语法。新版必须先实例化 OpenAI() 客户端:

pip install openai --upgrade
# 确保版本 >= 1.0.0

2. stream 模式下的错误处理

流式输出中途断了,默认不会抛异常,你拿到的就是半截内容。建议加个 try-catch:

try:
    for chunk in stream:
        delta = chunk.choices[0].delta.content
        if delta:
            print(delta, end="", flush=True)
except Exception as e:
    print(f"\n流式输出中断: {e}")
    # 这里可以做重试逻辑

3. 超时设置

OpenAI SDK 默认超时 600 秒,国内网络环境下建议主动设短,配合重试:

from openai import OpenAI
import httpx

client = OpenAI(
    api_key="your-key",
    base_url="https://api.ofox.ai/v1",
    timeout=httpx.Timeout(30.0, connect=10.0),
    max_retries=3,
)

4. Token 计算

max_tokens 只控制输出长度,输入的 token 也算钱。我之前给客服系统塞了个 3000 字的 system prompt,每次对话光 prompt 就花了一大截 token,账单看得肉疼。后来精简到 800 字,效果差别不大,成本直接砍了一半。

小结

三种方案各有适用场景:

  • 有运维能力、追求完全可控 → 自建中转
  • 个人开发者、免费试水 → Cloudflare Worker
  • 生产环境、要稳定要省心 → 聚合 API 平台

说白了,我们是写业务逻辑的,不是搞网络运维的。能花几分钟改个 base_url 解决的事,别花两天去折腾 Nginx 配置。省下来的时间多写两个 feature,甲方还更高兴。

有问题评论区聊,踩了其他坑的兄弟也来说说,大家互相避坑。