FastAPI 实战:构建企业级多模型 API 网关

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

FastAPI 实战:构建企业级多模型 API 网关

背景

最近在做大模型 API 接入相关的项目,需要解决几个问题:
各厂商 API 格式不统一,切换成本高
需要统一鉴权、限流、日志
业务层不想关心底层是哪个模型
于是决定用 FastAPI 搭建一个 API 网关,统一封装对外暴露。

架构设计

整体架构:客户端 -> API 网关(FastAPI)-> 大模型厂商 API
网关核心职责:
协议转换:统一 OpenAI 格式,后端适配各厂商
负载均衡:多 Key 轮询,避免单 Key 限流
熔断降级:某厂商挂了自动切换
日志监控:记录调用量、延迟、成功率

核心代码

统一请求模型

from pydantic import BaseModel
from typing import Optional, List

class ChatMessage(BaseModel):
    role: str
    content: str

class ChatRequest(BaseModel):
    model: str
    messages: List[ChatMessage]
    temperature: Optional[float] = 0.7
    max_tokens: Optional[int] = 2048

多厂商路由

import httpx
from fastapi import FastAPI, HTTPException

app = FastAPI()

PROVIDERS = {
    "deepseek-chat": {"base_url": "https://api.deepseek.com", "key": "sk-xxx"},
}

@app.post("/v1/chat/completions")
async def chat_completion(request: ChatRequest):
    provider = PROVIDERS.get(request.model)
    if not provider:
        raise HTTPException(status_code=400, detail="Unsupported model")
    
    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{provider['base_url']}/v1/chat/completions",
            headers={"Authorization": f"Bearer {provider['key']}"},
            json=request.dict(),
            timeout=60.0
        )
        return response.json()

轮询负载均衡

from itertools import cycle

class KeyPool:
    def __init__(self, keys: List[str]):
        self.keys = cycle(keys)
    
    def get_key(self):
        return next(self.keys)

openai_keys = KeyPool(["sk-key1", "sk-key2", "sk-key3"])

熔断降级

from tenacity import retry, stop_after_attempt, wait_exponential

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=10),
    retry_error_callback=lambda _: fallback_response()
)
async def call_with_fallback(provider, request):
    pass

踩坑记录

流式响应 SSE

大模型 API 支持流式返回,FastAPI 需要特殊处理:

from fastapi.responses import StreamingResponse

@app.post("/v1/chat/completions")
async def chat_stream(request: ChatRequest):
    async def generate():
        async with httpx.AsyncClient() as client:
            async with client.stream("POST", url, json=request.dict()) as response:
                async for chunk in response.aiter_text():
                    yield f"data: {chunk}\n\n"
    
    return StreamingResponse(generate(), media_type="text/event-stream")

坑点:httpx 的 stream 和 aiter_text 要注意编码,否则中文会乱码。

超时控制

大模型响应慢,默认 5 秒超时不够:

from concurrent.futures import ThreadPoolExecutor

executor = ThreadPoolExecutor(max_workers=4)

def log_async(*args):
    executor.submit(write_log, *args)
timeout = httpx.Timeout(60.0, connect=10.0)

并发性能

FastAPI 默认用 async,但某些阻塞操作(如日志写入)会拖垮:

from concurrent.futures import ThreadPoolExecutor

executor = ThreadPoolExecutor(max_workers=4)

def log_async(*args):
    executor.submit(write_log, *args)

部署

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

docker build -t api-gateway .
docker run -d -p 8000:8000 api-gateway

生产环境注意事项

这套架构已经在实际项目中跑了一段时间,几点经验:

Key 池管理:建议用 Redis 存储 Key 状态,避免单点故障
限流策略:按用户 + 按 Key 双重限流,防止被刷
日志采集:接入 Prometheus + Grafana,实时监控 QPS 和延迟
灰度发布:新模型接入时,先切 5% 流量观察稳定性

总结

统一接口Pydantic 模型 + FastAPI 路由,新增模型只需改配置
厂商适配配置化路由表,一行代码接入新厂商
负载均衡Key 池轮询,多 Key 自动轮询
熔断降级tenacity 重试,失败自动切换备用
流式输出StreamingResponse + SSE,支持 SSE 流式返回

关于作者

独立开发者,专注后端架构与 AI 工程化。
做过多个大模型接入相关的项目,熟悉 DeepSeek、OpenAI、Claude 等主流厂商的 API 对接和性能优化。
有技术问题欢迎交流。


 

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值