智能体开发技术(Python+FastAPI版) 课件 第5-8章 智能语音记分- 智能在线客服_第1页
智能体开发技术(Python+FastAPI版) 课件 第5-8章 智能语音记分- 智能在线客服_第2页
智能体开发技术(Python+FastAPI版) 课件 第5-8章 智能语音记分- 智能在线客服_第3页
智能体开发技术(Python+FastAPI版) 课件 第5-8章 智能语音记分- 智能在线客服_第4页
智能体开发技术(Python+FastAPI版) 课件 第5-8章 智能语音记分- 智能在线客服_第5页
已阅读5页,还剩203页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

智能语音记分content目录01语音识别与合成02Web版语音记分03Python版语音记分语音识别与合成01本地录音文件识别Whisper语音识别模型Whisper语音识别模型由OpenAI公司研发并开源,可以直接在本地部署和调用。要使用Whisper模型,必须先完成依赖库的安装。如果之前未安装PyTorch,则此处需要先利用pipinstalltorch命令安装其CPU版本,再利用以下命令安装transformers库及其依赖包。pipinstalltransformersaccelerate安装完成后,编写以下代码便可实现语音文件的识别。目前Whisper主要支持WAV、FLAC、MP3这3种格式的音频文件,读者可以自行制作或下载相应格式的文件用于测试。本地录音文件识别Vosk语音识别模型Vosk是一个开源的语音识别模型,支持多国语言,包括普通话。其中文语音模型包括两个版本:一个大小为42MB的小模型版本以及一个大小为1.3GB的大模型版本。其中,小模型版本的实测效果并不是很理想,但是运行速度快,因此常作为语音唤醒模型。首先,下载支持中文的语音识别模型vosk-model-small-cn-0.22和vosk-model-cn-0.22,将这两个模型文件解压到某个目录下,读者可以先加载这两个模型进行测试,再决定后续是否采用该模型。其次,执行“pipinstallSpeechRecognitionvoskpyaudio”命令安装两个依赖库,并编写以下代码实现语音文件的识别。本地实时语音识别本地实时语音识别同样支持Whisper或Vosk模型。通过speech_recognition库读取麦克风实时语音,便可以实现相应效果。使用Vosk模型的示例代码如下。本地实时语音识别当代码运行并提示“请说话…”时,对着计算机的麦克风说话,尽量使用标准普通话,说话速度慢一点,发音清楚一点,运行结果类似如下。也可以使用Whisper模型实现实时语音识别,代码如下。本地实时语音识别也可以使用Whisper模型实现实时语音识别,代码如下。Whisper模型存在文件大、推理速度慢的缺点,不建议用于设计实时语音识别系统。本地语音识别的优势在于节省了云端API的费用,但是对CPU或GPU的推理速度要求较高,读者可以根据实际情况选择合适的方案。阿里云语音识别阿里云提供在线语音识别模型供开发者调用,以实现语音识别功能,目前其识别准确率要远高于本地模型。要使用阿里云的语音识别模型Paraformer,只需要确保已经成功安装了Dashscope的Python库并拥有DashscopeAPIKey,这类准备工作在前文已经介绍过。读者也可以参考其官网的在线帮助文档获取更多接口调用示例。阿里云语音识别录音文件识别根据在线帮助文档,参考Paraformer录音文件识别PythonAPI的示例代码,录音文件识别分为两类:本地文件识别,通过指定本地音频文件进行实时识别;云端文件识别,通过指定多个音频文件的URL进行异步识别。以下代码可以实现录音文件的实时语音识别功能。阿里云语音识别录音文件识别为了提升效率,进行批量化处理,Paraformer模型也支持异步调用,代码如下。阿里云语音识别实时语音识别Paraformer模型同样支持实时语音识别,这对智能语音记分系统来说至关重要。实时语音识别通过实现回调接口的方式流式输出实时识别结果。根据官方文档,实时语音识别的代码如下。阿里云语音识别实时语音识别运行上述代码,将打开麦克风并进行实时识别,Paraformer的识别准确率非常高,运行结果类似如下。WebSocket通信HTTP是一种无状态的、无连接的、单向的应用层协议。它采用请求/响应模型。通信请求只能由客户端发起,服务器对请求做出应答处理。这种通信模型有一个弊端:HTTP无法实现服务器主动向客户端发送消息。这种单向请求的特点导致服务器有连续的状态变化时,客户端要获知这些变化非常麻烦。大多数Web应用程序通过频繁的异步AJAX请求实现长轮询,轮询效率低,资源浪费大(因为必须不停地建立连接,或者HTTP连接始终打开)。而WebSocket就是专门用于解决该问题的。WebSocket连接允许客户端和服务器之间进行全双工通信,以便任意一方可以通过建立的连接将数据推送到另一端。WebSocket只需要建立一次连接,就可以一直保持连接状态。相较于轮询方式要不停地建立连接,这种方式的效率得到了很大提高。图5-1展示了AJAX轮询与WebSocket通信过程。WebSocket通信WebSocket通信阿里云提供了两种语音识别的模型接口。第一种是智能语音交互接口,该接口默认支持WebSocket,可以直接使用JavaScript完成交互。但是该接口的开通无法使用之前已经申请好的APIKey,之前的代码也无法重用,且代码相对较复杂。本书采用第二种接口,即直接使用之前申请好的APIKey,并重用前文Python调用Paraformer的识别代码。使用此接口只需要定义一个Python的WebSocket服务器接口,用于与前端JavaScript进行交互,逻辑上比较好理解,同时可以了解WebSocket服务器和客户端的开发逻辑,一举两得。WebSocket通信开发WebSocket服务器要在Python中开发WebSocket服务器,需要先安装websockets库,安装命令为pipinstallwebsockets,并编写以下代码实现WebSocket服务器端口。WebSocket通信开发WebSocket服务器完成上述代码的编写后直接运行,此时Python会启动一个WebSocket服务并绑定端口8765。利用Apifox创建一个WebScoket接口,并对该接口进行测试,测试结果如图5-2所示。WebSocket通信开发JavaScript客户端前面完成了服务器的开发,接下来开发JavaScript客户端,代码及注释如下。JavaScript语音识别利用JavaScript进行实时语音识别的核心流程包含以下4个步骤。(1)利用JavaScript的MediaRecorderAPI在网页端进行实时录音操作;默认的API不支持WAV格式,建议使用RecordRTC.js库直接将语音录制为WAV格式。(2)利用WebSocket将网页中的录音数据实时传输给后端。(3)后端对获取到的实时二进制数据进行累加,累加到一定大小(如64KB)时,将该二进制文件保存到一个临时文件中。(4)读取该临时文件,并使用Paraformer的录音文件识别方案进行识别,获取识别结果。(5)Python将识别到的结果通过WebSocket回传给前端,并删除之前的临时文件。JavaScript语音识别MediaRecorderAPI虽然JavaScript内置的Media​RecorderAPI无法直接将音频录制为WAV或MP3格式,但是仍然有必要了解一下其工作机制。先通过API获取浏览器权限调用麦克风(摄像头等硬件的调用与此类似),再定义录制格式等参数,最后处理不同事件。以下代码展示了从录制音频到在本地播放的全过程,用作后续使用RecordRTC.js库的基础参考。JavaScript语音识别RecordRTC.js库因为原生MediaRecorderAPI无法支持WAV格式的音频录音,所以需要使用第三方库来录制音频,智能语音记分系统采用RecordRTC.js库。读者可自行下载该库并将其保存到当前项目目录下,在HTML界面中引用该库,编写以下代码进行测试。JavaScript语音识别后端WebSocket接口后端WebSocket接口主要用于实时接收来自前端的(二进制)音频数据,将其拼接为64KB大小并保存到临时文件夹中。保存文件时需要注意,必须使用wave库将二进制文件转换为WAV文件,否则数据将出现乱码,无法正常使用。调用Paraformer接口进行语音识别。JavaScript语音识别后端WebSocket接口上述代码会在当前目录的audio目录下产生很多64KB大小左右的临时文件,建议通过定时任务将其定时删除。同时,所有函数的定义和调用全部采用异步机制进行,以确保系统的及时响应和运行效率。因为当前端提交音频文件到后端后,后端一方面需要调用Paraformer将音频文件转换为文本文件,另一方面需要继续接收前端发送来的新数据,在这种情况下,如果不使用异步机制,则必然会导致程序阻塞,从而大幅降低系统运行效率。JavaScript语音识别前端音频采集及识别前端代码无非是在RecordRTC.js库的基础用法上加上WebSocket连接和数据发送的代码。那么,什么时候将数据发送出去呢?录音结束后才发送肯定无法被接受。此时,可以利用RecordRTC.js库的ondataavailable事件设置何时发送。该事件会设置一个时间,若设置为500毫秒,则每隔500毫秒会触发一次该事件,在该事件中发送数据即可达到实时发送的目的。语音合成与播放利用pyttsx3库实现本地语音合成运行“pipinstallpyttsx3”命令安装库,并编写以下代码调用本地系统的语音合成服务,合成后的语音可以直接播放,也可以将其保存到文件中。语音合成与播放利用阿里云的语音合成服务Sambert实现语音合成阿里云的语音合成服务Sambert不仅支持合成不同格式的文件,支持设置音频参数或选择不同类型的音色,还支持对合成的语音进行实时播放或将其保存到文件中。以下代码演示了其用法。语音合成与播放利用阿里云的语音合成服务Sambert实现语音合成上述代码将文本合成为语音,保存为MP3格式的文件。更多详细参数可参考其在线帮助文档。如果要实时播放合成的语音,则需要安装pyaudio,并编写以下代码。语音合成与播放前端播放语音合成文件编写一个FastAPI后端接口,用于接收前端提交的文本,完成语音合成后,将音频文件的路径响应给前端,具体代码如下。Web版语音记分02功能与实现思路智能语音记分系统主要应用于各类比赛。一方面,该系统通过语音指令代替人工实现快速记分,可以提供更好的用户体验;另一方面,该系统可以在不暂停比赛的情况下通过语音完成记分操作,使用起来更加便捷。图5-3所示为一个标准的Web界面,可以使用语音控制记分,也可以手动单击按钮实现记分功能。同时,其支持撤销最后一次得分,以应对一些记分错误的情况。这里将界面元素设计得比较大,目的是使该应用可以安装在一台嵌入式设备(如树莓派等)上,并连接一个较小的触控屏,以便随身携带。功能与实现思路梳理Web版智能语音记分系统各个功能的实现思路。(1)开始本局。获取浏览器麦克风权限并开始录音,建立与后端WebSocket服务器的连接,以便实现语音识别。(2)加减号按钮。加减号按钮用于进行手动操作,每次加减1分,这个得分可以通过函数参数进行传递,这样语音控制时也可以调用该函数,只是传递的得分由语音识别而来。(3)每次只要有加减分数的操作都要记录到日志中,以便赛后回溯。同样地,撤销得分也可以根据该日志记录来进行,读取最后一条日志记录,解析其中的内容,并进行逆向操作,就可以撤销最后一次的得分。(4)结束本局。结束本局主要需完成两件事:一是关闭与WebSocket服务器的连接,二是汇总比分并清空本局比分,以便开始下一局。(5)所有针对文本框、文本域、总比分等的加减操作或记录操作,均使用标准的JavaScript进行处理。为了计算分数的加减,需要将文本框中的数字通过ParseInt()函数转换为整数进行处理。前端界面实现前端界面由标准的HTML+CSS实现,代码如下。前端界面实现上述HTML代码对应的style.css文件内容如下。前端JavaScript代码实现前端代码中除了语音识别功能,基本都是JavaScript本地操作,逻辑并不复杂,但是绝大部分操作的相关细节需要注意。尤其是在什么情况下应该调用哪个函数,更新哪个得分,务必确保无误。后台代码实现后台代码主要分为两部分:第一部分是FastAPI定义与渲染、静态目录定义等代码,第二部分是WebSocket服务器和语音识别代码。FastAPI定义与渲染代码比较简单,因为除渲染模板界面外,没有其他功能需要FastAPI来处理。当然,读者也可以自行添加接口来处理前端的一些比赛数据,如保存每一次的比赛结果数据等。这类功能的实现与一个标准的Web应用的实现没有任何区别,前文已经详细讲解过,所以这里不再实现这类功能。Python版语音记分03tkinter绘制界面Python中开发界面的库有很多,比较知名的有Python内置的小型应用开发库tkinter,以及功能更全面的wxPython库,也包括功能更加强大的、从大名鼎鼎的C++界面库QT移植而来的PyQT库。因为智能语音记分系统的界面相对简单,功能也不复杂,所以直接采用tkinter实现。Python版智能语音记分系统的运行截图如图5-4所示。tkinter绘制界面与HTML类似,tkinter也提供了各种控制库用于绘制界面所需的元素。它们的区别主要有以下两点。(1)tkinter并没有提供类似的CSS,所有元素的样式必须在声明元素时设置,但是其名称与CSS的样式类似,能够见名知意。(2)tkinter没有采用DIV布局,一个简单方案是直接使用绝对定位将元素放置于界面中需要的位置。以下代码演示了如何使用tkinter绘制Python版智能语音记分系统界面。语音唤醒功能语音唤醒服务的实现思路如下:在本地运行Vosk模型,使其保持处于启动状态,一旦检测到唤醒词,如“你好中国”,就启动Paraformer的语音识别功能来识别后面所说的话,这样就不用保持Paraformer时刻处于启动状态,而是只在需要时才启动。以下代码演示了如何使用Vosk进行语音唤醒并进入一段5秒的延迟,延迟结束后继续检测唤醒词。模拟语音识别结束后自动停止的操作,直到下一次唤醒,代码如下。语音唤醒功能通过以上代码逻辑实现对Paraformer的语音唤醒,只需要将上述代码的loop()函数替换为Paraformer的语音识别代码。上述代码的运行过程如下。完整功能代码首先,实现完整的Vosk语音唤醒及语音识别功能。经测试,在使用智能语音记分系统时,用户通常说的指令词为“红队加×分”,这一句话通常在4秒之内可以完成,因此设置延迟时间为4秒。完整功能代码完整功能代码其次,完成非语音操作部分,包括得分的加减,以及日志写入、撤销等操作。完整功能代码智能考勤content目录01需求与设计分析02OpenCV版本实现03Web端版本实现04活体检测防作弊需求与设计分析01核心功能列表基于人脸识别和活体检测的智能考勤系统,其核心功能是准确的人脸识别和基于防作弊机制的活体检测功能,并提供相应的界面用于考勤数据的查询、导出等。为了让用户能够及时得知是否打卡成功,建议添加语音播放功能,并同步显示当天的最新的考勤数据。另外,可以将智能考勤系统整合到企业内部的办公自动化或人力资源系统中,这部分内容不在本书讨论范畴,但是在设计时可以考虑相应的拓展性。图6-1展示了智能考勤系统纯Web端通过WebSocket实现的界面截图。整体实现思路(1)人脸数据采集:前端界面可以通过JavaScript调用MediaRecorderAPI来实现摄像头调用,并利用canvas元素进行实时截图;也可以基于Python的OpenCV库来调用摄像头实时获取人脸数据。两者思路完全一致,只是实现方法有所差异,本章后续内容会对此进行详细讲解。(2)人脸识别:核心在于检测摄像头中是否存在人脸,并提取出人脸轮廓数据。face_recognition库提供的face_locations()函数可以直接读取并返回人脸在整段视频中的位置信息。如果有多张人脸,则返回多条人脸位置信息。(3)人脸位置标注:为了给用户提供实时的可视化反馈,最好是在识别到人脸时实时在摄像头视频画面中绘制位置框。在Python中,可以使用OpenCV库直接进行绘制,在JavaScript中,可以使用“DIV+固定定位”的方案进行绘制。整体实现思路(4)人脸对比:考勤系统一般会先录入人脸数据,将其保存为图像,并将每一张人脸照片识别为一组编码,此编码在face_recognition库中是一组128维的特征编码向量。人脸对比时,主要对比录入的人脸的特征和识别的人脸的特征,如果相似度较高,则认为两张人脸属于同一个人。(5)数据管理:需要使用数据库对人脸特征向量和考勤数据进行保存,所以使用SQLModel来操作数据库。可以使用3张表来保存数据:第一张表用于保存人员基本信息,如姓名、部门等;第二张表用于保存首次录入的人脸数据;第三张表用于保存每一次的考勤记录。(6)活体检测:为了防止考勤时使用事先拍摄好的照片进行作弊,通常需要进行活体检测。活体检测的方案有很多,本章智能考勤系统的实现思路是基于face_recognition库所识别的脸部的68个关键特征点的坐标值来进行眨眼、张嘴、点头、摇头等动作的实时计算,以检测是否为活体。face_recognition的用法要使用face_recognition,需要先安装环境,主要安装OpenCV、Dlib和face_recognition这3个库,运行“pipinstallopencv-pythondlibface_recognition”命令即可完成安装。其中,OpenCV库主要用于采集摄像头数据、进行图案绘制、实时绘制人脸框等,也包括处理来自前端的视频数据的转码等;Dlib是face_recognition的依赖包。主要函数和功能(1)load_image_file(filename):加载图像文件,并返回表示该图像的NumPy数组。该函数用于从磁盘加载图像数据,以便后续进行人脸识别或分析。(2)face_locations(image,model="hog"):在图像中检测人脸,并返回一个列表,其中每个元素表示检测到的人脸的位置。位置以(top,right,bottom,left)四元组形式表示,分别代表人脸框的上、右、下、左边界。可以选择使用hog或cnn模型来进行检测,默认使用hog。face_recognition的用法(3)face_landmarks(image):在图像中检测人脸并标记68个关键特征点,返回一个字典类型的数据,其中包含每个检测到的人脸的关键特征点坐标。关键特征点包括眼睛、眉毛、鼻子、嘴巴、下巴等。该函数的返回值主要用于活体检测。(4)face_encoding(image,location=None,num_jitters=1,model="small"):返回图像的128维特征编码向量。其中,location是人脸的位置,是可选项,若不指定,则编码整张人脸;num_jitters表示抽样次数,值越大表示计算速度越慢,但是可以提升准确率;model表示使用哪种模型,默认值为small,其计算量小,只针对脸部的5个关键特征点进行编码。(5)compare_faces(known_face_encodings,face_encoding_to_check,tolerance=0.6):将一个人脸编码与一组已知人脸编码进行比较,查看其中是否有相似人脸,并返回一个布尔值数组,表示待比较人脸与已知人脸的匹配结果,当两组编码的差距小于阈值时,认为其是一个人并返回true,否则返回false。可选参数tolerance用于指定容错度阈值,取值为0~1,默认值为0.6,该值越大,说明容错度越高。face_recognition的用法下述代码展示了如何使用face_recognition模型识别人脸并在图像上标注出位置。OpenCV版本实现02利用OpenCV采集摄像头数据代码演示了如何使用OpenCV实时采集摄像头数据,并借助face_recognition判断是否存在人脸,如果存在,则将人脸通过矩形框标注出来。人脸数据存储与对比代码展示了如何进行人脸对比,并找到正确的人脸进行姓名和位置标注。人脸数据存储与对比上述代码中有以下两点需要注意。首先,由于Mr-Zhang.png这张图像是由AI生成的,编者使用提示词让AI生成了一张佩戴眼镜的人的图像,以体现真实的人脸识别时面部有所变化的情况,如图6-4所示。但是在实际生产环境中,智能考勤系统中存储的均是真实的人脸数据,个体差异通常比较大,不会存在此类长得特别像的情况,所以在实际环境中,调用compare_face()函数时,需要调整tolerance参数以达到识别相对准确的目的。人脸数据存储与对比其次,OpenCV中利用putText()函数绘制文字标注时,无法绘制中文标注,因为该函数只支持绘制ASCII字符。如果需要绘制中文标注,则需要安装PIL(即Python图像库),安装命令为pipinstallPillow,并由该库生成中文字符。以下代码演示了PIL库的基础功能,后续章节中使用到其他功能时再进行补充。设计智能考勤系统数据表其核心功能主要涉及3张表。第一张表为用户信息表,用于保存用户的基本信息;第二张表为人脸编码表,用于保存预存储的人脸编码信息;第三张表为考勤记录表,用于记录每次考勤的数据。实现新增人脸数据功能新增人脸数据功能通过Web界面实现交互,利用FastAPI提供后台数据操作。前端界面可以使用两种方案来完成新增:第一种方案是直接上传人脸图像并编码保存;第二种方案是打开摄像头读取人脸数据并截图,上传截图并编码保存。后端代码实现若要新增人脸数据,则需要提供后台接口来获取前端人脸图像,且前端提交的图像与对应的人员图像是正确关联的,进而利用face_recognition进行人脸编码和保存。因此后端代码需要实现以下功能。(1)提供/user接口,用于查询人员信息,并渲染给前端模板界面。前端在提交人脸图像时,同时提交userid的信息,后台可以正确保存对应人员的人脸编码。(2)提供/face/add接口,用于获取前端提交的userid和人脸图像,编码后将其保存到数据表中。(3)创建SQLModel数据映射关系,用于关联对应的3张表,以在接口代码中实现数据的查询或新增等操作。实现新增人脸数据功能首先,实现数据表的映射关系,代码如下。实现新增人脸数据功能其次,编写/user接口代码,该接口用于渲染前端模板界面,列出所有人员信息。同时,该接口实现了Users和Faces两张表的连接查询,用于确认哪些人员还没有上传人脸数据。此处使用LeftJoin(左外连接),将Users作为左表,Faces作为右表。左表Users会显示所有数据,而右表中如果未匹配到userid,则显示为空,说明未上传人脸数据。这样即可在前端界面中清楚地知道哪些人员需要上传人脸图像,哪些人员不需要上传人脸图像。具体实现代码如下。实现新增人脸数据功能上述/user接口只是将人员信息渲染出来,未实现人脸编码信息的存储,所以需要使用/face/add接口将人脸编码信息保存到数据表中,同时,如果前端提交的图像未包含有效的人脸信息,则需要提示用户,具体代码如下。实现新增人脸数据功能前端代码实现前端模板界面需要填充所有用户信息,同时,为了将人脸图像与userid关联起来,以便后端将人脸编码关联到正确的userid上,需要对文件上传框进行特殊处理。此处的处理方案是为每一条人员信息生成一个隐藏的文件上传框,通过按钮来触发文件上传、浏览功能,并根据元素的相对层级定位来进行元素操作。实现新增人脸数据功能前端代码实现最后,完成前后端功能对接和调试。前端代码运行结果如图6-5所示。实现人脸考勤功能整体实现思路可以分为以下4个步骤。(1)从Faces表中查询所有人脸的编码信息,并将其从字符串类型转换为Python列表类型。(2)利用OpenCV打开摄像头,实时采集人脸数据,并根据采集到的人脸信息与已知的人脸编码列表进行对比。(3)如果人脸对比成功,则记录一条考勤信息到Checks表中,如果是当天的第一条考勤数据,则同时记录到checkdate列和checkstart列,否则记录到checkend列。(4)如果人脸对比成功,则通过语音进行提示,告知用户打卡成功,无须继续采集人脸数据。同时,代码需要进行限制,如10分钟内不允许进行第2次打卡。该限制方案可以通过查询数据库来实现。实现人脸考勤功能以下代码演示了如何进行考勤并记录考勤数据,文件名为pycheckin.py实现Web端考勤数据查询功能实现两个接口,一个接口为/check/month,用于渲染默认的当月考勤记录数据;另一个接口为/check/query,用于在前端通过设置查询条件(如姓名、部门、性别或日期)来实现对考勤记录的查询。以下代码用于实现后端的查询。实现Web端考勤数据查询功能前端界面的布局和代码如下。实现Web端考勤数据查询功能前端界面的布局和代码如下。Web端版本实现03前端采集摄像头数据摄像头视频的实时渲染可以使用HTML的video元素来完成,但是video元素并不能直接实现截图。要实现视频截图,还需要使用canvas元素。canvas元素是HTML中绘制复杂图像的元素,其核心是绘图功能。一些HTML游戏也可以使用canvas实现。具体实现方案是当单击“截图”按钮时,动态生成一个canvas元素,先将视频帧渲染到canvas中,再将canvas数据转换为图像数据。下述代码演示了其具体实现。前端采集摄像头数据以下代码用于列出所有摄像头设备的deviceId,在请求权限时指定该设备即可。基于WebSocket进行实时检测首先,开发Python端的WebSocket服务器,用于接收前端实时传输过来的视频截图,并进行人脸检测,检测到人脸后将人脸位置回传给前端,代码如下。基于WebSocket进行实时检测其次,开发前端界面用于实时截取摄像头图像,并传输给WebSocket服务器,WebSocket服务器将识别到的人脸位置回传给前端,前端再动态增加1个或多个DIV(由人脸的数量决定),并根据摄像头video元素相对于当前界面的位置(offsetWidth或offsetHeight)配合后端回传的人脸位置进行运算,将DIV绘制在对应的人脸位置上,该DIV必须使用固定定位才能准确地定位人脸位置。同时,为了体现人脸识别的实时性,前端代码将不再使用“截图”按钮手动操作,而是使用setInterval()函数进行定时任务调用,这样用户可以体验到更好的实时性效果。具体代码如下。基于WebSocket进行实时检测基于前端界面进行考勤首先,优化WebSocket端代码,加入考勤功能,代码如下。基于前端界面进行考勤其次,修改前端代码,对单张人脸的位置信息进行检测,并对打卡成功或重复打卡的响应内容进行检测,同时语音播放考勤结果。打卡成功并显示考勤记录为了更加直观地让用户看到考勤数据,可以在视频下方添加一个表格,将当天的考勤数据实时添加到表格中,并使数据倒序排列,让最后一条考勤记录显示在最上方。活体检测防作弊04人脸68个关键特征点通过神经网络模型识别人脸的68个关键特征点,进而计算距离或比例来得到结果。使用face_recognition库可以准确标注出这68个点位的像素坐标。人脸68个关键特征点face_recognition库的face_landmarks()函数可以识别并标记出人脸中对应的68个点的坐标,并返回一个“列表+字典”对象,其中包括不同部位的坐标数据。例如,以下数据就是一张人脸的68个关键特征点的坐标信息,其中每一个元组中的数据代表对应的(x,y)坐标。人脸68个关键特征点上面的数据一共包含9种类型的坐标信息,对应的特征部位及下标如下。人脸68个关键特征点基于特征点定位,以下代码绘制了人脸上眼睛和嘴巴的特征点位连接起来的线条。指令动作检测原理下面列举4个常用的动作检测算法。(1)眨眼。因为每只眼睛由6个坐标点构成,眨眼动作通常由两只眼睛同步完成,所以只需要计算眼睛的高度与宽度之间的比例便可以确定是睁眼还是闭眼。指令动作检测原理(2)张嘴。通常情况下,活体人脸处于闭嘴状态,只有特殊情况才会张嘴,如大笑,或者有指令要求时。所以,其检测算法与眼睛的检测算法是类似的,只需要计算上下嘴唇的距离与嘴唇宽度的比例,即可判断是否张嘴。(3)点头。通常,可以通过计算鼻尖或眉毛到下巴之间的距离变化来判断是否点头。例如,点头时,其距离会变短,未点头时,其距离相对更长。(4)摇头。如果仅检测是否摇头,则只需要计算左右脸颊的距离是否发生变化。如果还要确定是向左摇头还是向右摇头,则需要计算鼻梁与左脸颊和右脸颊之间的距离变化。活体检测核心代码1.眨眼检测代码活体检测核心代码2.张嘴检测代码活体检测核心代码3.点头检测代码前端连续截图测试以下代码将在语音播放提示后连续2秒进行截图,并将图像实时显示到界面中,用于测试截图频率的设置是否合理。活体检测与考勤1.后端检测与考勤代码后端的代码主要解决3个问题:读取前端批量上传的图像、对图像进行活体检测、活体检测通过后实现考勤。创建一个新的模块文件livecheck.py,用于进行眨眼的活体检测。此处,除了计算EAR值,还需要进行批量图像的处理及对离散系数的判断,以返回检测消息。活体检测与考勤接下来实现后端接口,用于渲染前端模板界面并接收前端批量上传的图像,代码如下。活体检测与考勤2.前端截图与响应的处理前端界面主要用于处理摄像头截图,将图像中的Base64编码内容提取出来,以JSON格式上传给后端,根据后端的检测结果进行语音播放。AI智慧课堂content目录01功能与设计分析02主体功能开发03出题和考试功能04登录与Token鉴权05定时任务处理功能与设计分析01核心功能列表(1)老师授课时进行录屏或者录音,建议进行录屏,这样不仅可以快速获取当次课堂的主要内容,也可以让学生在需要的时候回看视频,以加深对课堂内容的理解。(2)提取出视频的关键帧,用于快速预览当次视频的主要内容。(3)抽取视频中的音频,进行语音识别,这部分内容在第5章中已经做了介绍。本章直接使用语音识别技术即可。(4)将识别到的视频或音频中的文字交由大模型进行总结,形成课堂笔记,并以HTML或Markdown格式输出,在前端对HTML或Markdown格式的文档进行渲染,让内容的可读性更强。(5)为课堂内容总结出一个核心关键字,并利用在线搜索拓展课堂内容,用于出题或进行话题拓展,并将搜索出来的结果作为扩展阅读在前端界面中显示出来,供学生访问。(6)利用总结的内容通过大模型生成思维导图,学生不仅可以下载思维导图文件,还可以在线预览思维导图的内容。(7)利用大模型基于当次课堂的内容生成考题,包括单选题和简答题等题型。学生可以在线答题,并交由AI进行自动阅卷和评分。核心功能列表AI智慧课堂的界面如图7-1所示。整体实现思路(1)抽取视频中的音频。该部分功能不需要AI的介入,只需要使用Python的moviepy库就可以非常方便地将视频中的语音提取出来,并保存为MP3文件。提取完成后,可以利用Whisper进行本地语音识别,或利用Paraformer进行准确率更高的语音识别,将其转换为文本,后续的所有操作均基于该文本内容。(2)提取视频的关键帧用于快速预览视频的大致内容。这一功能并没有那么重要,因此本章主要演示一下其用法。目前比较常用的方案是使用OpenCV读取视频帧,如每隔10秒读取一帧,并计算相邻帧之间的颜色直方图差异,如果差异较大,说明是不同的画面,则截取该帧并保存为图像。OpenCV中有封装好的函数可以直接用于计算直方图和两张图之间的差异。(3)对识别到的文字进行整理总结并生成课堂笔记,这是大模型所擅长的,将原文内容结合提示词交给大模型处理即可,没有额外的操作。此处有一点需要注意,为了让前端的笔记内容可读性更强,通常建议让大模型将其生成为HTML格式,并在前端渲染出来。整体实现思路(4)大模型生成思维导图。其实大模型本身的输入只能是提示词,输出只能是文本或JSON数据,无法直接生成思维导图。获取到JSON数据后,可利用Python的xmind库将其转换为思维导图文件(XMIND文件)。生成XMIND文件后,学生即可在前端下载及使用该文件。(5)搜索出来的结果既可以用于完善出题的内容和范围,又可以将搜索结果列表呈现到前端作为学生的拓展学习内容。(6)关于AI出题和评分,首先,需要给定JSON格式的提示词模板让大模型返回。其次,针对AI评分功能,单选题本质上不需要AI进行评分,系统通过对比答案即可完成,所以AI评分的核心是对简答题进行评分。只需要通过提示词将学生答案和标准答案进行对比,就可以得到一个相对准确的分值。最后,需要通过Web系统和对数据库的操作,将这些功能整合起来,使AI智慧课堂的完成度更高。数据库设计数据库设计数据库设计完成数据表的定义和创建后,即可在model.py文件中定义数据映射关系,代码如下。主体功能开发02视频文件预处理首先,创建一个公共模块文件module.py,用于进行各种处理,以便在main.py中进行调用。在module.py模板文件中实现提取音频和音频转文字的功能。视频文件预处理其次,新建一个FastAPI项目并开发后端接口与前端进行交互。实现首页的渲染、视频上传和预处理等功能的后端接口代码。视频文件预处理再次,创建首页的模板界面,该界面用于视频文件上传及显示视频信息。由于后续功能较多,因此这里将HTML、CSS和JavaScript分为3个文件分别进行保存。将首页命名为index.html,代码如下。视频文件预处理该界面引入的JavaScript源文件script.js中的代码如下。视频文件预处理此时,用户登录功能暂时还不需要,可以先不实现。接下来实现整个界面的CSS,文件名为style.css,内容如下。视频文件预处理最后,测试首页、后端视频转语音以及语音识别成文字的功能是否正常。如果代码运行正常,则运行结果如图7-2所示。生成课堂笔记以下代码在module.py中添加了一个函数summarize(),用于对当次课堂的内容进行摘要。该代码的功能就是让大模型对文本内容进行总结,其重点在于编写一段清晰明了的提示词指令,让大模型清楚自己的任务。示例代码如下。生成课堂笔记课堂笔记生成成功后,需要将其在数据库中保存起来。因为上述代码最好在上传视频成功后就进行调用,所以需要对后端接口/upload进行修改,代码如下。生成课堂笔记为了将课堂笔记在前端界面中正常显示出来,还需要开发一个后端接口和一个前端模板界面。后端接口从前端获取参数videoid,并查询该视频的信息,并将其填充到模板界面中,代码如下。生成课堂笔记模板界面文件detail.html的源代码如下。生成思维导图利用大模型生成思维导图数据生成思维导图利用大模型生成思维导图数据生成JSON数据后,同样需要将其保存到数据库中。在main.py的/upload接口中保存该JSON字符串,相关代码如下。生成思维导图生成思维导图文件有了正确的JSON数据后,即可利用Python中的xmind库生成思维导图文件。这一过程的关键操作就是利用递归来读取JSON数据中的层级,并通过xmind库的各类接口写入对应的内容,代码如下。生成思维导图前端渲染与下载前端要渲染思维导图,需要将数据库中的JSON数据读取到前端,并利用jsmind库进行渲染。此处需要在detail.html模板界面中先引入jsmind库的CSS样式和JavaScript库文件,实现代码如下。生成思维导图前端渲染与下载在前端渲染的思维导图效果如图7-4所示。生成视频关键帧视频关键帧的提取主要依赖OpenCV库。OpenCV库的VideoCapture()函数不仅可以获取摄像头数据,还可以获取视频数据。以下代码展示了如何提取关键帧,并将其保存到对应的以视频文件名命名的文件夹中。生成视频关键帧视频帧率的截取代码可以放到视频上传之后。在前端界面中遍历并显示图像时,只需要前端添加模板渲染部分的代码,并以视频的文件名进行关联。生成视频关键帧同时,需要在后端接口/detail中添加一段代码,用以读取和生成模板界面可用的keyframes。修改后的完整代码如下。生成视频关键帧视频关键帧展示的运行结果如图7-5所示。拓展知识引用首先,利用关键字在线搜索并获取搜索结果,将其保存到视频信息表的reference列中。其次,更新/upload接口,保存生成的搜索结果,与前面生成的课堂笔记和思维导图的保存方式完全一致。拓展知识引用最后,实现/detail接口更新和前端界面显示功能。/detail接口代码如下。建议将detail.html前端界面显示代码添加到界面末尾。出题和考试功能03生成考题以下代码(位于module.py文件中)演示了如何让大模型生成考题并按照指定格式输出。生成考题考题生成后需要保存到数据库中,此处将考题的JSON数据保存到视频信息表的examjson列中。修改/upload接口代码,保存考题并调用insert_exam()函数对考题进行解析,保存每一道考题信息到考题信息表中。生成考题接下来在module.py中新增函数insert_exam(),通过解析考题的JSON字符串内容,提取每一道考题并将其作为一行数据保存到考题信息表中。前端渲染考题以下代码实现了/exam后端接口。前端渲染考题后端接口完成后,继续开发前端模板界面exam.html,代码及注释如下。前端渲染考题上述HTML界面对应的CSS如下。提交试卷并评分一般可以通过遍历界面中的单选框的值和文本域的内容,对采集到的答案进行提交。以下代码为doExam()函数的JavaScript代码。提交试卷并评分提交答案时,上述代码构建的JSON数据格式如下。登录与Token鉴权04Token处理机制1.存储型Token存储型Token极为简单的方案就是生成一串随机字符,或者利用用户名、时间戳等元素来生成一串散列字符串,以确保唯一性。这样下次进行权限验证时,只需将前端传递过来的Token与数据库中保存的Token进行比较,找到对应的用户信息,就可以获取当前登录的用户是哪一位,其角色权限有哪些,并进行各种接口的判断。存储型Token与Session校验在机制上非常类似,主要区别在于Session是由Web服务器维护的,可定制性较弱,而Token是由系统程序维护的,可以操作的空间更大。例如,存储型Token可以将随机字符保存到Redis服务器中供各类应用程序调用,这一操作是普通的Session无法做到的。Token处理机制2.解密型Token解密型Token是指用户首次完成登录验证后,对Token进行可逆运算的加密处理,生成一个密文,该密文可以由用户名、ID、角色、时间戳等各种信息汇集后生成。这样在进行解密时,就可以解密出原始的用户名、ID、角色、时间戳等信息,并用于系统。解密型Token不需要存储,只需要生成一次后响应给前端,后续前端每次都会携带该Token用于认证。服务器解密后就可以了解是哪一位用户,以进行后续处理。通常解密型Token最好带有一个有效期信息,以便让登录信息定期失效,防止出现Token泄露后永久可用的情况。加密与解密处理目前的密码应用领域主要使用两种加密算法。第一种是不可逆加密算法,如常见的MD5、安全散列算法(SecureHashAlgorithm,SHA)等算法就是不可逆加密算法,也称为摘要算法。所谓不可逆是指无法根据密文反向解密出明文,通常这种加密算法可以应用于数字指纹识别或密码保存、密码对比等场景。在进行登录验证时,只需对用户输入的密码进行MD5加密,再与数据库中的密码字段进行比较即可确定用户输入的密码是否正确。加密与解密处理第二种加密算法通常称为可逆加密算法,即可以根据密文解密出明文,这通常用于数据通信过程的加密。加密本身只是为了通信过程的安全,最终都需要解密以获取原始数据。所谓对称加密,是指加密和解密使用相同的密钥,如主流的加密算法——高级加密标准(AdvancedEncryptionStandard,AES)算法。非对称加密,是指加密时会生成一对公私钥,使用公钥加密,使用私钥解密,如主流的RSA算法。登录与Token认证首先,后端进行AES的加解密处理。建议在.env环境变量文件中添加以下两个AES加密时会用到的参数,以便于维护AES密钥和初始向量。其次,编写以下代码对AES的加解密进行封装,解析解密后的内容,返回程序需要的信息。登录与Token认证再次,实现登录的后台接口和前端操作。在main.py中新建一个/login接口,用于登录校验和Token生成。登录与Token认证最后,处理前端登录请求,在script.js中添加以下代码。前后端校验处理除了实现登录和退出操作,还需要在每个模板界面中添加一段JavaScript代码,用于更新登录成功后的状态。将以下代码添加到各个模板界面的顶部<script>标签中。定时任务处理05定时任务处理定时任务的功能应该如何实现呢?只需要循环获取视频信息表中内容为空的所有字段,如果content为空,则说明未执行语音转文字的任务,此时定时任务调用audio_text()函数来完成该任务。如果summary为空,则说明语音转文字任务已经完成,但是未完成课堂笔记,此时可调用summarize()函数来完成该任务,以此类推。定时任务处理新建一个源文件schedule.py,编写以下代码实现定时任务的处理。智能在线客服content目录01功能与设计分析02LlamaIndex框架应用03向量数据库04项目功能实现05扩展功能优化功能与设计分析01RAG与向量数据库要计算用户提问与文档片段之间的相似度,首先需要将文本向量化,这一过程称为词嵌入。在AI模型中,针对文本的训练和推理,首先需要将文本向量化。以下代码演示了如何通过Ollama的词嵌入接口获取某个Token的词向量。理解词嵌入RAG与向量数据库可以看出,“国”和“家”两个Token的向量是不一样的,同时每个Token的向量有4096个维度。Token的向量是将文字转换为数字的极为重要的手段,只有转换为数字后才能进行运算。同时,不同的模型,其向量的维度是不同的。这里的4096仅代表“qwen3:8b”这个模型的向量维度为4096。另外,这个维度的含义是用4096个数字来描述一个Token,其中的数字均是模型训练后的结果。输出的内容大致为RAG与向量数据库计算相似度主要有以下3种方法。(1)欧氏距离:测量向量之间的直接距离,距离越短,说明相似度越高。(2)余弦相似度:关注向量之间的角度,角度越小,说明相似度越高。(3)点积相似度:通过计算两个向量的点积来判断其相似度,点积值越大,意味着两组向量越相似。向量相似度RAG与向量数据库RAG工作流程核心功能列表以蜗牛学苑的智能在线客服系统为例进行讲解。该系统主要包含以下功能。(1)管理员可以上传新的文档并进行分段保存,也可以查询文档内容和分段内容等。(2)普通用户可以通过AI对话窗口提任意问题。(3)提供联网搜索功能,以拓展AI的知识面,针对一些文档中不存在但是网络中可能存在的内容,可以进行额外补充。(4)不仅要能准确回答用户的问题,还需要能够引起用户兴趣,或促进后续流程,如建议用户到实地考察,或者要求用户留下手机号或微信号等联系方式。(5)当发现用户留下了联系方式后,应将联系方式通过FunctionCalling向某位用户发送邮件提醒。同时,为了便于后续咨询时及时掌握用户的需求,将保存当次对话的记录。整体实现思路(1)管理员可以通过Web界面对私有知识库进行管理,主要实现文档的上传、分段、修改和查询等功能。修改功能可以由删除和新增功能来代替。此处的文档在完成分段后将主要保存到向量数据库中,以便于后续操作。(2)普通用户与智能在线客服系统进行对话时,与真人对话一样,也要综合考虑各种可能的情况。这部分并没有技术难度,在AI问答系统中已经完成了相应的功能,包括联网搜索功能,此处仅需要加上知识库并完善提示词。(3)给予用户建议或者试图获取用户的联系方式,这些功能均可以通过大模型的提示词达成。(4)当用户留下联系方式后,需要通过FunctionCalling来进行函数调用,让大模型解析出联系方式并保存到数据库中。LlamaIndex框架应用02LlamaIndex概述LlamaIndex的功能与特点主要包括以下几点。(1)支持多种索引类型。LlamaIndex支持多种索引结构,包括列表索引、树形索引、图索引等,以满足不同场景下的数据管理需求。(2)灵活的数据源集成。无论是结构化数据还是非结构化数据,LlamaIndex都能轻松对接,如文档、数据库、API返回的数据等。(3)增强的检索与问答能力。LlamaIndex提供了基于上下文的增强型检索策略,使得大模型在回答用户问题时能够提供更相关、更精确的答案。(4)模块化设计。LlamaIndex的组件设计非常灵活,开发者可以根据自己的需求自定义数据处理管道、索引构建流程等。(5)开源与社区支持。LlamaIndex是开源项目,拥有活跃的社区支持和不断更新的文档,开发者可以轻松获取帮助和资源。LlamaIndex核心操作LlamaIndex的核心功能是读取文档、分段文档、建立索引、检索分段等。所以要使用LlamaIndex,必须先在项目目录下创建一个目录docs,用于存放各种文档,如Word、Markdown、PDF、TXT文档等。另外,默认情况下,LlamaIndex只支持使用OpenAI进行词嵌入和大模型对话,所以需要提前配置好Ollama环境。LlamaIndex核心操作上述代码的处理过程主要包含以下4个步骤。(1)定义词嵌入模型和AI对话模型Ollama。上述代码中虽然两者都使用了同一个模型qwen3:8b,但是其实这两个过程是独立的。词嵌入模型用于将文档转换为词向量,不同的模型词向量的结果也不同。(2)使用LlamaIndex内置的文档读取器来加载文档内容。LlamaIndex支持读取各类文档,如Word、PDF、Markdown等,在模块llama_index.readers.file中可以查看所有支持的Reader对象。当然,有些文档的读取除了需要这些支持的Reader对象,还需要额外安装Python库。(3)读取文档后,接下来需要进行向量化处理,并创建索引。创建索引只是为了让后续检索效率更快。创建完索引后即可进行持久化保存。默认情况下,LlamaIndex内置了一个轻量级的向量数据库,用于将向量和索引保存到JSON文件中。(4)通过提示词检索相关文档分段,并通过大模型进行回复。此过程通过index.as_query_engine()进行了封装,其实可以细分为3个步骤:根据用户的问题检索相似度最高的文档片段,将文档片段作为提示词的一部分提交给大模型,由大模型根据用户提问和文档片段构成的提示词进行回复。LlamaIndex核心操作上述代码的运行结果如下。文档分段与检索当LlamaIndex加载一份文档后,首先需要对文档进行分段。之所以要进行分段,核心目的就是将长文档变成文档片段,进而检索出与提示词关联度较高的片段用于大模型对话处理。以下代码可以查看文档的分段数据。文档分段文档分段与检索当文档分段完成后,即可对分段文档建立索引,那么此时需要依赖词嵌入模型对文档进行索引和向量化保存。默认情况下,LlamaIndex使用的是OpenAI的词嵌入模型,而通常国内无法正常访问到OpenAI,导致连接失败。因此,需要在代码中通过Settings指定为Ollama词嵌入模型,当然,也可以指定为国内可访问的其他模型。以下代码演示了创建索引的过程。创建索引文档分段与检索当完成索引的创建与保存后,即可进行文档检索。以下代码演示了对已保存的索引进行检索,并将匹配成功的文档片段输出的过程。文档检索文档分段与检索第一种方案是增加检索结果的返回数量,修改index.as_retriever()的参数similarity_top_k=5,可以按照相似度排序检索出5篇文档,如果仍然检索不出来,则增加值到10、20或者更大;第二种方案是修改用户提问,使之更加匹配原始文档内容,但是该方法不存在通用性,因为系统无法控制用户提出什么样的问题。优化检索结果文档分段与检索上述代码的运行结果如下。优化检索结果处理流式响应利用LlamaIndex内置函数index.as_chat_engine()创建流式响应的具体实现代码如下。处理流式响应基于检索结果自行拼接提示词,并调用对话模型来实现流式响应的具体实现代码如下。处理流式响应既然可以使用Ollama来处理流式响应,那么可以对上述代码加以修改,使用通义千问的云端模型来进行回复,具体代码如下。文档分段策略1.分段策略概述文档分段主要存在以下4个方面的问题。(1)段落过大:可能导致检索到的文档包含过多无关信息,增加了大模型理解语义的难度,降低了答案的准确性,甚至超出了大模型上下文大小的限制。(2)段落过小:可能导致检索到的文档只包含部分信息,无法全面回答用户所提的问题。(3)分段不当:可能会破坏语义的连贯性,导致原本一个完整的知识被拆分到多个段落中。(4)忽略文档结构:通常很多文档是有章节划分的,一章或者一节通常就是一个完整的话题,如果分段不当,则该结构就会被破坏,进而导致分段不当。大致了解了文档的结构后,有以下结论:文档遵守Markdown格式,有明确的层次结构,且属于问答式的内容,可以非常容易地将问题和答案放到同一个段落中,既不会导致分段不当,又可以实现高效检索。下面基于上述文档来进一步学习各种分段策略具体是如何切分文档的。文档分段策略2.Token级固定大小分段使用TokenTextSplitter()按照Token数量来进行固定大小的分段。该方案仅供演示,实际使用过程中不建议使用,因为它只关注Token,而不会关注句子,常常将一个句子从中间截断,导致AI完全无法正确、完整地表达语句。文档分段策略3.语句级固定大小分段SentenceSplitter()也是一种固定大小的分段策略,该方案相对于TokenTextSplitter()来说,最大的优势在于不会将一个句子从中间截断,无论段落划分效果如何,至少可以保证段末的语句是完整的。所以,虽然设置了chunk_size=500,但是并不保证每一段的字数均为500。文档分段策略4.语义分段语义分段指根据文本的语义进行切分,将语义关联紧密的句子或段落聚合在一起。通常做法是先将文本分成基础单元(如句子),再计算相邻单元的语义相似度,如果相似度高于某个阈值,则合并这些单元,直到相似度显著下降时才创建一个新的块。该分段方案适用于长文本文档,不太适用于短文本文档,所分段落通常较长。同时,因为需要使用相似度来比较语句和段落,所以必须使用词嵌入模型,导致分段过程运算量较大,所花费的时间也比较长。以下代码对WoniuAI-V6.txt这个较长的文档进行分段,共分出了13个段落。文档分段策略5.递归分段递归分段采用“分而治之”的策略。首先,尝试使用一组优先级较高的、较大的文本分隔符(如段落标记、章节标记)来分割文本。其次,检查分割出的每个段落的大小。如果某个段落仍然超过预设的大小限制,则换用下一组更低优先级、更细粒度的分隔符(如句子结束符、换行符)对其进行更细粒度的分割,此过程递归进行,直到所有块都满足大小要求(注意:所得段落大小并不严格一致,而是大小不一)。此分段策略会对文档进行多粒度分段,以便检索时可以检索到最相关的文档片段。文档分段策略6.文档结构分段文档结构分段是指基于文档原本的章节层次或标签元素等进行分段。在LlamaIndex中,主要针对Markdown、HTML、JSON等文档进行结构分段。此处需要注意的是,针对HTML、JSON文档时,需要使用FlatReader对象来读取文档。Markdown文档的分段规则是按照章节层次分段,这在前面已经有所介绍。HTML文档是根据常用的段落标签(如P、H1~H6、Li、Section等)进行分段。JSON文档的分段是严格按照列表中的项目数量进行分段,如果顶层为字典,则只会分为一段。以下代码演示了这3种文档的结构分段。文档分段策略7.混合策略分段混合策略分段是指对上述各种分段策略进行混合处理,在创建索引时将各种分隔器通过参数transformations指定。以下代码演示了结合文档结构分段与语义分段两种策略来创建索引的过程。检索结果重排序在RAG技术体系中,可以优化的位置其实有两个:第一个是如何实现合理分段,第二个是如何实现精准检索。目前已经介绍了不同的分段策略,下面从检索精准度的角度来分析一下还有哪些方面可以优化。默认情况下,LlamaIndex将根据向量相似度评分来对检索结果进行排序,进而实现top_k的选择和使用。使用该对象时,需要加载一个语言模型来分析检索结果与问题的语义相关性,进而实现重排序。本书推荐使用模型BAAI/bge-reranker-v2-m3。该模型对中英文的支持效果较好。通过以下代码可完成模型的自动下载。向量数据库03Chroma的核心操作Chroma的安装非常简单,运行“pipinstallchromadb”命令即可安装。下面来看看Chroma如何对文档创建索引并进行相似度查询。Chroma的核心操作上述代码只演示了基础使用过程,一切都在内存中操作。而真实情况下肯定不能将数据仅保存到内存中,必须进行持久化存储。同时,为了让语义更加准确,建议使用Ollama作为词嵌入模型。下述代码完善了这两个功能。Chroma的核心操作上述代码运行后,会在./dbstore/chroma目录下创建向量和索引文件等内容,还会有一个chroma.sqlite3的SQLite数据库文件,其中保存了很多基础信息。如果读者想查看该数据库中的内容,则必须先安装工具DBBrowserforSQLite。该数据库中保存的数据如图8-4所示。Chroma的核心操作当完成文档添加并创建好索引后,即可对持久化向量数据进行查询,以下是查询部分的代码。Chroma的核心操作通过对比发现,使用Ollama的qwen3:8b模型进行词嵌入

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论