当前位置: 首页 > news >正文

【AIGC】OpenAI 集成 Langchain 操作实战使用详解

目录

一、前言

二、前置准备

2.1 安装 Langchain必须的依赖

2.1.1 python环境

2.1.2 langchain openai 环境

2.1.3 准备一个apikey

2.1.4 langchain 核心组件

三、Langchain 各组件使用

3.1 Chat models组件

3.1.1 Invocation 使用

3.1.1.1 结果解析

3.2 提示词模板

3.2.1 什么是提示词模板

3.2.2 创建提示词模板

3.2.2.1 PromptTemplate 简单提示词模板

3.2.2.2 ChatPromptTemplate 聊天提示词模板

3.2.2.3 MessagePlaceholer 聊天提示词模板

3.2.2.4 少样本提示词模板

3.2.2.5 示例选择器

3.3 memory组件

3.3.1 ChatMessageHistory 案例代码

3.3.2 流式输出案例代码

3.4 向量数据库与文档检索

3.4.1 安装向量数据库

3.4.2 代码操作示例

3.4.3 组合大模型组件使用

四、写在文末


一、前言

OpenAI作为人工智能领域的先锋,其提供的API为开发者打开了构建智能应用的大门。而作为LLM领域的佼佼者Langchain,随着RAG在众多的领域进行落地实践,Langchanin的热度也越来越高,然而,想要在实际项目中有效利用Langchanin提供的各种能力,了解如何使用Langchain进行集成是非常重要的。本文将详细介绍如何使用OpenAI集成Langchain,并使用Langchain的各种核心组件能力。

二、前置准备

在正式开始使用Langchain之前,你需要在本地准备基础的开发和运行环境,比如python环境、Langchain组件等,参考下面的操作步骤即可。

2.1 安装 Langchain必须的依赖

2.1.1 python环境

建议版本 3.10

2.1.2 langchain openai 环境

使用下面的命令进行安装

pip install langchain openai

2.1.3 准备一个apikey

后面程序中调用API时候需要用到

2.1.4 langchain 核心组件

langchain 官网地址如下:ChatOpenAI | 🦜️🔗 LangChain

可以基于此文档查看langchain提供的各个组件以及API

三、Langchain 各组件使用

接下来将通过实际案例展示Langchain 各组件的详细使用

3.1 Chat models组件

文档地址:Chat models | 🦜️🔗 LangChain,官方展示了可以对接LangChain的多种大模型,这里选择ChatOpenAi;

执行下面命令安装依赖组件

pip install -qU langchain-openai

3.1.1 Invocation 使用

参考官方提供案例

然后编写自己的代码,如下:


#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate#langchain的openai的sdk
from langchain_openai import ChatOpenAIllm = ChatOpenAI(# 此处需要填入openai的key,可以直接填入,但建议最好可以配置到本地环境变量中api_key ='sk-...'
)messages = [("system","You are a helpful assistant that translates English to Chinese. Translate the user sentence.",),("human", "I love programming."),
]
ai_msg = llm.invoke(messages)
print(ai_msg)

运行上面的代码,可以看到目标的英文被翻译成了中文

或者使用下面的这种写法也是可以的

#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage#langchain的openai的sdk
from langchain_openai import ChatOpenAI#llm=ChatOpenAI()model = ChatOpenAI(# 此处需要填入openai的key,可以直接填入,但建议最好可以配置到本地环境变量中api_key ='sk-...'
)msg=[SystemMessage(content="请将下面的内容翻译成英语."), HumanMessage(content="你好,请问你要去哪里")
]res = model.invoke(msg)
print(res)

3.1.1.1 结果解析

如果上面的输出结果看起来不够直观,langchain的包里面还提供了内容解析的工具,只需要导入StrOutputParser包即可

#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate#langchain的openai的sdk
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser#llm=ChatOpenAI()llm = ChatOpenAI(# 此处需要填入openai的key,可以直接填入,但建议最好可以配置到本地环境变量中api_key ='sk-...'
)prompt=ChatPromptTemplate.from_messages([("system","您是世界级的技术专家."),("user","{input}"),
])#通过langcian的链式调用,生成一个提示词的chain
chain=prompt | llmresult=chain.invoke({"input":"帮我写一篇AI的技术文章,100字以内"})print(result)parser = StrOutputParser()
parser_str = parser.invoke(result)
print(parser_str)

再次运行上面的程序,此时得到的就是纯粹的内容了

3.2 提示词模板

3.2.1 什么是提示词模板

语言模型以文本作为输入,这个文本通常被称为提示词,在开发过程中,对于提示词来说不能直接硬编码,这样不利于提示词管理,而是通过提示词模板进行维护,类似于开发过程中遇到的短信模板,邮件模板等。

提示词模板是一种特殊的文本,它 可以为特定任务提供额外的上下文信息。 在LLM 应 用中,用户输入通常不直接被传递给模型本身, 而是被添加到一个更大的文本,即提示词模板中。提示词模板为当前的具体任务提供了额外的上下文信息,这能够更好地引导模型生成预期的输出。

一个提示词模板通常包含如下内容:

  • 发给大语言模型(LLM)指令;

  • 一组问答示例,以告诉AI以什么格式返回请求;

  • 发给大语言模型的问题;

3.2.2 创建提示词模板

在LangChain中,最简单的,可以使用PromptTemplate类创建简单的提示词模板。在提示词模板可以内嵌任意数量的模板参数,然后通过参数值格式化模板内容。

也可以使用MessagePromptTemplate来创建提示词模板。可以用一个或多MessagePromptTemplate创建一个ChatPromptTemplate

如下示例

from langchain.prompts.chat import(ChatPromptTemplate,SystemMessagePromptTemplate,HumanMessagePromptTemplate,
)template =
("You are a helpful assistant that translates [input_languagel to""(output_language}."
)system_message_prompt=SystemMessagePromptTemplate.from_template(template)human_template ="(text}"human_message_promptHumanMessagePromptTemplate.from_template(human_template)chat_prompt =ChatPromptTemplate.from_messages([system_message_prompt,human_message_promptchat_prompt.format_messages(input_language="English",output_language="French",text="I love programming."

上述代码首先定义了两个模板:

  • 一个是系统消息模板,描述了任务的上下文(翻译助手的角色和翻译任务);

  • 另一个是人类消息模板,其中的内容是用户的输入。然后,使用ChatPromptTemplate的from_messages方法将这两个模板结合起来,生成一个聊天提示词模板。

  • 当想要检查发送给模型的提示词是否确实与预期的提示词相符时,可以调用ChatPromptTemplate的format_messages方法,查看该提示词模板的最终呈现

msg=[SystemMessage(content="请将下面的内容翻译成英语."), HumanMessage(content="你好,请问你要去哪里")
]

通过这种方式,不仅可以让聊天模型包装器生成预期的输出,对开发者来说,也不用担心是否符合提示词消息列表的数据格式,只需要提供具体的任务描述即可。

3.2.2.1 PromptTemplate 简单提示词模板

这是最简单的一种提示词模板,调用PromptTemplate的from_template方法,在模板内容中预留占位符作为后续的输入参数即可

#langchain聊天的提示词模板
from langchain_core.prompts import PromptTemplateprompt_template = PromptTemplate.from_template("给我讲一个关于{topic}的历史故事")result = prompt_template.format(topic="足球")print(result)

运行一下,可以看到下面的效果,可以看到调用format方法的时候,最终“足球”就作为入参带入到模板中输出了

3.2.2.2 ChatPromptTemplate 聊天提示词模板

如下是一段基本的提示词模板代码案例,设置了两个模板参数,调用的时候动态传入

#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate#数组的每一个元素代表一个消息,每个消息元组,第一个参数代表消息角色,第二个参数代表消息内容
#消息角色:system代表系统消息,human代表人类消息,ai代表LLM返回的消息内容
#消息定义了2个模板参数name和user_input
chat_template = ChatPromptTemplate.from_messages([("system","你是一个人工智能助手,你的名字是{name}"),("human","你好"),("ai","我很好"),("human","{user_input}")]
)#通过模板参数格式化模板内容
result = chat_template.format_messages(name="小明",user_input="你叫什么名")
print(result)

运行一下看到如下的效果输出

补充:

  • ChatPromptTemplate 用于聊天对话的场景中;

  • 后续接入大模型之后,就可以将参数拼接模板一起传给大模型,大模型就可以返回预期的结果了

ChatPromptTemplate 即聊天模型(Chat Model)提示词模板,聊天模型以聊天消息列表作为输入,这个聊天消息列表的消息内容也可以通过提示词模板进行管理,这些聊天消息与原始的字符串不同,因为每个消息都与“角色(Role)”相关联。

例如在OpenAI的Chat Completion API中,OpenAI的聊天模型,给不同聊天消息定义了三种角色类型,分别是:助手(Assistant),人类(Human),或系统(System)角色:

  • 助手(Assistant)消息指的是当前消息是AI回答的内容;

  • 人类(Human)消息值得是你发给AI的内容;

  • 系统(System)消息通常是用来给AI身份进行描述;

示例代码

参考下面的案例代码,结合代码中的注释进行理解,在提示词模板中,我们传入了两个变量,后续在调用的时候,只需要给这两个变量赋值即可

#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.output_parsers import StrOutputParser#langchain的openai的sdk
from langchain_openai import ChatOpenAImodel = ChatOpenAI(# 此处需要填入openai的key,可以直接填入,但建议最好可以配置到本地环境变量中api_key ='sk-...'
)#定义模板
prompt_template=ChatPromptTemplate.from_messages([("system","您是世界级的翻译专家,使用{language}语言翻译如下内容"),("user","{input}"),
])#内容输出解析器
output_parser=StrOutputParser()#得到一个链
chain = prompt_template | model | output_parser#输出结果
result = chain.invoke({'language':'中文','input':'hello world'})
print(result)

或者使用下面的这种写法

  • SystemMessage,对应着上面一种写法中的 'system',由langchain自身API提供

  • HumanMessage,对应着上面一种写法中的 'user',由langchain自身API提供

#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage#langchain的openai的sdk
from langchain_openai import ChatOpenAI#llm=ChatOpenAI()model = ChatOpenAI(# 此处需要填入openai的key,可以直接填入,但建议最好可以配置到本地环境变量中api_key ='sk-...'
)msg=[SystemMessage(content="请将下面的内容翻译成英语."), HumanMessage(content="你好,请问你要去哪里")
]res = model.invoke(msg)
print(res)
3.2.2.3 MessagePlaceholer 聊天提示词模板

这个提示词模板负责在特定的位置添加消息列表,在上面的ChatPromptTemplate中,我们看到了如何格式化两条消息,每条消息都是一个字符串。但是如果我们希望用户传入一个消息列表,并将其插入到特定的位置该怎么办呢?这就需要使用到MessagePlaceholer 的方式。如下示例代码:

#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholderfrom langchain_core.messages import SystemMessage, HumanMessageprompt_template = ChatPromptTemplate.from_messages([('system', 'You are a helpful assistant '),#这里可以传入一组消息MessagesPlaceholder('msgs')
])result = prompt_template.invoke({"msgs":[HumanMessage(content="你好")]})
print(result)

通过上面的运行结果不难看出,结果生成了2条消息,第一条是系统消息,第二条是我们传入的HumanMessage,如果我们传入了5条消息,那么一共会生成6条消息(系统消息加上传入的5条),这对于将一系列消息插入到特定的位置非常有用。

还有一种实现相同效果的的替代方法是,不直接使用MessagesPlaceholder,而是下面这种:

#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholderfrom langchain_core.messages import SystemMessage, HumanMessageprompt_template = ChatPromptTemplate.from_messages([('system', 'You are a helpful assistant '),#这里可以传入一组消息# MessagesPlaceholder('msgs')('placeholder','{msgs}')
])result = prompt_template.invoke({"msgs":[HumanMessage(content="你好")]})
print(result)

效果是一样的

3.2.2.4 少样本提示词模板

即Few-shot prompt template , 这种提示词模板中包含了少量的样本信息,这样做的目的是为了帮助模型更好的理解用户的意图,从而更好的回答问题或执行任务,少样本提示词模板是指使用一组少量的示例来指导模型处理新的输入。使用这些提示词可以用来训练模型,以便模型可以更好的理解或回答类似的问题。

Q:钢铁侠是谁?
A:钢铁侠是漫威中的一个英雄人物。Q:什么是AI大模型?
A:...

告诉模型,Q是问题,A是答案,按照这种格式进行交互问答。后续大模型在回答问题的时候,就会参考你提供给它的示例,一定程度上可以避免大模型回答时产生的幻觉问题。

#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate,PromptTemplate
from langchain_core.prompts.few_shot import FewShotPromptTemplatefrom langchain_core.messages import SystemMessage, HumanMessageexamples = [{"question":"什么是人工智能?","answer":"人工智能(Artificial Intelligence)是指通过计算机模拟、扩展或扩展人的智能来构建智能系统的技术。"},{"question":"钢铁侠在漫威电影中一共出现了几次变身","answer":"钢铁侠在漫威电影中一共出现了3次变身,分别是钢铁侠、浩克和美队。"},{"question":"詹姆斯一共打了多少赛季的篮球了?","answer":"詹姆斯一共打了5个赛季的篮球,包括2003-2004赛季,2004-2005赛季,2005-2006赛季,2006-2007赛季,2007-2008赛季。"}
]example_prompt = PromptTemplate(input_variables=["question","answer"],template="问题:{question}\n答案:{answer}"
)#接收examples示例数组参数,通过example_prompt提示词模板批量渲染示例内容
#suffix和input_variables参数用于在提示词模板最后追加内容,input_variables用于定义suffix中包含的模板参数
prompt = FewShotPromptTemplate(examples=examples,example_prompt=example_prompt,suffix="问题:{input}",input_variables=["input"]
)print(prompt.format(input="詹姆斯在哪些赛季中出现过?"))

如下是一个使用openai调用的少样本案例代码

from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_openai import ChatOpenAI
import os# 设置OpenAI API密钥# 创建示例格式化器
example_prompt = PromptTemplate.from_template("Question: {question}\n{answer}")# 准备示例集
examples = [{"question": "1+1等于几?", "answer": "答案是2"},{"question": "地球是什么形状?", "answer": "地球近似于一个球体"},
]# 创建Few-Shot提示模板
prompt = FewShotPromptTemplate(examples=examples,example_prompt=example_prompt,suffix="Question: {input}",input_variables=["input"],
)# 创建OpenAI模型实例
llm = ChatOpenAI(# 此处需要填入openai的key,可以直接填入,但建议最好可以配置到本地环境变量中api_key ='sk-...'
)# 生成提示并获取回答
user_question = "太阳系中最大的行星是哪个?"
full_prompt = prompt.invoke({"input": user_question}).to_string()
response = llm.invoke(full_prompt)print(f"问题: {user_question}")
print(f"回答: {response}")

运行一下可以看到下面的结果

3.2.2.5 示例选择器

LangChain提供示例选择器来提高效率,避免一次性发送所有示例给模型,同时减少使用的Token数量。如果有大量示例,可能需要选择要包含在提示中的示例,示例选择器是负责执行此操作的类。

LangChain有几种不同类型的示例选择器

名称

描述

SemanticSimilarityExampleSelector

使用输入和示例之间的语义相似性来决定选择哪些示例。

MaxMarginalRelevanceExampleSelector

使用输入和示例之间的最大边际相关性来决定选择哪些示例。

LengthBasedExampleSelector

根据一定长度内可以容纳的数量来选择示例

NGramOverlapExampleSelector

使用输入和示例之间的 ngram 重叠来决定选择哪些示例。

在下面的案例中,我们使用SemanticSimilarityExampleSelector类,该类根据输入的相似性选择小样本示例,它使用嵌入模型计算输入和小样本之间的相似性,然后使用向量数据库执行相似性搜索,获取输入相似的示例。

  • 这里涉及向量计算、向量数据库,在AI领域这两个主要用于数据库相似度搜索,例如,查询相似文章内容,相似图片、视频等

先安装下面的向量数据库

pip install chromadb

完整的代码如下

from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain_community.vectorstores import Chromafrom langchain_openai import OpenAIEmbeddingsexamples = [{"question":"什么是人工智能?","answer":"人工智能(Artificial Intelligence)是指通过计算机模拟、扩展或扩展人的智能来构建智能系统的技术。"},{"question":"钢铁侠在漫威电影中一共出现了几次变身","answer":"钢铁侠在漫威电影中一共出现了3次变身,分别是钢铁侠、浩克和美队。"},{"question":"詹姆斯一共打了多少赛季的篮球了?","answer":"詹姆斯一共打了5个赛季的篮球,包括2003-2004赛季,2004-2005赛季,2005-2006赛季,2006-2007赛季,2007-2008赛季。"}
]# 初始化示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(#提供可选择的示例列表examples,#用于生成嵌入的嵌入类,该嵌入用于衡量语义的相似性OpenAIEmbeddings(api_key='sk-...'),#用于存储嵌入和执行相似度搜索的VectorStore类Chroma,#用于生成的示例数k=1
)question = "詹姆斯在哪些赛季打过篮球?"result_examples = example_selector.select_examples({"question":question})for example in result_examples:print("\\n")for key, value in example.items():print(f"{key}: {value}")

运行一下上述代码,在输出的结果中可以看到参考了我们给定的示例样本,选择了最接近的问题的答案

3.3 memory组件

在多轮对话中,为了使大模型能够记住上下文对话,可以考虑使用这个memory组件,提前安装依赖包

pip install langchain_community

该模块中提供了ChatHistory,它允许聊天机器人记住过去的互动,并在后续的回答问题时考虑它们;

3.3.1 ChatMessageHistory 案例代码

参考如下代码


from langchain_community.chat_message_histories import ChatMessageHistory#langchain聊天的提示词模板
from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholder
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.runnables import RunnableWithMessageHistory#langchain的openai的sdk
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser#创建模型
model = ChatOpenAI(# 此处需要填入openai的key,可以直接填入,但建议最好可以配置到本地环境变量中api_key ='sk-...'
)msg=[SystemMessage(content="请将下面的内容翻译成英语."), HumanMessage(content="你好,请问你要去哪里")
]parser=StrOutputParser()#定义提示词模板
prompt_template = ChatPromptTemplate = ChatPromptTemplate.from_messages([('system','你是一个乐于助人的助手,请用{language}尽你所能回答所有问题'),MessagesPlaceholder(variable_name="my_msg")])chain = prompt_template | model#保存聊天的历史记录
store={}#定义一个获取session_id的函数,返回一共消息的历史对象
def get_history(session_id: str):if session_id not in store:store[session_id] = ChatMessageHistory()return store[session_id]do_msg = RunnableWithMessageHistory(chain,get_history,input_messages_key='my_msg' #每次聊天发送消息的key
)#给当前会话添加一个session
config={'configurable':{'session_id':'xm113'}}#第一轮对话
result_1 = do_msg.invoke({"my_msg": [HumanMessage(content="你好,我是小明")],"language": "中文"},config=config
)print(result_1.content)#第二轮对话
result_2 = do_msg.invoke({"my_msg": [HumanMessage(content="请问我的名字是什么")],"language": "中文"},config=config
)
print(result_2.content)

运行上面的代码,通过控制台的输出结果不难看出,大模型在回答我们的第二个问题的时候,由于使用了ChatMessageHistory,在第一次的对话中,记住了第一轮对话的内容,所以第二轮对话中可以正确的输出答案

3.3.2 流式输出案例代码

流式输出是一种允许数据在生成的同时逐步传输的技术,而无需等待整个过程完成

流式输出技术使得数据可以实时地、逐步地传输,而不是等待所有数据生成完毕后再一次性传输。这种技术特别适用于处理大型语言模型(LLM)和聊天模型的输出,因为这些模型的运行时间通常较长,且输出数据量可能很大。通过流式输出,用户可以在数据生成的过程中就接收到部分结果,从而提高效率和用户体验。

基于上一个案例中的2轮对话,我们再加一轮对话,此时采用流式输出的方式,只需要调整下调用的api即可,如下:

#第三轮对话,此时返回的数据是流式的
for resp in do_msg.stream({"my_msg": [HumanMessage(content="给我讲一个笑话")],"language": "中文"},config=config
): print(resp.content)

运行上面的代码,观察输出效果,可以看到结果是一个一个字输出的

3.4 向量数据库与文档检索

向量数据库是实现文档检索的基础必要实现组件,类似与我们在学习es的时候,为了能从es中搜索出相似度最高的文档,es需要先将原始存入的数据进行分词之后再存储。

langchain构建的向量数据库与文档检索也是如此,不过文档存储是放在向量数据库中,即文档存储之前需要先进行向量化,而后才能进行搜索。

支持从向量数据库或其他数据源检索数据,以便与LLM(大语言模型)的工作流集成,这对于应用程序来说非常重要,这些应用程序需要获取数据以作为模型推理的一部分进行推理,就像检索增强生成(RAG)的情况类似。

3.4.1 安装向量数据库

向量数据库的可选组件有很多种,这里选用chroma,执行下面的命令安装

pip install langchain-chroma

3.4.2 代码操作示例

完整的操作步骤:

  • 初始化文档;

  • 文档存入向量数据库,进行文档向量化;

  • 使用检索器进行文档检索;

参考下面的完整代码


from langchain_community.chat_message_histories import ChatMessageHistoryfrom langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAIfrom langchain_core.documents import Document
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddingsimport osos.environ["OPENAI_API_KEY"] = 'sk-...'#提供测试数据,作为向量数据库数据的来源
documents = [Document(page_content="狗是人类的好朋友,以忠诚和友好而文明",metadata={"source": "哺乳动物手册"},),Document(page_content="猫是比较独立的宠物,喜欢有自己独立的空间,但是可以为人类提供一定的陪伴和情绪价值",metadata={"source": "哺乳动物手册"},),Document(page_content="兔子是一种乖巧而偏静的动物,既可以作为宠物,也可以作为家养动物",metadata={"source": "静态宠物手册"},),Document(page_content="老虎是一个非常凶猛的动物,但是在非洲可以作为宠物,一般是捕食性动物",metadata={"source": "大型动物手册"},),Document(page_content="长颈鹿是一种非常呆萌可爱的动物,一般在动物园才能看到",metadata={"source": "大型动物手册"}),
]#实例化向量空间
vector_store = Chroma.from_documents(documents, embedding = OpenAIEmbeddings())#相似度查询,返回相似度分数,分数越低,相似度越高
result = vector_store.similarity_search_with_score("东北虎")
print(result)

运行上述的代码,通过控制台的结果输出不难发现,由于本次检索的关键字里面包含“虎“,在原始的文档中,与虎相关的文档有一个,所以最终检索的结果中,将包含老虎的那一条放在最前面,而且分数最低,这也就符合我们的预期

当然,也可以使用检索器来做,即RunnableLambda这个对象,如下:

#实例化向量空间
vector_store = Chroma.from_documents(documents, embedding = OpenAIEmbeddings())#相似度查询,返回相似度分数,分数越低,相似度越高
# result = vector_store.similarity_search_with_score("东北虎")
# print(result)#检索器,k=1,选取相似度最高的第一个返回
retriever = RunnableLambda(vector_store.similarity_search_with_score).bind(k=1)target_doc = retriever.batch(['华南虎','橘猫'])
print(target_doc)

再次运行上面的代码,此时返回了符合条件的两个文档

3.4.3 组合大模型组件使用

事实上,在实际使用中可能会结合大模型一起使用,比如在下面的代码中,结合大模型与向量数据库一起使用,同时问题通过参数的方式传入,这样更为灵活一点


from langchain_community.chat_message_histories import ChatMessageHistoryfrom langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAIfrom langchain_core.documents import Document
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddingsfrom langchain_core.runnables import RunnableLambda,RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholderimport osos.environ["OPENAI_API_KEY"] = 'sk...'#创建模型
model = ChatOpenAI(# 此处需要填入openai的key,可以直接填入,但建议最好可以配置到本地环境变量中api_key ='sk...'
)msg=[SystemMessage(content="请将下面的内容翻译成英语."), HumanMessage(content="你好,请问你要去哪里")
]#提供测试数据,作为向量数据库数据的来源
documents = [Document(page_content="狗是人类的好朋友,以忠诚和友好而文明",metadata={"source": "哺乳动物手册"},),Document(page_content="猫是比较独立的宠物,喜欢有自己独立的空间,但是可以为人类提供一定的陪伴和情绪价值",metadata={"source": "哺乳动物手册"},),Document(page_content="兔子是一种乖巧而偏静的动物,既可以作为宠物,也可以作为家养动物",metadata={"source": "静态宠物手册"},),Document(page_content="老虎是一个非常凶猛的动物,但是在非洲可以作为宠物,一般是捕食性动物",metadata={"source": "大型动物手册"},),Document(page_content="长颈鹿是一种非常呆萌可爱的动物,一般在动物园才能看到",metadata={"source": "大型动物手册"}),
]#实例化向量空间
vector_store = Chroma.from_documents(documents, embedding = OpenAIEmbeddings())#相似度查询,返回相似度分数,分数越低,相似度越高
# result = vector_store.similarity_search_with_score("东北虎")
# print(result)#检索器,k=1,选取相似度最高的第一个返回
retriever = RunnableLambda(vector_store.similarity_search_with_score).bind(k=1)#增加提示词模板
message="""使用提供的上下文回答这个问题:{question}上下文:{context}
"""prompt_template = ChatPromptTemplate.from_messages([('human',message)
])#动态传递问题,允许用户的问题之后传递给prompt和model
chain = {'question':RunnablePassthrough(),'context':retriever} | prompt_template | modelresp = chain.invoke("请谈谈老虎")print(resp)

从输出结果不难看出,最终的回答参考了本地向量数据库的答案

四、写在文末

本文通过案例详细介绍了OpenAI 集成 Langchain 的使用,并针对Langchain的核心组件以代码的方式进行了操作演示,希望对看到的同学有用哦,本篇到此结束,感谢观看。

相关文章:

【AIGC】OpenAI 集成 Langchain 操作实战使用详解

目录 一、前言 二、前置准备 2.1 安装 Langchain必须的依赖 2.1.1 python环境 2.1.2 langchain openai 环境 2.1.3 准备一个apikey 2.1.4 langchain 核心组件 三、Langchain 各组件使用 3.1 Chat models组件 3.1.1 Invocation 使用 3.1.1.1 结果解析 3.2 提示词模板…...

热key探测技术架构设计与实践

参考: 得物热点探测技术架构设计与实践 Redis数据倾斜与JD开源hotkey源码分析揭秘 京东热点检测 HotKey 学习笔记 hotkey: 京东App后台中间件,毫秒级探测热点数据,毫秒级推送至服务器集群内存,大幅降低热key对数据层查询压力 …...

【最新】 ubuntu24安装 1panel 保姆级教程

系统:ubuntu24.04.1 安装软件 :1panel 第一步:更新系统 sudo apt update sudo apt upgrade 如下图 第二步:安装1panel,运行如下命令 curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o …...

微信小程序threejs三维开发

微信小程序threejs开发 import * as THREE from three; const { performance, document, window, HTMLCanvasElement, requestAnimationFrame, cancelAnimationFrame, core, Event, Event0 } THREE .DHTML import Stats from three/examples/jsm/libs/stats.module.js; im…...

Starship:快速且高度可定制的命令行框架!!

Starship 是一款专为开发者设计的现代、快速且高度可定制的命令行框架。它通过简洁的界面提供丰富的环境信息,帮助用户更高效地进行日常开发工作。 软件介绍: Starship 是用 Rust 编写的开源项目,以其轻量级和极速启动而著称。它能够跨平台运…...

流水线(Pipeline)

在现代 CPU 设计中,流水线(Pipeline) 是将指令处理拆分为多个阶段以提高执行效率的关键技术。为了更精细地分析性能,流水线通常被分为 前端流水线(Frontend Pipeline) 和 后端流水线(Backend Pi…...

Symbian(塞班)操作系统

Symbian(塞班)是由多家通信巨头联合开发的专为移动设备设计的操作系统,曾是全球智能手机市场的早期主导者。以下是其核心定义与技术特点的整合分析: ​一、定义与起源 ​系统定位 Symbian是由英国Psion公司的EPOC操作系统演变而来…...

CSS -属性值的计算过程

目录 一、抛出两个问题1.如果我们学过优先级关系,那么请思考如下样式为何会生效2.如果我们学习过继承,那么可以知道color是可以被子元素继承使用的,那么请思考下述情景为何不生效 二、属性值计算过程1.确定声明值2.层叠冲突3.使用继承4.使用默…...

施磊老师c++(七)

STL组件 文章目录 STL组件1.整体学习内容2.vector容器3.deque和listdeque--双端队列容器list--链表容器 4.vector,deque,list对比主要内容面经问题 5.详解容器适配器--stack, queue, priority_queue容器适配器stack-栈queue-队列priority_queue-优先级队列总结 6.无序关联容器关…...

Codeforces 158B. Taxi

题目 题目链接:https://codeforces.com/problemset/problem/158/B time limit per test:3 seconds;memory limit per test:256 megabytes After the lessons n groups of schoolchildren went outside and decided to visit Polycarpus to celebrate his birthda…...

hadoop伪分布式搭建--启动过程中如果发现某个datanode出现问题,如何处理?

一、问题定位&#xff1a; &#xff08;1&#xff09;检查DataNode日志&#xff1a; DataNode日志通常位于$HADOOP_HOME/logs/或/var/log/hadoop-hdfs/目录下&#xff0c;文件名为hadoop-hdfs-datanode-<hostname>.log。重点关注以下错误类型&#xff1a; ——Incompa…...

MySQL(事物上)

目录 示例&#xff1a; 一 引入事物 1. 概念 2. 事物的4大特性 3. 为什么要有事物&#xff1f; 二 事物操作 1. 查看存储引擎支持的事物 2. 事物的提交方式 2.1 查看事物的默认提交方式 2.2 设置事物的默认提交方式 2.3 查看事物的全局隔离级别 2.4 验证事物的回滚…...

人工智能 Day06 pandas库进阶

1.处理缺失数据 总体流程是这样的&#xff0c; 归根在于如何处理NAN&#xff0c;接下来详细赘述 1.1. 处理缺失值的相关函数 判断缺失值 pd.isnull(df)&#xff1a;用于判断 DataFrame df 中的元素是否为缺失值&#xff08;NaN &#xff09;&#xff0c;返回一个与df 形状相同…...

C# --- LINQ

C# --- LINQ 什么是LINQFluent Syntax 和 SQL-Like QueryLINQ Operations 什么是LINQ LINQ的全称为Language Integrated Query, 为各种查询(包括对象查询&#xff0c;数据库查询&#xff0c;XML查询) 提供了统一模型.LINQ源于SQL&#xff0c;但比SQL更加强大&#xff0c;更加灵…...

C语言之 条件编译和预处理指令

条件编译 在编译⼀个程序的时候我们如果要将⼀条语句&#xff08;⼀组语句&#xff09;编译或者放弃是很⽅便的。因为我们有条件编译指令。 ⽐如说&#xff1a; 调试性的代码删除可惜&#xff0c;保留⼜碍事&#xff0c;所以我们可以选择性的编译。 #define M 1 int main() …...

JVM常用概念之锁省略

问题 synchronized(同步-重量级锁)会解除所有编译器优化吗? 基础知识 使用当前的 Java 内存模型&#xff0c;未观察到的锁不一定会产生任何内存效应。除其他情况外&#xff0c;这意味着对非共享对象进行同步是徒劳的&#xff0c;因此运行时不必在那里做任何事情。这给编译优…...

[网络][tcp协议]:tcp报头

tcp(传输控制协议)是一种面向字节流的传输层协议,相较于udp协议,tcp能保证传输数据的可靠性与准确性,tcp也是目前最常见的传输层协议 本文主要介绍tcp报头各个字段的含义与用途 注:保留6位和6位标记位是目前最普遍的写法,在我查资料时,发现有一些拓展情况,会在后文细说 最简单的…...

传输层自学

传输实体&#xff1a;完成传输层任务的硬件或软件 可能位于&#xff1a; 操作系统内核独立的用户进程绑定在网络应用中的链接库网络接口卡 1.功能&#xff1a; 网络层与传输层作用范围比较&#xff1f; 网络层负责把数据从源机送达到目的机 传输层负责把数据送达到具体的应…...

FFmpeg —— 各系统下ffmpeg硬件加速和API支持情况(文内表格形式详细阐述)

介绍 FFmpeg 作为一款功能强大的多媒体处理工具,支持多种硬件加速技术,能够显著提升视频编解码的效率,尤其是在处理高分辨率、高码率视频时表现尤为突出。不同操作系统下,FFmpeg 的硬件加速实现方式和支持的 API 各有特点。 在 Windows 系统上,FFmpeg 主要依赖 DirectX Vi…...

RUOYI框架在实际项目中的应用二:Ruoyi前后端分离版本

如需观看Ruoyi框架的整体介绍&#xff0c;请移步&#xff1a;RUOYI框架在实际项目中的应用一&#xff1a;ruoyi简介 一、Ruoyi前后端分离版本-RuoYi-Vue 1、官方资料 1&#xff1a;代码地址&#xff1a;https://gitee.com/y_project/RuoYi-Vue.git 2&#xff1a;文档介绍地址…...

2.12[A]distribute sys

在分布式训练中&#xff0c;特别是使用3D并行&#xff08;数据并行、流水线并行和模型并行&#xff09;时&#xff0c;不同阶段的GPU可能因为通信或数据依赖而出现空闲时间&#xff0c;这些空闲时间就是所谓的“气泡”。这些气泡会降低整体的训练效率&#xff0c;导致GPU资源的…...

R语言的移动应用开发

R语言的移动应用开发 在数据科学和统计分析的大潮中&#xff0c;R语言因其强大的数据处理和可视化能力而备受青睐。然而&#xff0c;R语言对移动应用开发的适用性并未得到广泛关注。本文将探讨R语言在移动应用开发中的潜力及其工具&#xff0c;并提供一些实践示例&#xff0c;…...

解决 Redis 后台持久化失败的问题:内存不足导致 fork 失败

文章目录 解决 Redis 后台持久化失败的问题&#xff1a;内存不足导致 fork 失败问题背景与成因解决方案修改内核参数 vm.overcommit_memory增加系统内存或 Swap 空间调整 Redis 配置 stop-writes-on-bgsave-error 在 Docker 环境中的注意事项总结 解决 Redis 后台持久化失败的问…...

交换机控制软件的实现步骤猜测

一、主要目的 提出对交换机软件控制逻辑的猜测。 二、交换机控制软件的组成 (一)背景 1、交换机有很多的RJ45水晶头端口。 2、每个端口支持同时发送和接收字节数据。 3、每个端口接收的数据需要查表后才能转发给目标端口。 (二)端口状态扫描线程 负责扫描每个端口的状态&#x…...

100.HarmonyOS NEXT跑马灯组件教程:实际应用与场景示例

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT跑马灯组件教程&#xff1a;实际应用与场景示例 文章目录 HarmonyOS NEXT跑马灯组件教程&#xff1a;实际应用与场景示例1. 跑马灯组…...

【计算机网络】2物理层

物理层任务:实现相邻节点之间比特(或)的传输 1.通信基础 1.1.基本概念 1.1.1.信源,信宿,信道,数据,信号 数据通信系统主要划分为信源、信道、信宿三部分。 信源:产生和发送数据的源头。 信宿:接收数据的终点。 信道:信号的传输介质。 数据和信号都有模拟或数字…...

2.3 滑动窗口专题:最大连续1的个数 III(LeetCode 1004)

1. ​题目链接 1004. 最大连续1的个数 III - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/max-consecutive-ones-iii/ 2. ​题目描述 给定一个二进制数组 nums 和一个整数 k&#xff0c;允许将最多 k 个 0 翻转为 1&#xff0c;求翻转后最长的连续 1 …...

怎么解决在Mac上每次打开文件夹都会弹出一个新窗口的问题

在Mac上每次打开文件夹都会弹出一个新窗口的问题&#xff0c;可以通过以下方法解决‌ ‌调整Finder设置‌&#xff1a; 打开Finder&#xff0c;点击“Finder”菜单&#xff0c;选择“偏好设置”。在偏好设置中&#xff0c;选择“通用”标签。取消勾选“在标签页中打开文件夹”或…...

Python异常处理

异常处理 概述 在Python中&#xff0c;在处理可能会引发异常的代码块时&#xff0c;使用try和except语句。可以帮助我们捕获并处理异常&#xff0c; 而不是让程序因为一个未处理的异常而完全崩溃。 try-except try-except-finally try-finally try-except-else try-except-…...

VSTO(C#)Excel开发8:打包发布安装卸载

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

ImportError: cannot import name ‘genai‘ from ‘google‘ (unknown location) 问题如何处理

这个错误通常发生在没有正确安装Google的生成式AI库。需要安装官方的google-generativeai库&#xff1a; pip install google-generativeai如果代码中使用的导入方式与新版SDK不兼容&#xff0c;可能需要调整导入语句。根据当前代码上下文&#xff0c;正确的导入方式应该是&am…...

Advanced Intelligent Systems 软体机器手助力截肢者玩转鼠标

随着科技的不断进步&#xff0c;假肢技术在改善截肢者生活质量方面取得了显著成就。然而&#xff0c;截肢群体在就业方面仍面临巨大困难&#xff0c;适龄截肢群体的就业率仅为健全群体的一半。现有的肌电控制假肢手在与计算机交互时存在诸多挑战&#xff0c;特别是截肢者在使用…...

kubernetes对于一个nginx服务的增删改查

1、创建 Nginx 服务 1.1、创建 Deployment Deployment 用于管理 Pod 副本和更新策略。 方式一&#xff1a;命令式创建 kubectl create deployment nginx-deployment --imagenginx:latest --replicas3 --port80--replicas3&#xff1a;指定副本数为 3 --port80&#xff1a;容…...

我的世界1.20.1forge模组进阶开发教程生物篇(1)——生成

生物生成 生物生成Alexmob介绍:**1. 核心功能与技术实现****2. 项目结构与代码质量****3. 社区协作与维护****4. 扩展性与开发挑战****5. 开发者学习价值**食蚁兽一、实体属性与行为控制(`EntityAnteater`类)二、实体注册与生成规则(`AMEntityRegistry`类)三、全局生成逻辑…...

1.5 Spring Boot项目打包和运行

本文介绍了如何使用Spring Boot进行项目打包和运行。首先&#xff0c;讲解了如何将Spring Boot项目打包为可执行的JAR包&#xff0c;并直接运行&#xff0c;无需部署到外部Web服务器。接着&#xff0c;介绍了如何将项目打包为WAR包&#xff0c;以便部署到Web容器中&#xff0c;…...

287. 寻找重复数

由于题目规定数组中的数的范围是1-n&#xff0c;因此可以构造出下标n和值nums[n]的映射f(n)&#xff0c;然后构成一个链表&#xff0c;当有重复数字时&#xff0c;链表存在环&#xff0c;找到重复数字即找到链表环的入口&#xff0c;参考142. 环形链表II。 class Solution {pu…...

如何高效解决 Java 内存泄漏问题方法论

目录 一、系统化的诊断与优化方法论 二、获取内存快照&#xff1a;内存泄漏的第一步 &#xff08;一&#xff09;自动生成 Heap Dump &#xff08;二&#xff09;手动生成 Heap Dump 三、导入分析工具&#xff1a;MAT 和 JProfiler &#xff08;一&#xff09;MAT (Memor…...

【Agent】OpenManus 项目架构分析

这是我录制的一个视频&#xff0c;主要是描述我理解的 OpenManus 的思维逻辑&#xff0c;通过这个小的思维逻辑的复现&#xff0c;为后面要再分析其他 Agent 的实现做一个准备。 1. 项目概述 OpenManus 是一个基于大语言模型的智能体框架&#xff0c;旨在提供一个无需邀请码的…...

hive-进阶版-1

第6章 hive内部表与外部表的区别 Hive 是一个基于 Hadoop 的数据仓库工具&#xff0c;用于对大规模数据集进行数据存储、查询和分析。Hive 支持内部表&#xff08;Managed Table&#xff09;和外部表&#xff08;External Table&#xff09;两种表类型&#xff0c;它们在数据…...

规模效应的三重边界:大白话解读-deepseek为例

前言&#xff1a;当Scaling Laws遇见边际递减效应 在人工智能的狂飙突进中&#xff0c;大语言模型如同不断膨胀的星体&#xff0c;吞噬着海量算力与数据。OpenAI于2020年揭开的Scaling Laws&#xff0c;曾为这场盛宴指明方向&#xff1a;模型性能随参数规模&#xff08;N&…...

考研系列-408真题计算机网络篇(18-23)

写在前面 此文章是本人在备考过程中408真题计算机网络部分&#xff08;2018年-2023年&#xff09;的易错题及相应的知识点整理&#xff0c;后期复习也常常用到&#xff0c;对于知识提炼归纳理解起到了很大的作用&#xff0c;分享出来希望帮助到大家~ # 2018 1.停止-等待协议的…...

windows协议不再续签,华为再无windows可用,将于四月发布鸿蒙PC

大家好&#xff0c;我是国货系创始人张云泽&#xff0c;最近不少小伙伴在后台问&#xff1a;“听说Windows协议要到期了&#xff1f;我的电脑会不会变砖&#xff1f;”还有人说&#xff1a;“华为笔记本以后用不了Windows了&#xff1f;鸿蒙系统能用吗&#xff1f;”今天咱们就…...

【二分算法】-- 点名

文章目录 1. 题目2. 题目解析3. 代码 1. 题目 在线oj 2. 题目解析 前四种解决方法&#xff1a; 哈希表直接遍历找结果位运算数学&#xff08;高斯求和公式&#xff09; 这四种方法的时间复杂度都是0&#xff08;N&#xff09; 第五种解决方法&#xff1a; 【二段性】&…...

强化学习 - PPO控制无人机

PPO&#xff08;Proximal Policy Optimization&#xff0c;近端策略优化&#xff09;是一种强化学习算法&#xff0c;用于训练智能体&#xff08;无人机&#xff09;如何在环境中做出决策。它本质上是 策略梯度&#xff08;Policy Gradient&#xff09;方法 的一种改进&#xf…...

【AHE数据集】 NCAR Anthropogenic Heat Flux (AHF) 数据集

数据概述 数据集由 美国国家大气研究中心(NCAR, National Center for Atmospheric Research) 的 气候与全球动力学实验室(CGD, Climate & Global Dynamics Laboratory) 提供。NCAR 由 美国国家科学基金会(NSF, National Science Foundation) 资助,并由 大学大气研究…...

Part1:基于国内源完成Kubernetes集群部署

集群规划 操作系统&#xff1a;CentOS7 内核版本&#xff1a;5.4&#xff08;需升级&#xff09; 组件版本说明操作系统内核5.4RPM方式升级docker26.1.4yum安装cri-docker0.3.16二进制安装kubeadm1.30.11yum安装kubealet1.30.11yum安装kubectl1.30.11yum安装kubectl1.30.11yu…...

强化学习的一些概念

目录 强化学习 打个比方 核心要素 State Action Reward 几个代码demo 学习目标 强化学习 强化学习&#xff08;Reinforcement Learning, RL&#xff09;是机器学习的一个分支&#xff0c;旨在让智能体&#xff08;Agent&#xff09;通过与环境的交互学习最优策略&#xff0c;以…...

花生好车:重构汽车新零售生态的破局者

在传统汽车零售行业面临消费升级与渠道变革的双重压力下&#xff0c;花生好车以颠覆性的商业模式在短短九年内崛起为行业独角兽。这家成立于2015年的汽车新零售平台&#xff0c;通过重构供应链体系、创新融资租赁模式、深耕下沉市场三大战略维度&#xff0c;正在重塑中国汽车消…...

K8S下nodelocaldns crash问题导致域名请求响应缓慢

前言 最近做项目&#xff0c;有业务出现偶发的部署导致响应很慢的情况&#xff0c;据了解&#xff0c;业务使用域名访问&#xff0c;相同的nginx代理&#xff0c;唯一的区别就是K8S重新部署了。那么问题大概率出现在容器平台&#xff0c;毕竟业务是重启几次正常&#xff0c;偶…...

实现悬浮按钮拖动,兼容h5和微信小程序

h5用js写&#xff0c;微信小程序用 代码里面没有完全实现吸附边缘的功能&#xff0c;需要吸附边缘的话还得自己再完善下&#xff08;h5的吸附边缘是可以的&#xff0c;小程序的还有点问题&#xff09; 主要功能是&#xff1a;图片上写文字的悬浮按钮&#xff0c;文字使用的是…...