智能体开发技术(Python+FastAPI版) 课件全套 第1-8章 大模型与智能体开发- 智能在线客服_第1页
智能体开发技术(Python+FastAPI版) 课件全套 第1-8章 大模型与智能体开发- 智能在线客服_第2页
智能体开发技术(Python+FastAPI版) 课件全套 第1-8章 大模型与智能体开发- 智能在线客服_第3页
智能体开发技术(Python+FastAPI版) 课件全套 第1-8章 大模型与智能体开发- 智能在线客服_第4页
智能体开发技术(Python+FastAPI版) 课件全套 第1-8章 大模型与智能体开发- 智能在线客服_第5页
已阅读5页,还剩384页未读 继续免费阅读

下载本文档

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

文档简介

大模型与智能体开发content目录01对接云端大模型接口02本地部署大模型03AI智能体开发技术对接云端大模型接口01准备PyCharm开发环境安装MinicondaPython运行环境的安装和配置通常有两种方式第一种方式是使用原生的Python安装包直接在本地安装Python,并利用pip命令安装其他依赖库;第二种方式是先配置Conda虚拟环境,再在Conda虚拟环境中安装和配置Python环境。在Anaconda官方网站下载Miniconda安装包,正常安装即可。安装完成后,需要创建一个Python运行环境,配置环境变量,打开或创建文件C:\Users\<用户>\.condarc,添加一个envs_dirs变量,用于指定Python虚拟环境的默认安装目录,文件内容大致如下。准备PyCharm开发环境对GPU提供支持打开命令提示符窗口,先利用condaactivate命令激活Python环境,再运行以下命令安装PyTorch的GPU版本。condainstallpytorchtorchvisiontorchaudiopytorch-cuda-cpytorch-cnvidia此次安装要下载约1.3GB大小的文件,安装过程较为漫长。如果安装过程并未报错,则说明GPU版本安装成功。如果安装不成功,则可以考虑下载Python的扩展名为.whl的离线安装文件,并运行“pipinstalltorch-2.3.1+cu121-xxxx.whl”命令进行安装。安装完成后,如果在运行Python代码时出现以下错误,则需要配置操作系统环境变量KMP_DUPLICATE_LIB_OK=True或通过Python代码进行临时处理。准备PyCharm开发环境配置pip源为了使使用pip安装第三方依赖库时速度更快,建议将pip的源配置为国内镜像源。在用户主目录(即C:\Users\<用户名>)下创建pip文件夹,并在该文件夹中创建文件pip.conf,内容设置如下。准备PyCharm开发环境创建PyCharm项目PyCharm有专业版和社区版两个版本,专业版提供对超文本标记语言(HypertextMarkupLanguage,HTML)界面的智能提示的支持,所以本书所有实验和项目均在PyCharm专业版环境下开发调试。读者可前往PyCharm官网下载其较新版本并完成安装。对接通义千问申请通义千问的APIKey先访问阿里云官网,注册一个账号并进行实名认证,再选择“大模型服务平台百炼”选项,如图1-2所示。对接通义千问在阿里云百炼界面中,创建APIKey,用于在Python调用其接口时进行鉴权,如图1-3所示。对接通义千问创建完APIKey后,可以进入API参考界面,查看各种AI模型的调用方法。阿里云文档中心的功能非常完善,并且提供了针对各种编程语言的示例代码供用户参考,如图1-4所示。对接通义千问使用OpenAI进行调用OpenAI公司是最早提供大模型API对接的厂商之一,因此,后续的一些AI厂商提供了兼容OpenAI软件开发工具包(SoftwareDevelopmentKit,SDK)接口的对接方案。在Python中需要利用pipinstallopenai命令安装SDK,并通过以下代码完成对接。对接通义千问注意:APIKey不建议直接写在代码中,通常的做法是将其保存到项目的环境变量文件中,并通过dotenv库进行调用,以便于统一维护。其操作步骤如下。(1)利用pip命令安装第三方库dotenv,具体命令为pipinstalldotenv。(2)在当前项目的根目录下创建一个文件.env(注意,文件名以.开头),内容如下。Dashscope_API_Key='sk-30a2d87612584e2697867a796b3d4f01'#如果有其他APIKey或系统级变量,则以同样的方式进行定义即可在代码中,直接通过dotenv库的load_dotenv()函数将其内容加载为环境变量,并进行读取。对接DeepSeek使用Dashscope进行调用通义千问模型除能采用OpenAI兼容接口调用外,还因为阿里云本身也提供了SDK进行调用,所以只需在Python中利用pipinstalldashscope命令进行安装即可直接使用。对接通义千问使用requests库进行调用几乎所有的AI模型厂商均提供了标准的HTTP接口,即使没有提供SDK,也不影响使用Python或其他编程语言与AI模型进行交互。以下代码展示了如何利用Python的requests库通过发送原始HTTP请求的方式与AI模型进行通信。对接DeepSeek访问DeepSeek的API开放平台,并注册账号,创建DeepSeek的APIKey,如图1-5所示。对接DeepSeek创建成功后,务必将明文的APIKey复制并保存。否则,下一次使用DeepSeek时需要重新创建APIKey。成功创建APIKey后,便可以在Python中进行调用了。DeepSeek同样支持基于OpenAI的兼容模式调用,或直接使用HTTP进行调用,基础的调用代码如下。对接DeepSeek其调用过程与通义千问的调用过程基本一致,此处不做过多解释。此外,通过Python的requests库也可以正常调用DeepSeek,代码如下。对接OpenRouter平台登录OpenRouter访问OpenRouter官网,单击右上角的“Signin”按钮进行登录,目前支持3种登录方式:Google、MetaMask及本站登录。OpenRouter登录界面如图1-6所示。登录成功后,可以查看OpenRouter支持的所有模型,其中包括DeepSeek、QWen、Claude、OpenAIO3等模型。对接OpenRouter平台单击登录后的用户头像,选择“Keys”选项,进入APIKey的管理界面创建APIKey即可。创建OpenRouter的APIKey如图1-7所示。创建APIKey对接OpenRouter平台如果确定需要长期使用OpenRouter,则需要绑定信用卡。目前,OpenRouter支持各类信用卡,国内主要支持Visa信用卡。如果读者没有Visa信用卡,则无法绑定。新增支付界面如图1-8所示。信用卡支付对接OpenRouter平台OpenRouter平台上的模型有很多,几乎包含国内外所有的主流大模型。下述代码演示了如何调用Claude3.7,读者如果感兴趣,也可以在Cline、Continue或Copilot等AI编程助手中对接该模型辅助编程。因为本书的主题是智能体开发,所以不单独讲解该部分内容。对接OpenRouter本地部署大模型02安装与配置Ollama01安装与配置OllamaOllama是一个开源框架,专为在本地部署和管理大模型提供便利,支持在Windows、macOS和Linux上进行安装,也可以通过Docker简化部署。Ollama支持多种大模型,如CodeLlama、Qwen、DeepSeek、Gemma等,通过将模型权重、配置和数据捆绑到一个包中,有助于优化设置和配置细节,使整个安装和配置过程变得非常简单。安装与配置Ollama01安装与配置Ollama拉取并测试大模型当完成上述安装与配置后,即可访问Ollama官网搜索各类大模型并进行拉取操作。此处以新发布的Qwen3大模型为例进行讲解。在Ollama中搜索Qwen,找到并拉取Qwen3模型,如图1-12所示。CherryStudio对接Ollama01安装与配置1.CherryStudio是目前主流的一个AI对话应用程序客户端,非常适用于日常对话和进行各种大模型与智能体的调试。访问其官网并下载对应操作系统版本的安装文件后正常安装即可。为了方便后续调试模型上下文协议服务器,安装CherryStudio后,建议读者同步完成Node.js及相关组件的安装。访问Node.js官网下载并安装Node.js,安装完成后运行“node-v”命令,如果显示正常的版本号,则说明安装成功,如下所示。CherryStudio对接Ollama02对接OllamaCherryStudio是目前主流的一个AI对话应用程序客户端,非常适用于日常对话和进行各种大模型与智能体的调试。访问其官网并下载对应操作系统版本的安装文件后正常安装即可。为了方便后续调试模型上下文协议服务器,安装CherryStudio后,建议读者同步完成Node.js及相关组件的安装。访问Node.js官网下载并安装Node.js,安装完成后运行“node-v”命令,如果显示正常的版本号,则说明安装成功,如下所示。安装与配置Ollama03CherryStudio对接Ollama2.对接OllamaCherryStudio提供了对接各类大模型的功能,不仅限于DeepSeek、Qwen、硅基流动、OpenAI、OpenRouter等,还支持对接本地的Ollama模型。当启动Ollama服务后,Ollama默认会开启一个端口为11434的HTTP服务,用于各类应用程序或编程语言的调用。在CherryStudio中设置对接Ollama的Qwen3模型,如图1-15所示。安装与配置Ollama03CherryStudio对接Ollama完成模型的对接后,便可在CherryStudio的聊天窗口中进行模型测试。如果成功,则可以看到图1-16所示的对话效果。调用OllamaAPI基于Ollama的SDK进行调用要使用Ollama的SDK调用大模型,需要先安装Ollama的Python库,利用pip命令进行安装即可。调用OllamaAPI基于Ollama的SDK进行调用运行上述代码即可调用Ollama的Qwen3模型并进行输出。但是上述代码的输出过程通常会等待很久,因为未使用流式响应进行处理。以下代码采用改进的流式响应模式进行输出,输出过程大大缩短了。调用OllamaAPI基于HTTP接口进行调用HTTP接口是Ollama另一种方式的接口调用,可以使用Python或其他编程语言进行调用,其通用性更强,可以访问/ollama/ollama/blob/main/docs/api.md查看各类接口的请求规范。调用OllamaAPI在Ollama中实现多轮对话Ollama提供的接口/api/generate只能实现单次对话,即不带记忆功能。为了实现常规AI对话中的带记忆功能的多轮对话,可以调用/api/chat接口,此接口发送的消息主体为一个列表,可以保存前面的对话内容进而实现记忆功能。调用OllamaAPI在Ollama中实现多轮对话(1)为了解决多轮对话的问题,此处使用了死循环来模拟用户的多轮对话,当然,在调试代码时可以随时停止代码运行。(2)增加了系统提示词,即"role":"system",这是AI模型标准角色设定。该系统提示词指示模型不需要进行思考,直接回答问题,以节省调试时间,简化模型输出。是否省略思考过程,完全由开发者自行决定,并无好坏之分。通常来说,对于一些复杂的推理过程,可以对其思考过程进行展示,但是一般的常规问答可以不展示。除此之外,在AI模型中,通常有两种标准角色:user和assistant。其中,user一般指用户提问的内容,而assistant指AI模型的回答,这类角色名称适用于目前的绝大部分AI模型。(3)为了保存对话历史,通常要设置一个模块级全局变量来进行操作(如上述代码中定义的messages),以记录每一轮对话。同时,每一轮对话完毕必须将用户的提问内容和AI的回答均添加到消息体中,每开启一轮新的对话,均需要将前面轮次的对话发送给大模型以便实现记忆功能。AI智能体开发技术03FunctionCalling技术目前,AI智能体开发和应用是展现AI实力的一种非常好的方式,大量的企业有AI智能体开发的需求,且各个行业和研究人员都在进行各种形式的探索,以实现AI能力的最大化,帮助企业和组织降低成本,提升效率。AI大模型本身的能力在于理解用户的输入,并给予用户正确的响应内容,而响应的内容通常是文本或图像等数据,AI大模型本身并不具备函数调用能力。例如,对于提示词“明天去北京出差适合穿什么衣服?”,Ollama的回答如图1-17所示。FunctionCalling技术一般情况下,有两种方案可以让AI给出穿衣建议,具体如下。(1)第一种方案是联网搜索与北京天气有关的数据,并将搜索结果的网页作为提示词的一部分提交给大模型进行分析,进而得出正确的穿衣建议;但是此类基于搜索的结果通常并不完全准确,存在一定数据错误的情况,这取决于搜索引擎对数据爬取的通用性与准确性。(2)第二种方案是开发一个天气预报函数并准确描述该函数的功能,交由大模型对用户提问进行分析,并返回JSON数据,告诉智能体应该调用哪个函数、传递什么参数,智能体会根据模型的输出进行解析和调用,进而获取天气预报的实时数据,再交由大模型进行分析并给出正确的穿衣建议。这种方案的基本过程需要配合AI的FunctionCalling技术来实现。FunctionCalling技术MCP技术1.通过AI提示词操作本地文件系统打开CherryStudio,在设置界面中选择“MCP服务器”选项,并手动添加一个MCP服务,按照图1-19所示的参数进行设置,并单击右上方的开关来开启该MCP服务。MCP技术1.通过AI提示词操作本地文件系统完成上述设置后,进入CherryStudio的常规提问框,尝试使用图1-20所示的提示词来使用MCP服务进行文件写入操作。MCP技术2.通过AI提示词获取穿衣建议除了使用本地MCP服务,还可以使用远程的公共MCP服务,如使用高德地图MCP服务获取地理位置信息、查询酒店或地址、获取实时天气情况等。高德地图MCP服务提供了免费的调用额度,足够开发者调试所用。首先,访问高德官网,注册账号并进行实名认证;其次,创建应用并添加Key,如图1-21所示。MCP技术2.通过AI提示词获取穿衣建议当完成Key的添加后,按照图1-22在CherryStudio中对接高德地图MCP服务,进行参数填写并确保可以正常启动服务。MCP技术2.通过AI提示词获取穿衣建议完成CherryStudio与高德地图MCP服务的对接并成功开启服务后,便可在提问框中进行提问了,AI模型会根据需要驱动智能体(本处即CherryStudio本身)进行远程函数调用,其对话效果如图1-23所示。使用Python调用FunctionCallingFunctionCalling由OpenAI公司提出,现在已经被大多数模型所支持,也是扩展AI能力边界的一种好方式。下面将使用DeepSeek演示如何利用Python代码来调用FunctionCalling。以下代码展示了利用大模型对提示词的理解来返回对函数的调用,实现本地文件写入及天气预报的功能。其中,天气预报的功能直接调用高德的天气预报接口实现,具体代码及注释如下。使用Python开发MCP服务MCP服务部署在stdio本地调用模式下,不需要在Python中运行上述代码,而是在CherryStudio中利用Python命令来运行。按照图1-24进行配置,即可在CherryStudio中通过提示词进行文件写入,具体操作过程与调用filesystem服务相同。使用Python开发MCP服务MCP服务部署在mcp库中,如果想将函数以sse方式发布,则要对代码进行以下修改,并在PyCharm中开启服务。FastAPI开发框架content目录01FastAPI快速使用02Jinja2模板引擎03SQLModel数据处理04FastAPI对接大模型FastAPI快速使用01快速入门FastAPI概述FastAPI是一个用于构建API的现代、快速且高性能的Web框架,使用Python开发,并基于标准的Python类型进行提示。FastAPI目前被大量企业采用,具有以下重要特性。(1)快速且高性能:具有可与Node.js和Go并肩的极高性能,是最快的PythonWeb框架之一。(2)高效编码:提高功能开发速度200%~300%。(3)更少的漏洞:减少约40%的人为(开发者)导致的错误。(4)智能:极佳的编辑器支持,处处皆可自动补全,减少调试时间。(5)简单:易于使用和学习,阅读文档的时间更短。(6)简短:使代码重复最小化,通过不同的参数声明实现丰富功能,且漏洞更少。(7)健壮:生产可用级别的代码,以及自动生成交互式文档。(8)标准化:基于(并完全兼容)API的相关开放标准OpenAPI和JSONSchema。快速入门安装FastAPI直接运行“pipinstallfastapi”命令即可安装FastAPI。另外,为了保证后续针对数据库和模板引擎的操作正确无误,建议同时安装Uvicorn服务运行环境Jinja2模板引擎和SQLModel数据库框架,安装命令如下。快速入门快速实现接口与响应FastAPI可以定义Get、Post等各种类型的HTTP接口,并支持以多种方式获取前端界面传递过来的参数,也可以向前端传送响应的各种类型的内容,默认情况下响应JSON数据。以下代码定义了两个接口并实现了简单的逻辑,可以快速完成一个后台接口的开发。快速入门快速实现接口与响应在PyCharm中运行上述代码,FastAPI服务会正常启动,此时若能够通过浏览器访问:8000/,并在浏览器中看到“HelloWorld”,则说明请求发送成功。FastAPI默认设置中提供了接口文档和调试功能(SwaggerUI),访问:8000/docs即可看到当前项目的所有接口,方便地对Post请求接口进行调试,如图2-1所示。快速入门快速实现接口与响应FastAPI除了提供SwaggerUI用于查阅接口文档和调试接口,还额外提供ReDoc文档用于以更加简洁的界面展示接口规范,访问:8000/redoc即可查看接口规范,如图2-2所示。快速入门快速实现接口与响应事实上,对于开发过程中的接口调试,除了使用SwaggerUI,还推荐使用Apifox等工具来进行调试和管理。相较于SwaggerUI,Apifox的功能更加强大,不仅支持调试,还可以对接口进行测试,并支持WebSocket协议。最关键的是,Apifox可以保存每次的请求数据,以供下次使用。图2-3展示了如何在Apifox中发送登录请求。URL及参数无论是Get还是Post等请求,均需要一个唯一的URL,而在URL中也可以定义参数。参数一般分为两类,分别是路径参数与查询参数。FastAPI的URL和地址栏参数及相关定义主要用于解决以下4个问题。(1)定义服务器接口的URL,从根目录/开始。(2)定义接收前端数据的请求类型,如Get、Post、Put或Delete等。(3)获取请求地址中的查询参数或路径参数。(4)通过将@app.get/post等装饰器与被装饰的函数绑定,对请求进行后台处理。URL及参数上述代码中由于均为Get请求,因此既可以直接在浏览器地址栏中访问,又可以在SwaggerUI中进行访问和调试。当访问:8000/user/123时,输出为{"user_id":"123"}格式的JSON数据,这是完全正确的。RESTful接口描述性状态迁移(RepresentationalStateTransfer,REST)的设计目的是希望在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适合通信的架构。因此REST指的是一组架构约束条件和原则。如果一个架构符合REST的约束条件和原则,则称它为RESTful架构,这个架构同样具有RESTful风格。对于Web开发者来说,是否完全掌握RESTful的定义并不关键,但熟悉其核心的几个要素十分必要,如定义HTTP请求类型和服务器URL接口规范的标准。例如,对一个用户的操作,其资源对象是用户,而请求类型和接口定义应该遵循表2-1所示的基本标准进行。JSON请求体在当前的互联网通信过程中,JSON数据格式在前后端通信中的使用更加广泛,除了后端可以向前端响应JSON数据,前端还可以向后端提交JSON数据。在FastAPI中,这类接口和请求的定义与获取也较为方便,下述代码展示了这一过程。JSON请求体除了常规的将整个Post请求体正文作为JSON数据提交,在FastAPI中,还可以借用Pydantic(一个数据验证库)的能力对JSON数据进行更加细致的处理和验证。以下代码展示了如何将一个数据模型映射为JSON请求字段,并进行数据类型的验证。会话管理HTTP本身是无状态协议,即客户端与服务器在交互过程中无记忆能力,服务器并不能区分是哪个客户端或浏览器发送的请求。为了保持HTTP的状态,通常选择使用Session和Cookie来进行管理(目前也大量使用Token来进行会话管理和鉴权)。在FastAPI中,可以通过SessionMiddleware中间件来管理Session,通过Cookie对象来读取前端发送的Cookie,或通过Response对象来向前端发送Cookie变量。会话管理下述代码演示了自定义Cookie变量的过程。会话管理事实上,会话管理和用户鉴权是Web系统中非常重要的技术,但是HTTP的Session和Cookie机制相对而言是比较落后的技术,其机制决定了这些技术不太适用于大型或分布式系统。在分布式系统中,要确保Session机制正常工作,需要在每一个系统节点中同步Session数据,这不仅开销巨大,实现过程也比较麻烦。因此,目前通常有以下两种解决方案。(1)Session的维护不再保存于Web服务器中,而是保存于一台统一的服务器(如Redis数据库)中。每次需要读取Session变量时,都直接从Redis服务器中获取,通过SessionID进行关联查找。这样,无论有多少个服务器节点,多少个应用系统,均统一与Redis服务器进行通信。这相当于让Redis对SessionID和Session变量进行统一管理。(2)使用Token机制进行鉴权,Token机制完全脱离了Session,由开发者自行实现,或使用主流的JWT/OAuth等标准进行处理,可以非常灵活并自主地处理鉴权过程。上述两种方案在FastAPI中均提供了支持,但是本书的核心目标是AI应用程序和智能体的开发,而非使用Web应用系统开发各种关键技术,所以不赘述Web应用开发的内容。后续项目使用到这部分内容时,会对其进行单独讲解。文件上传在FastAPI中,对文件上传提供了很好的封装,利用UploadFile对象即可方便地读取前端上传的二进制文件并进行保存。以下代码展示了如何获取上传的文件。。上述代码使用原始文件名称将上传的文件保存到当前目录下,在实际项目环境下,还需要考虑文件名的重命名,或者对文件类型、后缀名、文件大小等进行限制,后续在项目使用中再进行拓展。文件上传ase64编码的核心逻辑是使用64个字符(即6个二进制位的组合)来表示各种数据,而常规数据是由8个二进制位(即1个字节)表示的,所以这里存在一个转换关系。例如,针对常规字符Red,其在ASCII中对应82、101、100,对应的二进制为010100100110010101100100,一共24个二进制位;而在Base64编码中,每6个二进制位表示一个字符,如表2-2所示,所以Base64编码后的二进制变为010100100110010101100100,根据Base64编码索引,对应字符为UmVk。。数据验证在FastAPI中,对前端参数值进行验证变得非常方便。以下代码分别对路径参数和表单数据进行了验证。异步编程什么是异步编程异步编程使程序可以在等待某种操作(如网络请求或文件读取)时运行其他操作,而不是单纯地阻塞,从而提高了程序的响应速度和资源利用率。在Python中,异步编程通常通过以下3个基本构件来实现。(1)async:通常放置在函数定义之前,用于定义异步函数。(2)await:等待异步操作完成。(3)asyncio:提供对任务调度和事件循环的支持异步编程为了清晰展示异步编程和同步编程的区别,以下代码模拟了一个常规的任务操作,每个任务完成的时间不同。异步代码演示异步编程以下代码展示了如何在Python中实现异步编程。异步代码演示异步编程FastAPI默认提供了对异步编程的支持,定义接口时在函数前面添加关键字async即可,无须做额外操作。例如,定义一个文件上传的接口的代码如下。在FastAPI中使用异步编程Jinja2模板引擎02模板引擎的作用在互联网应用开发的早期,整个Web系统开发的生态远没有现在这样完善,服务器框架通常只能处理简单的HTTP请求。早期的Web服务器框架通常在服务器中直接写出HTML代码并响应给前端,类似如下方式。模板引擎的作用模板引擎的引入主要用于解决以下3个问题。(1)把Python代码和前端HTML代码分离,不再采用混编的方式来编写代码,在提高代码可维护性的同时提升代码的开发效率。(2)在渲染模板界面的同时,可以向模板界面传递变量和值,这些变量和值将在模板界面中被引用,从而直接在HTML界面中填充动态内容。(3)通过模板引擎特定的语法规则,可以在HTML中非常清楚地标识模板变量,同时服务器在渲染模板界面时,也能够更加高效地进行处理,提升服务器响应性能。模板引擎的作用就是将后端的数据动态填充到HTML界面中。在当今的开发过程中,除了使用模板引擎进行动态填充,还可以将数据以JSON格式响应给前端,交由前端的JavaScript或前端框架进行动态填充。目前,这两种方式同时存在,且无优劣之分,开发者可以根据业务需求或产品的形态及架构选择其中一种方式。Jinja2快速使用首先,定义一个HTML静态界面,并在界面中内嵌模板引擎标识符,用于获取变量的值。Jinja2快速使用其次,将上述模板界面保存到当前目录的templates目录下,并将其命名为basic.html,在后端编写以下代码,注意代码中的规范性要求。Jinja2核心语法Jinja2模板引擎定义了以下3种基本引用标识符。(1){%...%}:用于循环或判断语句。(2){{...}}:用于表达式的值的引用。(3){#...#}:用于模板引擎的注释。如果注释中存在模板引擎的语法,那么使用<!---->将不被模板引擎认为是注释,注释中的语句将被运行,此时应使用{#...#}进行注释。假设FastAPI在调用TemplateResponse时为模板界面传递了一个变量count,值为100,即参数context={"count":100},那么以下代码基本完整演示了模板引擎的用法。Jinja2核心语法除此以外,在模板界面中还可以直接调用Python的自定义函数,不过需要先将此函数注册到Jinja2模板引擎中。定义与调用函数的代码如下。在模板界面中,可以通过以下方式读取get_user()函数返回的数据。过滤器代码“loop|int”,这便是Jinja2中过滤器的用法。过滤器本质上是一个函数,它将变量作为函数的参数传递进去,处理后再返回新的值到调用处。例如,loop|int可以理解为loop=int(loop)。表2-3列出了Jinja2中常用的过滤器及其用法。应用示例在FastAPI中定义图书信息,代码如下。SQLModel数据处理03利用PyMySQL操作数据库由于任何一个应用系统基本上都会在后台使用数据库来永久保存数据,因此利用Python操作数据库是开发Web应用系统的一个必经过程。要使用Python操作数据库,必须先创建数据库和表。下面以MySQL为例,创建一张用户表,表名为users,包含userid、username、password、phone、role、createtime等数据,用户表中的数据如图2-10所示。利用PyMySQL操作数据库以下代码演示了如何利用PyMySQL连接MySQL数据库并查询users表的前3条信息。利用PyMySQL操作数据库默认情况下,游标返回的二维元组没有字段名,只能使用元组的下标来获取数据,并不是特别方便。尤其是列比较多的时候,使用下标很容易出错,且如果表的字段有所调整,则所有代码都必须进行调整,否则会显示错误的数据。为了解决这个问题,可以在实例化游标对象时使用字典类型的游标对象,返回列表+字典的数据结构。修改上述代码如下。另外,在PyMySQL中,针对数据库的插入、更新、删除等操作,只需要编写好对应的SQL语句,调用cursor.execute(sql)便可正常完成,使用连接对象mit()即可完成提交。SQLModel核心操作SQLModel基于SQLAlchemy,是Python中各类Web开发框架的首选数据库框架,可以很好地与FastAPI等框架集成,且具备ORM能力,从而使操作数据表变得更加方便。那么,什么是ORM?ORM的作用是在关系数据库和对象之间进行映射。这样,用户在对数据表进行具体操作的时候,无须编写SQL语句,像平时操作Python的类和对象一样操作数据库即可。为什么需要使用ORM对数据库操作进行封装呢?在在一个大型系统中,由于表和列非常多,如果全部使用原生SQL语句来实现数据库操作,那么一旦表结构发生变化,就需要重写很多SQL语句,为代码的维护和开发效率带来了极大的困扰。使用ORM对数据库进行封装后,就可以将业务处理和数据库操作完全分离开来,这样开发者只需要关心业务逻辑实现,而不用关注数据库是如何实现读写的。同时,对数据库的增删改查完全不用编写SQL语句,而是通过操作一个类和类中的方法或属性来实现。这就是所谓的对象与关系之间的映射。SQLModel核心操作以下代码演示了利用SQLModel操作用户表的增删改查操作。首先,创建一个users.py模块,用于连接数据库并定义映射关系(也称为模型类)。SQLModel核心操作其次,在FastAPI的接口中对用户表进行增删改查操作,代码如下。SQLModel核心操作上述代码可以在SwaggerUI中进行请求的发送和确认,且上述代码遵循了RESTful接口规范,读者可以通过实验进行感受。在SQLModel中,不用再编写原生的SQL语句,全部通过方法进行操作就可以达到目的,还可以使代码的可读性和可维护性变得更强。SQLModel复杂查询SQL的查询条件非常多,如多条件查询、分组查询、聚合函数统计、多表连接查询等,是SQL语句中很复杂的操作。但是SQLModel提供了对此类操作的支持,通常使用select()函数来构造查询语句。同时,针对一些复杂查询,如果使用SQLModel函数难以构建查询语句,则可以使用原生SQL语句来实现。以下代码演示了一些常用的复杂查询操作,以供读者参考。如果后续项目中使用到新的操作,则会对其单独进行讲解。SQLModel复杂查询为了调试方便,上述代码并没有被放到FastAPI的接口中,但是操作方式是完全一致的。其运行结果如下。FastAPI对接大模型04基于OpenAI库对接与DeepSeek的非流式响应的对话过程第1章已经讲解了如何在Python中使用OpenAI或基于HTTP接口来对接AI大模型,在FastAPI中,大模型的对接与之基本上没有本质上的区别,只是将对接过程封装在接口当中,并与前端进行交互。处理流式响应在FastAPI中向前端进行流式输出时主要涉及两种关键技术,分别是yield生成器和StreamingResponse对象。其中,yield生成器用于将大模型的流式输出转换为生成器输出而非标准的返回值;StreamingResponse对象用于向前端输出流式响应结果。流式响应结果在HTTP中将以Content-type:text/event-stream的形式反馈给前端,具体代码如下。处理流式响应开启上述服务后,可以在Python中编写以下代码进行测试,确认流式输出是否正常。前端JavaScript对接1.fetch()函数的用法fetch()函数提供了一个获取资源的接口(包括跨域请求),用于取代传统的XMLHttpRequest来发送异步JavaScript和XML(AsynchronousJavaScriptandXML,AJAX)请求,同时支持发送Get、Post请求等操作。为了了解fetch()函数的用法,先在服务器中编写以下代码,用于定义接口和渲染模板界面。前端JavaScript对接1.fetch()函数的用法编写模板界面文件fetch.html中的代码,该代码实现了使用fetch()函数发送一个Get请求并输出响应正文的功能。前端JavaScript对接2.在fetch()函数中处理流式响应流式响应的接收与普通的响应有所不同,主要区别在于:流式响应是分块读取的,需要循环读取响应的内容;返回的也不是普通的文本型正文,而是一系列逐步发送的数据块,需要构建一个针对响应的ReadableStream对象来读取数据流,所以在处理时有一些特别。首先,在后端接口中创建一个Get请求的接口,用于渲染模板界面,代码如下。前端JavaScript对接2.在fetch()函数中处理流式响应前端JavaScript对接2.在fetch()函数中处理流式响应其次,在templates目录中创建前端界面文件chat.html,代码如下。前端JavaScript对接3.浏览器兼容性处理上述代码在新版本的Chrome中完全可以正常工作,但是即使换成Firefox或Safari浏览器的最新版本,也极有可能无法工作。打开Firefox浏览器的控制台,可能会看到以下报错信息。上述错误的大致意思是响应的格式不对,无法解析为JSON数据,出错的代码语句为jsonObj=JSON.parse(chunk)。为了分析其原因,在该行代码之前插入一行输出语句console.log(chunk)来查看流式响应的输出有什么特别之处。响应的JSON格式异常如图2-13所示。前端JavaScript对接3.浏览器兼容性处理仔细观察响应的内容可以看出,因为在后端生成器中输出内容时,每一次生成都加了一个换行符\n(见2.4.2小节中的后端代码),所以在前端处理时,为响应的内容添加了\n作为分隔符,利用JavaScript的split()函数将其分隔为一个数组,格式为[{"content":"你好"},{"content":"再见"},""],并遍历数组中的每一项(最后一项除外),即可正常解析为JSON数据。前端JavaScript对接3.浏览器兼容性处理以下代码为更新后的doask()函数的代码。AI问答content目录01功能与设计分析02前后端准备工作03文本问答功能04图像识别与生成功能与设计分析01核心功能列表AI问答系统概述AI问答系统是目前极为常见的一种AI大模型的基础应用,很多AI应用均在此基础之上进行拓展。本章主要利用JavaScript和FastAPI实现基于前后端交互的AI问答,主要包括以下功能。(1)利用FastAPI与阿里云的大模型实现对接,并处理流式响应。(2)实现基于纯文本的AI问答,与平时使用的AI聊天应用类似。(3)调用阿里云的视频理解模型实现图像识别功能,解读图像的内容。(4)调用阿里云的通义万相模型实现文本生成图像功能,并在前端展示生成的图像。(5)由于大模型不具备实时联网功能,因此AI问答系统还要实现联网搜索与问答功能。(6)对接高德地图提供的MCP服务,用于实现地理位置查询、天气查询等功能。(7)提供基于JavaScript调用操作系统本地的语音合成接口,实现语音朗读功能。整体实现思路为什么选择阿里云首先,阿里云作为国内领先的大模型提供商,其发布的Qwen3模型的功能丝毫不逊色于其他大模型。其次,阿里云提供的大模型的功能较为全面,AI问答系统涉及的文本问答、图像识别、图像生成、联网搜索等功能均可以基于阿里云大模型实现。这样做的好处是,读者可以将学习的重心放在代码逻辑和实现上,而不是各类平台的接口对接上。整体实现思路前端界面设计AI问答系统的前端界面采用标准的HTML+CSS来实现,设计比较简洁。其主要有两个关键点需要注意:第一个关键点是聊天框中的问答,由于是动态生成的DIV,因此需要使用JavaScript的文档对象来动态创建一个DIV元素,即document.createElement('div');第二个关键点是图像识别时需要上传图像并显示,细心的读者可能已经发现,在AI问答系统项目的主界面中并没有出现文件上传的元素,而是对其进行了隐藏。文本问答功能此功能几乎可以通过对接任意大模型来实现,并在前端利用fetch()函数进行流式响应的读取和填充。整体实现思路图像识别功能首先,由于使用图像识别功能时,用户需要上传本地图像,因此会用到文件上传组件。然而,该组件的默认样式可能与整体界面风格不协调,因此建议将其隐藏。可以通过JavaScript代码来触发文件上传功能,以保持界面设计的一致性和用户体验的流畅性。其次,用户上传的图像不能直接传递至后台,而是应暂存到浏览器中,并显示预览图,可以考虑使用JavaScript的localStorage或sessionStorage对象来临时保存图像文件的Base64编码。此后,让用户编写提示词,确定提示词后,将图像与提示词一同上传给后台接口,后台接口会与大模型进行交互。AI问答系统中图像识别功能的运行结果如图3-2所示。整体实现思路图像生成功能图像生成功能主要通过调用阿里云的通义万相v2实现,此功能的实现分成两步:第一步,将用户的提示词提交给后台,再由后台转交给通义万相生成图像;第二步,等待通义万相生成结束后,获取图像的URL,并解析出图像名称,将其保存到项目目录中,将图像的路径通过响应返回给前端,由前端界面渲染该图像。注意:因为图像生成功能响应给前端的是图像的URL,所以不需要考虑流式响应的处理。整体实现思路联网搜索功能在AI问答系统中,联网搜索功能几乎成了标配,核心原因是AI大模型本身不具备实时能力,需要具备搜索功能才能分析及总结实时数据,并以大模型理解的表达形式响应给用户。联网搜索功能的本质就是根据用户的提问,通过搜索引擎进行搜索,并将返回的搜索结果连同用户的提问一起交给大模型进行总结、整理,并根据用户的提问来进行回答。联网搜索功能有两种实现方式:第一种是通过搜索引擎搜索用户提问,并将搜索结果界面的内容作为提示词输入大模型;第二种是直接调用搜索引擎提供的API,该方法可以更好地过滤搜索引擎的广告,以JSON格式返回结果。整体实现思路高德MCP服务的调用如果要在AI问答系统中集成MCP服务调用,则必须使用代码来开发MCP客户端。其中,Python的mcp库提供了对客户端开发的支持。但是,相对于开发MCP服务器,开发MCP客户端要更复杂一些,因为客户端涉及与服务器的连接、接口和规范的读取、与大模型的两次交互、异步处理、连接状态的维持等诸多操作。语音朗读功能实现该功能的方案有两种:第一种是直接利用JavaScript调用本地语音合成接口,实现简单,且JavaScript内置支持;第二种是调用云API来进行语音合成,并将合成的语音保存为文件,在前端利用JavaScript进行播放。本章采用第一种方案实现语音朗读功能。前后端准备工作02前端界面实现前端界面是标准的HTML+CSS实现,且当前只考虑在PC端实现,不考虑在移动端实现,也不考虑响应式布局,相对比较简单,通过常规的层叠样式表(CascadingStyleSheets,CSS)即可完成。在templates目录下创建一个名为chat.html的源代码文件,以便在FastAPI中作为模板进行渲染,其内容及注释如下。前端界面实现上述代码中引用的style.css文件的内容如下。如果要调试上述代码,则可以使用两种方案:第一种是直接打开该HTML文件进行调试;第二种是在FastAPI中进行调试。这里推荐使用第二种方案。静态目录设置因为前端的模板界面中通常会引入CSS文件、JavaScript源文件,或者一些静态的图像等内容,所以必须确保前端界面中至少有一个正确的路径。在FastAPI中,静态目录通常放置于项目根目录的static目录下,同时,要让chat.html中引用的JavaScript文件或CSS文件路径生效,必须完成以下两项设置。(1)将所有静态资源放置于static目录下。(2)在实例化FastAPI后,需要设置静态文件所在目录,代码如下。完成上述设置后,才能在HTML界面文件中使用<scriptsrc="/static/script.js"></script>正确引用JavaScript源文件。FastAPI多模块第2章中已经学习了FastAPI的一些关键特性,且将所有接口代码放到同一个Python源代码文件中,这样操作有一个弊端,即如果项目本身接口比较多,则该源代码文件会很大,且难以维护。为了解决该问题,FastAPI提供了APIRouter对象来帮助开发者进行多模板开发。也就是说,可以先将相关功能模板的接口放到单独的一个源文件中,再在main.py这类主代码中进行引入,以实现接口的多模块化处理。FastAPI多模块定义了上述两个接口后,再在main.py中进行引用,即可正常调用/get_test和/post_test这两个接口,代码如下。了解了上述功能后,可以将AI问答系统拆分为3个模块,分别是qa模块、recognize模块和generate模块。其中,qa模块用于常规问答,recognize模块用于图像识别,generate模块用于图像生成。另外,通常项目中还存在一些公共模块,用于在接口中调用。此时,可以创建一个名为module.py的源代码文件,用于存储非接口定义的公共代码。文本问答功能03后端代码实现首先,定义后端代码,创建文件qa.py,用于对接AI大模型并生成流式响应,其基本逻辑与第2章一致,代码如下。后端代码实现其次,在main.py中引用qa模块接口,并完善main.py中的其他代码。前端代码实现首先,讲解如何在JavaScript中实现语音合成功能,以便问答时直接调用,代码及注释如下。前端代码实现上述代码完成编写后,还不能马上使用,需要在AI的回复中添加一个“朗读”按钮来进行调用。同时,在实现对话功能前,先定义两个公共函数用于绑定Ctrl+Enter的按键事件,并将提问框滚动到底部,以查看最后的对话信息。前端代码实现实现上述两个功能模块后,即可实现chat.html界面中的“智能问答”按钮功能。调用doAsk()函数,用于在提问框中新建一个DIV并将用户提问框的内容添加到该DIV中。前端代码实现接下来实现doAnswer(

)函数,即前端与后端大模型通信的关键代码。联网搜索功能联网搜索功能采用阿里云AI搜索开放平台的服务接口来实现,不同于阿里云灵积模型的APIKey申请,阿里云AI搜索开放平台需要单独申请APIKey。在阿里云AI搜索开放平台上申请APIKey,如图3-4所示。联网搜索功能成功申请APIKey后,可以先编写一段Python代码进行测试。联网搜索功能如果测试通过,则可开始实现联网搜索的AI问答功能。在后台创建文件module.py,用于保存搜索功能代码,便于在接口中进行调用。联网搜索功能因为前文配置前端发送请求时已经考虑了是否需要实现联网搜索功能,所以构建的参数是params={"content":content,"search":false},这意味着如果用户勾选了“联网”复选框,则参数将变为{"content":content,"search":true},需要在后台qa模块的stream接口中调整代码。联网搜索功能上述代码的意思是,此次与大模型交互将不再单纯将用户的提问内容传给大模型,而是要将搜索结果一并作为提示词传给大模型。上述后端接口代码修改后,还需要同步修改前端的代码,主要修改doAnswer(

)函数的代码。开发MCP客户端联网搜索功能可以增强AI问答系统的问答能力,并可以针对任何提问进行搜索,功能实用性较强,但不够有针对性。而使用MCP服务可以有针对性地拓展AI问答系统的特殊功能,如天气查询、旅游规划、酒店查询等。本小节将通过实现一个MCP客户端,以调用高德地图服务,配合联网搜索功能,对AI问答系统进行完善。以下代码演示了如何通过Python代码获取高德地图的所有工具列表,并对其中的工具进行调用。开发MCP客户端上述代码运行后,会列出高德地图所有MCP服务器工具,下面取其中一个工具进行展示。前文所述代码的输出结果就是函数定义,有描述、有参数,至此,其本质上与自定义函数没有不同。同时,经过仔细分析会发现,inputSchema字段的值与FunctionCalling的函数定义部分完全一致。这非常有助于将其转换为大模型的函数定义。开发MCP客户端另外,由于mcp库的函数全部被定义为async异步处理函数,因此在上述代码中同样需要将函数定义为异步的,调用系统函数时必须使用await。理解了如何获取工具列表以及如何调用工具后,再与大模型进行整合就比较简单了。其核心过程就是先对用户提问进行处理,执行第一次大模型调用,再从中解析是否存在工具调用的需求,如果存在,则调用相应工具,最后是正常的流式响应的模型对话。在MCPClient类中,新增一个函数process_query(

),利用以下代码即可进行AI对话与函数调用。开发MCP客户端开发MCP客户端函数调用增强因为FunctionCalling或MCP等调用更多地会应用于对话式AI应用中,所以要将函数调用整合到当前项目中,是完全可行的,这主要取决于用户需要让AI解决哪些问题。下面以通过AI提问框来发送一封邮件为例,演示如何增强AI问答系统的对话功能,对于其他各类功能的拓展,其思路和逻辑与之大体相同。首先,定义一个函数,用于通过Python向特定邮箱地址发送一封邮件,将其保存到func_calling.py源文件中,具体代码如下。函数调用增强由于使用QQ邮箱服务器来发送邮件,因此读者需要进入QQ邮箱,开启SMTP服务,并申请一个授权码。具体操作如下:登录QQ邮箱→单击“设置”按钮→单击“账号”按钮,即可进入图3-5所示的界面。按照系统提示申请授权码,即可发送邮件。函数调用增强其次,完成邮件发送代码的编写后,需要完善两段代码。此时,需要根据FunctionCalling的格式要求来定义函数规格,以便大模型可以正确识别该函数的功能及参数;需要修改AI对话的过程,只有对函数调用进行独立的处理,才能将其整合到AI问答系统中。在func_calling.py代码中添加以下函数定义。函数调用增强修改qa.py模块中的智能问答功能,将函数调用与普通问答进行整合,修改后的代码如下。图像识别与生成04图像识别功能在介绍图像识别功能之前,要先了解图像识别功能的大模型接口规范要求,可以通过查看阿里云大模型服务平台的用户指南学习视觉理解的接口规范。因为该接口是OpenAI兼容接口,所以代码调用较为简单,唯一需要注意的是图像识别的正文需要包含图像的Base64编码和文本提示词,其大致结构如下。图像识别功能除了需要重新构建文本对话有所差异的请求,其他操作与文本对话基本一致。掌握了接口规范后,即可着手编写后端接口代码,并保存于recognize.py模块中,具体内容如下。图像识别前端图像识别通常分为两步:第一步是用户上传图像并编写提示词第二步是发送给后台以获取大模型的输出。因此,只设置一个按钮显然无法满足功能要求,至少需要两个按钮。第一个按钮是“识图”按钮,用于浏览图像并显示预览效果,第二个按钮仍然使用“智能问答”按钮来与后端进行交互。需要注意的是,此处涉及在“智能问答”按钮中如何判断用户是要进行文本问答还是要进行图像识别的问题。从chat.html源代码中可以看出,“识图”按钮调用的是addImage()函数,该函数的代码实现只是为了触发文件上传框的单击事件,用于模拟文件上传时的浏览文件功能,代码如下。图像识别前端当用户浏览图像后,接下来即可响应文件上传框中的onchange="saveAndPreview()"代码,saveAndPreview()函数用于将图像的Base64编码数据保存到sessionStorage中,并在提问框中进行预览显示。之所以使用sessionStorage而不是localStorage,是因为sessionStorage只用于临时存储数据,关闭浏览器后就会清空数据,不会永久保存,而AI问答系统也不需要永久保存。具体实现代码如下。图像识别前端如果上述代码的功能正常,则当用户浏览图像后,可以在提问框中显示预览图,其实现效果如图3-7所示。图像生成功能因为通义万相模型不支持使用OpenAI的SDK,所以必须使用Dashscope的SDK实现,根据文档的示例代码即可方便地生成图像。创建generate.py后端接口,实现代码如下。图像生成功能后端代码实现后,直接编写前端代码实现对接,并对生成的图像进行渲染即可。图像生成功能图3-8中的提示词还不够完善。此时,可以选择将这句提示词交给智能问答系统,让智能问答系统帮助用户优化得到一份更加完善的提示词。以下提示词是由本章的AI问答系统生成的。每日新闻摘要content目录01功能与设计分析02基础功能实现03扩展功能实现功能与设计分析01核心功能列表新闻摘要系统在设计该项目时,要考虑以下6点。(1)选择合适的新闻来源,本书选择的是新浪新闻。(2)通过爬虫技术获取新闻标题和新闻原文内容,以便于把内容交给AI大模型进行总结和摘要。(3)由于新闻不是随时更新的,因此每日新闻摘要项目需要具备定时更新新闻内容的能力。但是到更新时间时,因为可能某些新闻还未更新,所以数据库还要具备去重的能力。(4)既然是新闻摘要,用户的需求主要就是快速获取新闻的大致信息。所以其界面要尽量简洁,不宜提供过多功能。同时,如果用户对某个新闻比较感兴趣,则可能会想查看新闻原文内容,最好提供原文链接,让用户可以跳转阅读原文。(5)由于新闻类型比较丰富,如国内新闻、国际新闻、娱乐体育新闻、财经科技新闻等,因此应该具备新闻分类功能,以便用户快速找到自己感兴趣的新闻。(6)由于每天的新闻均保存在数据库中,因此需要支持按日期展示历史新闻,使用户可以快速查看过去某天的新闻内容。核心功能列表新闻摘要系统整体实现思路(1)新闻原文内容爬取。使用Python中的BeautifulSoup库可以非常方便地对网页内容进行解析和提取。(2)交给大模型进行总结摘要时,只需要编写好提示词模板,把要求和对应的新闻原文提交给大模型,大模型就可以返回摘要内容。其准确度主要取决于大模型本身的理解能力,不过目前通义千问或DeepSeek等大模型在这方面的表现都较为出色。(3)在新闻实时更新方面,需要设置一个定时任务爬取新浪新闻上的最新新闻。(4)新闻分类本质上也可以通过爬虫技术获得,但是由于每日新闻摘要项目只针对新浪新闻进行摘要,同一个新闻站点的新闻类型通常是固定的,因此可以在代码中预先写好分类。(5)更新新闻时,通常需要将更新时间插入数据表,而该时间可以作为分组依据。以日期进行SQL查询分组后,可以获得日期的列表,并在前端界面中通过超链接功能将每个日期单独设为一条超链接,用户单击相应超链接后就可以获取当天的新闻摘要。基础功能实现02前端界面布局在掌握了某个系统的功能需求后,通常要优先考虑进行项目的原型设计,或者直接开发原型界面,以便对需求和交互逻辑等进行更合理的规划。一旦界面元素和交互逻辑基本确定,就说明需求理解已经完整和准确;再从技术层面考虑前后端的具体实现,这样可以确保思路上的通畅。如果是团队开发某个项目,预先设计好原型界面可以使得成员之间的沟通更加顺畅。整个新闻摘要的界面布局并不复杂,主要由顶部分类、中部新闻摘要主体、底部的按日期浏览这几个部分构成,以下是HTML+CSS的布局代码。前端界面布局前端界面布局上述界面布局代码可以置于templates目录下,并由Jinja2模板引擎进行渲染,这一部分内容与第3章的模板界面渲染完全一致,此处不赘述。其实现效果如图4-2所示。一般来说,在设计前端界面时,由于还没有后台数据用于填充,因此可以先在HTML界面中任意填充一些数据进行占位,以预览真实的实现效果,后续可通过Jinja2模板引擎在相应位置进行动态填充,以正常实现功能。数据表结构根据前文分析的结果,设计每日新闻摘要的数据表结构,如图4-3所示。其中,id为自增长列,category为新闻类型,headline为新闻标题,hyperlink为原文超链接,content为新闻原始内容(保存与否均可,因为最终展现的不是原文而是摘要),summary为新闻摘要,createtime为该条数据的生成时间。目前,每日新闻摘要项目不需附加其他功能,只需要创建这一张表。BeautifulSoup库由于每日新闻摘要项目只需爬取新浪新闻网站上的公开数据,且只涉及几个固定界面,比较有针对性,因此相对容易处理。每日新闻摘要项目完成以下两个关键步骤后即可正常爬取到相应的内容:第一步是利用Python的requests库发送Get请求以获取界面的源代码;第二步是利用BeautifulSoup库对该源代码进行解析,将需要的内容提取出来。新浪新闻版块截图如图4-4所示,其中新闻部分的标题和超链接就是后续需要获取的内容。为了获取网页中元素的属性,需要在浏览器中按F12键打开开发者工具,以查看网页源代码和对应的元素。BeautifulSoup库运行“pipinstallbeautifulsoup4lxml”命令,在Python环境下安装BeautifulSoup库。运行以下代码,尝试进行爬取。BeautifulSoup库以同样的方式编写代码,具体如下。以此类推,可以获取其他类型的新闻。每日新闻摘要项目主要爬取今日要闻、国内新闻、国际新闻、财经科技、娱乐体育等几类新闻。读者也可以根据需要爬取其他类型的新闻,不影响每日新闻摘要项目的技术运用即可。爬取标题与超链接分析新闻首页的元素属性可以发现,除了今日要闻的元素及属性与其他类型新闻不同外,其他类型新闻的class属性、ul元素及HTML层次都是一样的,唯一区别在于id属性和data-client属性所对应的值不同。所以针对这些类型的新闻,可以将其封装到一个函数体中,并将id属性和data-client属性作为参数进行传递,实现复用爬虫代码。要将新闻标题、超链接和新闻类型保存到数据库中,需要创建一个模块代码文件crawler.py。该模块用于编写爬虫代码,并创建SQLModel库的数据映射关系。首先,在news.py中定义数据库引擎和映射关系,以便在其他模块代码中引用。爬取标题与超链接其次,编写crawler.py的代码。获取和摘要新闻当完成新闻标题和超链接的爬取及保存后,可以进一步爬取新闻的完整内容,并利用AI大模型对内容进行摘要,从而将其更新到数据库中。首先,数据库中已经保存了新闻的标题和链接,所以此时遍历news表中的新闻链接,即可对新闻的正文内容进行爬取。爬取的新闻正文可以保存到数据库中,也可以不保存到数据库中,因为每日新闻摘要项目最终呈现的只是经过大模型摘要后的简短文字,所以将摘要保存到数据表中即可。其次,如何对新闻正文内容进行摘要呢?只需要将新闻正文连同提示词提交给大模型,即可获取摘要内容,并将该内容更新到数据表对应的行中。最后,由于新闻正文内容通常比较多,因此对接云端大模型所消耗的Token也较多,如果读者本地部署有Ollama,则也可以尝试利用本地大模型进行摘要,以减少Token开销。每日新闻摘要项目仍然与云端大模型对接,以获取更好的总结效果。获取和摘要新闻创建summarize.py模块文件,内容如下前端界面渲染完成数据库的数据更新后,数据表中保存了新闻的标题、超链接和摘要,此时,便可以从数据库中查询此类信息,并通过模板界面将其渲染到前端。首先,在news.py模块中通过get_news_by_dc()函数增加查询代码,此处为了方便后续重用,设计参数date和category,以便通过日期和新闻类型来查询相应的新闻摘要。其中,date参数的默认值为None,如果不传递该参数的值,则表示获取当天的新闻摘要,否则获取指定日期的新闻摘要;而category的默认值为hot,表示默认获取今日要闻类型的新闻摘要,否则获取其他类型的新闻摘要。前端界面渲染其次,在main.py中添加接口代码,用以填充模板界面。前端界面渲染再次,重新修改news.html模板界面,利用Jinja2进行循环的动态填充。前端界面渲染最后,运行main.py,访问:8000/,如果效果如图4-6所示,则表示功能成功实现。扩展功能实现03新闻分类浏览在编写news.py模块的get_news_by_dc()函数时已经考虑新闻分类功能,因此,只需在main.py中添加相应接口即可实现功能。新闻分类浏览因为前端代码在之前已经添加了分类的超链接,所以不需要做任何修改便可以正常浏览分类新闻。上述代码运行后,新闻摘要分类浏览效果如图4-7所示。按日期浏览新闻如果不涉及新闻分类问题,那么按日期浏览新闻与按类型浏览新闻在实现思路上是相似的,例如,将接口从/china修改为/2025-05-15就实现了按日期浏览功能。但是现在的关键问题是每天的新闻均有不同类型,也就是说,每个日期下均有不同类型的新闻可以浏览。因此,用后台接口处理日期的同时也需要考虑类型。基于这样的思路,如果将接口地址设计为/2025-05-15/china,能否一次性解决问题?经过分析,这是可行的,但是有一个问题需要考虑,即按类型浏览和按日期浏览是两个超链接,用户是单独单击的。例如,用户想浏览2025-05-13的新闻,默认可以访问接口/2025-05-13/hot,这本身没有问题,但是如果用户想访问2025-05-13的财经科技新闻,则必须访问/2025-05-13/finance接口。此时,如何让这个日期保持不变是首先需要解决的问题。按日期浏览新闻可以在后台添加一个新的接口/{date}/{category},实现代码如下按日期浏览新闻接下来更新前端代码,主要更新分类选项卡的超链接地址和界面底部的日期列表。按日期浏览新闻完成上述代码后,整个系统便能够正常运行。访问:8000,调用首页接口渲染当天的今日要闻类型数据。此时,如果选择相关分类选项卡,则接口地址会调用当天的分类;如果单击某个日期的新闻,则默认访问该日期下的今日要闻,再选择其他类型,访问的是该日期下其他类型的新闻。细心的读者可以发现,原本的分类浏览接口/{category}不再使用,可以将其改为删除或注释。定时更新新闻因为新浪新闻会不定时更新,一天内可能会更新几次,所以为了保持对新闻的完整跟踪,建议每隔2小时更新一次新闻数据。基本实现思路如下:使用Python编写一个死循环来实现定时任务。由于新闻抓取和AI摘要这些功能在前端的代码中已经实现,因此只需要在该定时任务的代码中进行调用。在通过定时任务更新数据时,可能有些新闻并没有被更新,此时便不能将新闻标题和超链接信息新增到数据表中,否则会出现重复添加的问题。因此,在对数据表进行更新时,需要先判断更新的内

温馨提示

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

评论

0/150

提交评论