2025-05-26 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
前面我们已经学习如何通过 Langchain调用独立部署的DeepSeek-R1:32b
模型,且完成一些简单的应用,如: RAG 知识库的实现。
接下来我们学习如何通过LangChain实现一个Agent智能体,从而让 AI 模型帮忙实现做更多事情。
在开发之前我们先来了解下Agent智能体是什么,它主要解决什么问题?
Agent是使用 LLM 大模型作为推理引擎的系统,用于确定应采取哪些行动(Action)以及这些行动输入应该是什么,然后会把行动的输出结果反馈给到Agent,用于判断是否需要更多行动或者结束然后输出返回。
结合网上的资料和个人理解,Agent智能体的出现主要是解决以下问题:
AI Agent是模仿人类思考技术,具体如下图所示:
一句话弄明白,就是AI大模型可以作为一个大脑进行学习推理,但是 Agent技术利用 LLM大模型的推理能力,能根据人类输入,代替人类去做一些真正想要的事情,最后输出人类真正想要结果或者去执行某些行动。
为了更好理解 Agent技术, 我们可以看看目前AI协同工作类型,具体如下:
上面说到Agent技术是模仿人类思考技术,利用大模型进行推理,拆分人类输入的任务,那么 Agent其实最大的重点在于激发 LLM 大模型的推理能力,去拆分人类输入的任务。
那么如何激发 LLM 大模型的推理能力呢? 主要有以下几点:
思维链(Chain of Thoughts)已成为一种标准的提示技术,用于提高模型在复杂任务中的表现。模型被要求 “一步一步地思考”,将艰巨的任务分解为更小更简单的步骤。思维链将大任务转化为多个可管理的任务,并帮助人们理解模型的思维过程。
无思考链的 Prompt:
1 |
问:罗杰有5个网球,他又买了两盒网球,每盒有3个网球。他现在有多少网球? |
有思考链的 Prompt:
1 |
问:罗杰有5个网球,他又买了两盒网球,每盒有3个网球。他现在有多少网球? |
PS: DeepSeek
的推理模式出来后,现在大部分模型默认就支持思考链的回答了。
思维树 是思维链的另一种表现形式,通过在任务的每一步探索多种推理可能性来扩展思维链。它首先将问题分解为多个思考步骤,并在每个步骤中生成多个想法,从而创建一个树状结构。试错和纠错在现实世界的任务决策中是不可避免且至关重要的步骤。自我反思帮助 AI Agent 完善过去的行动决策、纠正以前的错误、从而不断改进。主要可以包括以下几种模式:
记忆模块负责存储信息,包括过去的交互、学习到的知识,甚至是临时的任务信息。
AI有了记忆后,就可以根据已知的记忆知识去更好回答用户提问。而在 AI Agent 定义里:
用户在与其交互过程中产生的内容都可以认为是 Agent 的记忆,和人类记忆的模式能够产生对应关系。
记忆可以分为几类:
而针对记忆这方面的技术, Embedding 技术和向量相似度计算就是记忆(向量数据库的核心),具体可以做以下理解:
AI 懂得使用工具才会更像人类。
AI Agent 除了记忆,还需要在获取到每一步子任务的工作后,Agent 都会判断是否需要通过调用外部工具来完成该子任务,并在完成后获取该外部工具返回的信息提供给 LLM,进行下一步子任务的工作。
目前AI 大模型接入工具的使用方式如下:
open("test.txt")
file_search
和code_interpreter
,能AI直接调用去搜索文件和解析文件的能力。目前绝大部分 AI Agent开发使用的工具的方式都是 Function Call
的方式,目前主流大模型基本都支持这个能力,具体如下:
模型 | 支持Function Call | 说明 |
---|---|---|
GPT-4 Turbo、GPT-4o、GPT-3.5 Turbo | 是 | OpenAI 系列模型,闭源 |
Claude 3(Opus/Sonnet/Haiku)、Claude 3.5 | 是 | Anthropic 系列模型,闭源 |
Gemini Pro、Gemini 1.5 Pro、Gemini Flash | 是 | OpenAI 系列模型,闭源 |
Llama 3(8B/70B)、Llama 3.1 | 是 | Meta Llama 系列,开源, 需要微调后才支持,不过有现成的 Gorilla 微调框架 |
Mistral Large、Mistral-7B-Instruct | 是 | Mistral AI 系列,开源,轻量级模型适合本地部署 |
通义千问(Qwen-Chat) | 是 | 阿里云系列 ,开源,基于 ReAct Prompting 原理优化工具 |
GLM-Z1-32B-0414、ChatGLM3-6B | 是 | 清华智谱系列模型,开源 |
DeepSeek V3 | 是 | DeepSeek,开源,专为函数调用优化,支持多工具协同 |
完整了解 Agent的知识后,解析来我们要通过Langchain框架去实现一个 AI Agent,获取获取当天的龙虎榜数据。
langchain_core.tools.tool
: Langchain用来创建工具的方法langchain.agents.create_tool_calling_agent
: 创建工具调用Agent的函数langchain.agents.AgentExecutor
: 创建 Agent执行器的类开始实现思路如下:
接下来我们声明一个工具函数,用于解决大模型无法判断当前的日期。
1 |
from langchain_core.tools import tool |
1 |
from pydantic import BaseModel, Field |
不同的模型对于工具调用不同, 目前已知支持最好的模型是GPT-4 Turbo
, 但是这个模型是闭源的, 国内支持较好是 DeepSeek但是也收费,对于调试模型更加友好可以利用g模型厂商 - siliconflow AI 云服务平台,从而减少我们的调试成本。
1 |
from langchain_openai import ChatOpenAI |
Prompt对于LLM大模型的实现有关键作用, 其中agent_scratchpad
的占位符对于 AI 大模型实现非常重要,主要用于 记录和传递 Agent 执行过程中的中间推理步骤,同时还会强制按照 tool所需要的参数进行输入调用。
Prompt 具体实现如下:
1 |
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder |
创建Agent, Langchain也提供不同的类型,如下:
目前我们使用的是 create_tool_calling_agent
, 具体实现如下:
1 |
from langchain.agents import create_tool_calling_agent, AgentExecutor |
PS:
handle_parsing_errors
: 当 Agent执行发生异常的时候,如传入参数不符合工具描述,是否抛出异常,当为 True错误信息会通过 intermediate_steps 传递到下一轮推理,模型基于历史步骤中的错误反馈重新生成正确的工具调用指令verbose
: 是否打印中间步骤,从而更好的理解模型推理过程以下是完整代码实现过程截图:
在 Agent中避免不了调试,尤其不同大模型对于工具的调用和判断是不一样的,同时执行过程异常 Langchain也比较难定位,所以因此我们可以使用LangSmith
进行调试。
前往LangSmith官网,注册账号,创建项目,获取API_KEY,设置环境变量,具体如下:
1 |
# 设置LangSimth 环境变量 |
再次运行Agent,可以前往LangSmith查看调试结果,如下图所示:
AI Agent的实现,对于我们来说,可以更好的理解大模型的能力,同时也可以更好的利用大模型能力,从而更好的实现业务场景。 回顾一下,AI Agent的知识点:
agent_scratchpad
占位符是非常重要,记录和传递 Agent 执行过程中的中间推理步骤,同时还会强制按照 tool 所需要的参数进行输入调用。以上就是 AI Agent的实现过程,希望对你有所帮助。
声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-03-31 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
回顾一下LangChain系列学习文章:
经过LangChain系列文章的学习后, 现在我们需要通过 LangChain + 大模型 + 低代码平台, 开发具备实际功能的 AI 应用:
低代码平台AI助手:通过用户输入自然语言能实现 低代码平台页面生成、编辑等
目标:通过用户输入自然语言能实现,完成低代码平台页面的生成,同时能低代码平台页面组件元素进行属性调整。
实际原理: 利用 AI大模型实现用户输入的自然语言与低代码平台特定 DSL语言(JSON Schema)互相转换
声明:本文部分材料是基于DeepSeek-R1模型生成。
对 Agent的一些思考, 首先 agent本身的 Prompt很重要, LLM 大模型会依据Prompt+用户输入去判断需要使用哪个工具
然后创建Agent, Langchain也提供不同的类型,如下:
利用 Agent 开发一个完整的低代码平台 AI 助手,整体实现过程如下:
https://langchain-ai.github.io/langgraph/agents/agents/#1-install-dependencies
2025-03-15 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
前面几篇学习LangChain,基本上完成对 LangChain从开发到上线有一个整体的了解,那么接下来我们就要开始实战了,我们将会使用LangChain开发一个问答机器人,这个问答机器人将会使用到RAG模型,那么接下来我们开始学习RAG。
RAG是一种用额外数据增强大模型知识的技术,俗称“RAG”(Retrieval-Augmented Generation),中文叫检索增强生成。
RAG是LangChain中一个重要的应用场景,它能够将检索和生成结合起来,从而生成更加精准的答案。
RAG模型由两个部分组成:Retriever和Generator。
Generator
生成索引向量,根据文档中问题和答案生成索引向量数据库。Retriever
检索对比类似,根据用户的问题,从生成的知识库中检索召回最相关的问题和答案。RAG技术是通过检索和生成相结合的方式找最相关的知识内容, 加入到大模型的提示语中,通过大模型推理得到用户问题在知识库中最合适的答案。
下面是我个人依据网上相关资料整理的通用RAG模型架构图:
生成向量索引有三个步骤,分别如下:
Embeddings
模型进行生成索引,然后存储到向量数据库VectorStore
。RAG模型使用Embeddings
模型将问题和答案进行编码,生成向量数据,这里我们必不可免需要对Embeddings
模型进行初步了解。
Embeddings模型,也叫嵌入模型,是一种将高维度的数据,如:自然语言、图片、视频等,转换成低维度的向量数据,如:多维矩阵数组等,方便后续进行相似度对比。
或者我们可以更加直观的理解,Embeddings
模型可以把我们人类能够理解的内容,转换成计算机能够计算理解的数据,从而实现更多的算法对比逻辑。
这两个步骤一般都是同时进行,一般也是 通过Embeddings嵌入模型去转换搜索内容为向量,然后通过检索到最后生成内容。
Ollama安装模型:
1 |
对话大模型 |
LangChain和 Streamlit安装
1 |
# python环境 3.12.4 |
requirements.txt
文件内容如下:
1 |
streamlit==1.39.0 |
streamlit是构建和共享数据应用程序的更快方法, 几分钟内将您的数据脚本转换为可共享的网络应用程序,全部采用纯 Python 编写,无需前端经验。
官方文档:https://docs.streamlit.io/get-started/installation
新建一个文件bot_chat.py
, 分步骤实现。
代码参考如下:
1 |
import streamlit as st |
执行效果如下:
1 |
|
上文件后, 执行效果如下:
聊天功能主要几点:
具体实现代码如下:
1 |
# step2 初始化聊天消息界面 |
这里实现一个Agent, 过程是 去调用一个检索工具,支持模板和用户输入,调用大模型进行检索,然后返回结果。
具体代码如下:
1 |
# step3 创建检索 agent |
这一步基本上就是解决用户输入显示与 Agent返回结果,同时通过 streamlit的 callbank函数去 展示 Agent的执行过程,具体如下:
1 |
# step5 用户输入查询与返回 |
1 |
streamlit run bot_chat.py |
执行效果如下:
对话中:
返回答案:
声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-03-12 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
从 LangChain系列文章开始到现在,我们学习 LangChain的基础知识和实战撸代码,现在我们假设已经开发好一个 LangChain链式任务,那么如何部署以及如何与 web服务进行互相调用呢?
那么接下来我们应该就学习LangServer与LangSmith,如何让 LangChain进行企业级开发。
LangServer: 帮开发者将 LangChain 部署一个 Restful 服务。
LangSmith: 监控 LangChain调用链路服务和提供更加友好的可视化界面。
LangServer是集成了FastApi + Pydantic的Restful框架。它提供了一些特性:
/invoke
、 batch
和 /stream
接口服务,支持单个服务器多个并发请求/stream_log
接口,实现链式任务中间态步骤返回/stream_events
更加清晰任务事件状态信息安装langchain-cli
全局命令,方便快速启动 Lang Server项目
1 |
pip install -U langchain-cli |
安装poetry
管理项目的依赖,更好管理服务依赖 pip包。
poetry
Python packaging and dependency management made easy, 翻译过来就是更加轻松管理 python项目和依赖
1 |
安装 pipx |
1 |
初始化一个langserver的项目 |
1 |
mylangserver # 项目名 |
在根目录下运行如下命令:
1 |
langchain server |
就可以直接访问 http://localhost:8080
,效果具体如下图:
server.py
文件server.py
文件,具体如下:1 |
from fastapi import FastAPI |
DeepSeek-R1
模型的接口通过 add_routes
新增一个模型对象,会自动封装成对应的 Restful接口,具体如下:
1 |
from fastapi import FastAPI |
接下来我们访问 http://localhost:8000/
,就会出现和/deepseek
相关的文档,具体如下图:
接口测试我们可以通过ApiFox (一个和 Postman类似 API 测试工具)进行测试,具体如下.
/invoke
发起一个对话请求, 具体如下图:/stream
流式调用,具体如下图:在LangChain中是可以通过 LangServe提供的 RemoteRunable
进行远程调用,和原来的调用大模型的使用方式其实是一样的, 具体代码如下:
1 |
# 实现langchain调用远端调用 LangServer |
这样子我们不仅可以在本地调用大模型,还能调用其他人提供 LangChain服务,从而实现更加复杂的功能。
LangServer生产部署,按照 LangChain官方推荐是通过Dockerfile
打包进行部署,其中也比较简单,具体执行如下命令:
1 |
打包镜像 |
或者是通过 docker-compose启动 docker服务,具体如下:
1 |
version: '3' |
最终执行docker-compose up -d
启动服务后,就可以通过http://localhost:8080/docs
访问到服务了。
LangSmith是 LangChain官方提供的监控工具,可以监控模型运行情况,一个 SASS服务需要我们将服务相关信息注册到 LangSmith网站上,因此可以按个人或公司需要判断是否允许使用。
LangSmith是一个用于构建生产级应用的平台。它允许您密切监控和评估您的应用,以便您可以快速而自信地发布应用。
传统软件应用程序是通过编写代码来构建的,而 AI 应用程序则需要编写提示来指导应用程序执行哪些操作。
LangSmith 提供了一套旨在实现和促进提示工程的工具,以帮助您找到适合您的应用程序的完美提示。
PS:LangSmith这里提示未来编程开发者的思维转变,我们实现功能的思路不再是针对一些实现逻辑,而是面向不同的 AI 模型,优化提示语实现我们想要的功能。
在 LangServer 中使用 LangSmith,需要先注册一个账号,然后获取 api key 添加到 LangServer中,具体使用代码如下:
1 |
import os |
具体使用教程可以参考LangSmith官方文档
LangSmith主要作用是监控 链路任务节点调用和扭转情况,可以更加清晰的分析链的运行情况和日志,具体效果如下图所示:
如果我们不想把自己的服务相关的日志信息暴露给 LangSmith, 我们还可以通过设置set_verbose
设置详细日志开关, 从而实现我们调用 LangChain链路的完整日志,具体如下:
1 |
from langchain.globals import set_verbose |
打开开关后,我们再调用helloworld.py
大模型,可以看到关键的日志信息,但是verbose只会输出关键日志,下面我们还可以 debug
查看更加详细的日志信息。
我们可以通过debug
设置日志级别,从而查看更加详细的日志信息,具体如下:
1 |
from langchain.globals import set_debug |
打开开关后,我们再调用helloworld.py
大模型,可以看到更加详细的日志信息,具体如下图:
本文我们主要学习了LangServer的去部署一个 LangChain链,通过 LangServe对于第三方就能加友好的访问我们的提供 LangChain服务,从而实现更加复杂的功能。回顾一下,我们主要学习了以下内容:
langchain serve
运行项目add_routes
添加接口,可以直接把一个 LangChain添加到 LangServer中且自动生成 Swagger文档 set_verbose
或者set_debug
设置详细日志开关, 从而实现我们调用 LangChain链路的完整日志声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-03-03 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
上一篇文章我们学习05篇 AI从零开始 - LangChain学习与实战(2) PromptTemplate降低AI幻觉,对 LangChain实际应用有了基本的了解,接下我们会进入 LangChain最重要的一次学习,就是 LangChain工作流编排原理与实战(LCEL), 学了本文基本上后续 LangChain实际开发都可以独立完成,本文内容较多,建议大家收藏,慢慢学习。
LCEL(LangChain Expression Language) 是 LangChain提出来一种强大的工作流编排模式,可以通过基础组件去构建复杂任务链条式,包括但不限于:
Pydantic
对象和 JSON
对象作为输入和输出,从而更好验证链路的正确性,并且LangServer的重要组成部分LCEL之所以有如此强大的功能,离不开它的设计理念 —— Runable Interface,LangChain一套标准且强大的接口设计规范,让所有的组件都按照这个去实现,从而实现 LCEL 工作流编排。
Runable Interface接口设计有以下几个方面“
同步调用方法:
结合await
实现异步调用的方法:
LangChain的输入和输出都是遵循schema
规范,从可运行对象结构自动生成对应的Pydantic
模型。
Pydantic
是用于数据建模/解析的Python库,它允许您定义一个数据模型,然后使用该模型验证输入和输出。
它可以帮助您确保输入和输出数据符合预期的格式和类型,从而提高代码的健壮性和可维护性。
同时Pydantic
内置了对JSON编码和解码的支持。
不过不同组件输入类型和输出类型是不同的,下面常用 LangChain组件输入和输出类型:
组件 | 输入类型 | 输出类型 |
---|---|---|
提示 Prompt | string | PromptTemplate提示值 |
聊天模型 | string、聊天信息列表、提示值 | string |
LLM | string、聊天信息列表、提示值 | string |
输出解析器 | LLM、 LLM的输出 | 取决于解析器的类型,如 jsonparser 输出的是 json格式 |
流式运行对于基于 LLM 开发的应用会对用户使用体验上有更好的体验,所以目前LangChain中重要的组件都实现 LangChain Runable Interface中的 stream
和astream
,如:PromptTemplate
、ChatModel
、LLM
、OutputParser
等。
上面弄清楚 LCEL的运行原理,我们还需要了解 Stream
这一概念,才能更好的理解 LCEL工作流编排。
Stream
指的是一个数据流,它表示一个连续的数据序列,可以是一个数据块、一个文件、一个数据库表、一个网络连接等。在计算机科学中,流通常用于表示实时数据传输,例如从网络连接中接收的数据、从文件中读取的数据等。流数据具有连续性、实时性和不可预测性等特点,因此处理流数据需要特殊的算法和数据结构。
在 LangChain中所有 Runable对象都实现了 stream(同步)
和 astream(异步)
接口,通过 stream
和 astream
接口,LangChain链式中的每个任务步骤都可以按照流式输入与输出。
从简单的任务,如发起一个 LLM调用,到复杂的任务,如:传输json数据等。
了解完 LCEL工作流编排原理,我们开始实战,下面我们通过几个的例子,来更好理解 LCEL工作流编排。
我们去调用一个 Ollama 大模型,然后调用 stream
方法,看看最终会输出什么?
1 |
# 实现langchain调用 ollama 大模型 |
最终输出效果,按照一块块输出,如下图:
进一步看看astream
调用和stream
调用有什么区别?
1 |
# 实现langchain调用 ollama 大模型 |
异步调用需要定义 async 方法,调用的话需要通过 asyncio.run() 方法,最终效果和stream
调用效果一样,不过在并行任务较多的情况下,astream
调用会利用更多的CPU资源,从而提高并行任务处理效率。
在实际应用中,我们很多场景其实 web服务通过 http协议传输,而且希望能被其他服务调用因此json
格式输出会更好,下面我们看看如何实现?
1 |
# 实现langchain调用 ollama 大模型 |
上文我们可以看到用到JsonOutputParser
,它保证每次输出都是json格式,所以最终输出效果如下:
我们先看调用一个 LLM模型会产生哪些事件?
1 |
# 实现langchain调用 ollama 大模型 |
输出如下图:
返回event
数据结构如下:
event
事件类型,如:stream_start
、stream_end
、stream_chunk
等data
事件数据,如:stream_chunk
事件数据为chunk
,stream_end
事件数据为end
等run_id
本次调用id,当多次任务并发的时候可以找到对应任务metadata
事件元数据,包括模型版本、模型名称、模型参数等tags
、name
、parent_ids
等完整的事件类型我们可以到 LangChain官方文档去查看,地址为如何使用 Stream Events
通过本文我们完整了解 LangChain LCEL流式调用和工作原理,从而为后续使用LangChain进入实际开发提供基础知识。 LCEL主要包含以下内容:
stream
、astream
astream_events
JsonOutputParser
等声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-02-20 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
上一节学习了04篇 AI从零开始 - LangChain学习与实战(1) 基础知识,对Langchain有了基础的认知和简单应用,其中我们使用PromptTemplate
去实现一次大模型对话。
同时我们在03篇 AI从零开始 - Prompt提示语学习与应用也学习了提示语生成规范,但是在结合 LangChain中我们应该如何利用PromptTemplate
提示模板+提示语规范去降低 AI幻觉呢?
AI幻觉, 指人工智能(尤其是大语言模型)生成看似合理但实际错误、虚构或与现实不符的内容的现象。本质是模型在缺乏真实理解能力的情况下,基于统计模式生成的「自信错误」。
下面是 Langchain执行一次 LLM 调用的流程图:
提示词模板跟平时大家使用邮件模板、短信模板类型,本质上是一个字符串模板,模板里包含了模板参数,可以通过输入参数来生成最终的提示词。
一个提示词模板包括以下内容:
可以使用PromptTemplate
类来创建一个提示词模板,它接收一个prompt
参数,这个参数是一个字符串,用于指定提示词模板。
1 |
from langchain_core.prompts import ChatPromptTemplate |
这样子我们就可以得到一个正确的Message
了, 如上代码执行结果如下:
返回的内容如下说明:
LangChain还抽象了其他提示语模版,具体如下:
ChatPromptTemplate
对象,可以设定大模型角色和示例MessagesPlaceHolder
主要作用在特定位置添加消息列表(等于占位符), 可以集中管理消息列表,更好聊天过程注入上下文。
1 |
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder |
在之前03篇 AI从零开始 - Prompt提示语学习与应用中也提到过示例的重要性, 这里我们不在说示例对应大模型应用中的重要性了。
我们看看 在 LangChain中如何讲示例集 给到大模型中,其中FewShot
主要作用是给大模型提供示例,让大模型更好的理解用户输入,从而生成更符合用户预期的结果,从而降低 AI 幻觉。
这里可以理解成模型的微小型训练,让大模型能依据我们提供少量示例(有点类似小RAG知识库),从而更加更加准确的答案。
在 LangChain 创建一个示例集,如下:
1 |
from langchain.prompts.few_shot import FewShotPromptTemplate |
输出结果如下:
示例集合等同于一个知识库,在正式环境中我们不可能把完整的知识库都给到模型,因此我们需要去分析用户输入,从而选择合适的示例,LangChain 提供了ExampleSelector
类来帮助我们实现这个功能。
LangChain 提供了不同的ExampleSelector
,具体如下:
SemanticSimilarityExampleSelector
: 语义相似性示例选择, 会根据用户输入,然后通过嵌入模型计算输入与示例之间的相似性,然后使用向量数据库进行相似搜索,从示例集合中选择最相似的示例。MaxMarginalRelevanceExampleSelector
: 基于 最大边际相关性(MMR) 的示例选择器, 希望在从示例集中选择与输入 既相关又多样化 的示例, 通过平衡 相关性 与 多样性 来优化示例选择效果。通常情况下,我们使用SemanticSimilarityExampleSelector
, 根据上面示例集合,我们根据问题去选择示例,如下:
1 |
# ExapleSelector 示例筛选器 |
具体输出效果如下图:
本文我们完整学习了 LangChain 中如何使用 PromptTemplate去更好的创建一个提示语模板,从而降低 大模型的自我创新性(降低AI 幻觉)。
这里总结一下整个实现过程 约等于 后续 RAG知识库训练过程,如下图所示:
声明:本文部分材料是基于DeepSeek-R1模型生成。