FastAPI 開發(fā) AI 應(yīng)用一:實(shí)現(xiàn)連續(xù)多輪對話
本文將通過一個(gè)完整的實(shí)戰(zhàn)項(xiàng)目,介紹如何使用 FastAPI 框架開發(fā) AI 聊天應(yīng)用,重點(diǎn)講解連續(xù)多輪對話的實(shí)現(xiàn)原理和核心技術(shù)。即使你是編程新手,也能跟著本教程一步步構(gòu)建出功能完整的 AI 聊天應(yīng)用。
本項(xiàng)目已經(jīng)開源之 Github,項(xiàng)目地址:https://github.com/wayn111/fastapi-ai-chat-demo。

一、項(xiàng)目概述
想象一下,你正在和一個(gè)聰明的 AI 助手對話,它不僅能回答你的問題,還能記住你們之前聊過的內(nèi)容。這就是我們要構(gòu)建的 AI 聊天應(yīng)用!
1. 核心功能
- 連續(xù)多輪對話:AI 能記住對話歷史,就像和真人聊天一樣自然
- 多角色切換:可以選擇不同的 AI 角色(智能助手、AI 老師、編程專家)
- 流式響應(yīng):AI 回復(fù)時(shí)有打字機(jī)效果,體驗(yàn)更流暢
- 會話管理:支持多個(gè)對話會話,可以隨時(shí)切換
- Web 界面:簡潔美觀的聊天界面,操作簡單
2. 技術(shù)棧
- 后端框架:FastAPI(Python 的現(xiàn)代 Web 框架)
- 數(shù)據(jù)存儲:Redis(高性能內(nèi)存數(shù)據(jù)庫)
- AI 模型:支持 OpenAI 接口請求調(diào)用
- 前端:HTML + CSS + JavaScript
- 服務(wù)器:Uvicorn(高性能 ASGI 服務(wù)器)
二、核心架構(gòu)
1. 應(yīng)用初始化
應(yīng)用啟動(dòng)時(shí)需要完成幾個(gè)關(guān)鍵的初始化步驟,就像搭建房子需要先打地基一樣:
(1) 創(chuàng)建 Web 應(yīng)用框架
使用 FastAPI 創(chuàng)建應(yīng)用實(shí)例,這是整個(gè)系統(tǒng)的核心。FastAPI 會自動(dòng)生成 API 文檔,讓開發(fā)和調(diào)試變得更簡單。
(2) 連接數(shù)據(jù)存儲
Redis 就像應(yīng)用的"大腦記憶",用來存儲所有的對話歷史。選擇 Redis 是因?yàn)樗俣瓤臁⒅С謹(jǐn)?shù)據(jù)過期,非常適合聊天應(yīng)用的場景。
(3) 連接 AI 服務(wù)
這是連接到 OpenAI 的"橋梁",讓我們能夠調(diào)用 GPT 模型進(jìn)行智能對話。通過配置 API 密鑰和基礎(chǔ) URL,建立與 AI 服務(wù)的通信通道。
(4) 配置 AI 角色
通過不同的"人設(shè)"提示詞,讓 AI 扮演不同的角色:
- 智能助手:友善專業(yè),適合日常問答
- AI 老師:耐心教學(xué),善于解釋復(fù)雜概念
- 編程專家:技術(shù)專業(yè),提供代碼建議
每個(gè)角色都有獨(dú)特的回答風(fēng)格,讓用戶獲得更個(gè)性化的體驗(yàn)。
2. 數(shù)據(jù)模型設(shè)計(jì)
在聊天應(yīng)用中,我們需要一個(gè)標(biāo)準(zhǔn)的"消息格式"來確保數(shù)據(jù)的一致性。就像寄信需要標(biāo)準(zhǔn)的信封格式一樣:
class ChatMessage(BaseModel):
role: str # 誰說的話:"user"(用戶) 或 "assistant"(AI)
content: str # 說了什么:具體的對話內(nèi)容
timestamp: float # 什么時(shí)候說的:消息時(shí)間戳為什么需要這個(gè)格式?
- role 字段:幫助 AI 區(qū)分哪些是用戶的問題,哪些是自己的回答
- content 字段:存儲實(shí)際的對話內(nèi)容
- timestamp 字段:記錄時(shí)間,方便按時(shí)間順序顯示對話
這種標(biāo)準(zhǔn)化的數(shù)據(jù)格式讓我們的應(yīng)用更加穩(wěn)定可靠,也方便后續(xù)的功能擴(kuò)展。
3. 多輪對話實(shí)現(xiàn)原理
多輪對話的"秘密"在于讓 AI 能夠"記住"之前聊過的內(nèi)容。就像人類對話一樣,我們需要上下文來理解當(dāng)前的話題。
(1) 工作原理
想象 AI 的"記憶"是這樣工作的:
① 系統(tǒng)角色設(shè)定:"你是一個(gè)友善的 AI 助手"
② 歷史對話:
- 用戶:"我叫小明"
- AI:"你好小明!"
- 用戶:"我喜歡編程"
- AI:"編程很有趣!"
③ 當(dāng)前問題:"你還記得我的名字嗎?"
當(dāng) AI 收到新問題時(shí),它會看到完整的對話歷史,所以能回答:"當(dāng)然記得,你是小明!"
4. 會話管理
會話管理就像給每個(gè)用戶分配一個(gè)"聊天房間",讓 AI 能夠記住每個(gè)用戶的對話歷史。
(1) 核心功能說明
① 生成會話 ID
def generate_session_id() -> str:
return str(uuid.uuid4())每個(gè)用戶開始聊天時(shí),系統(tǒng)會生成一個(gè)唯一的"房間號"(會話 ID),就像酒店給客人分配房間一樣。
② 保存對話消息
def save_message(user_id: str, session_id: str, message: ChatMessage):
conversation_key = get_conversation_key(user_id, session_id)
redis_client.lpush(conversation_key, json.dumps(message_data))
redis_client.ltrim(conversation_key, 0, 19) # 只保留最近20條消息通過 userid + 會話 id 生成 key,將消息保存到 Redis 隊(duì)列中
③ 獲取對話歷史
def get_conversation_history(user_id: str, session_id: str):
conversation_key = get_conversation_key(user_id, session_id)
messages = redis_client.lrange(conversation_key, 0, -1)
return [json.loads(msg) for msg in messages]從 userid + 會話 id 生成 key,從 Redis 中讀取用戶該會話的歷史消息,讓 AI 了解之前聊了什么
(2) 為什么這樣設(shè)計(jì)?
- 唯一性:每個(gè)會話都有獨(dú)特的 ID,避免混淆
- 持久化:消息存儲在 Redis 中,重啟應(yīng)用也不會丟失
- 性能優(yōu)化:只保留最近的消息,避免內(nèi)存占用過大
- 自動(dòng)清理:每次只保留最近 20 條消息,自動(dòng)清理舊數(shù)據(jù)
這種設(shè)計(jì)讓 AI 能夠"記住"每個(gè)用戶的對話歷史,實(shí)現(xiàn)真正的多輪對話體驗(yàn)。
5. 流式響應(yīng)核心
流式響應(yīng)就像 AI 在"實(shí)時(shí)打字",讓用戶看到回復(fù)逐字出現(xiàn),而不是等待很久后一次性顯示全部內(nèi)容。
(1) 工作流程
① 保存用戶消息
user_msg = ChatMessage(role="user", content=user_message)
save_message(session_id, user_msg)首先將用戶的問題保存到"聊天記錄本"中。
② 獲取對話歷史
history = get_conversation_history(session_id, limit=10)讀取最近 10 條對話記錄,讓 AI 了解聊天的上下文。
③ 構(gòu)建完整對話
messages = [
{"role": "system", "content": AI_ROLES[role]}, # AI角色設(shè)定
*history, # 歷史對話
{"role": "user", "content": user_message} # 當(dāng)前問題
]將角色設(shè)定、歷史對話和當(dāng)前問題組合成完整的對話上下文。
④ 調(diào)用 AI 服務(wù)
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
stream=True # 關(guān)鍵:啟用流式響應(yīng)
)在 openAi 接口請求格式中,stream=True 表示啟用流式響應(yīng)。
⑤ 實(shí)時(shí)返回回復(fù)
for chunk in response:
if chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
yield f"data: {json.dumps({'content': content})}\n\n"AI 每生成一小段文字,就立即發(fā)送給前端顯示。
(2) 技術(shù)亮點(diǎn)
- Server-Sent Events (SSE) :使用 SSE 協(xié)議實(shí)現(xiàn)服務(wù)器向?yàn)g覽器的實(shí)時(shí)推送
- 異步處理:不阻塞其他用戶的請求
- 錯(cuò)誤恢復(fù):網(wǎng)絡(luò)中斷時(shí)能夠優(yōu)雅處理
- 上下文保持:每次對話都能"記住"之前聊過的內(nèi)容
這種設(shè)計(jì)讓聊天體驗(yàn)更加自然流暢,就像和真人對話一樣!
二、核心功能實(shí)現(xiàn)
1. API 接口設(shè)計(jì)
我們的聊天應(yīng)用提供了 5 個(gè)核心 API 接口,就像一個(gè)完整的"聊天服務(wù)臺":
(1) 開始新對話
@app.post("/chat/start")
async def start_chat(user_id: str):
session_id = generate_session_id()
return {"session_id": session_id, "welcome_message": "你好!我是你的AI助手"}功能:為每個(gè)用戶創(chuàng)建一個(gè)新的"聊天房間",返回房間號(會話 ID)。
(2) 流式聊天
@app.get("/chat/stream")
async def chat_stream(user_id: str, session_id: str, message: str, role: str = "assistant"):
return StreamingResponse(generate_streaming_response(user_id, session_id, message, role))功能:這是核心接口!處理用戶消息,調(diào)用 AI 生成回復(fù),并實(shí)時(shí)返回。
(3) 獲取聊天歷史
@app.get("/chat/history")
async def get_chat_history(user_id: str, session_id: str):
history = await get_conversation_history(user_id, session_id)
return {"messages": history, "total": len(history)}功能:查看之前的聊天記錄,就像翻看聊天記錄本。
(4) 清除對話歷史
@app.delete("/chat/history/{session_id}")
async def clear_conversation_history(session_id: str, user_id: str):
redis_client.delete(get_conversation_key(user_id, session_id))
return {"message": "對話歷史已清除"}功能:清空聊天記錄,重新開始對話。
(5) 獲取 AI 角色列表
@app.get("/roles")
async def get_roles():
return {"roles": AI_ROLES, "default_role": "assistant"}功能:獲取所有可用的 AI 角色(助手、老師、程序員等)。
安全特性:
- 參數(shù)驗(yàn)證:檢查輸入?yún)?shù)的有效性
- 錯(cuò)誤處理:優(yōu)雅處理各種異常情況
- CORS 支持:允許跨域訪問
- 速率限制:防止惡意請求(可選)
2. 前端實(shí)現(xiàn)
前端就是用戶看到和操作的界面,我們用 HTML、CSS 和 JavaScript 構(gòu)建了一個(gè)現(xiàn)代化的聊天界面。
(1) 界面結(jié)構(gòu)
我們的聊天界面包含幾個(gè)主要部分:
<div class="chat-container">
<!-- 1. 頭部:顯示標(biāo)題和角色選擇 -->
<div class="chat-header">
<h1>?? AI智能助手</h1>
<select id="roleSelect">
<option value="assistant">?? 智能助手</option>
<option value="teacher">???? AI老師</option>
<option value="programmer">???? 編程專家</option>
</select>
</div>
<!-- 2. 消息區(qū)域:顯示對話內(nèi)容 -->
<div class="messages-container" id="messagesContainer">
<!-- 消息會動(dòng)態(tài)添加到這里 -->
</div>
<!-- 3. 輸入?yún)^(qū)域:用戶輸入消息 -->
<div class="input-container">
<input type="text" id="messageInput" placeholder="輸入你的消息...">
<button onclick="sendMessage()">?? 發(fā)送</button>
</div>
<!-- 4. 工具欄:常用功能按鈕 -->
<div class="toolbar">
<button onclick="clearHistory()">??? 清除歷史</button>
<button onclick="newChat()">?? 新對話</button>
</div>
</div>(2) 樣式設(shè)計(jì)特點(diǎn)
- 現(xiàn)代化外觀:使用漸變色和圓角設(shè)計(jì)
- 消息氣泡:用戶消息在右邊(藍(lán)色),AI 消息在左邊(白色)
- 響應(yīng)式布局:在手機(jī)和電腦上都能正常顯示
- 動(dòng)畫效果:按鈕懸停效果和打字指示器
- 清晰層次:不同區(qū)域有明確的視覺分割
3. JavaScript 核心邏輯
JavaScript 負(fù)責(zé)處理用戶交互和與后端的通信,就像聊天應(yīng)用的"大腦"。
(1) 核心功能實(shí)現(xiàn)
① 開始新對話
async function startNewChat() {
// 調(diào)用后端API創(chuàng)建新會話
const response = await fetch('/api/chat/start', { method: 'POST' });
const data = await response.json();
currentSessionId = data.session_id;
// 顯示歡迎消息
addMessage('assistant', '你好!我是你的AI助手,有什么可以幫助你的嗎?');
}② 發(fā)送消息
async function sendMessage() {
const message = document.getElementById('messageInput').value;
// 顯示用戶消息
addMessage('user', message);
// 使用EventSource接收流式響應(yīng)
const eventSource = new EventSource(`/api/chat/stream?session_id=${currentSessionId}&message=${message}`);
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
if (data.content) {
// 實(shí)時(shí)顯示AI回復(fù)
updateAIMessage(data.content);
}
};
}③ 添加消息到界面
function addMessage(role, content) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${role}`;
// 用戶消息顯示在右邊,AI消息顯示在左邊
const icon = role === 'user' ? '??' : '??';
messageDiv.innerHTML = `${icon} ${content}`;
document.getElementById('messagesContainer').appendChild(messageDiv);
// 自動(dòng)滾動(dòng)到最新消息
messageDiv.scrollIntoView({ behavior: 'smooth' });
}④ 清除歷史記錄
async function clearHistory() {
if (confirm('確定要清除所有對話歷史嗎?')) {
await fetch(`/api/chat/history/${currentSessionId}`, { method: 'DELETE' });
document.getElementById('messagesContainer').innerHTML = '';
addMessage('system', '對話歷史已清除');
}
}(2) 技術(shù)亮點(diǎn)
- EventSource:實(shí)現(xiàn)服務(wù)器推送,讓 AI 回復(fù)實(shí)時(shí)顯示
- DOM 操作:動(dòng)態(tài)添加和更新聊天消息
- 用戶體驗(yàn):自動(dòng)滾動(dòng)、按鈕狀態(tài)管理、錯(cuò)誤提示
- 響應(yīng)式設(shè)計(jì):適配不同設(shè)備和屏幕尺寸
這些 JavaScript 代碼讓聊天界面變得生動(dòng)有趣,用戶可以流暢地與 AI 進(jìn)行對話!
三、如何開始項(xiàng)目
1. 環(huán)境準(zhǔn)備
在開始之前,請確保你的電腦已安裝:
- Python 3.8+ :編程語言環(huán)境
- Redis:數(shù)據(jù)存儲服務(wù)
- OpenAI API 密鑰:用于調(diào)用 AI 模型
2. 項(xiàng)目結(jié)構(gòu)
讓我們先了解一下項(xiàng)目的文件組織結(jié)構(gòu):
fastapi-ai-chat-demo/
├── main.py # ?? 主應(yīng)用文件(核心邏輯)
├── config.py # ?? 配置文件(參數(shù)設(shè)置)
├── start_server.py # ?? 服務(wù)器啟動(dòng)腳本
├── requirements.txt # ?? 依賴包列表
├── .env.example # ?? 環(huán)境變量模板
├── static/
│ └── index.html # ?? 前端聊天界面
└── README.md # ?? 項(xiàng)目說明文檔文件說明:
- main.py:包含所有的 API 接口和核心業(yè)務(wù)邏輯
- config.py:存放配置參數(shù),如 Redis 連接信息、OpenAI 設(shè)置等
- static/index.html:聊天界面的前端代碼
- requirements.txt:列出了項(xiàng)目需要的所有 Python 包
3. 安裝步驟
(1) 克隆項(xiàng)目
git clone git@github.com:wayn111/fastapi-ai-chat-demo.git
cd fastapi-ai-chat-demo(2) 安裝依賴包
pip install -r requirements.txt這會安裝以下核心包:
- fastapi:Web 框架
- uvicorn:ASGI 服務(wù)器
- redis:Redis 客戶端
- openai:OpenAI API 客戶端
- pydantic:數(shù)據(jù)驗(yàn)證庫
(3) 配置環(huán)境變量
復(fù)制 .env.example 為 .env 并填入你的配置:
# OpenAI配置
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_BASE_URL=https://api.openai.com/v1
# Redis配置
REDIS_HOST=localhost
REDIS_PORT=6379(4) 啟動(dòng) Redis 服務(wù)
# Windows
redis-server
# Linux/macOS
sudo systemctl start redis(5) 運(yùn)行應(yīng)用
python start_server.py(6) 訪問應(yīng)用
打開瀏覽器訪問:http://localhost:8000

恭喜!你的 AI 聊天應(yīng)用已經(jīng)運(yùn)行起來了!
四、總結(jié)
本項(xiàng)目展示了使用 FastAPI 構(gòu)建 AI 聊天應(yīng)用的完整流程,核心技術(shù)包括:
- 異步編程:提升并發(fā)處理能力
- 流式響應(yīng):改善用戶體驗(yàn)
- 會話管理:實(shí)現(xiàn)多輪對話記憶
- 角色系統(tǒng):支持多樣化 AI 交互
這個(gè)架構(gòu)具有良好的擴(kuò)展性,可以輕松添加用戶認(rèn)證、多模態(tài)交互等高級功能。FastAPI 的高性能和完善的類型系統(tǒng)使其成為構(gòu)建現(xiàn)代 AI 應(yīng)用的理想選擇。




































