FastAPI + OpenAI SDK 实战:接入 DeepSeek 大模型与流式问答全流程拆解
项目实践FastAPI 接入大模型与 LangChain 配置FastAPI OpenAI SDK 实战接入 DeepSeek 大模型与流式问答全流程拆解一、前言介绍1.1 背景1.2 功能概览1.3 调用模型总览二、环境准备OpenAI 依赖下载与配置2.1 下载安装 OpenAI SDK2.2 配置 API Key环境变量2.3 配置兼容端点 base_url2.4 目录结构三、知识点讲解3.1 OpenAI 兼容模式compatible-mode3.2 MaaS 端点与 DeepSeek 模型3.3 流式 SSE四、代码逻辑拆解严格对照项目代码4.1 请求体模型schemas4.2 密钥读取与客户端初始化4.3 一次问答接口case14.4 流式问答接口case24.5 路由注册到 FastAPI4.6 最小可运行验证脚本case.pyFastAPI OpenAI SDK 实战接入 DeepSeek 大模型与流式问答全流程拆解一、前言介绍1.1 背景后端服务迟早要接大模型智能问答、简历润色、岗位推荐话术生成都离不开一次把用户输入发给模型、把模型回答拿回来的往返。本文聚焦最朴素也最常用的一条链路——用 OpenAI 官方 SDK 调通一个兼容 OpenAI 协议的大模型接口并让它在 FastAPI 里以接口形式对外提供1.2 功能概览一次问答接口接收问题文本调用模型返回完整回答流式问答接口same 模型但以 SSEtext/event-stream逐字吐字前端体验接近打字机入参校验用 Pydantic 模型约束请求体LangChain 配置用ChatDeepSeek封装同一模型便于后续接链Chain、记忆Memory、检索Retriever。1.3 调用模型总览客户端 → FastAPI 路由async def → Pydantic 校验入参 → OpenAI 客户端 / LangChain ChatModel → 大模型兼容端点base_url → 模型DeepSeek → 同步返回 or SSE 流式返回二、环境准备OpenAI 依赖下载与配置这一节把OpenAI 这套东西怎么装、怎么配单独拎出来讲清楚和业务代码拆解分开方便照抄。2.1 下载安装 OpenAI SDKpipinstallopenai就这一个包项目里所有大模型调用都靠它。它不只是调 OpenAI 官方而是任何兼容 OpenAI 协议的服务都能调——这是后面能直连百炼 MaaS 的前提。2.2 配置 API Key环境变量密钥不放代码里从环境变量读# 项目代码里实际读取的变量名 DASHSCOPE_API_KEYsk-xxxxxxxx代码中的位置importos raw_keyos.getenv(DASHSCOPE_API_KEY)api_keyraw_key.strip()第 1 行从环境变量取百炼 API Key第 2 行strip()去掉首尾空白防止复制 Key 时带入换行导致鉴权失败。2.3 配置兼容端点 base_url项目代码里写死的端点是阿里云百炼的 MaaS 兼容地址base_urlhttps://ws-xxxx.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/compatible-mode/v1是兼容开关缺了 SDK 会按官方域名去请求必然 404。模型名跟着这个端点走项目里填的是deepseek-v4-pro。2.4 目录结构app/ ├── apis/ │ └── llm/ │ └── case1.py # 大模型接口一次问答 流式问答 ├── schemas/ │ └── llm_case1.py # 请求体模型 main.py # 路由注册 case.py # 最小可运行验证脚本脱离 Web 框架三、知识点讲解3.1 OpenAI 兼容模式compatible-modeOpenAI 把对话接口定义成一套固定的请求/响应形状messages列表 model字段返回choices[0].message.content。只要厂商把自家接口伪装成这个形状OpenAI 官方 SDK 就能原样调用只需要把base_url指过去。设计意识客户端与厂商解耦。今天接这个端点、明天换另一个只改base_url和model业务代码一行不动。3.2 MaaS 端点与 DeepSeek 模型项目里指向的是阿里云百炼的 MaaS 兼容端点模型名填deepseek-v4-probase_urlhttps://ws-xxxx.cn-beijing.maas.aliyuncs.com/compatible-mode/v1modeldeepseek-v4-pro模型名必须与端点所在平台提供的清单一致写错会返回model not found。本文代码里就是deepseek-v4-pro不另作替换。3.3 流式 SSE非流式接口等模型把整段话说完再返回延迟高、首字时间长。流式接口让模型边生成边回传HTTP 上用SSEServer-Sent Events承载每一片以data: 内容\n\n格式推给前端结束发data: [DONE]\n\n。FastAPI 用StreamingResponse配合生成器即可实现。四、代码逻辑拆解严格对照项目代码4.1 请求体模型schemasclassLLMCase1(BaseModel):question:strField(...,description问题)第 1 行BaseModel继承Pydantic v2 的请求体第 2 行question用Field(...)必填缺字段 FastAPI 自动返回 422省去手写校验。另一个预留的会话模型classLLMCase2(BaseModel):user_id:strField(...,description用户ID)session_id:strField(...,description会话ID)message:strField(...,description消息)三个字段全必填为后续多轮对话 会话隔离预留结构本篇先不展开多轮记忆。4.2 密钥读取与客户端初始化importosfromopenaiimportOpenAI raw_keyos.getenv(DASHSCOPE_API_KEY)api_keyraw_key.strip()clientOpenAI(api_keyapi_key,base_urlhttps://ws-xxxx.cn-beijing.maas.aliyuncs.com/compatible-mode/v1,)第 3 行从环境变量取密钥不落代码第 4 行strip()去掉首尾空白防止复制 Key 时带入换行导致鉴权失败第 6–9 行构造 OpenAI 客户端base_url指向 MaaS 兼容端点api_key作为 Bearer 令牌随请求发出。设计意识客户端构造成本低但每次请求都 new 一个没必要高并发下建议做成模块级单例或连接池避免重复握手。4.3 一次问答接口case1llm1_router.post(/case1,summaryLLM1-case1)asyncdefcase1_api(llm1:LLMCase1):completionclient.chat.completions.create(modeldeepseek-v4-pro,messages[{role:system,content:You are a helpful assistant.},{role:user,content:llm1.question},],)ai_replycompletion.choices[0].message.contentreturn{code:1,message:请求成功,data:{ai_reply:ai_reply}}第 1 行prefix/llm1的路由组下挂/case1summary会显示在 Swagger第 2 行用 Pydantic 模型收参自动校验第 4 行create发起一次对话model指定deepseek-v4-pro第 5–9 行messages是角色数组system设定助手人设user放用户问题——这是 OpenAI 协议的标准对话结构第 10 行choices[0].message.content取模型文本回答第 11–13 行包成{code, message, data}统一返回体前端按data.ai_reply取答案。4.4 流式问答接口case2defstream_chunk(user_querstr:str):clientOpenAI(api_keyapi_key,base_urlBASE_URL)completionclient.chat.completions.create(modeldeepseek-v4-pro,messages[{role:system,content:You are a helpful assistant.},{role:user,content:user_querstr},],streamTrue,stream_options{include_usage:True},)foriincompletion:ifi.choices:choisei.choices[0]ifchoise.delta:deitachoise.deltaifdeita.content:yieldfdata:{deita.content}\n\nyielddata: [DONE]\n\n第 5 行streamTrue打开流式SDK 不再等完整结果而是返回一个可迭代对象每轮给一片增量第 6 行stream_options{include_usage: True}让最后一片带上 token 用量统计计费/监控用第 8–13 行遍历增量i.choices[0].delta.content是这一片增量文字用if层层判空是因为心跳包、首片、结束片可能choices或delta为空第 14 行yield fdata:{内容}\n\n按 SSE 格式吐字\n\n是 SSE 的分片分隔符缺了前端收不到第 15 行结束标志data: [DONE]前端据此关闭连接。路由侧用StreamingResponse包裹生成器llm1_router.post(/case2,summary流式回答)asyncdefcase2_api(llm1:LLMCase1):returnStreamingResponse(stream_chunk(llm1.question),media_typetext/event-stream)media_typetext/event-stream告诉浏览器这是 SSE 流否则会被当成普通文本一次性缓冲。4.5 路由注册到 FastAPIfromapp.apis.llm.case1importllm1_router app.include_router(llm1_router)一行把大模型路由组挂进应用/llm1/case1、/llm1/case2即生效Swagger 里归到文本处理标签下。4.6 最小可运行验证脚本case.py脱离 Web 框架单独验证连通性importosfromopenaiimportOpenAI raw_keyos.getenv(DASHSCOPE_API_KEY)api_keyraw_key.strip()clientOpenAI(api_keyapi_key,base_urlhttps://ws-xxxx.cn-beijing.maas.aliyuncs.com/compatible-mode/v1,)defget_response():completionclient.chat.completions.create(modeldeepseek-v4-pro,messages[{role:system,content:You are a helpful assistant.},{role:user,content:国内大模型哪个最好},],)returncompletion.choices[0].message.contentprint(get_response())与接口代码共用同一套客户端初始化逻辑只是把问题写死、直接print用来在不起 FastAPI 的情况下先确认 Key、端点、模型名三件套是否配通是排障第一招。

相关新闻

苹果AI战略转向:Siri智能化升级与商业模式重塑

苹果AI战略转向:Siri智能化升级与商业模式重塑

上周,当苹果 CEO 蒂姆库克在财报电话会议上被问及 AI 战略时,他给出了一个看似模糊但信息量巨大的回答:“我们相信 AI 有巨大潜力,我们将继续以深思熟虑的方式投资和创新。” 紧接着,他话锋一转,提到了一个…

2026/10/30 10:26:55 阅读更多 →
安卓Wi-Fi已保存不自动连接:NETWORK_SELECTION_PERMANENTLY_DISABLED状态解析与修复

安卓Wi-Fi已保存不自动连接:NETWORK_SELECTION_PERMANENTLY_DISABLED状态解析与修复

1. 问题现象与根源初探“WIFI已保存,但死活不自动连接”——这大概是每个安卓用户都至少遭遇过一次的糟心体验。你明明记得之前连得好好的,密码也正确,可手机就是像个倔强的孩子,盯着那个显示“已保存”的Wi-Fi信号,死…

2026/10/28 14:36:19 阅读更多 →
【20年架构师亲测】:2024程序员AI工具选型终极指南——5大维度实测对比,错过再等一年?

【20年架构师亲测】:2024程序员AI工具选型终极指南——5大维度实测对比,错过再等一年?

更多请点击: https://codechina.net 第一章:程序员选哪个AI 程序员在选择AI工具时,核心考量应聚焦于代码理解深度、本地可部署性、IDE集成能力与私有数据安全。通用大模型虽能回答技术问题,但缺乏对项目上下文、私有API契约和内部…

2026/10/24 23:18:55 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/31 0:19:11 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/31 10:20:19 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/31 10:20:23 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/31 0:59:28 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/31 10:30:19 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/31 9:29:43 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 18:03:41 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 11:00:40 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 0:09:01 阅读更多 →