本文是【大模型API中转站】系列篇。本系列致力于用最低的成本、最清晰的方法,帮你打通多模型 API 的任督二脉。建议先收藏,随用随查。
1. 开篇:我为什么需要这个方案
做 AI 应用最先撞墙的,从来不是"想不到怎么用",而是"接不进来":
- 官方 API 注册难、网络不通:OpenAI 的 Images / Sora 接口要海外卡、要稳定网络,国内服务器直连基本等于赌运气。
- 每家一套协议:豆包是火山 Ark 格式,可灵要 JWT 签名 + 轮询,Sora2 是 multipart/form-data,Veo3 又是另一套 JSON……每接一个模型就要写一份对接代码。
- Key 散落、计费混乱:十几个模型十几把 Key,散在代码和环境变量里,泄露和对账都是噩梦。
- 按量付费贵、还容易封号:直连官方既贵又有封号风险。
我手上这套真实的 AI 生图/生视频 SaaS 后端(FastAPI + Celery),就是靠**"中转站 + OpenAI 兼容协议"把上面这些坑一次性填平的。本文目标:带你从这套真实生产代码**里,看清"国内应用 → 中转站 → 各家大模型"这条通路到底怎么搭、代码怎么写。
文中接入环节以 4SAPI 这类聚合中转站为例(它把 GPT、Claude、Sora、可灵、Veo3 等模型统一成 OpenAI 兼容协议,一把 Key 全用)。
2. 原理速览
请求流向
你的应用(FastAPI/Celery)
│ OpenAI 兼容格式请求
▼
中转站(4sapi 等,国内可直连)
│ 协议转换 + 鉴权 + 计费
▼
各家官方 API(OpenAI / Anthropic / 火山 / 快手可灵 …)
中转站帮你处理了什么
- 格式转换:你只发 OpenAI 标准的
images.generate或/v1/chat/completions,中转站负责翻译成各家私有协议。 - 统一鉴权:一把
BearerKey 调所有模型,Key 不直连官方、不暴露在前端。 - 限流 / 计费 / 网络:国内有可直连的节点,省掉自己搭代理。
下面看这套代码是怎么把"中转"这件事落到实处的。
3. 接入实战
方案一:官方直连(仅作对比)
如果你直连官方,要面对的就是上面那一堆:海外网络、多套协议、多把 Key。代码层面就是写死一个个 SDK、为每家维护一份请求/响应解析。模型一多,对接成本线性上涨。这套项目早期就这么干过,后来全砍了(代码注释里那句 T02:已砍多平台兜底 就是证据)。
方案二:中转站接入(参考 4SAPI 接入思路)
这套代码的精髓:把"平台"降级成一个标签,真正驱动调用的只有两样东西 —— base_url 和 api_format。 换模型 = 换一行配置,不改代码。
① 环境准备
pip install openai httpx # OpenAI SDK + HTTP 客户端,两条腿走路
后端只依赖 openai(标准 SDK)和 httpx(直接发 HTTP),不为每家模型装一个专用 SDK。
② 配置 base_url 和 API Key(核心思想:配置即接入)
项目把每个模型的配置存进数据库(ai_models 表),运行时实时读取。关键在于 API Key 加密存储、出库即解密,以及 Key 留空时按平台回退到一把"中转站总 Key":
# ai_model_registry.py —— 模型配置出库即解密
def _row_to_runtime(m: AIModel) -> Dict[str, Any]:
provider = (m.extra_config or {}).get("provider") or m.model_id
# 1) 优先用模型自己的 Key(Fernet 密文解密)
# 2) 留空 → 回退到该平台的"中转站总 Key"(一把 Key 服务多个模型)
api_key = decrypt_value(m.api_key) or _resolve_platform_key(provider)
return {
"base_url": m.api_base_url, # 中转站地址,如 https://4sapi.com
"api_key": api_key, # 明文 Key,调用方直接用
"api_format": m.api_format, # images_api / chat_completions / sora2_http ...
"use_openai_sdk": bool(m.use_openai_sdk),
"provider_model_name": m.provider_model_name, # 传给上游的真实模型名
...
}
为什么这么设计:
4sapi一把 Key 就能服务fourapi / sora2 / veo3等一大票模型,不用每条都填一遍;个别模型想走独立账号分流量,再单独给它配 Key。管理员在后台改了base_url/api_key,下次调用立即生效(不做进程级缓存,避免改完不生效的脏读)。
③ 发起调用:OpenAI 兼容是关键
中转站最大的好处是绝大多数模型都能用 OpenAI 标准 SDK 调用。生图服务里,客户端就是标准 OpenAI 客户端,只是把 base_url 指向中转站:
# ai_image_service.py —— 客户端 = 标准 OpenAI SDK + 中转站 base_url
class AIClientFactory:
@classmethod
def build_client(cls, base_url: str, api_key: str) -> OpenAI:
return OpenAI(base_url=base_url, api_key=api_key) # 就这么简单
# 真正发请求:就是标准的 images.generate
response = self.client.images.generate(**api_params)
对于走原生 HTTP 的模型,鉴权也是统一的 Bearer Key:
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
}
with httpx.Client(timeout=timeout) as client:
response = client.post(self.api_url, json=params, headers=headers)
④ 参数适配器:一套接口,喂给不同模型
不同模型对"宽高比""参考图""批量"的要求不一样,项目用适配器模式把差异收敛到一个函数里。比如有的中转模型走的是 /v1/chat/completions(对话接口)来生图,适配器就把它包装成多模态对话:
# fourapi(4sapi 聚合)走 chat_completions 生图
def adapt_for_fourapi(prompt, aspect_ratio, ...):
full_prompt = f"请根据以下描述生成一张图片,直接生成图片:\n\n{prompt}"
content = [{"type": "text", "text": full_prompt}]
if reference_images: # 图生图:把参考图拼进 content
content.append({"type": "image_url", "image_url": {"url": reference_images}})
return {"stream": False, "messages": [{"role": "user", "content": content}]}
而标准 OpenAI 格式的模型,直接用通用适配器(size + n),无需为它单独写代码。新接一个走标准格式的模型,零代码改动。
⑤ 兼容多种返回格式 + 自动重试
中转站背后接了一堆模型,返回格式五花八门(SDK 对象 / data[].url / data[].b64_json / chat 的 Markdown 图片 / Base64 …)。项目做了一个"全都认"的提取器,并对临时错误自动重试、永久错误(鉴权/配额/模型不存在)立即放弃,避免白等十几秒:
# 永久错误关键词:命中就不重试,直接退积分
_PERMANENT_ERROR_KEYWORDS = (
"model_not_found", "channel not found", "unauthorized",
"invalid_api_key", "quota", ...
)
# 4xx 或响应体含上述关键词 → 标记为永久错误,跳过 retry
if 400 <= response.status_code < 500 or is_permanent_error_text(response.text):
raise PermanentAPIError(...)
⑥ 启动并测试
最小验证脚本(把 base_url 换成你的中转站地址、api_key 换成中转站 Key):
from openai import OpenAI
client = OpenAI(base_url="https://4sapi.com/v1", api_key="sk-你的中转站Key")
resp = client.images.generate(model="gpt-image-2", prompt="一只在赛博朋克城市奔跑的柴犬", n=1, size="1024x1024")
print(resp.data[0].url)
跑通这一步,就说明"应用 → 中转站 → 官方模型"这条通路打通了。剩下的就是按上面 ② 把模型配置进数据库/配置文件。
4. 成本与风险提示
- 费用构成:中转站按量计费(通常比官方便宜,且省掉自建海外代理服务器的固定成本)+ 你自己的应用服务器费用。一把 Key 调所有模型,对账也清爽。
- 数据隐私:请求会经过中转站,敏感数据(人脸、商业素材)务必评估合规性。代码里日志会把 Base64、长字符串脱敏(
sanitize_params_for_log),这是个好习惯,照抄。 - Key 安全:Key 一定要像本项目一样加密存储(Fernet),绝不写进前端、不提交进 Git。
- 稳定性:中转站是第三方依赖,建议像本项目一样做重试 + 永久错误识别 + 失败退款。对可用性要求极高的生产场景,建议多中转站冗余或保留官方直连兜底。
- 合规红线:中转用于"打通网络、统一协议、优化成本"是正当需求;不要用于绕过官方滥用限制等违规用途。
5. 总结与系列导航
一句话总结:如果你是国内开发者,要在应用里同时用上 GPT、Sora、可灵、Veo3 等多家模型,又不想被网络和多套协议折磨 —— "OpenAI 兼容 + 中转站 + 配置化模型表"就是这套生产代码验证过的最优解:换模型只改一行 base_url/api_format,一把 Key 调全部。
适用人群:做 AI SaaS、AI 工具、需要多模型横向切换的团队和独立开发者。
中转站选型可参考 4SAPI 的接入文档。如果你有更优雅的多模型聚合方案,欢迎在评论区交流,我会补充进系列。