FastAPI開發(fā)AI應(yīng)用:添加深度思考功能
本文將深入講解如何在 FastAPI AI 聊天應(yīng)用中接入 DeepkSeek 等有深度思考功能的模型時(shí),如何讓 AI 能夠展示其推理過程, 提升用戶對(duì) AI 回答的理解和信任度。通過本教程,你將學(xué)會(huì)如何處理 AI 模型的 reasoning_content (思考內(nèi)容)輸出, 并在前端優(yōu)雅地展示思考過程。
項(xiàng)目地址:https://github.com/wayn111/fastapi-ai-chat-demo
溫馨提示:本文全文約七千字,看完約需 10 分鐘。
本章概述
深度思考功能的核心在于正確處理兩種不同類型的數(shù)據(jù)流。本項(xiàng)目將使用 openai python sdk 提供的通用方式來檢測(cè) reasoning_content 和 content 字段來區(qū)分不同類型的內(nèi)容,前端則根據(jù) type 字段進(jìn)行差異化渲染。

核心功能
- 思考過程可視化:實(shí)時(shí)展示 AI 的推理步驟和思考邏輯
- 雙重內(nèi)容流:后端代碼如何區(qū)分思考內(nèi)容(reasoning_content)和最終回答(content)
- 差異化展示:前端展示時(shí),思考內(nèi)容和最終回答采用不同的視覺樣式
技術(shù)棧
- 后端框架:FastAPI(高性能異步 Web 框架)
- AI 集成:OpenAI SDK(支持 reasoning_content 的模型,比如 DeepSeek)
- 流式協(xié)議:Server-Sent Events(SSE)
- 前端渲染:Marked.js + Highlight.js(Markdown 和代碼高亮)
- 樣式設(shè)計(jì):HTML5 + CSS3(差異化視覺效果)
支持深度思考的模型
- OpenAI:o4-mini
- DeepSeek:deepseek-reasoner
- Qwen:qwen-plus
核心設(shè)計(jì)
設(shè)計(jì)理念
深度思考功能的實(shí)現(xiàn)基于三個(gè)核心設(shè)計(jì)原則:
1. 內(nèi)容分離原則思考內(nèi)容(reasoning_content)和最終回答(content)是兩個(gè)獨(dú)立的數(shù)據(jù)流,需要分別處理和展示。這樣可以讓用戶清楚地區(qū)分 AI 的思考過程和最終結(jié)論。
2. 實(shí)時(shí)展示原則思考過程應(yīng)該實(shí)時(shí)展示,讓用戶能夠跟隨 AI 的思維軌跡。這不僅提升了用戶體驗(yàn),還增加了 AI 回答的透明度和可信度。
3. 視覺區(qū)分原則思考內(nèi)容和最終回答需要采用不同的視覺樣式,讓用戶能夠一眼區(qū)分兩種不同類型的內(nèi)容。
代碼分層
深度思考功能的架構(gòu)分為三個(gè)清晰的層次:
1. 通用處理層(OpenAICompatibleProvider(BaseAIProvider))
這一層負(fù)責(zé)處理 AI 模型的原始輸出,識(shí)別和分離 reasoning_content 和 content:
# class OpenAICompatibleProvider(BaseAIProvider):
asyncdef generate_streaming_response(
self,
messages: List[AIMessage],
**kwargs
) -> AsyncGenerator[str, None]:
"""
生成流式AI響應(yīng),支持深度思考內(nèi)容
Args:
messages: 對(duì)話歷史消息列表
**kwargs: 其他參數(shù)
Yields:
str: 流式響應(yīng)內(nèi)容片段,包含類型標(biāo)識(shí)
"""
try:
# 格式化消息并構(gòu)建請(qǐng)求參數(shù)
system_prompt = kwargs.get('system_prompt')
formatted_messages = self.format_messages(messages, system_prompt)
request_params = self._build_request_params(formatted_messages, stream=True, **kwargs)
logger.info(f"調(diào)用{self.get_provider_display_name()}流式API - 模型: {request_params['model']}")
# 調(diào)用流式API
response = self.client.chat.completions.create(**request_params)
chunk_count = 0
import json
for chunk in response:
# 處理深度思考內(nèi)容
if hasattr(chunk.choices[0].delta, 'reasoning_content') and chunk.choices[0].delta.reasoning_content:
content = chunk.choices[0].delta.reasoning_content
chunk_count += 1
# 返回帶類型標(biāo)識(shí)的思考內(nèi)容
yieldf"data: {json.dumps({'type': 'reasoning', 'content': content})}\n\n"
# 處理普通回答內(nèi)容
elif hasattr(chunk.choices[0].delta, 'content') and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
chunk_count += 1
# 返回帶類型標(biāo)識(shí)的回答內(nèi)容
yieldf"data: {json.dumps({'type': 'content', 'content': content})}\n\n"
logger.info(f"{self.get_provider_display_name()}流式響應(yīng)完成 - 塊數(shù): {chunk_count}")
except Exception as e:
logger.error(f"{self.get_provider_display_name()}流式響應(yīng)失敗: {e}")
yieldf"抱歉,{self.get_provider_display_name()}流式服務(wù)暫時(shí)不可用:{str(e)}"核心特點(diǎn):
- 雙重檢測(cè):在返回的 response 中同時(shí)檢測(cè) reasoning_content 和 content 字段
- 類型標(biāo)識(shí):為每個(gè)數(shù)據(jù)塊添加 type 字段,便于前端區(qū)分處理 reasoning_content 和 content
- JSON 格式:使用結(jié)構(gòu)化的 JSON 格式傳輸數(shù)據(jù)
- 錯(cuò)誤處理:完善的異常處理機(jī)制
2. 接口傳輸層(FastAPI)
在 main.py 的流式響應(yīng)處理中,系統(tǒng)會(huì)解析每個(gè)數(shù)據(jù)塊并只保存 type: 'content' 的內(nèi)容到 Redis, 在大模型的多輪對(duì)話記憶中,無需添加 reasoning_content 字段。
full_response = ""
content_only_response = ""# 只保存 type: 'content' 的內(nèi)容
chunk_count = 0
asyncfor chunk in ai_manager.generate_streaming_response(
messages=ai_messages,
provider=provider,
model=model,
system_prompt=system_prompt
):
if chunk:
full_response += chunk
chunk_count += 1
# 解析chunk數(shù)據(jù),只保留 type: 'content' 的內(nèi)容到Redis
try:
if chunk.startswith("data: "):
json_str = chunk[6:].strip() # 移除 "data: " 前綴
if json_str:
chunk_data = json.loads(json_str)
# 只累積 type 為 'content' 的內(nèi)容用于保存到Redis
if chunk_data.get('type') == 'content'and'content'in chunk_data:
content_only_response += chunk_data['content']
except (json.JSONDecodeError, KeyError) as e:
# 如果解析失敗,按原來的方式處理(向后兼容)
logger.debug(f"解析chunk數(shù)據(jù)失敗,使用原始內(nèi)容: {e}")
yield chunk
logger.info(f"流式響應(yīng)完成 - 用戶: {user_id}, 會(huì)話: {session_id[:8]}..., 塊數(shù): {chunk_count}, 總長度: {len(full_response)}, 內(nèi)容長度: {len(content_only_response)}")
# 保存AI響應(yīng)(只保存 type: 'content' 的內(nèi)容)
ai_msg = ChatMessage(
role="assistant",
cnotallow=content_only_response, # 使用過濾后的內(nèi)容
timestamp=time.time()
)
await save_message_to_redis(user_id, session_id, ai_msg)3. 前端展示層(JavaScript)
這一層負(fù)責(zé)接收數(shù)據(jù)并進(jìn)行差異化展示:
// 項(xiàng)目中的實(shí)際前端處理邏輯
if (data.type === 'chunk' || data.type === 'content' || data.type === 'reasoning') {
if (data.type === 'reasoning') {
// 深度思考內(nèi)容
if (!reasoningElement) {
reasoningElement = document.createElement('div');
reasoningElement.className = 'message-content reasoning-content';
// 創(chuàng)建reasoning-body容器
const reasoningBody = document.createElement('div');
reasoningBody.className = 'reasoning-body';
reasoningElement.appendChild(reasoningBody);
// 將reasoning元素添加到消息容器的content wrapper中
const contentWrapper = messageContainer.querySelector('.message-content-wrapper');
contentWrapper.appendChild(reasoningElement);
}
reasoningMessage += data.content;
...
scrollToBottom();
} else {
// 普通內(nèi)容
if (!contentElement) {
contentElement = document.createElement('div');
contentElement.className = 'message-content';
// 將content元素添加到消息容器的content wrapper中
const contentWrapper = messageContainer.querySelector('.message-content-wrapper');
contentWrapper.appendChild(contentElement);
}
contentMessage += data.content;
...
scrollToBottom();
}
scrollToBottom();
}前端在接受 SSE 響應(yīng)上,要區(qū)分 data 返回的 type 類型是 reason 還是 content,以此作不同展示。
啟動(dòng)一下
python start_server.py打開瀏覽器訪問:http://localhost:8000
測(cè)試一下深度思考功能~
選擇 deepseek-reasoner,進(jìn)行模型問答,
圖片
1. 數(shù)學(xué)問題求解用戶:證明勾股定理
圖片
2. 編程問題分析
用戶:設(shè)計(jì)一個(gè)高效的排序算法
圖片
總結(jié)
本文詳細(xì)介紹了在 FastAPI AI 聊天應(yīng)用中集成深度思考功能的完整實(shí)現(xiàn)方案。通過分層設(shè)計(jì)(通用處理層、接口傳輸層、前端展示層),成功實(shí)現(xiàn)了 AI 推理過程的可視化展示。
最后覺得本文寫的不錯(cuò)的話,可以關(guān)注我,我會(huì)繼續(xù)更新 FastAPI 框架開發(fā) AI 聊天應(yīng)用代碼。






























