基于FastAPI+AsyncOpenAI 实现大模型异步流式/非流式接口开发
一、功能概述
本文分享基于Python异步生态,结合FastAPI框架与OpenAI官方异步客户端,实现大模型的SSE流式响应与非流式同步响应完整开发方案。实现了模型客户端统一封装、流式消息推送、自定义文本流式输出、异常捕获处理等核心能力,接口适配主流大模型的OpenAI兼容协议,可灵活切换不同模型配置。
二、核心依赖库
import asyncio
import json
from fastapi import Request, HTTPException
from sse_starlette import EventSourceResponse
from openai import AsyncOpenAI
asyncio:Python原生异步任务处理库,支撑所有异步逻辑FastAPI:高性能异步Web框架,用于构建接口服务sse_starlette:实现服务端推送事件(SSE),支撑流式响应核心能力AsyncOpenAI:OpenAI官方异步客户端,对接大模型的OpenAI兼容接口json:数据序列化与反序列化,统一接口返回格式HTTPException:FastAPI标准异常抛出,规范错误响应
三、核心模块设计与完整代码实现
整体核心代码(完整可运行)
import asyncio
import json
from fastapi import Request, HTTPException
from sse_starlette import EventSourceResponse
from openai import AsyncOpenAI
from src.config import base_config
# ===================== 核心方法区 =====================
async def get_openai_client(model_cfg_name: str):
"""组装并返回OpenAI异步客户端 + 模型名称"""
model_cfg = base_config.get_active_profile()[model_cfg_name]
model_name = model_cfg.get('model_name')
model_server = model_cfg.get('model_server')
access_token = model_cfg.get('access_token')
# 构建请求头
headers = {"Content-Type": "application/json"}
if access_token:
headers["Authorization"] = f"Bearer {access_token}"
# 初始化异步客户端
return AsyncOpenAI(
api_key="EMPTY",
base_url=model_server,
default_headers=headers
), model_name
async def get_stream(question: str, model_cfg_name: str):
"""流式请求统一入口 - 返回SSE流式响应对象"""
async def event_generator():
async for chunk in stream_chat(question, model_cfg_name):
yield chunk
return EventSourceResponse(event_generator(), media_type="text/event-stream")
async def stream_chat(question: str, model_cfg_name: str):
"""异步流式请求核心逻辑:调用大模型,逐段返回流式数据"""
client, model_name = await get_openai_client(model_cfg_name)
try:
completion = await client.chat.completions.create(
model=model_name,
max_tokens=8196,
temperature=0,
stream=True,
messages=[{"role": "user", "content": question}]
)
# 逐块迭代流式返回数据
async for chunk in completion:
chunk_content = chunk.choices[0].delta.content or ""
data = json.dumps({"text": chunk_content}, ensure_ascii=False)
yield data
except Exception as e:
# 异常捕获,返回标准化错误信息
error_data = json.dumps({"error": f"SSE API ERROR: {str(e)}"})
yield error_data
async def get_no_stream(question: str, model_cfg_name: str):
"""异步非流式请求接口:一次性返回完整响应结果"""
client, model_name = await get_openai_client(model_cfg_name)
try:
completion = await client.chat.completions.create(
model=model_name,
max_tokens=8196,
temperature=0,
stream=False,
messages=[{"role": "user", "content": question}]
)
result_json = completion.choices[0].message.content or ""
return result_json
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
async def test_no_stream(model_cfg_name: str):
"""非流式测试专用接口:固定提问内容,快速校验服务连通性"""
client, model_name = await get_openai_client(model_cfg_name)
try:
completion = await client.chat.completions.create(
model=model_name,
max_tokens=10,
temperature=0,
stream=False,
messages=[{"role": "user", "content": "你好"}]
)
result_json = completion.choices[0].message.content or ""
return result_json
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
async def own_stream_output(request: Request, text: str):
"""自定义字符串转流式响应:模拟大模型流式输出,适配相同前端逻辑"""
async def own_event_generator():
for char in text:
# 检测客户端断开连接,立即终止推送
if await request.is_disconnected():
break
data = json.dumps({"text": char}, ensure_ascii=False)
yield data
# 延迟避免消息推送过快,优化前端接收体验
await asyncio.sleep(0.01)
return EventSourceResponse(own_event_generator(), media_type="text/event-stream")
# ===================== 本地测试代码区 =====================
if __name__ == "__main__":
user_question = """你是谁"""
# 测试非流式接口
asyncio.run(get_no_stream(user_question, "model_qwen"))
# 测试流式接口(需结合FastAPI路由调用)
# asyncio.run(get_stream(user_question, "model_qwen"))
四、核心模块详解
1. 统一客户端封装 get_openai_client
- 核心作用:解耦模型配置与业务逻辑,根据配置名称动态读取模型服务地址、模型名称、令牌信息
- 关键细节:初始化
AsyncOpenAI时api_key传固定值EMPTY,真实鉴权通过请求头的Bearer Token实现,适配私有化部署的大模型服务 - 返回值:异步客户端实例 + 模型名称,供后续接口统一调用
2. 流式响应核心能力
(1)流式入口 get_stream
- 基于
EventSourceResponse创建SSE流式响应对象,指定媒体类型text/event-stream - 通过内部异步生成器
event_generator迭代获取流式数据,标准化流式返回格式
(2)流式请求逻辑 stream_chat
- 核心参数配置:
max_tokens=8196(最大生成长度)、temperature=0(生成结果无随机性,固定输出)、stream=True(开启流式) - 数据处理:异步迭代大模型返回的
chunk,提取增量文本内容,序列化为JSON字符串后逐段yield - 异常处理:全局捕获异常,返回标准化错误JSON,保证前端能统一解析
(3)自定义流式输出 own_stream_output
- 业务价值:无需调用大模型,将自定义文本内容模拟成流式输出,用于前端联调、兜底返回、静态文本流式展示等场景
- 核心特性:支持客户端断连检测,避免无效数据推送;添加毫秒级延迟,解决前端渲染卡顿问题;返回格式与真实大模型流式输出一致,前端无需修改逻辑
3. 非流式响应能力
(1)通用非流式 get_no_stream
- 一次性请求,一次性返回完整的大模型响应结果,适用于短文本问答、不需要实时展示的场景
- 异常抛出:捕获异常后抛出
HTTPException,返回500状态码+错误详情,符合FastAPI的异常处理规范
(2)测试专用非流式 test_no_stream
- 简化版非流式接口,固定提问内容为
你好,缩小max_tokens,用于快速校验模型服务是否连通、配置是否正确
五、核心配置与参数说明
| 参数名 | 取值/默认值 | 作用说明 |
|---|---|---|
stream | True/False | 控制是否开启流式响应,True=流式,False=非流式 |
max_tokens | 8196/10 | 大模型最大生成token数,限制返回内容长度 |
temperature | 0 | 生成温度,0为最小随机性,数值越大结果越多样 |
model_cfg_name | 自定义配置名 | 模型配置标识,用于切换不同大模型/不同部署环境 |
六、核心设计亮点
- 纯异步实现:全链路基于
async/await,无同步阻塞逻辑,大幅提升接口的并发处理能力,适配高请求量场景 - 逻辑解耦:配置读取、客户端创建、流式/非流式逻辑完全分离,便于后续扩展新模型、修改配置
- 健壮性保障:包含客户端断连检测、全局异常捕获、标准化返回格式,线上运行更稳定
- 灵活适配:流式与非流式接口共存,自定义流式输出兼容相同前端解析逻辑,开发成本低
七、本地测试方式
- 非流式测试:直接运行脚本,通过
asyncio.run()调用get_no_stream即可快速验证模型连通性与返回结果 - 流式测试:需在FastAPI中配置路由,通过接口请求触发流式返回,例如:
@app.get("/stream")绑定get_stream方法
八、适用场景
- 流式接口:在线对话、实时内容生成、长文本回复等需要前端实时展示的场景
- 非流式接口:批量问答、后台任务调用、短文本查询等无需实时展示的场景
- 自定义流式:前端联调、兜底提示语展示、静态内容流式渲染等轻量场景

1037

被折叠的 条评论
为什么被折叠?



