LangChain的开发流程
文章目录
- LangChain的开发流程
- 开发密钥指南
- 3种使用密钥的方法
- 编写一个取名程序
- LangChain表达式
LangChain的开发流程
为了更深人地理解LangChain的开发流程,本文将以构建聊天机器人为实际案例进行详细演示。下图展示了一个设计聊天机器人的LLM应用程序。

除了Wb服务器等传统组件,这个应用程序架构中还引人了两个额外的组件:一个LLM集成中间件,如LangChain(图上的中间部分),以及一个大语言模型(上图左侧)。中间件提供一个API,业务逻辑控制器调用它以启用聊天机器人功能。具体的LLM是基于配置决定的。当用户提问时(步骤①),聊天机器人控制器代码调用LangChain API(通过LangChain的6大模块设置的接口),在内部与LLM(步骤②)交互,由LLM来理解问题并生成回答(步骤③),显示在终端用户的聊天界面上(上图右侧的Web页面)。
清单1展示了如何使用LangChain和OpenAI的GPT-3.5-Turbo-0613大语言模型实现聊天机器人业务逻辑。这段Python代码首先创建了ChatOpenAI类的实例(代表GPT-3.5聊天模型包装器)。第49行在路径chat’下建立了一个POST端点,可以利用FastAPI库。当用户向聊天机器人提交一个问题时,chat函数就会被触发,请求对象在其输人属性中封装用户的提问。为了处理请求,代码第7行实例化了一个LLMChain链组件,接收了一个聊天模型包装器Ilm和一个提示词模板prompt,实现了一个LangChain的内置预配置聊天机器人,可以与终端用户交互。第8行处理用户的提问:运行LLMChain链组件,接收用户的提问并将其作为输人,返回大语言模型生成的响应。这个响应持有对用户提问的答案,并在第9行代码执行后返回给用户。
llm = ChatOpenAI(#LLM initialization parameters
model_name=("gpt-3.5-turbo-0613",openai_api_key="你的密钥"',
temperature=0.9)
_prompt=""你是一个发言友好的AI助理。请现在回答用户的提问:《question}。""
@app.post ("/chat")#Chatbot controller URL endpoint
async def chat (request):prompt PromptTemplate.from template(prompt)chat_chain = LLMChain(llm=llm,prompt=prompt)response=chat_chain(request.input)#终端用户的提问字符串return {"response":response ["text"])
开发密钥指南
LangChain自身是一个集成框架,不需要开发者注册和登录,也不需要设置密钥。但是在LLM开发过程中,要使用第三方平台的模型或者工具,需要遵守第三方的开发者协议,而且几乎所有的付费平台都使用密钥作为API调用的计费依据,这一点不仅适用于LLM,还适用于其他各种API工具。这意味着,如果你没有相应平台的密钥,你将无法使用其服务,特别是当你依赖像OpenAI这样的第三方平台时,保护密钥的安全并确保其不被泄露是非常关键的。在本文中,代码示例中使用了3种密钥策略。本节将以OpenAI平台为例,详细说明如何获取和使用密钥。尽管各个平台可能有所不同,但其密钥获取和使用方法大致相似。你可以查看第三方平台的官方文档或教程,通常会提供详细的步骤和示例。
获取开发密钥在开始使用OpenAI的API之前,你需要先注册一个OpenAI账户并获取API密钥。以下是获取密钥的步骤:访问OpenAI官方网站,如果你还没有账户,请点击“注册”并按照提示完成注册过程;登录你的账户,跳转到“我的”“API Keys”部分,你可以看到你的API密钥,或通过一个“+”选项来生成新的密钥;复制密钥并将其保存在一个安全的地方,确保不要与他人分享或公开你的密钥。
3种使用密钥的方法
- 方法1:直接将密钥硬编码在代码中。这是最直接的方法,但也是最不安全的。直接在代码中提供密钥的示例如下所示:
# 硬编码传参方式
openai_api_key="填人你的密钥"
from langchain.llms import OpenAI
11m OpenAI(openai_api_key openai_api_key)
# 或者在引人os模块后硬编码设置os的环境变量,简单地使用11m=OpenAI()来初始化类
import os
os.environ["OPENAI API KEY"]="填人你的密钥"
llm =OpenAI()
注意:这种方法的缺点是,如果你的代码被公开或与他人分享,你的密钥也可能被泄露。由于本书案例主要用于解释,因此每个需要开发密钥的代码示例都采用这种“显眼”的方式。但是推荐开发者使用方法2或者方法3。方法1通常是为了简化和说明如何使用API密钥,在教程、文档或示例代码中向用户展示如何设置和使用密钥,并不是实际应用中推荐的做法。在实际的生产环境或项目中,直接在代码中硬编码密钥是不推荐的。
- 方法2:使用环境变量。这是一种更安全的方法,你可以在你的本地环境或服务器上设置环境变量,将密钥保存为环境变量,然后在代码中使用它。例如,在Liux或macOS系统上,你可以在命令行中执行:
export OPENAI API KEY="填人你的密钥"
。当你在Python代码中初始化OpenAI类时,不需要传递任何参数,因为LangChain框架会自动从环境中检测并使用这个密钥。你可以简单地使用Ilm=OpenAIO命令来初始化类,如下所示:
from langchain.llms import OpenAI
llm OpenAI()
这样,即使代码被公开,你的密钥也不会被泄露,因为它不是直接写在代码中的。
- 方法3:使用getpass模块。这是一种交互式的方法,允许用户在运行代码时输人密钥,你可以简单地使用llm=OpenAI()命令来初始化类,如下所示:
import os
import getpass
os.environ ['OPENAI API KEY']=getpass.getpass ('OpenAI API Key:')
from langchain.llms mport OpenAI
llm =OpenAI()
当你运行这段代码时,它会提示你输人OpenAI API密钥。这种方法的好处是,密钥不会被保存在代码或环境变量中,而是直接从用户那里获取。管理和使用密钥是一个重要的任务,需要确保密钥的安全。上述3种方法提供了不同的密钥使用方式,你可以根据自身需求和安全考虑选择合适的方法。无论选择哪种方法,都要确保不要公开或与他人分享你的密钥。
编写一个取名程序
在LLM应用开发领域,LangChain为开发者带来了前所未有的可能性。通过编写一个取名程序,你将对LangChain框架有一个初步的了解。安装和基础配置首先,为了能够顺利进行开发工作,需要确保计算机上安装了相应的Python包。开发者可以通过以下命令轻松完成安装:pip install openai langchain每一个与API交互的应用都需要一个API密钥。开发者可以创建一个账户并获取密钥,为了保障API密钥的安全,最佳实践是将其设置为环境变量:export OPENAI_API_KEY="你的API密钥”
但是,如果开发者不熟悉如何设置环境变量,也可以直接在初始化模型包装器OpenAI时传人密钥:
from langchain.llms import OpenAI
llm=OpenAI(openai_api_key="你的API密钥")
编写取名程序有了这些基础设置,接下来就可以利用LLM进行实际的编程工作了。想象一下,有一个程序可以基于用户的描述来为公司、产品或项目提供创意取名建议。比如,当输人“为一家生产多彩袜子的公司起一个好名字”时:
llm.predict("
What would be a good company name for a company that makes"
"colorful socks?"
)
Feetful of Fun这个名字听起来不错。如此,一个简洁的、能提供创意取名建议的程序就诞生了。
LangChain表达式
LangChain秉持的核心设计理念是“做一件事并把它做好”。这种设计理念强调,每一个工具或组件都应该致力于解决一个特定的问题,并能够与其他工具或组件集成。在LangChain中,这种设计理念的体现是,它的各个组件都是独立且模块化的。例如,通过使用管道操作符“”,开发者可以轻松地实现各个组件链的组合,开发者可以像说话一样编写代码,“直接”和“简洁”就是LangChain表达式的精髓所在。这种表达式不仅使得代码结构更为清晰,还让编程的方式更加接近自然语言的表达,为开发者提供了更为直观和顺滑的编程体验。
考虑到LangChain的目标是构建LLM应用,因此,开发者可以轻松地利用其提供的组件,如PromptTemplate、ChatOpenAI和OutputParser,为LLM应用创建自定义的处理链。例如,基于StrOutputParser,开发者可以轻松地将LLM或Chat Model输出的原始格式转换为更易于处理的字符串格式。以下代码示例展示了LangChain表达式的实际应用:
from langchain.prompts import ChatPromptTemplate
from langchain.chat models import ChatopenAI
from langchain.schema.output parser import StrOutputParser
# 实例化提示词模板和聊天模型包装器
prompt =ChatPromptTemplate.from template("tell me a joke about (topic)")
model=ChatopenAI(openai_api_key="你的API密钥")
# 定义处理链
chain =prompt I model I StrOutputParser (
response =chain.invoke ({"foo":"bears"))
print(response)
# 输出:"why don't bears wear shoes?\n\nBecause they have bear feet!"
此外,LangChain的另一个关键是流水线处理。在软件开发中,氵流水线处理是一种将多个处理步骤组合在一起的方法,其中每个步骤的输出都是下一个步骤的输人。这种设计不仅简化了LLM应用开发流程,还确保了输出的高效性和可靠性。开发者们在使用LangChain构建LLM应用时,不仅可以利用其组件化的设计优势,还可以确保应用具有较高的灵活性和可扩展性,这些都是现代LLM应用开发中的关键要素。注意,使用管道操作符进行链式调用(即prompt|model|StrOutputParser()需要新版本的LangChain仓库支持,开发者们请务必将LangChain升级到最新版本。
为了帮助开发者更好地理解和使用LangChain表达式,接下来的部分将详细介绍LangChain中的一些常见表达式。提示词模板+模型包装器,提示词模板与模型包装器的组合构成了最基础的链组件,通常用在大多数复杂的链中。复杂的链组件通常都包含提示词模板和模型包装器,这是与LLM交互的基础组件,可以说缺一不可。请看以下示例:
from langchain.prompts import ChatPromptTemplate
from langchain.chat models import ChatopenAI
# 实例化提示词模板和聊天模型包装器
prompt =ChatPromptTemplate.from template ("tell me a joke about (topic)")
model=ChatOpenAI(openai_api_key="你的API密钥")
# 定义处理链
chain =prompt I model
# 调用处理链
response =chain.invoke ({"foo":"bears"))
print (response)
# 输出:AIMessage(content='Why don\'t bears use cell phones?\n\n
Because they always get terrible "grizzly"reception!',
additional_kwargs=(),example=False)
为了获得更加可控和有针对性的输出,确保输出的文本符合期望和需求,经常要将additional kwargs传人模型包装器。在下面给出的代码示例中,chain=,prompt|model.bind(stop=["n"])
这行代码表示,当LLM生成文本并遇到换行符n时,应该停止进一步的文本生成:
chain =prompt I model.bind(stop=["\n"])
response= chain.invoke ({"foo":"bears"})
#response:AIMessage(content="Why don't bears use cell phones?",
additional kwargs=(},example=False)
bind方法同样支持OpenAI的函数回调功能,可以将函数描述列表绑定到模型包装器上:
functions ={{"name":"joke","description":"A joke","parameters":{"type":"object","properties":{"setup":{"type":"string","description":"The setup for the joke"},"punchline":{"type":"string","description":"The punchline for the joke"}},"required":["setup","punchline"]}}
}
chain =prompt I model.bind(function call={"name":"joke"),functions=
functions)
response =chain.invoke ({"foo":"bears"},config=())
# 输出response:AIMessage (content='',additional_kwargs=('function_call':
('name':joke','arguments':(\n "setup":"Why don\'t bears wear
shoes?",\n "punchline":"Because they have bear feet!"\n)')),
example=False)
提示词模板+模型包装器+输出解析器。可以在提示词模板与模型包装器的组合基础上,再增加一个输出解析器。示例如下:
from langchain.schema.output parser import StrOutputParser
chain= prompt I model I StrOutputParser()
response= chain.invoke ({"foo":"bears"),config=())
#response:"Why don't bears wear shoes?\n\nBecause they have bear feet!"
当定义一个要返回的函数时,你可能不希望进行额外的处理,而只希望直接对函数进行解析。为了满足这个需求,LangChain为OpenAI提供了一个专门的函数回调解析器,名为JsonOutputFunctionsParser。这意味着在LangChain…output_parsers下的所有内置输出解析器的类型都是可用的。此外,还可以根据自己的需要使用自定义的输出解析器:
from langchain.output_parsers.openai functions import JsonOutputFunctionsParser
chain =prompt I model.bind(function call=("name":"joke"),functions=functions)| JsonOutputFunctionsParser()
)
response chain.invoke ({"foo":"bears"))
#response:('setup':"Why don't bears wear shoes?",
'punchline':'Because they have bear feet!')
多功能组合链,首先定义两个提示词模板prompt1和prompt2,分别用来询问某人来自哪个城市,以及这个城市位于哪个国家。chain1是由promptl、model和StrOutputParser组成的链,目的是根据给定的人名返回此人来自哪个城市。chain2是更复杂的链。它首先使用chainl的结果(城市),然后结合itemgetter提取的language键值,生成输入prompt2的完整问题。这个问题随后会被传递给模型,并通过StrOutputParser解析:
from operator import itemgetter
prompt1 = ChatPromptTemplate.from_template("what is the city (person)is from?")
prompt2 = ChatPromptTemplate.from template"what country is the city (city}in?respond in (language)"
chain1 promptl I model I StroutputParser (
chain2 =
{"city":chainl,"language":itemgetter("language"))
I prompt2
| model
I StrOutputParser()
chain2.invoke (("person":"obama","language":"spanish"))
当调用chain2并传递{"person'":"obama","language":"spanish"}
作为输入时,整个流程将按顺序执行,并返回最终结果:
'El pais en el que nacio la ciudad de Honolulu,Hawai,donde nacio Barack
Obama,el 44 presidente de los Estados Unidos,es Estados Unidos.'
下面我们加大难度,创建一个更复杂的组合链。先定义4个提示词模板,涉及颜色、水果、某国家国旗颜色,以及水果和国家(国旗)的颜色对应关系。chain1是一个简单的链,根据promptl生成一个随机颜色。chain2是一个复杂的链,首先使用RunnableMap和chainl来获取一个随机颜色。接下来,这个颜色被用作两个并行链的输人,分别询问此颜色的水果有什么,以及哪个国家的国旗是这个颜色的。示例代码如下:
from langchain.schema.runnable import RunnableMap
prompt1 =ChatPromptTemplate.from template ("generate a random color")
prompt2 =ChatPromptTemplate.from template ("what is a fruit of color:(color)")
prompt3 =ChatPromptTemplate.from template ("what is countries flag that has the color:{color)")
prompt4 =ChatPromptTemplate.from template ("What is the color of (fruit}and{country)")
chainl prompt1 I model I StrOutputParser()
chain2 RunnableMap(steps=("color":chain1))("fruit":prompt2 I model I StroutputParser (),"country":prompt3 I model I StroutputParser(),}I prompt4
最后,这两个并行链的返回结果(一个水果和一个国家)被用作prompt44的输人,询问这个水果和这个国家的国旗是什么颜色的。
chain2.invoke ((}ChatPromptValue(messages=[HumanMessage(content="What is the color of Afruit that has a color similar to #7E7DE6 is the Peruvian Apple Cactus (Cereusrepandus).It is a tropical fruit with a vibrant purple or violet exterior.andThe country's flag that has the color #7E7DE6 is North Macedonia.",additional_kwargs=(},example=False)])
相关文章:

LangChain的开发流程
文章目录 LangChain的开发流程开发密钥指南3种使用密钥的方法编写一个取名程序 LangChain表达式 LangChain的开发流程 为了更深人地理解LangChain的开发流程,本文将以构建聊天机器人为实际案例进行详细演示。下图展示了一个设计聊天机器人的LLM应用程序。 除了Wb服务…...

AI在自动化测试中的伦理挑战
在软件测试领域,人工智能(AI)已经不再是遥不可及的未来技术,而是正在深刻影响着测试过程的现实力量。尤其是在自动化测试领域,AI通过加速测试脚本生成、自动化缺陷检测、测试数据生成等功能,极大提升了测试…...

《Origin画百图》之同心环图
《Origin画百图》第四集——同心环图 入门操作可查看合集中的《30秒,带你入门Origin》 具体操作: 1.数据准备:需要X和Y两列数据 2. 选择菜单 绘图 > 条形图,饼图,面积图: 同心圆弧图 3. 这是绘制的基础图形&…...
TPA注意力机制详解及代码复现
基本原理 在深入探讨TPA注意力机制的数学表达之前,我们需要先理解其基本原理。TPA注意力机制是一种创新的注意力机制,旨在解决传统注意力机制在处理大规模数据时面临的内存和计算效率问题。 TPA注意力机制的核心思想是利用 张量分解 来压缩注意力机制中的Q、K、V表示,同时…...
深入理解Java并发编程中的原子操作、volatile关键字与读写锁
1. 原子操作与AtomicInteger等原子类 1.1 原子操作的原理 在多线程环境中,多个线程可能会同时访问和修改共享资源。如果这些操作不是原子性的(即可以被中断),那么可能会导致数据不一致或竞态条件(race condition)。原子操作是指不可分割的操作,即在多线程环境下,这些…...

HTML(快速入门)
欢迎大家来到我的博客~欢迎大家对我的博客提出指导,有错误的地方会改进的哦~点击这里了解更多内容 目录 一、前言二、HTML基础2.1 什么是HTML?2.2 认识HTML标签2.2.1 HTML标签当中的基本结构2.2.2 标签层次结构 2.3 HTML常见标签2.3.1 标题标签2.3.2 段落标签2.3.3…...

SpringBoot Web开发(SpringMVC)
SpringBoot Web开发(SpringMVC) MVC 核心组件和调用流程 Spring MVC与许多其他Web框架一样,是围绕前端控制器模式设计的,其中中央 Servlet DispatcherServlet 做整体请求处理调度! . 除了DispatcherServletSpringMVC还会提供其他…...
汽车蓝牙钥匙定位仿真小程序
此需求来自于粉丝的真实需求,假期没事,牛刀小试。 一、项目背景 如今,智能车钥匙和移动端定位技术已经相当普及。为了探索蓝牙 Beacon 在短距离定位场景下的可行性,我们搭建了一个简易原型:利用 UniApp 在移动端采集蓝牙信标的 RSSI(信号强度),通过三边定位算法估算钥…...

K8S中高级存储之PV和PVC
高级存储 PV和PVC 由于kubernetes支持的存储系统有很多,要求客户全都掌握,显然不现实。为了能够屏蔽底层存储实现的细节,方便用户使用, kubernetes引入PV和PVC两种资源对象。 PV(Persistent Volume) PV是…...

【C语言进阶】- 动态内存管理
动态内存管理 1.1 为什么存在动态内存分配1.2 动态内存函数介绍2.1 malloc函数的使用2.2 free函数的使用2.3 calloc函数的使用2.4 realloc函数的使用3.1 常见的动态内存错误3.2 常见笔试题 1.1 为什么存在动态内存分配 我们已经掌握的内存开辟方式有: int val 20;…...
Python实现基于TD3(Twin Delayed Deep Deterministic Policy Gradient)算法来实时更新路径规划算法
下面是一个使用Python实现基于TD3(Twin Delayed Deep Deterministic Policy Gradient)算法来实时更新路径规划算法的三个参数(sigma0,rho0 和 theta)的示例代码。该算法将依据障碍物环境进行优化。 实现思路 环境定义…...
pytorch实现半监督学习
半监督学习(Semi-Supervised Learning,SSL)结合了有监督学习和无监督学习的特点,通常用于部分数据有标签、部分数据无标签的场景。其主要步骤如下: 1. 数据准备 有标签数据(Labeled Data)&…...
我的毕设之路:(2)系统类型的论文写法
一般先进行毕设的设计与实现,再在现成毕设基础上进行描述形成文档,那么论文也就成形了。 1 需求分析:毕业设计根据开题报告和要求进行需求分析和功能确定,区分贴合主题的主要功能和拓展功能能,删除偏离无关紧要的功能…...

LosslessScaling-学习版[steam价值30元的游戏无损放大/补帧工具]
LosslessScaling 链接:https://pan.xunlei.com/s/VOHc-yZBgwBOoqtdZAv114ZTA1?pwdxiih# 解压后运行"A-绿化-解压后运行我.cmd"...
concurrent.futures.Future对象详解:利用线程池与进程池实现异步操作
concurrent.futures.Future对象详解:利用线程池与进程池实现异步操作 一、前言二、使用线程池三、使用进程池四、注意事项五、结语 一、前言 在现代编程中,异步操作已成为提升程序性能和响应速度的关键手段。Python的concurrent.futures模块为此提供了强…...
StarRocks 安装部署
StarRocks 安装部署 StarRocks端口: 官方《配置检查》有服务端口详细描述: https://docs.starrocks.io/zh/docs/deployment/environment_configurations/ StarRocks架构:https://docs.starrocks.io/zh/docs/introduction/Architecture/ Sta…...

Python Matplotlib库:从入门到精通
Python Matplotlib库:从入门到精通 在数据分析和科学计算领域,可视化是一项至关重要的技能。Matplotlib作为Python中最流行的绘图库之一,为我们提供了强大的绘图功能。本文将带你从Matplotlib的基础开始,逐步掌握其高级用法&…...

线程概念、操作
一、背景知识 1、地址空间进一步理解 在父子进程对同一变量进行修改时发生写时拷贝,这时候拷贝的基本单位是4KB,会将该变量所在的页框全拷贝一份,这是因为修改该变量很有可能会修改其周围的变量(局部性原理)…...
【PySide6拓展】QSoundEffect
文章目录 【PySide6拓展】QSoundEffect 音效播放类**基本概念****什么是 QSoundEffect?****QSoundEffect 的特点****安装 PySide6** **如何使用 QSoundEffect?****1. 播放音效****示例代码:播放音效** **代码解析****QSoundEffect 的高级用法…...
33【脚本解析语言】
脚本语言也叫解析语言 脚本一词,相信很多人都听过,那么什么是脚本语言,我们在开发时有一个调试功能,但是发布版是需要编译执行的,体积比较大,同时这使得我们每次更新都需要重新编译,客户再…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...