OpenAI API 接入教程:Base URL 停在 /v1,每步有通过标准
OpenAI API 接入教程先把 API Key、Base URL 和模型 ID 分开配置,用 curl 验证 Responses 或兼容端点,再接 Python SDK,并检查流式结束、用量字段和 401、404、429。

OpenAI API 接入最稳妥的顺序是:先用一条可观察的 HTTP 请求确认地址、鉴权和模型,再接入 SDK;不要一开始就把网关、框架、代理和业务代码一起调试。
“ChatGPT 中转 API”通常指 OpenAI 风格的程序接口,不等于 ChatGPT 网页订阅。本文同时区分 OpenAI 兼容 API、官方 Responses 与 Chat Completions,避免把产品账户、协议和计费边界混在一起。
直接复制:OpenAI API 接入第一条兼容请求
下面以 GPTZZZ OpenAI 兼容入口为例。三个值职责不同:Base URL 决定路由,API Key 决定身份,Model ID 决定调用哪个模型。示例模型 gpt-5.5 在 GPTZZZ 的四个 GPT 分组里都有;换模型时,新模型也要在这个 Key 所属的分组里。
export GPTZZZ_BASE_URL="https://gptzzz.ai/v1"
export GPTZZZ_API_KEY="YOUR_GPTZZZ_API_KEY"
export GPTZZZ_MODEL="gpt-5.5"
curl --fail-with-body -sS -D /tmp/gptzzz-openai-headers.txt \
"$GPTZZZ_BASE_URL/chat/completions" \
-H "Authorization: Bearer $GPTZZZ_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"model\":\"$GPTZZZ_MODEL\",\"messages\":[{\"role\":\"user\",\"content\":\"只回复 OPENAI_OK\"}],\"stream\":false}"
Windows PowerShell:
$env:GPTZZZ_BASE_URL = "https://gptzzz.ai/v1"
$env:GPTZZZ_API_KEY = "YOUR_GPTZZZ_API_KEY"
$env:GPTZZZ_MODEL = "gpt-5.5"
$body = @{
model = $env:GPTZZZ_MODEL
messages = @(@{ role = "user"; content = "只回复 OPENAI_OK" })
stream = $false
} | ConvertTo-Json -Depth 5
Invoke-RestMethod -Method Post -Uri "$env:GPTZZZ_BASE_URL/chat/completions" `
-Headers @{ Authorization = "Bearer $env:GPTZZZ_API_KEY" } `
-ContentType "application/json; charset=utf-8" `
-Body ([System.Text.Encoding]::UTF8.GetBytes($body))
通过标准:HTTP 2xx,响应为 JSON,choices[0].message.content 非空,finish_reason 可解释,model 与 usage 可读取;若响应头含请求 ID,一并留存。
同一个模型在不同分组价格不同。opai puls、opai pro、pro200-500不降智 是 GPT 订阅号池分组,GPT官key 是官方 Key 分组;一个 Key 只属于一个分组,在控制台 /keys 页面创建 Key 时选定。下面是几个常用模型的报价:
| 模型 | 分组 · 倍率 | 输入 ¥/百万 Token | 输出 ¥/百万 Token |
|---|---|---|---|
| gpt-5.5 价格 | opai puls · 0.05x | ¥0.25 | ¥1.50 |
| gpt-5.5 价格 | opai pro · 0.1x | ¥0.50 | ¥3.00 |
| gpt-5.5 价格 | pro200-500不降智 · 0.25x | ¥1.25 | ¥7.50 |
| gpt-5.5 价格 | GPT官key · 0.54x | ¥3.91 | ¥23.40 |
| gpt-5.4 价格 | opai puls · 0.05x | ¥0.13 | ¥0.75 |
| gpt-5.4 价格 | opai pro · 0.1x | ¥0.25 | ¥1.50 |
| gpt-5.4 价格 | GPT官key · 0.54x | ¥7.81 | ¥46.90 |
| gpt-5-nano 价格 | GPT官key · 0.54x | ¥0.34 | ¥2.71 |
gpt-5.5 和 gpt-5.4 在价格页标有“长上下文”:单次输入超过 272K Token 时,整次请求按更高阶梯计价。GPTZZZ 首页写明 OpenAI 分组已实测 /v1/models、/v1/chat/completions(含流式、工具调用、JSON 模式)与 /v1/responses,暂不支持 embeddings。表中价格取自 2026-10-09 的模型价格页,单位是元/百万 Token(充值 ¥1 = 余额 $1),已乘分组倍率;实际扣费以 GPTZZZ 模型价格页和控制台为准。
OpenAI 官方当前基线:Responses API
OpenAI 官方建议新文本项目使用 Responses API。先在官方端点完成基线,再测试中转站是否真的实现 /responses;“Chat Completions 可用”不能证明 Responses 兼容。
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
curl --fail-with-body -sS \
"https://api.openai.com/v1/responses" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.6","input":"Reply with exactly: OPENAI_OK"}'
import os
from openai import OpenAI
official = OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1"),
)
response = official.responses.create(
model="gpt-5.6",
input="Reply with exactly: OPENAI_OK",
)
if response.status != "completed" or not response.output_text.strip():
raise RuntimeError(f"unexpected response status={response.status!r}")
print(response.output_text)
print(response._request_id)
Responses 的 output 可能包含 reasoning、工具调用或多个消息项,不要硬编码 output[0].content[0].text;SDK 的 output_text 会聚合文本。模型参数支持范围仍取决于具体模型。
Base URL 与完整接口路径的边界
| 场景 | SDK Base URL | 完整请求路径 |
|---|---|---|
| OpenAI 官方 Responses | https://api.openai.com/v1 | POST /v1/responses |
| OpenAI 官方 Chat Completions | https://api.openai.com/v1 | POST /v1/chat/completions |
| GPTZZZ OpenAI 兼容聊天 | https://gptzzz.ai/v1 | POST /v1/chat/completions |
“Base URL”和“完整 Endpoint”不是同一字段。OpenAI SDK 的 base_url 应停在版本根,调用 chat.completions.create() 后由 SDK 追加 chat/completions。若某客户端明确要求完整 Endpoint,才填资源路径。
核对 OpenAI Base URL 时,先确认客户端字段要求 API 根还是完整 Endpoint;官方 SDK 应填版本根,中转 SDK 示例同样停在 /v1。
Python SDK:请求与响应验证
安装官方 SDK,并显式传入中转站配置:
python -m pip install -U openai
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["GPTZZZ_API_KEY"],
base_url=os.environ.get("GPTZZZ_BASE_URL", "https://gptzzz.ai/v1"),
timeout=90.0,
max_retries=2,
)
response = client.chat.completions.create(
model=os.environ["GPTZZZ_MODEL"],
messages=[{"role": "user", "content": "只回复 OPENAI_OK"}],
)
choice = response.choices[0]
if not response.id or not response.model or not choice.message.content:
raise RuntimeError(f"unexpected response: {response.model_dump_json()}")
if choice.finish_reason not in {"stop", "length", "tool_calls", "content_filter"}:
raise RuntimeError(f"unexpected finish_reason={choice.finish_reason!r}")
print(choice.message.content)
print({
"response_id": response.id,
"request_id": response._request_id,
"model": response.model,
"finish_reason": choice.finish_reason,
"total_tokens": response.usage.total_tokens if response.usage else None,
})
示例接受多个合法结束原因,是为了避免把“输出达到上限”或“模型请求工具”误判成传输错误;业务仍需按任务契约分别处理。
OpenAI 流式输出怎样验收
官方 Responses 流是 SSE,常见事件包括 response.created、response.output_text.delta、response.completed 与 error:
completed = False
for event in official.responses.create(
model="gpt-5.6",
input="Say hello.",
stream=True,
):
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
elif event.type == "response.completed":
completed = True
elif event.type == "error":
raise RuntimeError(str(event))
if not completed:
raise RuntimeError("Responses stream did not complete")
中转站若只实现 Chat Completions,则使用下面的兼容流探针;两种事件模型不要混用:
stream = client.chat.completions.create(
model=os.environ["GPTZZZ_MODEL"],
messages=[{"role": "user", "content": "分三点解释 API 网关"}],
stream=True,
stream_options={"include_usage": True},
)
finished = False
total_tokens = None
for chunk in stream:
if chunk.usage is not None:
total_tokens = chunk.usage.total_tokens
if not chunk.choices:
continue
choice = chunk.choices[0]
if choice.delta.content:
print(choice.delta.content, end="", flush=True)
if choice.finish_reason is not None:
finished = True
print(f"\nfinish_reason={choice.finish_reason}")
if not finished or total_tokens is None:
raise RuntimeError("stream ended without finish_reason or usage")
print(f"usage.total_tokens={total_tokens}")
兼容网关常使用 data-only SSE。客户端需要处理空增量、工具调用增量、正常结束、用户取消和 HTTP 200 之后的流内错误。只有消费到协议终点,结果才能记为完整。
自定义模型与 OpenAI 兼容边界
Model ID 不是营销名称。先从目标平台的模型列表或控制台复制可用 ID,再把请求模型、响应模型、日期和网关路由记录在同一条证据中。
| 能力 | 不能只凭兼容标签推断 | 验收证据 |
|---|---|---|
| Responses API | /responses 与语义流式事件 | 完整事件序列、状态与 usage |
| Chat Completions | 角色、结束原因、并行工具 | 请求/响应 Schema 与工具回传 |
| 结构化输出 | Schema 是否被严格执行 | 对输出做本地 JSON Schema 校验 |
| 模型别名 | 名称是否映射到预期上游 | 响应 model、请求 ID 与控制台记录 |
401、404、429 与流式中断排查
| 现象 | 优先检查 | 处理 |
|---|---|---|
| 401 | Bearer 格式、密钥状态、变量是否加载 | 修复凭据,不自动重试 |
| 403 | 项目、模型权限或策略 | 读取错误类型,不循环重试 |
| 404 | 重复 /v1、错误资源或模型 ID | 打印脱敏后的最终 URL |
| 422 | 参数类型或组合无法处理 | 修正语义校验失败 |
| 429 | 速率、并发、额度与重试提示 | 带抖动的有限指数退避 |
| 5xx | 网关或上游暂态异常 | 仅对幂等任务限次重试 |
| 流式半截 | 代理缓冲、网络断开、取消传播 | 标记不完整,不盲目重放 |
迁移旧客户端前先看 OpenAI 兼容 API 迁移清单;密钥存储参考 API Key 安全指南;工具与流式语义用 兼容性测试矩阵复验;状态码分层见 API 中转站错误码排查。
验证指标与回滚
固定 20 条短请求与 5 条流式请求,记录成功率(完整结束数 ÷ 总请求数)、TTFT、总耗时、HTTP 状态、finish_reason、输入/输出 Token、重试次数和 request ID。切换前保存旧 Base URL、Key 变量名、Model ID 与 SDK 版本。
- 停止在途请求,避免同一业务动作在两个端点重复执行。
- 恢复旧 Base URL、旧模型与旧凭据来源,不复用中转 Key。
- 关闭连接池并启动新进程,重新运行同一条 curl 和 Python 基线。
- 只有完整结束率、错误语义和用量恢复后才结束回滚。
官方资料
- OpenAI API Quickstart
- OpenAI API Overview
- OpenAI Text generation / Responses
- OpenAI Streaming API responses
- OpenAI Python SDK reference
- OpenAI API error codes
使用 Claude 模型的对应教程见 Claude API 中转接入;从测试 Key 到首个请求的完整流程见 API 中转站怎么用。
常见问题
OpenAI API Base URL 应该填到哪里?
OpenAI 官方 SDK 的默认 API 根是 https://api.openai.com/v1;GPTZZZ 的 OpenAI 兼容 SDK Base URL 填 https://gptzzz.ai/v1。SDK 会继续追加资源路径,不要把 /chat/completions 再写进 base_url。
OpenAI API Key 应该放在哪个环境变量?
官方 OpenAI SDK 默认读取 OPENAI_API_KEY。接入中转站时可使用独立的 GPTZZZ_API_KEY 并显式传给客户端,避免官方密钥和中转密钥混用;任何密钥都不要写进浏览器、Git 或日志。
OpenAI 兼容 API 怎样用 curl 验证?
向 Base URL 后的 /chat/completions 发送 Bearer 鉴权和最小 messages 请求,同时保存 HTTP 状态、JSON 响应、model、choices、finish_reason、usage 与请求 ID。
OpenAI API 返回 404 是否因为重复 /v1?
很常见。先打印脱敏后的最终路径;SDK base_url 通常停在 /v1,若把完整 /v1/chat/completions 当成 Base URL,SDK 再追加路径就会得到错误地址。
OpenAI API 流式输出怎样确认完整结束?
不要把收到首个文本增量当成功。应消费完整流,确认最终 finish_reason 或协议结束事件,并保存用量;中途断开必须标记为不完整。
OpenAI Responses API 与 Chat Completions 有什么区别?
它们是不同资源与响应事件契约。OpenAI 兼容网关常先实现 Chat Completions;客户端使用 Responses 时,必须确认网关真的实现 /responses、流式事件、工具状态与错误对象,不能只凭“OpenAI 兼容”推断。
OpenAI Python SDK 如何修改 base_url?
在 OpenAI(...) 构造器传入 base_url,或为官方 SDK 设置 OPENAI_BASE_URL。值应是 API 根,例如 https://relay.example/v1,而不是完整 /responses 或 /chat/completions。
OpenAI API 返回 401 怎么排查?
检查 Authorization 是否为 Bearer、Key 是否来自当前目标平台、环境变量是否在启动进程中加载,以及项目和密钥权限;401 不应自动重试,也不要在日志中打印完整 Key。
国内使用 OpenAI API 中转要注意什么?
国内通过中转站使用 OpenAI 兼容 API 时,配置步骤与本文相同:替换 Base URL、使用测试 Key、逐项验证请求与错误码。除技术验证外,还应核对服务的合同条款、数据跨境边界与退出路径,避免把未经验证的服务直接接入生产环境。
本文技术参数与官方资料复核于 2026-10-09;模型、价格、限额与客户端界面会变化,使用前请再次核对官方文档和当前控制台。

