智能體開發(fā)技術(Python+FastAPI版) 課件 第5-8章 智能語音記分- 智能在線客服_第1頁
智能體開發(fā)技術(Python+FastAPI版) 課件 第5-8章 智能語音記分- 智能在線客服_第2頁
智能體開發(fā)技術(Python+FastAPI版) 課件 第5-8章 智能語音記分- 智能在線客服_第3頁
智能體開發(fā)技術(Python+FastAPI版) 課件 第5-8章 智能語音記分- 智能在線客服_第4頁
智能體開發(fā)技術(Python+FastAPI版) 課件 第5-8章 智能語音記分- 智能在線客服_第5頁
已閱讀5頁,還剩203頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

智能語音記分content目錄01語音識別與合成02Web版語音記分03Python版語音記分語音識別與合成01本地錄音文件識別Whisper語音識別模型Whisper語音識別模型由OpenAI公司研發(fā)并開源,可以直接在本地部署和調(diào)用。要使用Whisper模型,必須先完成依賴庫的安裝。如果之前未安裝PyTorch,則此處需要先利用pipinstalltorch命令安裝其CPU版本,再利用以下命令安裝transformers庫及其依賴包。pipinstalltransformersaccelerate安裝完成后,編寫以下代碼便可實現(xiàn)語音文件的識別。目前Whisper主要支持WAV、FLAC、MP3這3種格式的音頻文件,讀者可以自行制作或下載相應格式的文件用于測試。本地錄音文件識別Vosk語音識別模型Vosk是一個開源的語音識別模型,支持多國語言,包括普通話。其中文語音模型包括兩個版本:一個大小為42MB的小模型版本以及一個大小為1.3GB的大模型版本。其中,小模型版本的實測效果并不是很理想,但是運行速度快,因此常作為語音喚醒模型。首先,下載支持中文的語音識別模型vosk-model-small-cn-0.22和vosk-model-cn-0.22,將這兩個模型文件解壓到某個目錄下,讀者可以先加載這兩個模型進行測試,再決定后續(xù)是否采用該模型。其次,執(zhí)行“pipinstallSpeechRecognitionvoskpyaudio”命令安裝兩個依賴庫,并編寫以下代碼實現(xiàn)語音文件的識別。本地實時語音識別本地實時語音識別同樣支持Whisper或Vosk模型。通過speech_recognition庫讀取麥克風實時語音,便可以實現(xiàn)相應效果。使用Vosk模型的示例代碼如下。本地實時語音識別當代碼運行并提示“請說話…”時,對著計算機的麥克風說話,盡量使用標準普通話,說話速度慢一點,發(fā)音清楚一點,運行結果類似如下。也可以使用Whisper模型實現(xiàn)實時語音識別,代碼如下。本地實時語音識別也可以使用Whisper模型實現(xiàn)實時語音識別,代碼如下。Whisper模型存在文件大、推理速度慢的缺點,不建議用于設計實時語音識別系統(tǒng)。本地語音識別的優(yōu)勢在于節(jié)省了云端API的費用,但是對CPU或GPU的推理速度要求較高,讀者可以根據(jù)實際情況選擇合適的方案。阿里云語音識別阿里云提供在線語音識別模型供開發(fā)者調(diào)用,以實現(xiàn)語音識別功能,目前其識別準確率要遠高于本地模型。要使用阿里云的語音識別模型Paraformer,只需要確保已經(jīng)成功安裝了Dashscope的Python庫并擁有DashscopeAPIKey,這類準備工作在前文已經(jīng)介紹過。讀者也可以參考其官網(wǎng)的在線幫助文檔獲取更多接口調(diào)用示例。阿里云語音識別錄音文件識別根據(jù)在線幫助文檔,參考Paraformer錄音文件識別PythonAPI的示例代碼,錄音文件識別分為兩類:本地文件識別,通過指定本地音頻文件進行實時識別;云端文件識別,通過指定多個音頻文件的URL進行異步識別。以下代碼可以實現(xiàn)錄音文件的實時語音識別功能。阿里云語音識別錄音文件識別為了提升效率,進行批量化處理,Paraformer模型也支持異步調(diào)用,代碼如下。阿里云語音識別實時語音識別Paraformer模型同樣支持實時語音識別,這對智能語音記分系統(tǒng)來說至關重要。實時語音識別通過實現(xiàn)回調(diào)接口的方式流式輸出實時識別結果。根據(jù)官方文檔,實時語音識別的代碼如下。阿里云語音識別實時語音識別運行上述代碼,將打開麥克風并進行實時識別,Paraformer的識別準確率非常高,運行結果類似如下。WebSocket通信HTTP是一種無狀態(tài)的、無連接的、單向的應用層協(xié)議。它采用請求/響應模型。通信請求只能由客戶端發(fā)起,服務器對請求做出應答處理。這種通信模型有一個弊端:HTTP無法實現(xiàn)服務器主動向客戶端發(fā)送消息。這種單向請求的特點導致服務器有連續(xù)的狀態(tài)變化時,客戶端要獲知這些變化非常麻煩。大多數(shù)Web應用程序通過頻繁的異步AJAX請求實現(xiàn)長輪詢,輪詢效率低,資源浪費大(因為必須不停地建立連接,或者HTTP連接始終打開)。而WebSocket就是專門用于解決該問題的。WebSocket連接允許客戶端和服務器之間進行全雙工通信,以便任意一方可以通過建立的連接將數(shù)據(jù)推送到另一端。WebSocket只需要建立一次連接,就可以一直保持連接狀態(tài)。相較于輪詢方式要不停地建立連接,這種方式的效率得到了很大提高。圖5-1展示了AJAX輪詢與WebSocket通信過程。WebSocket通信WebSocket通信阿里云提供了兩種語音識別的模型接口。第一種是智能語音交互接口,該接口默認支持WebSocket,可以直接使用JavaScript完成交互。但是該接口的開通無法使用之前已經(jīng)申請好的APIKey,之前的代碼也無法重用,且代碼相對較復雜。本書采用第二種接口,即直接使用之前申請好的APIKey,并重用前文Python調(diào)用Paraformer的識別代碼。使用此接口只需要定義一個Python的WebSocket服務器接口,用于與前端JavaScript進行交互,邏輯上比較好理解,同時可以了解WebSocket服務器和客戶端的開發(fā)邏輯,一舉兩得。WebSocket通信開發(fā)WebSocket服務器要在Python中開發(fā)WebSocket服務器,需要先安裝websockets庫,安裝命令為pipinstallwebsockets,并編寫以下代碼實現(xiàn)WebSocket服務器端口。WebSocket通信開發(fā)WebSocket服務器完成上述代碼的編寫后直接運行,此時Python會啟動一個WebSocket服務并綁定端口8765。利用Apifox創(chuàng)建一個WebScoket接口,并對該接口進行測試,測試結果如圖5-2所示。WebSocket通信開發(fā)JavaScript客戶端前面完成了服務器的開發(fā),接下來開發(fā)JavaScript客戶端,代碼及注釋如下。JavaScript語音識別利用JavaScript進行實時語音識別的核心流程包含以下4個步驟。(1)利用JavaScript的MediaRecorderAPI在網(wǎng)頁端進行實時錄音操作;默認的API不支持WAV格式,建議使用RecordRTC.js庫直接將語音錄制為WAV格式。(2)利用WebSocket將網(wǎng)頁中的錄音數(shù)據(jù)實時傳輸給后端。(3)后端對獲取到的實時二進制數(shù)據(jù)進行累加,累加到一定大?。ㄈ?4KB)時,將該二進制文件保存到一個臨時文件中。(4)讀取該臨時文件,并使用Paraformer的錄音文件識別方案進行識別,獲取識別結果。(5)Python將識別到的結果通過WebSocket回傳給前端,并刪除之前的臨時文件。JavaScript語音識別MediaRecorderAPI雖然JavaScript內(nèi)置的Media?RecorderAPI無法直接將音頻錄制為WAV或MP3格式,但是仍然有必要了解一下其工作機制。先通過API獲取瀏覽器權限調(diào)用麥克風(攝像頭等硬件的調(diào)用與此類似),再定義錄制格式等參數(shù),最后處理不同事件。以下代碼展示了從錄制音頻到在本地播放的全過程,用作后續(xù)使用RecordRTC.js庫的基礎參考。JavaScript語音識別RecordRTC.js庫因為原生MediaRecorderAPI無法支持WAV格式的音頻錄音,所以需要使用第三方庫來錄制音頻,智能語音記分系統(tǒng)采用RecordRTC.js庫。讀者可自行下載該庫并將其保存到當前項目目錄下,在HTML界面中引用該庫,編寫以下代碼進行測試。JavaScript語音識別后端WebSocket接口后端WebSocket接口主要用于實時接收來自前端的(二進制)音頻數(shù)據(jù),將其拼接為64KB大小并保存到臨時文件夾中。保存文件時需要注意,必須使用wave庫將二進制文件轉(zhuǎn)換為WAV文件,否則數(shù)據(jù)將出現(xiàn)亂碼,無法正常使用。調(diào)用Paraformer接口進行語音識別。JavaScript語音識別后端WebSocket接口上述代碼會在當前目錄的audio目錄下產(chǎn)生很多64KB大小左右的臨時文件,建議通過定時任務將其定時刪除。同時,所有函數(shù)的定義和調(diào)用全部采用異步機制進行,以確保系統(tǒng)的及時響應和運行效率。因為當前端提交音頻文件到后端后,后端一方面需要調(diào)用Paraformer將音頻文件轉(zhuǎn)換為文本文件,另一方面需要繼續(xù)接收前端發(fā)送來的新數(shù)據(jù),在這種情況下,如果不使用異步機制,則必然會導致程序阻塞,從而大幅降低系統(tǒng)運行效率。JavaScript語音識別前端音頻采集及識別前端代碼無非是在RecordRTC.js庫的基礎用法上加上WebSocket連接和數(shù)據(jù)發(fā)送的代碼。那么,什么時候?qū)?shù)據(jù)發(fā)送出去呢?錄音結束后才發(fā)送肯定無法被接受。此時,可以利用RecordRTC.js庫的ondataavailable事件設置何時發(fā)送。該事件會設置一個時間,若設置為500毫秒,則每隔500毫秒會觸發(fā)一次該事件,在該事件中發(fā)送數(shù)據(jù)即可達到實時發(fā)送的目的。語音合成與播放利用pyttsx3庫實現(xiàn)本地語音合成運行“pipinstallpyttsx3”命令安裝庫,并編寫以下代碼調(diào)用本地系統(tǒng)的語音合成服務,合成后的語音可以直接播放,也可以將其保存到文件中。語音合成與播放利用阿里云的語音合成服務Sambert實現(xiàn)語音合成阿里云的語音合成服務Sambert不僅支持合成不同格式的文件,支持設置音頻參數(shù)或選擇不同類型的音色,還支持對合成的語音進行實時播放或?qū)⑵浔4娴轿募?。以下代碼演示了其用法。語音合成與播放利用阿里云的語音合成服務Sambert實現(xiàn)語音合成上述代碼將文本合成為語音,保存為MP3格式的文件。更多詳細參數(shù)可參考其在線幫助文檔。如果要實時播放合成的語音,則需要安裝pyaudio,并編寫以下代碼。語音合成與播放前端播放語音合成文件編寫一個FastAPI后端接口,用于接收前端提交的文本,完成語音合成后,將音頻文件的路徑響應給前端,具體代碼如下。Web版語音記分02功能與實現(xiàn)思路智能語音記分系統(tǒng)主要應用于各類比賽。一方面,該系統(tǒng)通過語音指令代替人工實現(xiàn)快速記分,可以提供更好的用戶體驗;另一方面,該系統(tǒng)可以在不暫停比賽的情況下通過語音完成記分操作,使用起來更加便捷。圖5-3所示為一個標準的Web界面,可以使用語音控制記分,也可以手動單擊按鈕實現(xiàn)記分功能。同時,其支持撤銷最后一次得分,以應對一些記分錯誤的情況。這里將界面元素設計得比較大,目的是使該應用可以安裝在一臺嵌入式設備(如樹莓派等)上,并連接一個較小的觸控屏,以便隨身攜帶。功能與實現(xiàn)思路梳理Web版智能語音記分系統(tǒng)各個功能的實現(xiàn)思路。(1)開始本局。獲取瀏覽器麥克風權限并開始錄音,建立與后端WebSocket服務器的連接,以便實現(xiàn)語音識別。(2)加減號按鈕。加減號按鈕用于進行手動操作,每次加減1分,這個得分可以通過函數(shù)參數(shù)進行傳遞,這樣語音控制時也可以調(diào)用該函數(shù),只是傳遞的得分由語音識別而來。(3)每次只要有加減分數(shù)的操作都要記錄到日志中,以便賽后回溯。同樣地,撤銷得分也可以根據(jù)該日志記錄來進行,讀取最后一條日志記錄,解析其中的內(nèi)容,并進行逆向操作,就可以撤銷最后一次的得分。(4)結束本局。結束本局主要需完成兩件事:一是關閉與WebSocket服務器的連接,二是匯總比分并清空本局比分,以便開始下一局。(5)所有針對文本框、文本域、總比分等的加減操作或記錄操作,均使用標準的JavaScript進行處理。為了計算分數(shù)的加減,需要將文本框中的數(shù)字通過ParseInt()函數(shù)轉(zhuǎn)換為整數(shù)進行處理。前端界面實現(xiàn)前端界面由標準的HTML+CSS實現(xiàn),代碼如下。前端界面實現(xiàn)上述HTML代碼對應的style.css文件內(nèi)容如下。前端JavaScript代碼實現(xiàn)前端代碼中除了語音識別功能,基本都是JavaScript本地操作,邏輯并不復雜,但是絕大部分操作的相關細節(jié)需要注意。尤其是在什么情況下應該調(diào)用哪個函數(shù),更新哪個得分,務必確保無誤。后臺代碼實現(xiàn)后臺代碼主要分為兩部分:第一部分是FastAPI定義與渲染、靜態(tài)目錄定義等代碼,第二部分是WebSocket服務器和語音識別代碼。FastAPI定義與渲染代碼比較簡單,因為除渲染模板界面外,沒有其他功能需要FastAPI來處理。當然,讀者也可以自行添加接口來處理前端的一些比賽數(shù)據(jù),如保存每一次的比賽結果數(shù)據(jù)等。這類功能的實現(xiàn)與一個標準的Web應用的實現(xiàn)沒有任何區(qū)別,前文已經(jīng)詳細講解過,所以這里不再實現(xiàn)這類功能。Python版語音記分03tkinter繪制界面Python中開發(fā)界面的庫有很多,比較知名的有Python內(nèi)置的小型應用開發(fā)庫tkinter,以及功能更全面的wxPython庫,也包括功能更加強大的、從大名鼎鼎的C++界面庫QT移植而來的PyQT庫。因為智能語音記分系統(tǒng)的界面相對簡單,功能也不復雜,所以直接采用tkinter實現(xiàn)。Python版智能語音記分系統(tǒng)的運行截圖如圖5-4所示。tkinter繪制界面與HTML類似,tkinter也提供了各種控制庫用于繪制界面所需的元素。它們的區(qū)別主要有以下兩點。(1)tkinter并沒有提供類似的CSS,所有元素的樣式必須在聲明元素時設置,但是其名稱與CSS的樣式類似,能夠見名知意。(2)tkinter沒有采用DIV布局,一個簡單方案是直接使用絕對定位將元素放置于界面中需要的位置。以下代碼演示了如何使用tkinter繪制Python版智能語音記分系統(tǒng)界面。語音喚醒功能語音喚醒服務的實現(xiàn)思路如下:在本地運行Vosk模型,使其保持處于啟動狀態(tài),一旦檢測到喚醒詞,如“你好中國”,就啟動Paraformer的語音識別功能來識別后面所說的話,這樣就不用保持Paraformer時刻處于啟動狀態(tài),而是只在需要時才啟動。以下代碼演示了如何使用Vosk進行語音喚醒并進入一段5秒的延遲,延遲結束后繼續(xù)檢測喚醒詞。模擬語音識別結束后自動停止的操作,直到下一次喚醒,代碼如下。語音喚醒功能通過以上代碼邏輯實現(xiàn)對Paraformer的語音喚醒,只需要將上述代碼的loop()函數(shù)替換為Paraformer的語音識別代碼。上述代碼的運行過程如下。完整功能代碼首先,實現(xiàn)完整的Vosk語音喚醒及語音識別功能。經(jīng)測試,在使用智能語音記分系統(tǒng)時,用戶通常說的指令詞為“紅隊加×分”,這一句話通常在4秒之內(nèi)可以完成,因此設置延遲時間為4秒。完整功能代碼完整功能代碼其次,完成非語音操作部分,包括得分的加減,以及日志寫入、撤銷等操作。完整功能代碼智能考勤content目錄01需求與設計分析02OpenCV版本實現(xiàn)03Web端版本實現(xiàn)04活體檢測防作弊需求與設計分析01核心功能列表基于人臉識別和活體檢測的智能考勤系統(tǒng),其核心功能是準確的人臉識別和基于防作弊機制的活體檢測功能,并提供相應的界面用于考勤數(shù)據(jù)的查詢、導出等。為了讓用戶能夠及時得知是否打卡成功,建議添加語音播放功能,并同步顯示當天的最新的考勤數(shù)據(jù)。另外,可以將智能考勤系統(tǒng)整合到企業(yè)內(nèi)部的辦公自動化或人力資源系統(tǒng)中,這部分內(nèi)容不在本書討論范疇,但是在設計時可以考慮相應的拓展性。圖6-1展示了智能考勤系統(tǒng)純Web端通過WebSocket實現(xiàn)的界面截圖。整體實現(xiàn)思路(1)人臉數(shù)據(jù)采集:前端界面可以通過JavaScript調(diào)用MediaRecorderAPI來實現(xiàn)攝像頭調(diào)用,并利用canvas元素進行實時截圖;也可以基于Python的OpenCV庫來調(diào)用攝像頭實時獲取人臉數(shù)據(jù)。兩者思路完全一致,只是實現(xiàn)方法有所差異,本章后續(xù)內(nèi)容會對此進行詳細講解。(2)人臉識別:核心在于檢測攝像頭中是否存在人臉,并提取出人臉輪廓數(shù)據(jù)。face_recognition庫提供的face_locations()函數(shù)可以直接讀取并返回人臉在整段視頻中的位置信息。如果有多張人臉,則返回多條人臉位置信息。(3)人臉位置標注:為了給用戶提供實時的可視化反饋,最好是在識別到人臉時實時在攝像頭視頻畫面中繪制位置框。在Python中,可以使用OpenCV庫直接進行繪制,在JavaScript中,可以使用“DIV+固定定位”的方案進行繪制。整體實現(xiàn)思路(4)人臉對比:考勤系統(tǒng)一般會先錄入人臉數(shù)據(jù),將其保存為圖像,并將每一張人臉照片識別為一組編碼,此編碼在face_recognition庫中是一組128維的特征編碼向量。人臉對比時,主要對比錄入的人臉的特征和識別的人臉的特征,如果相似度較高,則認為兩張人臉屬于同一個人。(5)數(shù)據(jù)管理:需要使用數(shù)據(jù)庫對人臉特征向量和考勤數(shù)據(jù)進行保存,所以使用SQLModel來操作數(shù)據(jù)庫??梢允褂?張表來保存數(shù)據(jù):第一張表用于保存人員基本信息,如姓名、部門等;第二張表用于保存首次錄入的人臉數(shù)據(jù);第三張表用于保存每一次的考勤記錄。(6)活體檢測:為了防止考勤時使用事先拍攝好的照片進行作弊,通常需要進行活體檢測。活體檢測的方案有很多,本章智能考勤系統(tǒng)的實現(xiàn)思路是基于face_recognition庫所識別的臉部的68個關鍵特征點的坐標值來進行眨眼、張嘴、點頭、搖頭等動作的實時計算,以檢測是否為活體。face_recognition的用法要使用face_recognition,需要先安裝環(huán)境,主要安裝OpenCV、Dlib和face_recognition這3個庫,運行“pipinstallopencv-pythondlibface_recognition”命令即可完成安裝。其中,OpenCV庫主要用于采集攝像頭數(shù)據(jù)、進行圖案繪制、實時繪制人臉框等,也包括處理來自前端的視頻數(shù)據(jù)的轉(zhuǎn)碼等;Dlib是face_recognition的依賴包。主要函數(shù)和功能(1)load_image_file(filename):加載圖像文件,并返回表示該圖像的NumPy數(shù)組。該函數(shù)用于從磁盤加載圖像數(shù)據(jù),以便后續(xù)進行人臉識別或分析。(2)face_locations(image,model="hog"):在圖像中檢測人臉,并返回一個列表,其中每個元素表示檢測到的人臉的位置。位置以(top,right,bottom,left)四元組形式表示,分別代表人臉框的上、右、下、左邊界。可以選擇使用hog或cnn模型來進行檢測,默認使用hog。face_recognition的用法(3)face_landmarks(image):在圖像中檢測人臉并標記68個關鍵特征點,返回一個字典類型的數(shù)據(jù),其中包含每個檢測到的人臉的關鍵特征點坐標。關鍵特征點包括眼睛、眉毛、鼻子、嘴巴、下巴等。該函數(shù)的返回值主要用于活體檢測。(4)face_encoding(image,location=None,num_jitters=1,model="small"):返回圖像的128維特征編碼向量。其中,location是人臉的位置,是可選項,若不指定,則編碼整張人臉;num_jitters表示抽樣次數(shù),值越大表示計算速度越慢,但是可以提升準確率;model表示使用哪種模型,默認值為small,其計算量小,只針對臉部的5個關鍵特征點進行編碼。(5)compare_faces(known_face_encodings,face_encoding_to_check,tolerance=0.6):將一個人臉編碼與一組已知人臉編碼進行比較,查看其中是否有相似人臉,并返回一個布爾值數(shù)組,表示待比較人臉與已知人臉的匹配結果,當兩組編碼的差距小于閾值時,認為其是一個人并返回true,否則返回false??蛇x參數(shù)tolerance用于指定容錯度閾值,取值為0~1,默認值為0.6,該值越大,說明容錯度越高。face_recognition的用法下述代碼展示了如何使用face_recognition模型識別人臉并在圖像上標注出位置。OpenCV版本實現(xiàn)02利用OpenCV采集攝像頭數(shù)據(jù)代碼演示了如何使用OpenCV實時采集攝像頭數(shù)據(jù),并借助face_recognition判斷是否存在人臉,如果存在,則將人臉通過矩形框標注出來。人臉數(shù)據(jù)存儲與對比代碼展示了如何進行人臉對比,并找到正確的人臉進行姓名和位置標注。人臉數(shù)據(jù)存儲與對比上述代碼中有以下兩點需要注意。首先,由于Mr-Zhang.png這張圖像是由AI生成的,編者使用提示詞讓AI生成了一張佩戴眼鏡的人的圖像,以體現(xiàn)真實的人臉識別時面部有所變化的情況,如圖6-4所示。但是在實際生產(chǎn)環(huán)境中,智能考勤系統(tǒng)中存儲的均是真實的人臉數(shù)據(jù),個體差異通常比較大,不會存在此類長得特別像的情況,所以在實際環(huán)境中,調(diào)用compare_face()函數(shù)時,需要調(diào)整tolerance參數(shù)以達到識別相對準確的目的。人臉數(shù)據(jù)存儲與對比其次,OpenCV中利用putText()函數(shù)繪制文字標注時,無法繪制中文標注,因為該函數(shù)只支持繪制ASCII字符。如果需要繪制中文標注,則需要安裝PIL(即Python圖像庫),安裝命令為pipinstallPillow,并由該庫生成中文字符。以下代碼演示了PIL庫的基礎功能,后續(xù)章節(jié)中使用到其他功能時再進行補充。設計智能考勤系統(tǒng)數(shù)據(jù)表其核心功能主要涉及3張表。第一張表為用戶信息表,用于保存用戶的基本信息;第二張表為人臉編碼表,用于保存預存儲的人臉編碼信息;第三張表為考勤記錄表,用于記錄每次考勤的數(shù)據(jù)。實現(xiàn)新增人臉數(shù)據(jù)功能新增人臉數(shù)據(jù)功能通過Web界面實現(xiàn)交互,利用FastAPI提供后臺數(shù)據(jù)操作。前端界面可以使用兩種方案來完成新增:第一種方案是直接上傳人臉圖像并編碼保存;第二種方案是打開攝像頭讀取人臉數(shù)據(jù)并截圖,上傳截圖并編碼保存。后端代碼實現(xiàn)若要新增人臉數(shù)據(jù),則需要提供后臺接口來獲取前端人臉圖像,且前端提交的圖像與對應的人員圖像是正確關聯(lián)的,進而利用face_recognition進行人臉編碼和保存。因此后端代碼需要實現(xiàn)以下功能。(1)提供/user接口,用于查詢?nèi)藛T信息,并渲染給前端模板界面。前端在提交人臉圖像時,同時提交userid的信息,后臺可以正確保存對應人員的人臉編碼。(2)提供/face/add接口,用于獲取前端提交的userid和人臉圖像,編碼后將其保存到數(shù)據(jù)表中。(3)創(chuàng)建SQLModel數(shù)據(jù)映射關系,用于關聯(lián)對應的3張表,以在接口代碼中實現(xiàn)數(shù)據(jù)的查詢或新增等操作。實現(xiàn)新增人臉數(shù)據(jù)功能首先,實現(xiàn)數(shù)據(jù)表的映射關系,代碼如下。實現(xiàn)新增人臉數(shù)據(jù)功能其次,編寫/user接口代碼,該接口用于渲染前端模板界面,列出所有人員信息。同時,該接口實現(xiàn)了Users和Faces兩張表的連接查詢,用于確認哪些人員還沒有上傳人臉數(shù)據(jù)。此處使用LeftJoin(左外連接),將Users作為左表,F(xiàn)aces作為右表。左表Users會顯示所有數(shù)據(jù),而右表中如果未匹配到userid,則顯示為空,說明未上傳人臉數(shù)據(jù)。這樣即可在前端界面中清楚地知道哪些人員需要上傳人臉圖像,哪些人員不需要上傳人臉圖像。具體實現(xiàn)代碼如下。實現(xiàn)新增人臉數(shù)據(jù)功能上述/user接口只是將人員信息渲染出來,未實現(xiàn)人臉編碼信息的存儲,所以需要使用/face/add接口將人臉編碼信息保存到數(shù)據(jù)表中,同時,如果前端提交的圖像未包含有效的人臉信息,則需要提示用戶,具體代碼如下。實現(xiàn)新增人臉數(shù)據(jù)功能前端代碼實現(xiàn)前端模板界面需要填充所有用戶信息,同時,為了將人臉圖像與userid關聯(lián)起來,以便后端將人臉編碼關聯(lián)到正確的userid上,需要對文件上傳框進行特殊處理。此處的處理方案是為每一條人員信息生成一個隱藏的文件上傳框,通過按鈕來觸發(fā)文件上傳、瀏覽功能,并根據(jù)元素的相對層級定位來進行元素操作。實現(xiàn)新增人臉數(shù)據(jù)功能前端代碼實現(xiàn)最后,完成前后端功能對接和調(diào)試。前端代碼運行結果如圖6-5所示。實現(xiàn)人臉考勤功能整體實現(xiàn)思路可以分為以下4個步驟。(1)從Faces表中查詢所有人臉的編碼信息,并將其從字符串類型轉(zhuǎn)換為Python列表類型。(2)利用OpenCV打開攝像頭,實時采集人臉數(shù)據(jù),并根據(jù)采集到的人臉信息與已知的人臉編碼列表進行對比。(3)如果人臉對比成功,則記錄一條考勤信息到Checks表中,如果是當天的第一條考勤數(shù)據(jù),則同時記錄到checkdate列和checkstart列,否則記錄到checkend列。(4)如果人臉對比成功,則通過語音進行提示,告知用戶打卡成功,無須繼續(xù)采集人臉數(shù)據(jù)。同時,代碼需要進行限制,如10分鐘內(nèi)不允許進行第2次打卡。該限制方案可以通過查詢數(shù)據(jù)庫來實現(xiàn)。實現(xiàn)人臉考勤功能以下代碼演示了如何進行考勤并記錄考勤數(shù)據(jù),文件名為pycheckin.py實現(xiàn)Web端考勤數(shù)據(jù)查詢功能實現(xiàn)兩個接口,一個接口為/check/month,用于渲染默認的當月考勤記錄數(shù)據(jù);另一個接口為/check/query,用于在前端通過設置查詢條件(如姓名、部門、性別或日期)來實現(xiàn)對考勤記錄的查詢。以下代碼用于實現(xiàn)后端的查詢。實現(xiàn)Web端考勤數(shù)據(jù)查詢功能前端界面的布局和代碼如下。實現(xiàn)Web端考勤數(shù)據(jù)查詢功能前端界面的布局和代碼如下。Web端版本實現(xiàn)03前端采集攝像頭數(shù)據(jù)攝像頭視頻的實時渲染可以使用HTML的video元素來完成,但是video元素并不能直接實現(xiàn)截圖。要實現(xiàn)視頻截圖,還需要使用canvas元素。canvas元素是HTML中繪制復雜圖像的元素,其核心是繪圖功能。一些HTML游戲也可以使用canvas實現(xiàn)。具體實現(xiàn)方案是當單擊“截圖”按鈕時,動態(tài)生成一個canvas元素,先將視頻幀渲染到canvas中,再將canvas數(shù)據(jù)轉(zhuǎn)換為圖像數(shù)據(jù)。下述代碼演示了其具體實現(xiàn)。前端采集攝像頭數(shù)據(jù)以下代碼用于列出所有攝像頭設備的deviceId,在請求權限時指定該設備即可?;赪ebSocket進行實時檢測首先,開發(fā)Python端的WebSocket服務器,用于接收前端實時傳輸過來的視頻截圖,并進行人臉檢測,檢測到人臉后將人臉位置回傳給前端,代碼如下。基于WebSocket進行實時檢測其次,開發(fā)前端界面用于實時截取攝像頭圖像,并傳輸給WebSocket服務器,WebSocket服務器將識別到的人臉位置回傳給前端,前端再動態(tài)增加1個或多個DIV(由人臉的數(shù)量決定),并根據(jù)攝像頭video元素相對于當前界面的位置(offsetWidth或offsetHeight)配合后端回傳的人臉位置進行運算,將DIV繪制在對應的人臉位置上,該DIV必須使用固定定位才能準確地定位人臉位置。同時,為了體現(xiàn)人臉識別的實時性,前端代碼將不再使用“截圖”按鈕手動操作,而是使用setInterval()函數(shù)進行定時任務調(diào)用,這樣用戶可以體驗到更好的實時性效果。具體代碼如下。基于WebSocket進行實時檢測基于前端界面進行考勤首先,優(yōu)化WebSocket端代碼,加入考勤功能,代碼如下?;谇岸私缑孢M行考勤其次,修改前端代碼,對單張人臉的位置信息進行檢測,并對打卡成功或重復打卡的響應內(nèi)容進行檢測,同時語音播放考勤結果。打卡成功并顯示考勤記錄為了更加直觀地讓用戶看到考勤數(shù)據(jù),可以在視頻下方添加一個表格,將當天的考勤數(shù)據(jù)實時添加到表格中,并使數(shù)據(jù)倒序排列,讓最后一條考勤記錄顯示在最上方。活體檢測防作弊04人臉68個關鍵特征點通過神經(jīng)網(wǎng)絡模型識別人臉的68個關鍵特征點,進而計算距離或比例來得到結果。使用face_recognition庫可以準確標注出這68個點位的像素坐標。人臉68個關鍵特征點face_recognition庫的face_landmarks()函數(shù)可以識別并標記出人臉中對應的68個點的坐標,并返回一個“列表+字典”對象,其中包括不同部位的坐標數(shù)據(jù)。例如,以下數(shù)據(jù)就是一張人臉的68個關鍵特征點的坐標信息,其中每一個元組中的數(shù)據(jù)代表對應的(x,y)坐標。人臉68個關鍵特征點上面的數(shù)據(jù)一共包含9種類型的坐標信息,對應的特征部位及下標如下。人臉68個關鍵特征點基于特征點定位,以下代碼繪制了人臉上眼睛和嘴巴的特征點位連接起來的線條。指令動作檢測原理下面列舉4個常用的動作檢測算法。(1)眨眼。因為每只眼睛由6個坐標點構成,眨眼動作通常由兩只眼睛同步完成,所以只需要計算眼睛的高度與寬度之間的比例便可以確定是睜眼還是閉眼。指令動作檢測原理(2)張嘴。通常情況下,活體人臉處于閉嘴狀態(tài),只有特殊情況才會張嘴,如大笑,或者有指令要求時。所以,其檢測算法與眼睛的檢測算法是類似的,只需要計算上下嘴唇的距離與嘴唇寬度的比例,即可判斷是否張嘴。(3)點頭。通常,可以通過計算鼻尖或眉毛到下巴之間的距離變化來判斷是否點頭。例如,點頭時,其距離會變短,未點頭時,其距離相對更長。(4)搖頭。如果僅檢測是否搖頭,則只需要計算左右臉頰的距離是否發(fā)生變化。如果還要確定是向左搖頭還是向右搖頭,則需要計算鼻梁與左臉頰和右臉頰之間的距離變化?;铙w檢測核心代碼1.眨眼檢測代碼活體檢測核心代碼2.張嘴檢測代碼活體檢測核心代碼3.點頭檢測代碼前端連續(xù)截圖測試以下代碼將在語音播放提示后連續(xù)2秒進行截圖,并將圖像實時顯示到界面中,用于測試截圖頻率的設置是否合理。活體檢測與考勤1.后端檢測與考勤代碼后端的代碼主要解決3個問題:讀取前端批量上傳的圖像、對圖像進行活體檢測、活體檢測通過后實現(xiàn)考勤。創(chuàng)建一個新的模塊文件livecheck.py,用于進行眨眼的活體檢測。此處,除了計算EAR值,還需要進行批量圖像的處理及對離散系數(shù)的判斷,以返回檢測消息。活體檢測與考勤接下來實現(xiàn)后端接口,用于渲染前端模板界面并接收前端批量上傳的圖像,代碼如下?;铙w檢測與考勤2.前端截圖與響應的處理前端界面主要用于處理攝像頭截圖,將圖像中的Base64編碼內(nèi)容提取出來,以JSON格式上傳給后端,根據(jù)后端的檢測結果進行語音播放。AI智慧課堂content目錄01功能與設計分析02主體功能開發(fā)03出題和考試功能04登錄與Token鑒權05定時任務處理功能與設計分析01核心功能列表(1)老師授課時進行錄屏或者錄音,建議進行錄屏,這樣不僅可以快速獲取當次課堂的主要內(nèi)容,也可以讓學生在需要的時候回看視頻,以加深對課堂內(nèi)容的理解。(2)提取出視頻的關鍵幀,用于快速預覽當次視頻的主要內(nèi)容。(3)抽取視頻中的音頻,進行語音識別,這部分內(nèi)容在第5章中已經(jīng)做了介紹。本章直接使用語音識別技術即可。(4)將識別到的視頻或音頻中的文字交由大模型進行總結,形成課堂筆記,并以HTML或Markdown格式輸出,在前端對HTML或Markdown格式的文檔進行渲染,讓內(nèi)容的可讀性更強。(5)為課堂內(nèi)容總結出一個核心關鍵字,并利用在線搜索拓展課堂內(nèi)容,用于出題或進行話題拓展,并將搜索出來的結果作為擴展閱讀在前端界面中顯示出來,供學生訪問。(6)利用總結的內(nèi)容通過大模型生成思維導圖,學生不僅可以下載思維導圖文件,還可以在線預覽思維導圖的內(nèi)容。(7)利用大模型基于當次課堂的內(nèi)容生成考題,包括單選題和簡答題等題型。學生可以在線答題,并交由AI進行自動閱卷和評分。核心功能列表AI智慧課堂的界面如圖7-1所示。整體實現(xiàn)思路(1)抽取視頻中的音頻。該部分功能不需要AI的介入,只需要使用Python的moviepy庫就可以非常方便地將視頻中的語音提取出來,并保存為MP3文件。提取完成后,可以利用Whisper進行本地語音識別,或利用Paraformer進行準確率更高的語音識別,將其轉(zhuǎn)換為文本,后續(xù)的所有操作均基于該文本內(nèi)容。(2)提取視頻的關鍵幀用于快速預覽視頻的大致內(nèi)容。這一功能并沒有那么重要,因此本章主要演示一下其用法。目前比較常用的方案是使用OpenCV讀取視頻幀,如每隔10秒讀取一幀,并計算相鄰幀之間的顏色直方圖差異,如果差異較大,說明是不同的畫面,則截取該幀并保存為圖像。OpenCV中有封裝好的函數(shù)可以直接用于計算直方圖和兩張圖之間的差異。(3)對識別到的文字進行整理總結并生成課堂筆記,這是大模型所擅長的,將原文內(nèi)容結合提示詞交給大模型處理即可,沒有額外的操作。此處有一點需要注意,為了讓前端的筆記內(nèi)容可讀性更強,通常建議讓大模型將其生成為HTML格式,并在前端渲染出來。整體實現(xiàn)思路(4)大模型生成思維導圖。其實大模型本身的輸入只能是提示詞,輸出只能是文本或JSON數(shù)據(jù),無法直接生成思維導圖。獲取到JSON數(shù)據(jù)后,可利用Python的xmind庫將其轉(zhuǎn)換為思維導圖文件(XMIND文件)。生成XMIND文件后,學生即可在前端下載及使用該文件。(5)搜索出來的結果既可以用于完善出題的內(nèi)容和范圍,又可以將搜索結果列表呈現(xiàn)到前端作為學生的拓展學習內(nèi)容。(6)關于AI出題和評分,首先,需要給定JSON格式的提示詞模板讓大模型返回。其次,針對AI評分功能,單選題本質(zhì)上不需要AI進行評分,系統(tǒng)通過對比答案即可完成,所以AI評分的核心是對簡答題進行評分。只需要通過提示詞將學生答案和標準答案進行對比,就可以得到一個相對準確的分值。最后,需要通過Web系統(tǒng)和對數(shù)據(jù)庫的操作,將這些功能整合起來,使AI智慧課堂的完成度更高。數(shù)據(jù)庫設計數(shù)據(jù)庫設計數(shù)據(jù)庫設計完成數(shù)據(jù)表的定義和創(chuàng)建后,即可在model.py文件中定義數(shù)據(jù)映射關系,代碼如下。主體功能開發(fā)02視頻文件預處理首先,創(chuàng)建一個公共模塊文件module.py,用于進行各種處理,以便在main.py中進行調(diào)用。在module.py模板文件中實現(xiàn)提取音頻和音頻轉(zhuǎn)文字的功能。視頻文件預處理其次,新建一個FastAPI項目并開發(fā)后端接口與前端進行交互。實現(xiàn)首頁的渲染、視頻上傳和預處理等功能的后端接口代碼。視頻文件預處理再次,創(chuàng)建首頁的模板界面,該界面用于視頻文件上傳及顯示視頻信息。由于后續(xù)功能較多,因此這里將HTML、CSS和JavaScript分為3個文件分別進行保存。將首頁命名為index.html,代碼如下。視頻文件預處理該界面引入的JavaScript源文件script.js中的代碼如下。視頻文件預處理此時,用戶登錄功能暫時還不需要,可以先不實現(xiàn)。接下來實現(xiàn)整個界面的CSS,文件名為style.css,內(nèi)容如下。視頻文件預處理最后,測試首頁、后端視頻轉(zhuǎn)語音以及語音識別成文字的功能是否正常。如果代碼運行正常,則運行結果如圖7-2所示。生成課堂筆記以下代碼在module.py中添加了一個函數(shù)summarize(),用于對當次課堂的內(nèi)容進行摘要。該代碼的功能就是讓大模型對文本內(nèi)容進行總結,其重點在于編寫一段清晰明了的提示詞指令,讓大模型清楚自己的任務。示例代碼如下。生成課堂筆記課堂筆記生成成功后,需要將其在數(shù)據(jù)庫中保存起來。因為上述代碼最好在上傳視頻成功后就進行調(diào)用,所以需要對后端接口/upload進行修改,代碼如下。生成課堂筆記為了將課堂筆記在前端界面中正常顯示出來,還需要開發(fā)一個后端接口和一個前端模板界面。后端接口從前端獲取參數(shù)videoid,并查詢該視頻的信息,并將其填充到模板界面中,代碼如下。生成課堂筆記模板界面文件detail.html的源代碼如下。生成思維導圖利用大模型生成思維導圖數(shù)據(jù)生成思維導圖利用大模型生成思維導圖數(shù)據(jù)生成JSON數(shù)據(jù)后,同樣需要將其保存到數(shù)據(jù)庫中。在main.py的/upload接口中保存該JSON字符串,相關代碼如下。生成思維導圖生成思維導圖文件有了正確的JSON數(shù)據(jù)后,即可利用Python中的xmind庫生成思維導圖文件。這一過程的關鍵操作就是利用遞歸來讀取JSON數(shù)據(jù)中的層級,并通過xmind庫的各類接口寫入對應的內(nèi)容,代碼如下。生成思維導圖前端渲染與下載前端要渲染思維導圖,需要將數(shù)據(jù)庫中的JSON數(shù)據(jù)讀取到前端,并利用jsmind庫進行渲染。此處需要在detail.html模板界面中先引入jsmind庫的CSS樣式和JavaScript庫文件,實現(xiàn)代碼如下。生成思維導圖前端渲染與下載在前端渲染的思維導圖效果如圖7-4所示。生成視頻關鍵幀視頻關鍵幀的提取主要依賴OpenCV庫。OpenCV庫的VideoCapture()函數(shù)不僅可以獲取攝像頭數(shù)據(jù),還可以獲取視頻數(shù)據(jù)。以下代碼展示了如何提取關鍵幀,并將其保存到對應的以視頻文件名命名的文件夾中。生成視頻關鍵幀視頻幀率的截取代碼可以放到視頻上傳之后。在前端界面中遍歷并顯示圖像時,只需要前端添加模板渲染部分的代碼,并以視頻的文件名進行關聯(lián)。生成視頻關鍵幀同時,需要在后端接口/detail中添加一段代碼,用以讀取和生成模板界面可用的keyframes。修改后的完整代碼如下。生成視頻關鍵幀視頻關鍵幀展示的運行結果如圖7-5所示。拓展知識引用首先,利用關鍵字在線搜索并獲取搜索結果,將其保存到視頻信息表的reference列中。其次,更新/upload接口,保存生成的搜索結果,與前面生成的課堂筆記和思維導圖的保存方式完全一致。拓展知識引用最后,實現(xiàn)/detail接口更新和前端界面顯示功能。/detail接口代碼如下。建議將detail.html前端界面顯示代碼添加到界面末尾。出題和考試功能03生成考題以下代碼(位于module.py文件中)演示了如何讓大模型生成考題并按照指定格式輸出。生成考題考題生成后需要保存到數(shù)據(jù)庫中,此處將考題的JSON數(shù)據(jù)保存到視頻信息表的examjson列中。修改/upload接口代碼,保存考題并調(diào)用insert_exam()函數(shù)對考題進行解析,保存每一道考題信息到考題信息表中。生成考題接下來在module.py中新增函數(shù)insert_exam(),通過解析考題的JSON字符串內(nèi)容,提取每一道考題并將其作為一行數(shù)據(jù)保存到考題信息表中。前端渲染考題以下代碼實現(xiàn)了/exam后端接口。前端渲染考題后端接口完成后,繼續(xù)開發(fā)前端模板界面exam.html,代碼及注釋如下。前端渲染考題上述HTML界面對應的CSS如下。提交試卷并評分一般可以通過遍歷界面中的單選框的值和文本域的內(nèi)容,對采集到的答案進行提交。以下代碼為doExam()函數(shù)的JavaScript代碼。提交試卷并評分提交答案時,上述代碼構建的JSON數(shù)據(jù)格式如下。登錄與Token鑒權04Token處理機制1.存儲型Token存儲型Token極為簡單的方案就是生成一串隨機字符,或者利用用戶名、時間戳等元素來生成一串散列字符串,以確保唯一性。這樣下次進行權限驗證時,只需將前端傳遞過來的Token與數(shù)據(jù)庫中保存的Token進行比較,找到對應的用戶信息,就可以獲取當前登錄的用戶是哪一位,其角色權限有哪些,并進行各種接口的判斷。存儲型Token與Session校驗在機制上非常類似,主要區(qū)別在于Session是由Web服務器維護的,可定制性較弱,而Token是由系統(tǒng)程序維護的,可以操作的空間更大。例如,存儲型Token可以將隨機字符保存到Redis服務器中供各類應用程序調(diào)用,這一操作是普通的Session無法做到的。Token處理機制2.解密型Token解密型Token是指用戶首次完成登錄驗證后,對Token進行可逆運算的加密處理,生成一個密文,該密文可以由用戶名、ID、角色、時間戳等各種信息匯集后生成。這樣在進行解密時,就可以解密出原始的用戶名、ID、角色、時間戳等信息,并用于系統(tǒng)。解密型Token不需要存儲,只需要生成一次后響應給前端,后續(xù)前端每次都會攜帶該Token用于認證。服務器解密后就可以了解是哪一位用戶,以進行后續(xù)處理。通常解密型Token最好帶有一個有效期信息,以便讓登錄信息定期失效,防止出現(xiàn)Token泄露后永久可用的情況。加密與解密處理目前的密碼應用領域主要使用兩種加密算法。第一種是不可逆加密算法,如常見的MD5、安全散列算法(SecureHashAlgorithm,SHA)等算法就是不可逆加密算法,也稱為摘要算法。所謂不可逆是指無法根據(jù)密文反向解密出明文,通常這種加密算法可以應用于數(shù)字指紋識別或密碼保存、密碼對比等場景。在進行登錄驗證時,只需對用戶輸入的密碼進行MD5加密,再與數(shù)據(jù)庫中的密碼字段進行比較即可確定用戶輸入的密碼是否正確。加密與解密處理第二種加密算法通常稱為可逆加密算法,即可以根據(jù)密文解密出明文,這通常用于數(shù)據(jù)通信過程的加密。加密本身只是為了通信過程的安全,最終都需要解密以獲取原始數(shù)據(jù)。所謂對稱加密,是指加密和解密使用相同的密鑰,如主流的加密算法——高級加密標準(AdvancedEncryptionStandard,AES)算法。非對稱加密,是指加密時會生成一對公私鑰,使用公鑰加密,使用私鑰解密,如主流的RSA算法。登錄與Token認證首先,后端進行AES的加解密處理。建議在.env環(huán)境變量文件中添加以下兩個AES加密時會用到的參數(shù),以便于維護AES密鑰和初始向量。其次,編寫以下代碼對AES的加解密進行封裝,解析解密后的內(nèi)容,返回程序需要的信息。登錄與Token認證再次,實現(xiàn)登錄的后臺接口和前端操作。在main.py中新建一個/login接口,用于登錄校驗和Token生成。登錄與Token認證最后,處理前端登錄請求,在script.js中添加以下代碼。前后端校驗處理除了實現(xiàn)登錄和退出操作,還需要在每個模板界面中添加一段JavaScript代碼,用于更新登錄成功后的狀態(tài)。將以下代碼添加到各個模板界面的頂部<script>標簽中。定時任務處理05定時任務處理定時任務的功能應該如何實現(xiàn)呢?只需要循環(huán)獲取視頻信息表中內(nèi)容為空的所有字段,如果content為空,則說明未執(zhí)行語音轉(zhuǎn)文字的任務,此時定時任務調(diào)用audio_text()函數(shù)來完成該任務。如果summary為空,則說明語音轉(zhuǎn)文字任務已經(jīng)完成,但是未完成課堂筆記,此時可調(diào)用summarize()函數(shù)來完成該任務,以此類推。定時任務處理新建一個源文件schedule.py,編寫以下代碼實現(xiàn)定時任務的處理。智能在線客服content目錄01功能與設計分析02LlamaIndex框架應用03向量數(shù)據(jù)庫04項目功能實現(xiàn)05擴展功能優(yōu)化功能與設計分析01RAG與向量數(shù)據(jù)庫要計算用戶提問與文檔片段之間的相似度,首先需要將文本向量化,這一過程稱為詞嵌入。在AI模型中,針對文本的訓練和推理,首先需要將文本向量化。以下代碼演示了如何通過Ollama的詞嵌入接口獲取某個Token的詞向量。理解詞嵌入RAG與向量數(shù)據(jù)庫可以看出,“國”和“家”兩個Token的向量是不一樣的,同時每個Token的向量有4096個維度。Token的向量是將文字轉(zhuǎn)換為數(shù)字的極為重要的手段,只有轉(zhuǎn)換為數(shù)字后才能進行運算。同時,不同的模型,其向量的維度是不同的。這里的4096僅代表“qwen3:8b”這個模型的向量維度為4096。另外,這個維度的含義是用4096個數(shù)字來描述一個Token,其中的數(shù)字均是模型訓練后的結果。輸出的內(nèi)容大致為RAG與向量數(shù)據(jù)庫計算相似度主要有以下3種方法。(1)歐氏距離:測量向量之間的直接距離,距離越短,說明相似度越高。(2)余弦相似度:關注向量之間的角度,角度越小,說明相似度越高。(3)點積相似度:通過計算兩個向量的點積來判斷其相似度,點積值越大,意味著兩組向量越相似。向量相似度RAG與向量數(shù)據(jù)庫RAG工作流程核心功能列表以蝸牛學苑的智能在線客服系統(tǒng)為例進行講解。該系統(tǒng)主要包含以下功能。(1)管理員可以上傳新的文檔并進行分段保存,也可以查詢文檔內(nèi)容和分段內(nèi)容等。(2)普通用戶可以通過AI對話窗口提任意問題。(3)提供聯(lián)網(wǎng)搜索功能,以拓展AI的知識面,針對一些文檔中不存在但是網(wǎng)絡中可能存在的內(nèi)容,可以進行額外補充。(4)不僅要能準確回答用戶的問題,還需要能夠引起用戶興趣,或促進后續(xù)流程,如建議用戶到實地考察,或者要求用戶留下手機號或微信號等聯(lián)系方式。(5)當發(fā)現(xiàn)用戶留下了聯(lián)系方式后,應將聯(lián)系方式通過FunctionCalling向某位用戶發(fā)送郵件提醒。同時,為了便于后續(xù)咨詢時及時掌握用戶的需求,將保存當次對話的記錄。整體實現(xiàn)思路(1)管理員可以通過Web界面對私有知識庫進行管理,主要實現(xiàn)文檔的上傳、分段、修改和查詢等功能。修改功能可以由刪除和新增功能來代替。此處的文檔在完成分段后將主要保存到向量數(shù)據(jù)庫中,以便于后續(xù)操作。(2)普通用戶與智能在線客服系統(tǒng)進行對話時,與真人對話一樣,也要綜合考慮各種可能的情況。這部分并沒有技術難度,在AI問答系統(tǒng)中已經(jīng)完成了相應的功能,包括聯(lián)網(wǎng)搜索功能,此處僅需要加上知識庫并完善提示詞。(3)給予用戶建議或者試圖獲取用戶的聯(lián)系方式,這些功能均可以通過大模型的提示詞達成。(4)當用戶留下聯(lián)系方式后,需要通過FunctionCalling來進行函數(shù)調(diào)用,讓大模型解析出聯(lián)系方式并保存到數(shù)據(jù)庫中。LlamaIndex框架應用02LlamaIndex概述LlamaIndex的功能與特點主要包括以下幾點。(1)支持多種索引類型。LlamaIndex支持多種索引結構,包括列表索引、樹形索引、圖索引等,以滿足不同場景下的數(shù)據(jù)管理需求。(2)靈活的數(shù)據(jù)源集成。無論是結構化數(shù)據(jù)還是非結構化數(shù)據(jù),LlamaIndex都能輕松對接,如文檔、數(shù)據(jù)庫、API返回的數(shù)據(jù)等。(3)增強的檢索與問答能力。LlamaIndex提供了基于上下文的增強型檢索策略,使得大模型在回答用戶問題時能夠提供更相關、更精確的答案。(4)模塊化設計。LlamaIndex的組件設計非常靈活,開發(fā)者可以根據(jù)自己的需求自定義數(shù)據(jù)處理管道、索引構建流程等。(5)開源與社區(qū)支持。LlamaIndex是開源項目,擁有活躍的社區(qū)支持和不斷更新的文檔,開發(fā)者可以輕松獲取幫助和資源。LlamaIndex核心操作LlamaIndex的核心功能是讀取文檔、分段文檔、建立索引、檢索分段等。所以要使用LlamaIndex,必須先在項目目錄下創(chuàng)建一個目錄docs,用于存放各種文檔,如Word、Markdown、PDF、TXT文檔等。另外,默認情況下,LlamaIndex只支持使用OpenAI進行詞嵌入和大模型對話,所以需要提前配置好Ollama環(huán)境。LlamaIndex核心操作上述代碼的處理過程主要包含以下4個步驟。(1)定義詞嵌入模型和AI對話模型Ollama。上述代碼中雖然兩者都使用了同一個模型qwen3:8b,但是其實這兩個過程是獨立的。詞嵌入模型用于將文檔轉(zhuǎn)換為詞向量,不同的模型詞向量的結果也不同。(2)使用LlamaIndex內(nèi)置的文檔讀取器來加載文檔內(nèi)容。LlamaIndex支持讀取各類文檔,如Word、PDF、Markdown等,在模塊llama_index.readers.file中可以查看所有支持的Reader對象。當然,有些文檔的讀取除了需要這些支持的Reader對象,還需要額外安裝Python庫。(3)讀取文檔后,接下來需要進行向量化處理,并創(chuàng)建索引。創(chuàng)建索引只是為了讓后續(xù)檢索效率更快。創(chuàng)建完索引后即可進行持久化保存。默認情況下,LlamaIndex內(nèi)置了一個輕量級的向量數(shù)據(jù)庫,用于將向量和索引保存到JSON文件中。(4)通過提示詞檢索相關文檔分段,并通過大模型進行回復。此過程通過index.as_query_engine()進行了封裝,其實可以細分為3個步驟:根據(jù)用戶的問題檢索相似度最高的文檔片段,將文檔片段作為提示詞的一部分提交給大模型,由大模型根據(jù)用戶提問和文檔片段構成的提示詞進行回復。LlamaIndex核心操作上述代碼的運行結果如下。文檔分段與檢索當LlamaIndex加載一份文檔后,首先需要對文檔進行分段。之所以要進行分段,核心目的就是將長文檔變成文檔片段,進而檢索出與提示詞關聯(lián)度較高的片段用于大模型對話處理。以下代碼可以查看文檔的分段數(shù)據(jù)。文檔分段文檔分段與檢索當文檔分段完成后,即可對分段文檔建立索引,那么此時需要依賴詞嵌入模型對文檔進行索引和向量化保存。默認情況下,LlamaIndex使用的是OpenAI的詞嵌入模型,而通常國內(nèi)無法正常訪問到OpenAI,導致連接失敗。因此,需要在代碼中通過Settings指定為Ollama詞嵌入模型,當然,也可以指定為國內(nèi)可訪問的其他模型。以下代碼演示了創(chuàng)建索引的過程。創(chuàng)建索引文檔分段與檢索當完成索引的創(chuàng)建與保存后,即可進行文檔檢索。以下代碼演示了對已保存的索引進行檢索,并將匹配成功的文檔片段輸出的過程。文檔檢索文檔分段與檢索第一種方案是增加檢索結果的返回數(shù)量,修改index.as_retriever()的參數(shù)similarity_top_k=5,可以按照相似度排序檢索出5篇文檔,如果仍然檢索不出來,則增加值到10、20或者更大;第二種方案是修改用戶提問,使之更加匹配原始文檔內(nèi)容,但是該方法不存在通用性,因為系統(tǒng)無法控制用戶提出什么樣的問題。優(yōu)化檢索結果文檔分段與檢索上述代碼的運行結果如下。優(yōu)化檢索結果處理流式響應利用LlamaIndex內(nèi)置函數(shù)index.as_chat_engine()創(chuàng)建流式響應的具體實現(xiàn)代碼如下。處理流式響應基于檢索結果自行拼接提示詞,并調(diào)用對話模型來實現(xiàn)流式響應的具體實現(xiàn)代碼如下。處理流式響應既然可以使用Ollama來處理流式響應,那么可以對上述代碼加以修改,使用通義千問的云端模型來進行回復,具體代碼如下。文檔分段策略1.分段策略概述文檔分段主要存在以下4個方面的問題。(1)段落過大:可能導致檢索到的文檔包含過多無關信息,增加了大模型理解語義的難度,降低了答案的準確性,甚至超出了大模型上下文大小的限制。(2)段落過?。嚎赡軐е聶z索到的文檔只包含部分信息,無法全面回答用戶所提的問題。(3)分段不當:可能會破壞語義的連貫性,導致原本一個完整的知識被拆分到多個段落中。(4)忽略文檔結構:通常很多文檔是有章節(jié)劃分的,一章或者一節(jié)通常就是一個完整的話題,如果分段不當,則該結構就會被破壞,進而導致分段不當。大致了解了文檔的結構后,有以下結論:文檔遵守Markdown格式,有明確的層次結構,且屬于問答式的內(nèi)容,可以非常容易地將問題和答案放到同一個段落中,既不會導致分段不當,又可以實現(xiàn)高效檢索。下面基于上述文檔來進一步學習各種分段策略具體是如何切分文檔的。文檔分段策略2.Token級固定大小分段使用TokenTextSplitter()按照Token數(shù)量來進行固定大小的分段。該方案僅供演示,實際使用過程中不建議使用,因為它只關注Token,而不會關注句子,常常將一個句子從中間截斷,導致AI完全無法正確、完整地表達語句。文檔分段策略3.語句級固定大小分段SentenceSplitter()也是一種固定大小的分段策略,該方案相對于TokenTextSplitter()來說,最大的優(yōu)勢在于不會將一個句子從中間截斷,無論段落劃分效果如何,至少可以保證段末的語句是完整的。所以,雖然設置了chunk_size=500,但是并不保證每一段的字數(shù)均為500。文檔分段策略4.語義分段語義分段指根據(jù)文本的語義進行切分,將語義關聯(lián)緊密的句子或段落聚合在一起。通常做法是先將文本分成基礎單元(如句子),再計算相鄰單元的語義相似度,如果相似度高于某個閾值,則合并這些單元,直到相似度顯著下降時才創(chuàng)建一個新的塊。該分段方案適用于長文本文檔,不太適用于短文本文檔,所分段落通常較長。同時,因為需要使用相似度來比較語句和段落,所以必須使用詞嵌入模型,導致分段過程運算量較大,所花費的時間也比較長。以下代碼對WoniuAI-V6.txt這個較長的文檔進行分段,共分出了13個段落。文檔分段策略5.遞歸分段遞歸分段采用“分而治之”的策略。首先,嘗試使用一組優(yōu)先級較高的、較大的文本分隔符(如段落標記、章節(jié)標記)來分割文本。其次,檢查分割出的每個段落的大小。如果某個段落仍然超過預設的大小限制,則換用下一組更低優(yōu)先級、更細粒度的分隔符(如句子結束符、換行符)對其進行更細粒度的分割,此過程遞歸進行,直到所有塊都滿足大小要求(注意:所得段落大小并不嚴格一致,而是大小不一)。此分段策略會對文檔進行多粒度分段,以便檢索時可以檢索到最相關的文檔片段。文檔分段策略6.文檔結構分段文檔結構分段是指基于文檔原本的章節(jié)層次或標簽元素等進行分段。在LlamaIndex中,主要針對Markdown、HTML、JSON等文檔進行結構分段。此處需要注意的是,針對HTML、JSON文檔時,需要使用FlatReader對象來讀取文檔。Markdown文檔的分段規(guī)則是按照章節(jié)層次分段,這在前面已經(jīng)有所介紹。HTML文檔是根據(jù)常用的段落標簽(如P、H1~H6、Li、Section等)進行分段。JSON文檔的分段是嚴格按照列表中的項目數(shù)量進行分段,如果頂層為字典,則只會分為一段。以下代碼演示了這3種文檔的結構分段。文檔分段策略7.混合策略分段混合策略分段是指對上述各種分段策略進行混合處理,在創(chuàng)建索引時將各種分隔器通過參數(shù)transformations指定。以下代碼演示了結合文檔結構分段與語義分段兩種策略來創(chuàng)建索引的過程。檢索結果重排序在RAG技術體系中,可以優(yōu)化的位置其實有兩個:第一個是如何實現(xiàn)合理分段,第二個是如何實現(xiàn)精準檢索。目前已經(jīng)介紹了不同的分段策略,下面從檢索精準度的角度來分析一下還有哪些方面可以優(yōu)化。默認情況下,LlamaIndex將根據(jù)向量相似度評分來對檢索結果進行排序,進而實現(xiàn)top_k的選擇和使用。使用該對象時,需要加載一個語言模型來分析檢索結果與問題的語義相關性,進而實現(xiàn)重排序。本書推薦使用模型BAAI/bge-reranker-v2-m3。該模型對中英文的支持效果較好。通過以下代碼可完成模型的自動下載。向量數(shù)據(jù)庫03Chroma的核心操作Chroma的安裝非常簡單,運行“pipinstallchromadb”命令即可安裝。下面來看看Chroma如何對文檔創(chuàng)建索引并進行相似度查詢。Chroma的核心操作上述代碼只演示了基礎使用過程,一切都在內(nèi)存中操作。而真實情況下肯定不能將數(shù)據(jù)僅保存到內(nèi)存中,必須進行持久化存儲。同時,為了讓語義更加準確,建議使用Ollama作為詞嵌入模型。下述代碼完善了這兩個功能。Chroma的核心操作上述代碼運行后,會在./dbstore/chroma目錄下創(chuàng)建向量和索引文件等內(nèi)容,還會有一個chroma.sqlite3的SQLite數(shù)據(jù)庫文件,其中保存了很多基礎信息。如果讀者想查看該數(shù)據(jù)庫中的內(nèi)容,則必須先安裝工具DBBrowserforSQLite。該數(shù)據(jù)庫中保存的數(shù)據(jù)如圖8-4所示。Chroma的核心操作當完成文檔添加并創(chuàng)建好索引后,即可對持久化向量數(shù)據(jù)進行查詢,以下是查詢部分的代碼。Chroma的核心操作通過對比發(fā)現(xiàn),使用Ollama的qwen3:8b模型進行詞嵌入

溫馨提示

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

最新文檔

評論

0/150

提交評論