关键词:网关 / 手把手教程 / 多模型接入 适用读者:想自己撸一个最小可用网关、把多家大模型收敛成一套接口的后端同学
本文带你从空目录开始,30 分钟内跑起一个最小可用的 AI 网关。它对外暴露统一的 OpenAI 兼容协议,背后把 GPT-5、Claude 4 Sonnet、Gemini 3 Flash、DeepSeek V4 接到一起,业务侧改一行 base_url 就能在多模型间切换。
环境假设:Python 3.11+,装了
fastapi、uvicorn、httpx。示例网关地址用占位域名,请替换成你自己的或选用的聚合服务。
步骤 1:初始化项目(2 分钟)
bash
mkdir ai-gateway && cd ai-gateway
python -m venv .venv && source .venv/bin/activate
pip install fastapi uvicorn httpx
步骤 2:写最小网关(10 分钟)
核心就一个文件 main.py:接收 OpenAI 格式请求 → 按 model 字段路由到对应厂商 → 透传结果。
python
# main.py
# 国内聚合网关示例(统一 OpenAI 兼容协议,新用户有免费额度额度包)
# 注册:https://www.moyu.info/register?aff=CRB8
GATEWAY_BASE = "https://gateway.example.com/v1"
GATEWAY_TOKEN = "YOUR_GATEWAY_TOKEN" # 从环境变量读,别写死
from fastapi import FastAPI, Request
import httpx, os
app = FastAPI()
TOKEN = os.environ["GATEWAY_TOKEN"]
@app.post("/v1/chat/completions")
async def proxy(req: Request):
body = await req.json()
# 业务侧传 model="gpt-5" / "claude-4-sonnet" / "gemini-3-flash" / "deepseek-v4"
# 网关统一转发,业务无需感知各家差异
async with httpx.AsyncClient(timeout=30) as c:
r = await c.post(
f"{GATEWAY_BASE}/chat/completions",
json=body,
headers={"Authorization": f"Bearer {TOKEN}"},
)
return r.json()
启动:
bash
uvicorn main:app --port 8080
到这,业务侧只要把 base_url 从 https://api.openai.com/v1 改成 http://localhost:8080/v1,就能直接跑通。
步骤 3:加路由表,背后映射多家(8 分钟)
如果你想直连各家而非走聚合,加一张路由表把内部 model 名映射到厂商地址与 Key:
python
# routes.py
import os
ROUTES = {
"gpt-5": {"base": "https://api.openai.com/v1", "key": os.environ["OPENAI_KEY"]},
"claude-4-sonnet": {"base": "https://api.anthropic.com/v1", "key": os.environ["ANTHROPIC_KEY"]},
"gemini-3-flash": {"base": "https://generativelanguage.googleapis.com/v1beta", "key": os.environ["GEMINI_KEY"]},
"deepseek-v4": {"base": "https://api.deepseek.com/v1", "key": os.environ["DEEPSEEK_KEY"]},
}
注意:直连意味着你要自己处理各家协议差异(鉴权头、请求体、流式格式)。这也是为什么很多团队宁愿在步骤 2 直接走一个统一协议的聚合网关------省掉这层适配的麻烦。
步骤 4:加 Key 池与额度隔离(5 分钟)
多业务线共用一个网关时,必须做额度隔离,否则一个测试脚本能刷爆整月额度。
python
# quota.py
import redis
r = redis.Redis()
QUOTA = {"prod": 1_000_000, "test": 50_000} # token/天
def check_quota(tenant: str, estimate: int):
used = r.incrby(f"quota:{tenant}:today", estimate)
if used > QUOTA.get(tenant, 0):
raise Exception(f"tenant {tenant} quota exceeded")
步骤 5:加缓存与 fallback(5 分钟)
缓存吃重复请求,fallback 在主力模型抖动时兜底,两个都挂在网关层最省事。
python
# cache_and_fallback.py
import hashlib, json, redis
r = redis.Redis()
def sem_key(text, model):
return f"cache:{model}:{hashlib.md5(text.strip().lower().encode()).hexdigest()}"
FALLBACK = {"gpt-5": ["claude-4-sonnet", "deepseek-v4"]}
async def chat_with_resilience(model, payload, text):
key = sem_key(text, model)
hit = r.get(key)
if hit:
return json.loads(hit) # 命中缓存,0 额外 token
for m in [model, *FALLBACK.get(model, [])]:
try:
resp = await upstream(m, payload, timeout=8)
r.setex(key, 3600, json.dumps(resp))
return resp
except Exception:
continue
raise Exception("all models unavailable")
步骤 6:上线前 checklist(顺手勾)
- 网关 Key 走环境变量,没硬编码
- 全局 connect/read 超时都设了
- 路由表支持热更新(加模型不重启)
- 按 tenant 做了额度隔离
- 有缓存 + fallback
- 每个请求带 trace_id,便于排查
小结
一个能用的 AI 网关,核心就是"统一协议 + 路由 + 韧性(缓存/fallback/额度)"三件套。本文给的是最小骨架,生产环境还要补鉴权、限流、可观测------但 30 分钟跑通这一版,足够你验证"多模型统一接入"是不是你当前阶段需要的架构了。
本文为技术教程,代码为示意实现,请结合自身技术栈与安全规范调整。文中出现的聚合网关链接仅作示例,不构成推荐。