智能體開發(fā)技術(shù)(Python+FastAPI版) 課件 第1-4章 大模型與智能體開發(fā)- 每日新聞?wù)猒第1頁
智能體開發(fā)技術(shù)(Python+FastAPI版) 課件 第1-4章 大模型與智能體開發(fā)- 每日新聞?wù)猒第2頁
智能體開發(fā)技術(shù)(Python+FastAPI版) 課件 第1-4章 大模型與智能體開發(fā)- 每日新聞?wù)猒第3頁
智能體開發(fā)技術(shù)(Python+FastAPI版) 課件 第1-4章 大模型與智能體開發(fā)- 每日新聞?wù)猒第4頁
智能體開發(fā)技術(shù)(Python+FastAPI版) 課件 第1-4章 大模型與智能體開發(fā)- 每日新聞?wù)猒第5頁
已閱讀5頁,還剩176頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

大模型與智能體開發(fā)content目錄01對接云端大模型接口02本地部署大模型03AI智能體開發(fā)技術(shù)對接云端大模型接口01準備PyCharm開發(fā)環(huán)境安裝MinicondaPython運行環(huán)境的安裝和配置通常有兩種方式第一種方式是使用原生的Python安裝包直接在本地安裝Python,并利用pip命令安裝其他依賴庫;第二種方式是先配置Conda虛擬環(huán)境,再在Conda虛擬環(huán)境中安裝和配置Python環(huán)境。在Anaconda官方網(wǎng)站下載Miniconda安裝包,正常安裝即可。安裝完成后,需要創(chuàng)建一個Python運行環(huán)境,配置環(huán)境變量,打開或創(chuàng)建文件C:\Users\<用戶>\.condarc,添加一個envs_dirs變量,用于指定Python虛擬環(huán)境的默認安裝目錄,文件內(nèi)容大致如下。準備PyCharm開發(fā)環(huán)境對GPU提供支持打開命令提示符窗口,先利用condaactivate命令激活Python環(huán)境,再運行以下命令安裝PyTorch的GPU版本。condainstallpytorchtorchvisiontorchaudiopytorch-cuda-cpytorch-cnvidia此次安裝要下載約1.3GB大小的文件,安裝過程較為漫長。如果安裝過程并未報錯,則說明GPU版本安裝成功。如果安裝不成功,則可以考慮下載Python的擴展名為.whl的離線安裝文件,并運行“pipinstalltorch-2.3.1+cu121-xxxx.whl”命令進行安裝。安裝完成后,如果在運行Python代碼時出現(xiàn)以下錯誤,則需要配置操作系統(tǒng)環(huán)境變量KMP_DUPLICATE_LIB_OK=True或通過Python代碼進行臨時處理。準備PyCharm開發(fā)環(huán)境配置pip源為了使使用pip安裝第三方依賴庫時速度更快,建議將pip的源配置為國內(nèi)鏡像源。在用戶主目錄(即C:\Users\<用戶名>)下創(chuàng)建pip文件夾,并在該文件夾中創(chuàng)建文件pip.conf,內(nèi)容設(shè)置如下。準備PyCharm開發(fā)環(huán)境創(chuàng)建PyCharm項目PyCharm有專業(yè)版和社區(qū)版兩個版本,專業(yè)版提供對超文本標記語言(HypertextMarkupLanguage,HTML)界面的智能提示的支持,所以本書所有實驗和項目均在PyCharm專業(yè)版環(huán)境下開發(fā)調(diào)試。讀者可前往PyCharm官網(wǎng)下載其較新版本并完成安裝。對接通義千問申請通義千問的APIKey先訪問阿里云官網(wǎng),注冊一個賬號并進行實名認證,再選擇“大模型服務(wù)平臺百煉”選項,如圖1-2所示。對接通義千問在阿里云百煉界面中,創(chuàng)建APIKey,用于在Python調(diào)用其接口時進行鑒權(quán),如圖1-3所示。對接通義千問創(chuàng)建完APIKey后,可以進入API參考界面,查看各種AI模型的調(diào)用方法。阿里云文檔中心的功能非常完善,并且提供了針對各種編程語言的示例代碼供用戶參考,如圖1-4所示。對接通義千問使用OpenAI進行調(diào)用OpenAI公司是最早提供大模型API對接的廠商之一,因此,后續(xù)的一些AI廠商提供了兼容OpenAI軟件開發(fā)工具包(SoftwareDevelopmentKit,SDK)接口的對接方案。在Python中需要利用pipinstallopenai命令安裝SDK,并通過以下代碼完成對接。對接通義千問注意:APIKey不建議直接寫在代碼中,通常的做法是將其保存到項目的環(huán)境變量文件中,并通過dotenv庫進行調(diào)用,以便于統(tǒng)一維護。其操作步驟如下。(1)利用pip命令安裝第三方庫dotenv,具體命令為pipinstalldotenv。(2)在當(dāng)前項目的根目錄下創(chuàng)建一個文件.env(注意,文件名以.開頭),內(nèi)容如下。Dashscope_API_Key='sk-30a2d87612584e2697867a796b3d4f01'#如果有其他APIKey或系統(tǒng)級變量,則以同樣的方式進行定義即可在代碼中,直接通過dotenv庫的load_dotenv()函數(shù)將其內(nèi)容加載為環(huán)境變量,并進行讀取。對接DeepSeek使用Dashscope進行調(diào)用通義千問模型除能采用OpenAI兼容接口調(diào)用外,還因為阿里云本身也提供了SDK進行調(diào)用,所以只需在Python中利用pipinstalldashscope命令進行安裝即可直接使用。對接通義千問使用requests庫進行調(diào)用幾乎所有的AI模型廠商均提供了標準的HTTP接口,即使沒有提供SDK,也不影響使用Python或其他編程語言與AI模型進行交互。以下代碼展示了如何利用Python的requests庫通過發(fā)送原始HTTP請求的方式與AI模型進行通信。對接DeepSeek訪問DeepSeek的API開放平臺,并注冊賬號,創(chuàng)建DeepSeek的APIKey,如圖1-5所示。對接DeepSeek創(chuàng)建成功后,務(wù)必將明文的APIKey復(fù)制并保存。否則,下一次使用DeepSeek時需要重新創(chuàng)建APIKey。成功創(chuàng)建APIKey后,便可以在Python中進行調(diào)用了。DeepSeek同樣支持基于OpenAI的兼容模式調(diào)用,或直接使用HTTP進行調(diào)用,基礎(chǔ)的調(diào)用代碼如下。對接DeepSeek其調(diào)用過程與通義千問的調(diào)用過程基本一致,此處不做過多解釋。此外,通過Python的requests庫也可以正常調(diào)用DeepSeek,代碼如下。對接OpenRouter平臺登錄OpenRouter訪問OpenRouter官網(wǎng),單擊右上角的“Signin”按鈕進行登錄,目前支持3種登錄方式:Google、MetaMask及本站登錄。OpenRouter登錄界面如圖1-6所示。登錄成功后,可以查看OpenRouter支持的所有模型,其中包括DeepSeek、QWen、Claude、OpenAIO3等模型。對接OpenRouter平臺單擊登錄后的用戶頭像,選擇“Keys”選項,進入APIKey的管理界面創(chuàng)建APIKey即可。創(chuàng)建OpenRouter的APIKey如圖1-7所示。創(chuàng)建APIKey對接OpenRouter平臺如果確定需要長期使用OpenRouter,則需要綁定信用卡。目前,OpenRouter支持各類信用卡,國內(nèi)主要支持Visa信用卡。如果讀者沒有Visa信用卡,則無法綁定。新增支付界面如圖1-8所示。信用卡支付對接OpenRouter平臺OpenRouter平臺上的模型有很多,幾乎包含國內(nèi)外所有的主流大模型。下述代碼演示了如何調(diào)用Claude3.7,讀者如果感興趣,也可以在Cline、Continue或Copilot等AI編程助手中對接該模型輔助編程。因為本書的主題是智能體開發(fā),所以不單獨講解該部分內(nèi)容。對接OpenRouter本地部署大模型02安裝與配置Ollama01安裝與配置OllamaOllama是一個開源框架,專為在本地部署和管理大模型提供便利,支持在Windows、macOS和Linux上進行安裝,也可以通過Docker簡化部署。Ollama支持多種大模型,如CodeLlama、Qwen、DeepSeek、Gemma等,通過將模型權(quán)重、配置和數(shù)據(jù)捆綁到一個包中,有助于優(yōu)化設(shè)置和配置細節(jié),使整個安裝和配置過程變得非常簡單。安裝與配置Ollama01安裝與配置Ollama拉取并測試大模型當(dāng)完成上述安裝與配置后,即可訪問Ollama官網(wǎng)搜索各類大模型并進行拉取操作。此處以新發(fā)布的Qwen3大模型為例進行講解。在Ollama中搜索Qwen,找到并拉取Qwen3模型,如圖1-12所示。CherryStudio對接Ollama01安裝與配置1.CherryStudio是目前主流的一個AI對話應(yīng)用程序客戶端,非常適用于日常對話和進行各種大模型與智能體的調(diào)試。訪問其官網(wǎng)并下載對應(yīng)操作系統(tǒng)版本的安裝文件后正常安裝即可。為了方便后續(xù)調(diào)試模型上下文協(xié)議服務(wù)器,安裝CherryStudio后,建議讀者同步完成Node.js及相關(guān)組件的安裝。訪問Node.js官網(wǎng)下載并安裝Node.js,安裝完成后運行“node-v”命令,如果顯示正常的版本號,則說明安裝成功,如下所示。CherryStudio對接Ollama02對接OllamaCherryStudio是目前主流的一個AI對話應(yīng)用程序客戶端,非常適用于日常對話和進行各種大模型與智能體的調(diào)試。訪問其官網(wǎng)并下載對應(yīng)操作系統(tǒng)版本的安裝文件后正常安裝即可。為了方便后續(xù)調(diào)試模型上下文協(xié)議服務(wù)器,安裝CherryStudio后,建議讀者同步完成Node.js及相關(guān)組件的安裝。訪問Node.js官網(wǎng)下載并安裝Node.js,安裝完成后運行“node-v”命令,如果顯示正常的版本號,則說明安裝成功,如下所示。安裝與配置Ollama03CherryStudio對接Ollama2.對接OllamaCherryStudio提供了對接各類大模型的功能,不僅限于DeepSeek、Qwen、硅基流動、OpenAI、OpenRouter等,還支持對接本地的Ollama模型。當(dāng)啟動Ollama服務(wù)后,Ollama默認會開啟一個端口為11434的HTTP服務(wù),用于各類應(yīng)用程序或編程語言的調(diào)用。在CherryStudio中設(shè)置對接Ollama的Qwen3模型,如圖1-15所示。安裝與配置Ollama03CherryStudio對接Ollama完成模型的對接后,便可在CherryStudio的聊天窗口中進行模型測試。如果成功,則可以看到圖1-16所示的對話效果。調(diào)用OllamaAPI基于Ollama的SDK進行調(diào)用要使用Ollama的SDK調(diào)用大模型,需要先安裝Ollama的Python庫,利用pip命令進行安裝即可。調(diào)用OllamaAPI基于Ollama的SDK進行調(diào)用運行上述代碼即可調(diào)用Ollama的Qwen3模型并進行輸出。但是上述代碼的輸出過程通常會等待很久,因為未使用流式響應(yīng)進行處理。以下代碼采用改進的流式響應(yīng)模式進行輸出,輸出過程大大縮短了。調(diào)用OllamaAPI基于HTTP接口進行調(diào)用HTTP接口是Ollama另一種方式的接口調(diào)用,可以使用Python或其他編程語言進行調(diào)用,其通用性更強,可以訪問/ollama/ollama/blob/main/docs/api.md查看各類接口的請求規(guī)范。調(diào)用OllamaAPI在Ollama中實現(xiàn)多輪對話Ollama提供的接口/api/generate只能實現(xiàn)單次對話,即不帶記憶功能。為了實現(xiàn)常規(guī)AI對話中的帶記憶功能的多輪對話,可以調(diào)用/api/chat接口,此接口發(fā)送的消息主體為一個列表,可以保存前面的對話內(nèi)容進而實現(xiàn)記憶功能。調(diào)用OllamaAPI在Ollama中實現(xiàn)多輪對話(1)為了解決多輪對話的問題,此處使用了死循環(huán)來模擬用戶的多輪對話,當(dāng)然,在調(diào)試代碼時可以隨時停止代碼運行。(2)增加了系統(tǒng)提示詞,即"role":"system",這是AI模型標準角色設(shè)定。該系統(tǒng)提示詞指示模型不需要進行思考,直接回答問題,以節(jié)省調(diào)試時間,簡化模型輸出。是否省略思考過程,完全由開發(fā)者自行決定,并無好壞之分。通常來說,對于一些復(fù)雜的推理過程,可以對其思考過程進行展示,但是一般的常規(guī)問答可以不展示。除此之外,在AI模型中,通常有兩種標準角色:user和assistant。其中,user一般指用戶提問的內(nèi)容,而assistant指AI模型的回答,這類角色名稱適用于目前的絕大部分AI模型。(3)為了保存對話歷史,通常要設(shè)置一個模塊級全局變量來進行操作(如上述代碼中定義的messages),以記錄每一輪對話。同時,每一輪對話完畢必須將用戶的提問內(nèi)容和AI的回答均添加到消息體中,每開啟一輪新的對話,均需要將前面輪次的對話發(fā)送給大模型以便實現(xiàn)記憶功能。AI智能體開發(fā)技術(shù)03FunctionCalling技術(shù)目前,AI智能體開發(fā)和應(yīng)用是展現(xiàn)AI實力的一種非常好的方式,大量的企業(yè)有AI智能體開發(fā)的需求,且各個行業(yè)和研究人員都在進行各種形式的探索,以實現(xiàn)AI能力的最大化,幫助企業(yè)和組織降低成本,提升效率。AI大模型本身的能力在于理解用戶的輸入,并給予用戶正確的響應(yīng)內(nèi)容,而響應(yīng)的內(nèi)容通常是文本或圖像等數(shù)據(jù),AI大模型本身并不具備函數(shù)調(diào)用能力。例如,對于提示詞“明天去北京出差適合穿什么衣服?”,Ollama的回答如圖1-17所示。FunctionCalling技術(shù)一般情況下,有兩種方案可以讓AI給出穿衣建議,具體如下。(1)第一種方案是聯(lián)網(wǎng)搜索與北京天氣有關(guān)的數(shù)據(jù),并將搜索結(jié)果的網(wǎng)頁作為提示詞的一部分提交給大模型進行分析,進而得出正確的穿衣建議;但是此類基于搜索的結(jié)果通常并不完全準確,存在一定數(shù)據(jù)錯誤的情況,這取決于搜索引擎對數(shù)據(jù)爬取的通用性與準確性。(2)第二種方案是開發(fā)一個天氣預(yù)報函數(shù)并準確描述該函數(shù)的功能,交由大模型對用戶提問進行分析,并返回JSON數(shù)據(jù),告訴智能體應(yīng)該調(diào)用哪個函數(shù)、傳遞什么參數(shù),智能體會根據(jù)模型的輸出進行解析和調(diào)用,進而獲取天氣預(yù)報的實時數(shù)據(jù),再交由大模型進行分析并給出正確的穿衣建議。這種方案的基本過程需要配合AI的FunctionCalling技術(shù)來實現(xiàn)。FunctionCalling技術(shù)MCP技術(shù)1.通過AI提示詞操作本地文件系統(tǒng)打開CherryStudio,在設(shè)置界面中選擇“MCP服務(wù)器”選項,并手動添加一個MCP服務(wù),按照圖1-19所示的參數(shù)進行設(shè)置,并單擊右上方的開關(guān)來開啟該MCP服務(wù)。MCP技術(shù)1.通過AI提示詞操作本地文件系統(tǒng)完成上述設(shè)置后,進入CherryStudio的常規(guī)提問框,嘗試使用圖1-20所示的提示詞來使用MCP服務(wù)進行文件寫入操作。MCP技術(shù)2.通過AI提示詞獲取穿衣建議除了使用本地MCP服務(wù),還可以使用遠程的公共MCP服務(wù),如使用高德地圖MCP服務(wù)獲取地理位置信息、查詢酒店或地址、獲取實時天氣情況等。高德地圖MCP服務(wù)提供了免費的調(diào)用額度,足夠開發(fā)者調(diào)試所用。首先,訪問高德官網(wǎng),注冊賬號并進行實名認證;其次,創(chuàng)建應(yīng)用并添加Key,如圖1-21所示。MCP技術(shù)2.通過AI提示詞獲取穿衣建議當(dāng)完成Key的添加后,按照圖1-22在CherryStudio中對接高德地圖MCP服務(wù),進行參數(shù)填寫并確??梢哉臃?wù)。MCP技術(shù)2.通過AI提示詞獲取穿衣建議完成CherryStudio與高德地圖MCP服務(wù)的對接并成功開啟服務(wù)后,便可在提問框中進行提問了,AI模型會根據(jù)需要驅(qū)動智能體(本處即CherryStudio本身)進行遠程函數(shù)調(diào)用,其對話效果如圖1-23所示。使用Python調(diào)用FunctionCallingFunctionCalling由OpenAI公司提出,現(xiàn)在已經(jīng)被大多數(shù)模型所支持,也是擴展AI能力邊界的一種好方式。下面將使用DeepSeek演示如何利用Python代碼來調(diào)用FunctionCalling。以下代碼展示了利用大模型對提示詞的理解來返回對函數(shù)的調(diào)用,實現(xiàn)本地文件寫入及天氣預(yù)報的功能。其中,天氣預(yù)報的功能直接調(diào)用高德的天氣預(yù)報接口實現(xiàn),具體代碼及注釋如下。使用Python開發(fā)MCP服務(wù)MCP服務(wù)部署在stdio本地調(diào)用模式下,不需要在Python中運行上述代碼,而是在CherryStudio中利用Python命令來運行。按照圖1-24進行配置,即可在CherryStudio中通過提示詞進行文件寫入,具體操作過程與調(diào)用filesystem服務(wù)相同。使用Python開發(fā)MCP服務(wù)MCP服務(wù)部署在mcp庫中,如果想將函數(shù)以sse方式發(fā)布,則要對代碼進行以下修改,并在PyCharm中開啟服務(wù)。FastAPI開發(fā)框架content目錄01FastAPI快速使用02Jinja2模板引擎03SQLModel數(shù)據(jù)處理04FastAPI對接大模型FastAPI快速使用01快速入門FastAPI概述FastAPI是一個用于構(gòu)建API的現(xiàn)代、快速且高性能的Web框架,使用Python開發(fā),并基于標準的Python類型進行提示。FastAPI目前被大量企業(yè)采用,具有以下重要特性。(1)快速且高性能:具有可與Node.js和Go并肩的極高性能,是最快的PythonWeb框架之一。(2)高效編碼:提高功能開發(fā)速度200%~300%。(3)更少的漏洞:減少約40%的人為(開發(fā)者)導(dǎo)致的錯誤。(4)智能:極佳的編輯器支持,處處皆可自動補全,減少調(diào)試時間。(5)簡單:易于使用和學(xué)習(xí),閱讀文檔的時間更短。(6)簡短:使代碼重復(fù)最小化,通過不同的參數(shù)聲明實現(xiàn)豐富功能,且漏洞更少。(7)健壯:生產(chǎn)可用級別的代碼,以及自動生成交互式文檔。(8)標準化:基于(并完全兼容)API的相關(guān)開放標準OpenAPI和JSONSchema。快速入門安裝FastAPI直接運行“pipinstallfastapi”命令即可安裝FastAPI。另外,為了保證后續(xù)針對數(shù)據(jù)庫和模板引擎的操作正確無誤,建議同時安裝Uvicorn服務(wù)運行環(huán)境Jinja2模板引擎和SQLModel數(shù)據(jù)庫框架,安裝命令如下。快速入門快速實現(xiàn)接口與響應(yīng)FastAPI可以定義Get、Post等各種類型的HTTP接口,并支持以多種方式獲取前端界面?zhèn)鬟f過來的參數(shù),也可以向前端傳送響應(yīng)的各種類型的內(nèi)容,默認情況下響應(yīng)JSON數(shù)據(jù)。以下代碼定義了兩個接口并實現(xiàn)了簡單的邏輯,可以快速完成一個后臺接口的開發(fā)。快速入門快速實現(xiàn)接口與響應(yīng)在PyCharm中運行上述代碼,F(xiàn)astAPI服務(wù)會正常啟動,此時若能夠通過瀏覽器訪問:8000/,并在瀏覽器中看到“HelloWorld”,則說明請求發(fā)送成功。FastAPI默認設(shè)置中提供了接口文檔和調(diào)試功能(SwaggerUI),訪問:8000/docs即可看到當(dāng)前項目的所有接口,方便地對Post請求接口進行調(diào)試,如圖2-1所示??焖偃腴T快速實現(xiàn)接口與響應(yīng)FastAPI除了提供SwaggerUI用于查閱接口文檔和調(diào)試接口,還額外提供ReDoc文檔用于以更加簡潔的界面展示接口規(guī)范,訪問:8000/redoc即可查看接口規(guī)范,如圖2-2所示??焖偃腴T快速實現(xiàn)接口與響應(yīng)事實上,對于開發(fā)過程中的接口調(diào)試,除了使用SwaggerUI,還推薦使用Apifox等工具來進行調(diào)試和管理。相較于SwaggerUI,Apifox的功能更加強大,不僅支持調(diào)試,還可以對接口進行測試,并支持WebSocket協(xié)議。最關(guān)鍵的是,Apifox可以保存每次的請求數(shù)據(jù),以供下次使用。圖2-3展示了如何在Apifox中發(fā)送登錄請求。URL及參數(shù)無論是Get還是Post等請求,均需要一個唯一的URL,而在URL中也可以定義參數(shù)。參數(shù)一般分為兩類,分別是路徑參數(shù)與查詢參數(shù)。FastAPI的URL和地址欄參數(shù)及相關(guān)定義主要用于解決以下4個問題。(1)定義服務(wù)器接口的URL,從根目錄/開始。(2)定義接收前端數(shù)據(jù)的請求類型,如Get、Post、Put或Delete等。(3)獲取請求地址中的查詢參數(shù)或路徑參數(shù)。(4)通過將@app.get/post等裝飾器與被裝飾的函數(shù)綁定,對請求進行后臺處理。URL及參數(shù)上述代碼中由于均為Get請求,因此既可以直接在瀏覽器地址欄中訪問,又可以在SwaggerUI中進行訪問和調(diào)試。當(dāng)訪問:8000/user/123時,輸出為{"user_id":"123"}格式的JSON數(shù)據(jù),這是完全正確的。RESTful接口描述性狀態(tài)遷移(RepresentationalStateTransfer,REST)的設(shè)計目的是希望在符合架構(gòu)原理的前提下,理解和評估以網(wǎng)絡(luò)為基礎(chǔ)的應(yīng)用軟件的架構(gòu)設(shè)計,得到一個功能強、性能好、適合通信的架構(gòu)。因此REST指的是一組架構(gòu)約束條件和原則。如果一個架構(gòu)符合REST的約束條件和原則,則稱它為RESTful架構(gòu),這個架構(gòu)同樣具有RESTful風(fēng)格。對于Web開發(fā)者來說,是否完全掌握RESTful的定義并不關(guān)鍵,但熟悉其核心的幾個要素十分必要,如定義HTTP請求類型和服務(wù)器URL接口規(guī)范的標準。例如,對一個用戶的操作,其資源對象是用戶,而請求類型和接口定義應(yīng)該遵循表2-1所示的基本標準進行。JSON請求體在當(dāng)前的互聯(lián)網(wǎng)通信過程中,JSON數(shù)據(jù)格式在前后端通信中的使用更加廣泛,除了后端可以向前端響應(yīng)JSON數(shù)據(jù),前端還可以向后端提交JSON數(shù)據(jù)。在FastAPI中,這類接口和請求的定義與獲取也較為方便,下述代碼展示了這一過程。JSON請求體除了常規(guī)的將整個Post請求體正文作為JSON數(shù)據(jù)提交,在FastAPI中,還可以借用Pydantic(一個數(shù)據(jù)驗證庫)的能力對JSON數(shù)據(jù)進行更加細致的處理和驗證。以下代碼展示了如何將一個數(shù)據(jù)模型映射為JSON請求字段,并進行數(shù)據(jù)類型的驗證。會話管理HTTP本身是無狀態(tài)協(xié)議,即客戶端與服務(wù)器在交互過程中無記憶能力,服務(wù)器并不能區(qū)分是哪個客戶端或瀏覽器發(fā)送的請求。為了保持HTTP的狀態(tài),通常選擇使用Session和Cookie來進行管理(目前也大量使用Token來進行會話管理和鑒權(quán))。在FastAPI中,可以通過SessionMiddleware中間件來管理Session,通過Cookie對象來讀取前端發(fā)送的Cookie,或通過Response對象來向前端發(fā)送Cookie變量。會話管理下述代碼演示了自定義Cookie變量的過程。會話管理事實上,會話管理和用戶鑒權(quán)是Web系統(tǒng)中非常重要的技術(shù),但是HTTP的Session和Cookie機制相對而言是比較落后的技術(shù),其機制決定了這些技術(shù)不太適用于大型或分布式系統(tǒng)。在分布式系統(tǒng)中,要確保Session機制正常工作,需要在每一個系統(tǒng)節(jié)點中同步Session數(shù)據(jù),這不僅開銷巨大,實現(xiàn)過程也比較麻煩。因此,目前通常有以下兩種解決方案。(1)Session的維護不再保存于Web服務(wù)器中,而是保存于一臺統(tǒng)一的服務(wù)器(如Redis數(shù)據(jù)庫)中。每次需要讀取Session變量時,都直接從Redis服務(wù)器中獲取,通過SessionID進行關(guān)聯(lián)查找。這樣,無論有多少個服務(wù)器節(jié)點,多少個應(yīng)用系統(tǒng),均統(tǒng)一與Redis服務(wù)器進行通信。這相當(dāng)于讓Redis對SessionID和Session變量進行統(tǒng)一管理。(2)使用Token機制進行鑒權(quán),Token機制完全脫離了Session,由開發(fā)者自行實現(xiàn),或使用主流的JWT/OAuth等標準進行處理,可以非常靈活并自主地處理鑒權(quán)過程。上述兩種方案在FastAPI中均提供了支持,但是本書的核心目標是AI應(yīng)用程序和智能體的開發(fā),而非使用Web應(yīng)用系統(tǒng)開發(fā)各種關(guān)鍵技術(shù),所以不贅述Web應(yīng)用開發(fā)的內(nèi)容。后續(xù)項目使用到這部分內(nèi)容時,會對其進行單獨講解。文件上傳在FastAPI中,對文件上傳提供了很好的封裝,利用UploadFile對象即可方便地讀取前端上傳的二進制文件并進行保存。以下代碼展示了如何獲取上傳的文件。。上述代碼使用原始文件名稱將上傳的文件保存到當(dāng)前目錄下,在實際項目環(huán)境下,還需要考慮文件名的重命名,或者對文件類型、后綴名、文件大小等進行限制,后續(xù)在項目使用中再進行拓展。文件上傳ase64編碼的核心邏輯是使用64個字符(即6個二進制位的組合)來表示各種數(shù)據(jù),而常規(guī)數(shù)據(jù)是由8個二進制位(即1個字節(jié))表示的,所以這里存在一個轉(zhuǎn)換關(guān)系。例如,針對常規(guī)字符Red,其在ASCII中對應(yīng)82、101、100,對應(yīng)的二進制為010100100110010101100100,一共24個二進制位;而在Base64編碼中,每6個二進制位表示一個字符,如表2-2所示,所以Base64編碼后的二進制變?yōu)?10100100110010101100100,根據(jù)Base64編碼索引,對應(yīng)字符為UmVk。。數(shù)據(jù)驗證在FastAPI中,對前端參數(shù)值進行驗證變得非常方便。以下代碼分別對路徑參數(shù)和表單數(shù)據(jù)進行了驗證。異步編程什么是異步編程異步編程使程序可以在等待某種操作(如網(wǎng)絡(luò)請求或文件讀?。r運行其他操作,而不是單純地阻塞,從而提高了程序的響應(yīng)速度和資源利用率。在Python中,異步編程通常通過以下3個基本構(gòu)件來實現(xiàn)。(1)async:通常放置在函數(shù)定義之前,用于定義異步函數(shù)。(2)await:等待異步操作完成。(3)asyncio:提供對任務(wù)調(diào)度和事件循環(huán)的支持異步編程為了清晰展示異步編程和同步編程的區(qū)別,以下代碼模擬了一個常規(guī)的任務(wù)操作,每個任務(wù)完成的時間不同。異步代碼演示異步編程以下代碼展示了如何在Python中實現(xiàn)異步編程。異步代碼演示異步編程FastAPI默認提供了對異步編程的支持,定義接口時在函數(shù)前面添加關(guān)鍵字async即可,無須做額外操作。例如,定義一個文件上傳的接口的代碼如下。在FastAPI中使用異步編程Jinja2模板引擎02模板引擎的作用在互聯(lián)網(wǎng)應(yīng)用開發(fā)的早期,整個Web系統(tǒng)開發(fā)的生態(tài)遠沒有現(xiàn)在這樣完善,服務(wù)器框架通常只能處理簡單的HTTP請求。早期的Web服務(wù)器框架通常在服務(wù)器中直接寫出HTML代碼并響應(yīng)給前端,類似如下方式。模板引擎的作用模板引擎的引入主要用于解決以下3個問題。(1)把Python代碼和前端HTML代碼分離,不再采用混編的方式來編寫代碼,在提高代碼可維護性的同時提升代碼的開發(fā)效率。(2)在渲染模板界面的同時,可以向模板界面?zhèn)鬟f變量和值,這些變量和值將在模板界面中被引用,從而直接在HTML界面中填充動態(tài)內(nèi)容。(3)通過模板引擎特定的語法規(guī)則,可以在HTML中非常清楚地標識模板變量,同時服務(wù)器在渲染模板界面時,也能夠更加高效地進行處理,提升服務(wù)器響應(yīng)性能。模板引擎的作用就是將后端的數(shù)據(jù)動態(tài)填充到HTML界面中。在當(dāng)今的開發(fā)過程中,除了使用模板引擎進行動態(tài)填充,還可以將數(shù)據(jù)以JSON格式響應(yīng)給前端,交由前端的JavaScript或前端框架進行動態(tài)填充。目前,這兩種方式同時存在,且無優(yōu)劣之分,開發(fā)者可以根據(jù)業(yè)務(wù)需求或產(chǎn)品的形態(tài)及架構(gòu)選擇其中一種方式。Jinja2快速使用首先,定義一個HTML靜態(tài)界面,并在界面中內(nèi)嵌模板引擎標識符,用于獲取變量的值。Jinja2快速使用其次,將上述模板界面保存到當(dāng)前目錄的templates目錄下,并將其命名為basic.html,在后端編寫以下代碼,注意代碼中的規(guī)范性要求。Jinja2核心語法Jinja2模板引擎定義了以下3種基本引用標識符。(1){%...%}:用于循環(huán)或判斷語句。(2){{...}}:用于表達式的值的引用。(3){#...#}:用于模板引擎的注釋。如果注釋中存在模板引擎的語法,那么使用<!---->將不被模板引擎認為是注釋,注釋中的語句將被運行,此時應(yīng)使用{#...#}進行注釋。假設(shè)FastAPI在調(diào)用TemplateResponse時為模板界面?zhèn)鬟f了一個變量count,值為100,即參數(shù)context={"count":100},那么以下代碼基本完整演示了模板引擎的用法。Jinja2核心語法除此以外,在模板界面中還可以直接調(diào)用Python的自定義函數(shù),不過需要先將此函數(shù)注冊到Jinja2模板引擎中。定義與調(diào)用函數(shù)的代碼如下。在模板界面中,可以通過以下方式讀取get_user()函數(shù)返回的數(shù)據(jù)。過濾器代碼“l(fā)oop|int”,這便是Jinja2中過濾器的用法。過濾器本質(zhì)上是一個函數(shù),它將變量作為函數(shù)的參數(shù)傳遞進去,處理后再返回新的值到調(diào)用處。例如,loop|int可以理解為loop=int(loop)。表2-3列出了Jinja2中常用的過濾器及其用法。應(yīng)用示例在FastAPI中定義圖書信息,代碼如下。SQLModel數(shù)據(jù)處理03利用PyMySQL操作數(shù)據(jù)庫由于任何一個應(yīng)用系統(tǒng)基本上都會在后臺使用數(shù)據(jù)庫來永久保存數(shù)據(jù),因此利用Python操作數(shù)據(jù)庫是開發(fā)Web應(yīng)用系統(tǒng)的一個必經(jīng)過程。要使用Python操作數(shù)據(jù)庫,必須先創(chuàng)建數(shù)據(jù)庫和表。下面以MySQL為例,創(chuàng)建一張用戶表,表名為users,包含userid、username、password、phone、role、createtime等數(shù)據(jù),用戶表中的數(shù)據(jù)如圖2-10所示。利用PyMySQL操作數(shù)據(jù)庫以下代碼演示了如何利用PyMySQL連接MySQL數(shù)據(jù)庫并查詢users表的前3條信息。利用PyMySQL操作數(shù)據(jù)庫默認情況下,游標返回的二維元組沒有字段名,只能使用元組的下標來獲取數(shù)據(jù),并不是特別方便。尤其是列比較多的時候,使用下標很容易出錯,且如果表的字段有所調(diào)整,則所有代碼都必須進行調(diào)整,否則會顯示錯誤的數(shù)據(jù)。為了解決這個問題,可以在實例化游標對象時使用字典類型的游標對象,返回列表+字典的數(shù)據(jù)結(jié)構(gòu)。修改上述代碼如下。另外,在PyMySQL中,針對數(shù)據(jù)庫的插入、更新、刪除等操作,只需要編寫好對應(yīng)的SQL語句,調(diào)用cursor.execute(sql)便可正常完成,使用連接對象mit()即可完成提交。SQLModel核心操作SQLModel基于SQLAlchemy,是Python中各類Web開發(fā)框架的首選數(shù)據(jù)庫框架,可以很好地與FastAPI等框架集成,且具備ORM能力,從而使操作數(shù)據(jù)表變得更加方便。那么,什么是ORM?ORM的作用是在關(guān)系數(shù)據(jù)庫和對象之間進行映射。這樣,用戶在對數(shù)據(jù)表進行具體操作的時候,無須編寫SQL語句,像平時操作Python的類和對象一樣操作數(shù)據(jù)庫即可。為什么需要使用ORM對數(shù)據(jù)庫操作進行封裝呢?在在一個大型系統(tǒng)中,由于表和列非常多,如果全部使用原生SQL語句來實現(xiàn)數(shù)據(jù)庫操作,那么一旦表結(jié)構(gòu)發(fā)生變化,就需要重寫很多SQL語句,為代碼的維護和開發(fā)效率帶來了極大的困擾。使用ORM對數(shù)據(jù)庫進行封裝后,就可以將業(yè)務(wù)處理和數(shù)據(jù)庫操作完全分離開來,這樣開發(fā)者只需要關(guān)心業(yè)務(wù)邏輯實現(xiàn),而不用關(guān)注數(shù)據(jù)庫是如何實現(xiàn)讀寫的。同時,對數(shù)據(jù)庫的增刪改查完全不用編寫SQL語句,而是通過操作一個類和類中的方法或?qū)傩詠韺崿F(xiàn)。這就是所謂的對象與關(guān)系之間的映射。SQLModel核心操作以下代碼演示了利用SQLModel操作用戶表的增刪改查操作。首先,創(chuàng)建一個users.py模塊,用于連接數(shù)據(jù)庫并定義映射關(guān)系(也稱為模型類)。SQLModel核心操作其次,在FastAPI的接口中對用戶表進行增刪改查操作,代碼如下。SQLModel核心操作上述代碼可以在SwaggerUI中進行請求的發(fā)送和確認,且上述代碼遵循了RESTful接口規(guī)范,讀者可以通過實驗進行感受。在SQLModel中,不用再編寫原生的SQL語句,全部通過方法進行操作就可以達到目的,還可以使代碼的可讀性和可維護性變得更強。SQLModel復(fù)雜查詢SQL的查詢條件非常多,如多條件查詢、分組查詢、聚合函數(shù)統(tǒng)計、多表連接查詢等,是SQL語句中很復(fù)雜的操作。但是SQLModel提供了對此類操作的支持,通常使用select()函數(shù)來構(gòu)造查詢語句。同時,針對一些復(fù)雜查詢,如果使用SQLModel函數(shù)難以構(gòu)建查詢語句,則可以使用原生SQL語句來實現(xiàn)。以下代碼演示了一些常用的復(fù)雜查詢操作,以供讀者參考。如果后續(xù)項目中使用到新的操作,則會對其單獨進行講解。SQLModel復(fù)雜查詢?yōu)榱苏{(diào)試方便,上述代碼并沒有被放到FastAPI的接口中,但是操作方式是完全一致的。其運行結(jié)果如下。FastAPI對接大模型04基于OpenAI庫對接與DeepSeek的非流式響應(yīng)的對話過程第1章已經(jīng)講解了如何在Python中使用OpenAI或基于HTTP接口來對接AI大模型,在FastAPI中,大模型的對接與之基本上沒有本質(zhì)上的區(qū)別,只是將對接過程封裝在接口當(dāng)中,并與前端進行交互。處理流式響應(yīng)在FastAPI中向前端進行流式輸出時主要涉及兩種關(guān)鍵技術(shù),分別是yield生成器和StreamingResponse對象。其中,yield生成器用于將大模型的流式輸出轉(zhuǎn)換為生成器輸出而非標準的返回值;StreamingResponse對象用于向前端輸出流式響應(yīng)結(jié)果。流式響應(yīng)結(jié)果在HTTP中將以Content-type:text/event-stream的形式反饋給前端,具體代碼如下。處理流式響應(yīng)開啟上述服務(wù)后,可以在Python中編寫以下代碼進行測試,確認流式輸出是否正常。前端JavaScript對接1.fetch()函數(shù)的用法fetch()函數(shù)提供了一個獲取資源的接口(包括跨域請求),用于取代傳統(tǒng)的XMLHttpRequest來發(fā)送異步JavaScript和XML(AsynchronousJavaScriptandXML,AJAX)請求,同時支持發(fā)送Get、Post請求等操作。為了了解fetch()函數(shù)的用法,先在服務(wù)器中編寫以下代碼,用于定義接口和渲染模板界面。前端JavaScript對接1.fetch()函數(shù)的用法編寫模板界面文件fetch.html中的代碼,該代碼實現(xiàn)了使用fetch()函數(shù)發(fā)送一個Get請求并輸出響應(yīng)正文的功能。前端JavaScript對接2.在fetch()函數(shù)中處理流式響應(yīng)流式響應(yīng)的接收與普通的響應(yīng)有所不同,主要區(qū)別在于:流式響應(yīng)是分塊讀取的,需要循環(huán)讀取響應(yīng)的內(nèi)容;返回的也不是普通的文本型正文,而是一系列逐步發(fā)送的數(shù)據(jù)塊,需要構(gòu)建一個針對響應(yīng)的ReadableStream對象來讀取數(shù)據(jù)流,所以在處理時有一些特別。首先,在后端接口中創(chuàng)建一個Get請求的接口,用于渲染模板界面,代碼如下。前端JavaScript對接2.在fetch()函數(shù)中處理流式響應(yīng)前端JavaScript對接2.在fetch()函數(shù)中處理流式響應(yīng)其次,在templates目錄中創(chuàng)建前端界面文件chat.html,代碼如下。前端JavaScript對接3.瀏覽器兼容性處理上述代碼在新版本的Chrome中完全可以正常工作,但是即使換成Firefox或Safari瀏覽器的最新版本,也極有可能無法工作。打開Firefox瀏覽器的控制臺,可能會看到以下報錯信息。上述錯誤的大致意思是響應(yīng)的格式不對,無法解析為JSON數(shù)據(jù),出錯的代碼語句為jsonObj=JSON.parse(chunk)。為了分析其原因,在該行代碼之前插入一行輸出語句console.log(chunk)來查看流式響應(yīng)的輸出有什么特別之處。響應(yīng)的JSON格式異常如圖2-13所示。前端JavaScript對接3.瀏覽器兼容性處理仔細觀察響應(yīng)的內(nèi)容可以看出,因為在后端生成器中輸出內(nèi)容時,每一次生成都加了一個換行符\n(見2.4.2小節(jié)中的后端代碼),所以在前端處理時,為響應(yīng)的內(nèi)容添加了\n作為分隔符,利用JavaScript的split()函數(shù)將其分隔為一個數(shù)組,格式為[{"content":"你好"},{"content":"再見"},""],并遍歷數(shù)組中的每一項(最后一項除外),即可正常解析為JSON數(shù)據(jù)。前端JavaScript對接3.瀏覽器兼容性處理以下代碼為更新后的doask()函數(shù)的代碼。AI問答content目錄01功能與設(shè)計分析02前后端準備工作03文本問答功能04圖像識別與生成功能與設(shè)計分析01核心功能列表AI問答系統(tǒng)概述AI問答系統(tǒng)是目前極為常見的一種AI大模型的基礎(chǔ)應(yīng)用,很多AI應(yīng)用均在此基礎(chǔ)之上進行拓展。本章主要利用JavaScript和FastAPI實現(xiàn)基于前后端交互的AI問答,主要包括以下功能。(1)利用FastAPI與阿里云的大模型實現(xiàn)對接,并處理流式響應(yīng)。(2)實現(xiàn)基于純文本的AI問答,與平時使用的AI聊天應(yīng)用類似。(3)調(diào)用阿里云的視頻理解模型實現(xiàn)圖像識別功能,解讀圖像的內(nèi)容。(4)調(diào)用阿里云的通義萬相模型實現(xiàn)文本生成圖像功能,并在前端展示生成的圖像。(5)由于大模型不具備實時聯(lián)網(wǎng)功能,因此AI問答系統(tǒng)還要實現(xiàn)聯(lián)網(wǎng)搜索與問答功能。(6)對接高德地圖提供的MCP服務(wù),用于實現(xiàn)地理位置查詢、天氣查詢等功能。(7)提供基于JavaScript調(diào)用操作系統(tǒng)本地的語音合成接口,實現(xiàn)語音朗讀功能。整體實現(xiàn)思路為什么選擇阿里云首先,阿里云作為國內(nèi)領(lǐng)先的大模型提供商,其發(fā)布的Qwen3模型的功能絲毫不遜色于其他大模型。其次,阿里云提供的大模型的功能較為全面,AI問答系統(tǒng)涉及的文本問答、圖像識別、圖像生成、聯(lián)網(wǎng)搜索等功能均可以基于阿里云大模型實現(xiàn)。這樣做的好處是,讀者可以將學(xué)習(xí)的重心放在代碼邏輯和實現(xiàn)上,而不是各類平臺的接口對接上。整體實現(xiàn)思路前端界面設(shè)計AI問答系統(tǒng)的前端界面采用標準的HTML+CSS來實現(xiàn),設(shè)計比較簡潔。其主要有兩個關(guān)鍵點需要注意:第一個關(guān)鍵點是聊天框中的問答,由于是動態(tài)生成的DIV,因此需要使用JavaScript的文檔對象來動態(tài)創(chuàng)建一個DIV元素,即document.createElement('div');第二個關(guān)鍵點是圖像識別時需要上傳圖像并顯示,細心的讀者可能已經(jīng)發(fā)現(xiàn),在AI問答系統(tǒng)項目的主界面中并沒有出現(xiàn)文件上傳的元素,而是對其進行了隱藏。文本問答功能此功能幾乎可以通過對接任意大模型來實現(xiàn),并在前端利用fetch()函數(shù)進行流式響應(yīng)的讀取和填充。整體實現(xiàn)思路圖像識別功能首先,由于使用圖像識別功能時,用戶需要上傳本地圖像,因此會用到文件上傳組件。然而,該組件的默認樣式可能與整體界面風(fēng)格不協(xié)調(diào),因此建議將其隱藏。可以通過JavaScript代碼來觸發(fā)文件上傳功能,以保持界面設(shè)計的一致性和用戶體驗的流暢性。其次,用戶上傳的圖像不能直接傳遞至后臺,而是應(yīng)暫存到瀏覽器中,并顯示預(yù)覽圖,可以考慮使用JavaScript的localStorage或sessionStorage對象來臨時保存圖像文件的Base64編碼。此后,讓用戶編寫提示詞,確定提示詞后,將圖像與提示詞一同上傳給后臺接口,后臺接口會與大模型進行交互。AI問答系統(tǒng)中圖像識別功能的運行結(jié)果如圖3-2所示。整體實現(xiàn)思路圖像生成功能圖像生成功能主要通過調(diào)用阿里云的通義萬相v2實現(xiàn),此功能的實現(xiàn)分成兩步:第一步,將用戶的提示詞提交給后臺,再由后臺轉(zhuǎn)交給通義萬相生成圖像;第二步,等待通義萬相生成結(jié)束后,獲取圖像的URL,并解析出圖像名稱,將其保存到項目目錄中,將圖像的路徑通過響應(yīng)返回給前端,由前端界面渲染該圖像。注意:因為圖像生成功能響應(yīng)給前端的是圖像的URL,所以不需要考慮流式響應(yīng)的處理。整體實現(xiàn)思路聯(lián)網(wǎng)搜索功能在AI問答系統(tǒng)中,聯(lián)網(wǎng)搜索功能幾乎成了標配,核心原因是AI大模型本身不具備實時能力,需要具備搜索功能才能分析及總結(jié)實時數(shù)據(jù),并以大模型理解的表達形式響應(yīng)給用戶。聯(lián)網(wǎng)搜索功能的本質(zhì)就是根據(jù)用戶的提問,通過搜索引擎進行搜索,并將返回的搜索結(jié)果連同用戶的提問一起交給大模型進行總結(jié)、整理,并根據(jù)用戶的提問來進行回答。聯(lián)網(wǎng)搜索功能有兩種實現(xiàn)方式:第一種是通過搜索引擎搜索用戶提問,并將搜索結(jié)果界面的內(nèi)容作為提示詞輸入大模型;第二種是直接調(diào)用搜索引擎提供的API,該方法可以更好地過濾搜索引擎的廣告,以JSON格式返回結(jié)果。整體實現(xiàn)思路高德MCP服務(wù)的調(diào)用如果要在AI問答系統(tǒng)中集成MCP服務(wù)調(diào)用,則必須使用代碼來開發(fā)MCP客戶端。其中,Python的mcp庫提供了對客戶端開發(fā)的支持。但是,相對于開發(fā)MCP服務(wù)器,開發(fā)MCP客戶端要更復(fù)雜一些,因為客戶端涉及與服務(wù)器的連接、接口和規(guī)范的讀取、與大模型的兩次交互、異步處理、連接狀態(tài)的維持等諸多操作。語音朗讀功能實現(xiàn)該功能的方案有兩種:第一種是直接利用JavaScript調(diào)用本地語音合成接口,實現(xiàn)簡單,且JavaScript內(nèi)置支持;第二種是調(diào)用云API來進行語音合成,并將合成的語音保存為文件,在前端利用JavaScript進行播放。本章采用第一種方案實現(xiàn)語音朗讀功能。前后端準備工作02前端界面實現(xiàn)前端界面是標準的HTML+CSS實現(xiàn),且當(dāng)前只考慮在PC端實現(xiàn),不考慮在移動端實現(xiàn),也不考慮響應(yīng)式布局,相對比較簡單,通過常規(guī)的層疊樣式表(CascadingStyleSheets,CSS)即可完成。在templates目錄下創(chuàng)建一個名為chat.html的源代碼文件,以便在FastAPI中作為模板進行渲染,其內(nèi)容及注釋如下。前端界面實現(xiàn)上述代碼中引用的style.css文件的內(nèi)容如下。如果要調(diào)試上述代碼,則可以使用兩種方案:第一種是直接打開該HTML文件進行調(diào)試;第二種是在FastAPI中進行調(diào)試。這里推薦使用第二種方案。靜態(tài)目錄設(shè)置因為前端的模板界面中通常會引入CSS文件、JavaScript源文件,或者一些靜態(tài)的圖像等內(nèi)容,所以必須確保前端界面中至少有一個正確的路徑。在FastAPI中,靜態(tài)目錄通常放置于項目根目錄的static目錄下,同時,要讓chat.html中引用的JavaScript文件或CSS文件路徑生效,必須完成以下兩項設(shè)置。(1)將所有靜態(tài)資源放置于static目錄下。(2)在實例化FastAPI后,需要設(shè)置靜態(tài)文件所在目錄,代碼如下。完成上述設(shè)置后,才能在HTML界面文件中使用<scriptsrc="/static/script.js"></script>正確引用JavaScript源文件。FastAPI多模塊第2章中已經(jīng)學(xué)習(xí)了FastAPI的一些關(guān)鍵特性,且將所有接口代碼放到同一個Python源代碼文件中,這樣操作有一個弊端,即如果項目本身接口比較多,則該源代碼文件會很大,且難以維護。為了解決該問題,F(xiàn)astAPI提供了APIRouter對象來幫助開發(fā)者進行多模板開發(fā)。也就是說,可以先將相關(guān)功能模板的接口放到單獨的一個源文件中,再在main.py這類主代碼中進行引入,以實現(xiàn)接口的多模塊化處理。FastAPI多模塊定義了上述兩個接口后,再在main.py中進行引用,即可正常調(diào)用/get_test和/post_test這兩個接口,代碼如下。了解了上述功能后,可以將AI問答系統(tǒng)拆分為3個模塊,分別是qa模塊、recognize模塊和generate模塊。其中,qa模塊用于常規(guī)問答,recognize模塊用于圖像識別,generate模塊用于圖像生成。另外,通常項目中還存在一些公共模塊,用于在接口中調(diào)用。此時,可以創(chuàng)建一個名為module.py的源代碼文件,用于存儲非接口定義的公共代碼。文本問答功能03后端代碼實現(xiàn)首先,定義后端代碼,創(chuàng)建文件qa.py,用于對接AI大模型并生成流式響應(yīng),其基本邏輯與第2章一致,代碼如下。后端代碼實現(xiàn)其次,在main.py中引用qa模塊接口,并完善main.py中的其他代碼。前端代碼實現(xiàn)首先,講解如何在JavaScript中實現(xiàn)語音合成功能,以便問答時直接調(diào)用,代碼及注釋如下。前端代碼實現(xiàn)上述代碼完成編寫后,還不能馬上使用,需要在AI的回復(fù)中添加一個“朗讀”按鈕來進行調(diào)用。同時,在實現(xiàn)對話功能前,先定義兩個公共函數(shù)用于綁定Ctrl+Enter的按鍵事件,并將提問框滾動到底部,以查看最后的對話信息。前端代碼實現(xiàn)實現(xiàn)上述兩個功能模塊后,即可實現(xiàn)chat.html界面中的“智能問答”按鈕功能。調(diào)用doAsk()函數(shù),用于在提問框中新建一個DIV并將用戶提問框的內(nèi)容添加到該DIV中。前端代碼實現(xiàn)接下來實現(xiàn)doAnswer(

)函數(shù),即前端與后端大模型通信的關(guān)鍵代碼。聯(lián)網(wǎng)搜索功能聯(lián)網(wǎng)搜索功能采用阿里云AI搜索開放平臺的服務(wù)接口來實現(xiàn),不同于阿里云靈積模型的APIKey申請,阿里云AI搜索開放平臺需要單獨申請APIKey。在阿里云AI搜索開放平臺上申請APIKey,如圖3-4所示。聯(lián)網(wǎng)搜索功能成功申請APIKey后,可以先編寫一段Python代碼進行測試。聯(lián)網(wǎng)搜索功能如果測試通過,則可開始實現(xiàn)聯(lián)網(wǎng)搜索的AI問答功能。在后臺創(chuàng)建文件module.py,用于保存搜索功能代碼,便于在接口中進行調(diào)用。聯(lián)網(wǎng)搜索功能因為前文配置前端發(fā)送請求時已經(jīng)考慮了是否需要實現(xiàn)聯(lián)網(wǎng)搜索功能,所以構(gòu)建的參數(shù)是params={"content":content,"search":false},這意味著如果用戶勾選了“聯(lián)網(wǎng)”復(fù)選框,則參數(shù)將變?yōu)閧"content":content,"search":true},需要在后臺qa模塊的stream接口中調(diào)整代碼。聯(lián)網(wǎng)搜索功能上述代碼的意思是,此次與大模型交互將不再單純將用戶的提問內(nèi)容傳給大模型,而是要將搜索結(jié)果一并作為提示詞傳給大模型。上述后端接口代碼修改后,還需要同步修改前端的代碼,主要修改doAnswer(

)函數(shù)的代碼。開發(fā)MCP客戶端聯(lián)網(wǎng)搜索功能可以增強AI問答系統(tǒng)的問答能力,并可以針對任何提問進行搜索,功能實用性較強,但不夠有針對性。而使用MCP服務(wù)可以有針對性地拓展AI問答系統(tǒng)的特殊功能,如天氣查詢、旅游規(guī)劃、酒店查詢等。本小節(jié)將通過實現(xiàn)一個MCP客戶端,以調(diào)用高德地圖服務(wù),配合聯(lián)網(wǎng)搜索功能,對AI問答系統(tǒng)進行完善。以下代碼演示了如何通過Python代碼獲取高德地圖的所有工具列表,并對其中的工具進行調(diào)用。開發(fā)MCP客戶端上述代碼運行后,會列出高德地圖所有MCP服務(wù)器工具,下面取其中一個工具進行展示。前文所述代碼的輸出結(jié)果就是函數(shù)定義,有描述、有參數(shù),至此,其本質(zhì)上與自定義函數(shù)沒有不同。同時,經(jīng)過仔細分析會發(fā)現(xiàn),inputSchema字段的值與FunctionCalling的函數(shù)定義部分完全一致。這非常有助于將其轉(zhuǎn)換為大模型的函數(shù)定義。開發(fā)MCP客戶端另外,由于mcp庫的函數(shù)全部被定義為async異步處理函數(shù),因此在上述代碼中同樣需要將函數(shù)定義為異步的,調(diào)用系統(tǒng)函數(shù)時必須使用await。理解了如何獲取工具列表以及如何調(diào)用工具后,再與大模型進行整合就比較簡單了。其核心過程就是先對用戶提問進行處理,執(zhí)行第一次大模型調(diào)用,再從中解析是否存在工具調(diào)用的需求,如果存在,則調(diào)用相應(yīng)工具,最后是正常的流式響應(yīng)的模型對話。在MCPClient類中,新增一個函數(shù)process_query(

),利用以下代碼即可進行AI對話與函數(shù)調(diào)用。開發(fā)MCP客戶端開發(fā)MCP客戶端函數(shù)調(diào)用增強因為FunctionCalling或MCP等調(diào)用更多地會應(yīng)用于對話式AI應(yīng)用中,所以要將函數(shù)調(diào)用整合到當(dāng)前項目中,是完全可行的,這主要取決于用戶需要讓AI解決哪些問題。下面以通過AI提問框來發(fā)送一封郵件為例,演示如何增強AI問答系統(tǒng)的對話功能,對于其他各類功能的拓展,其思路和邏輯與之大體相同。首先,定義一個函數(shù),用于通過Python向特定郵箱地址發(fā)送一封郵件,將其保存到func_calling.py源文件中,具體代碼如下。函數(shù)調(diào)用增強由于使用QQ郵箱服務(wù)器來發(fā)送郵件,因此讀者需要進入QQ郵箱,開啟SMTP服務(wù),并申請一個授權(quán)碼。具體操作如下:登錄QQ郵箱→單擊“設(shè)置”按鈕→單擊“賬號”按鈕,即可進入圖3-5所示的界面。按照系統(tǒng)提示申請授權(quán)碼,即可發(fā)送郵件。函數(shù)調(diào)用增強其次,完成郵件發(fā)送代碼的編寫后,需要完善兩段代碼。此時,需要根據(jù)FunctionCalling的格式要求來定義函數(shù)規(guī)格,以便大模型可以正確識別該函數(shù)的功能及參數(shù);需要修改AI對話的過程,只有對函數(shù)調(diào)用進行獨立的處理,才能將其整合到AI問答系統(tǒng)中。在func_calling.py代碼中添加以下函數(shù)定義。函數(shù)調(diào)用增強修改qa.py模塊中的智能問答功能,將函數(shù)調(diào)用與普通問答進行整合,修改后的代碼如下。圖像識別與生成04圖像識別功能在介紹圖像識別功能之前,要先了解圖像識別功能的大模型接口規(guī)范要求,可以通過查看阿里云大模型服務(wù)平臺的用戶指南學(xué)習(xí)視覺理解的接口規(guī)范。因為該接口是OpenAI兼容接口,所以代碼調(diào)用較為簡單,唯一需要注意的是圖像識別的正文需要包含圖像的Base64編碼和文本提示詞,其大致結(jié)構(gòu)如下。圖像識別功能除了需要重新構(gòu)建文本對話有所差異的請求,其他操作與文本對話基本一致。掌握了接口規(guī)范后,即可著手編寫后端接口代碼,并保存于recognize.py模塊中,具體內(nèi)容如下。圖像識別前端圖像識別通常分為兩步:第一步是用戶上傳圖像并編寫提示詞第二步是發(fā)送給后臺以獲取大模型的輸出。因此,只設(shè)置一個按鈕顯然無法滿足功能要求,至少需要兩個按鈕。第一個按鈕是“識圖”按鈕,用于瀏覽圖像并顯示預(yù)覽效果,第二個按鈕仍然使用“智能問答”按鈕來與后端進行交互。需要注意的是,此處涉及在“智能問答”按鈕中如何判斷用戶是要進行文本問答還是要進行圖像識別的問題。從chat.html源代碼中可以看出,“識圖”按鈕調(diào)用的是addImage()函數(shù),該函數(shù)的代碼實現(xiàn)只是為了觸發(fā)文件上傳框的單擊事件,用于模擬文件上傳時的瀏覽文件功能,代碼如下。圖像識別前端當(dāng)用戶瀏覽圖像后,接下來即可響應(yīng)文件上傳框中的onchange="saveAndPreview()"代碼,saveAndPreview()函數(shù)用于將圖像的Base64編碼數(shù)據(jù)保存到sessionStorage中,并在提問框中進行預(yù)覽顯示。之所以使用sessionStorage而不是localStorage,是因為sessionStorage只用于臨時存儲數(shù)據(jù),關(guān)閉瀏覽器后就會清空數(shù)據(jù),不會永久保存,而AI問答系統(tǒng)也不需要永久保存。具體實現(xiàn)代碼如下。圖像識別前端如果上述代碼的功能正常,則當(dāng)用戶瀏覽圖像后,可以在提問框中顯示預(yù)覽圖,其實現(xiàn)效果如圖3-7所示。圖像生成功能因為通義萬相模型不支持使用OpenAI的SDK,所以必須使用Dashscope的SDK實現(xiàn),根據(jù)文檔的示例代碼即可方便地生成圖像。創(chuàng)建generate.py后端接口,實現(xiàn)代碼如下。圖像生成功能后端代碼實現(xiàn)后,直接編寫前端代碼實現(xiàn)對接,并對生成的圖像進行渲染即可。圖像生成功能圖3-8中的提示詞還不夠完善。此時,可以選擇將這句提示詞交給智能問答系統(tǒng),讓智能問答系統(tǒng)幫助用戶優(yōu)化得到一份更加完善的提示詞。以下提示詞是由本章的AI問答系統(tǒng)生成的。每日新聞?wù)猚ontent目錄01功能與設(shè)計分析02基礎(chǔ)功能實現(xiàn)03擴展功能實現(xiàn)功能與設(shè)計分析01核心功能列表新聞?wù)到y(tǒng)在設(shè)計該項目時,要考慮以下6點。(1)選擇合適的新聞來源,本書選擇的是新浪新聞。(2)通過爬蟲技術(shù)獲取新聞標題和新聞原文內(nèi)容,以便于把內(nèi)容交給AI大模型進行總結(jié)和摘要。(3)由于新聞不是隨時更新的,因此每日新聞?wù)椖啃枰邆涠〞r更新新聞內(nèi)容的能力。但是到更新時間時,因為可能某些新聞還未更新,所以數(shù)據(jù)庫還要具備去重的能力。(4)既然是新聞?wù)?,用戶的需求主要就是快速獲取新聞的大致信息。所以其界面要盡量簡潔,不宜提供過多功能。同時,如果用戶對某個新聞比較感興趣,則可能會想查看新聞原文內(nèi)容,最好提供原文鏈接,讓用戶可以跳轉(zhuǎn)閱讀原文。(5)由于新聞類型比較豐富,如國內(nèi)新聞、國際新聞、娛樂體育新聞、財經(jīng)科技新聞等,因此應(yīng)該具備新聞分類功能,以便用戶快速找到自己感興趣的新聞。(6)由于每天的新聞均保存在數(shù)據(jù)庫中,因此需要支持按日期展示歷史新聞,使用戶可以快速查看過去某天的新聞內(nèi)容。核心功能列表新聞?wù)到y(tǒng)整體實現(xiàn)思路(1)新聞原文內(nèi)容爬取。使用Python中的BeautifulSoup庫可以非常方便地對網(wǎng)頁內(nèi)容進行解析和提取。(2)交給大模型進行總結(jié)摘要時,只需要編寫好提示詞模板,把要求和對應(yīng)的新聞原文提交給大模型,大模型就可以返回摘要內(nèi)容。其準確度主要取決于大模型本身的理解能力,不過目前通義千問或DeepSeek等大模型在這方面的表現(xiàn)都較為出色。(3)在新聞實時更新方面,需要設(shè)置一個定時任務(wù)爬取新浪新聞上的最新新聞。(4)新聞分類本質(zhì)上也可以通過爬蟲技術(shù)獲得,但是由于每日新聞?wù)椖恐会槍π吕诵侣勥M行摘要,同一個新聞?wù)军c的新聞類型通常是固定的,因此可以在代碼中預(yù)先寫好分類。(5)更新新聞時,通常需要將更新時間插入數(shù)據(jù)表,而該時間可以作為分組依據(jù)。以日期進行SQL查詢分組后,可以獲得日期的列表,并在前端界面中通過超鏈接功能將每個日期單獨設(shè)為一條超鏈接,用戶單擊相應(yīng)超鏈接后就可以獲取當(dāng)天的新聞?wù);A(chǔ)功能實現(xiàn)02前端界面布局在掌握了某個系統(tǒng)的功能需求后,通常要優(yōu)先考慮進行項目的原型設(shè)計,或者直接開發(fā)原型界面,以便對需求和交互邏輯等進行更合理的規(guī)劃。一旦界面元素和交互邏輯基本確定,就說明需求理解已經(jīng)完整和準確;再從技術(shù)層面考慮前后端的具體實現(xiàn),這樣可以確保思路上的通暢。如果是團隊開發(fā)某個項目,預(yù)先設(shè)計好原型界面可以使得成員之間的溝通更加順暢。整個新聞?wù)慕缑娌季植⒉粡?fù)雜,主要由頂部分類、中部新聞?wù)黧w、底部的按日期瀏覽這幾個部分構(gòu)成,以下是HTML+CSS的布局代碼。前端界面布局前端界面布局上述界面布局代碼可以置于templates目錄下,并由Jinja2模板引擎進行渲染,這一部分內(nèi)容與第3章的模板界面渲染完全一致,此處不贅述。其實現(xiàn)效果如圖4-2所示。一般來說,在設(shè)計前端界面時,由于還沒有后臺數(shù)據(jù)用于填充,因此可以先在HTML界面中任意填充一些數(shù)據(jù)進行占位,以預(yù)覽真實的實現(xiàn)效果,后續(xù)可通過Jinja2模板引擎在相應(yīng)位置進行動態(tài)填充,以正常實現(xiàn)功能。數(shù)據(jù)表結(jié)構(gòu)根據(jù)前文分析的結(jié)果,設(shè)計每日新聞?wù)臄?shù)據(jù)表結(jié)構(gòu),如圖4-3所示。其中,id為自增長列,category為新聞類型,headline為新聞標題,hyperlink為原文超鏈接,content為新聞原始內(nèi)容(保存與否均可,因為最終展現(xiàn)的不是原文而是摘要),summary為新聞?wù)?,createtime為該條數(shù)據(jù)的生成時間。目前,每日新聞?wù)椖坎恍韪郊悠渌δ?,只需要?chuàng)建這一張表。BeautifulSoup庫由于每日新聞?wù)椖恐恍枧廊⌒吕诵侣劸W(wǎng)站上的公開數(shù)據(jù),且只涉及幾個固定界面,比較有針對性,因此相對容易處理。每日新聞?wù)椖客瓿梢韵聝蓚€關(guān)鍵步驟后即可正常爬取到相應(yīng)的內(nèi)容:第一步是利用Python的requests庫發(fā)送Get請求以獲取界面的源代碼;第二步是利用BeautifulSoup庫對該源代碼進行解析,將需要的內(nèi)容提取出來。新浪新聞版塊截圖如圖4-4所示,其中新聞部分的標題和超鏈接就是后續(xù)需要獲取的內(nèi)容。為了獲取網(wǎng)頁中元素的屬性,需要在瀏覽器中按F12鍵打開開發(fā)者工具,以查看網(wǎng)頁源代碼和對應(yīng)的元素。BeautifulSoup庫運行“pipinstallbeautifulsoup4lxml”命令,在Python環(huán)境下安裝BeautifulSoup庫。運行以下代碼,嘗試進行爬取。BeautifulSoup庫以同樣的方式編寫代碼,具體如下。以此類推,可以獲取其他類型的新聞。每日新聞?wù)椖恐饕廊〗袢找?、國?nèi)新聞、國際新聞、財經(jīng)科技、娛樂體育等幾類新聞。讀者也可以根據(jù)需要爬取其他類型的新聞,不影響每日新聞?wù)椖康募夹g(shù)運用即可。爬取標題與超鏈接分析新聞首頁的元素屬性可以發(fā)現(xiàn),除了今日要聞的元素及屬性與其他類型新聞不同外,其他類型新聞的class屬性、ul元素及H

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論