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

news2025/3/14 16:23:42

目录

一、前言

二、前置准备

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 ChatOpenAI

llm = 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 | llm

result=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_prompt
    HumanMessagePromptTemplate.from_template(human_template)
    chat_prompt =ChatPromptTemplate.from_messages([
    system_message_prompt,
    human_message_prompt

chat_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 PromptTemplate

prompt_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 ChatOpenAI

model = 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,MessagesPlaceholder

from langchain_core.messages import SystemMessage, HumanMessage

prompt_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,MessagesPlaceholder

from langchain_core.messages import SystemMessage, HumanMessage

prompt_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 FewShotPromptTemplate

from langchain_core.messages import SystemMessage, HumanMessage

examples = [
    {
        "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 Chroma

from langchain_openai import OpenAIEmbeddings

examples = [
    {
        "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 ChatMessageHistory

from langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAI

from langchain_core.documents import Document
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings

import os

os.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 ChatMessageHistory

from langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAI

from langchain_core.documents import Document
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings

from langchain_core.runnables import RunnableLambda,RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholder

import os

os.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 | model

resp = chain.invoke("请谈谈老虎")

print(resp)

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

四、写在文末

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2314966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Xxl-Job学习笔记

目录 概述 核心架构 核心特点 应用场景 什么是任务调度 快速入门 获取源码 初始化调度数据库 基本配置 数据源datasource 邮箱email(可选) 会话令牌access token 启动调度中心 启动执行器 依赖 yaml基本配置 XxlJobConfig类配置 定义执…

SAIL-RK3576核心板应用方案——无人机视觉定位与地面无人设备通信控制方案

本方案以 EFISH-RK3576-SBC工控板 或 SAIL-RK3576核心板 为核心,结合高精度视觉定位、实时通信与智能控制技术,实现无人机与地面无人设备的协同作业。方案适用于物流巡检、农业植保、应急救援等场景,具备高精度定位、低延迟通信与强环境适应性…

CSS 入门指南(一):基本概念 选择器 常用元素属性

一、初识 CSS 1, CSS 定义 层叠样式表(Cascading Style Sheets,缩写为 CSS),是一种 样式表 语言,用来描述 HTML 文档的呈现(美化内容) CSS 能够对网页中元素位置的排版进行 像素级 精确控制,实现美化页面…

HTML5(Web前端开发笔记第一期)

p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解 目录 三件套标签标题标签段落标签文本格式化标签图像标签超链接标签锚点链接默认链接地址 音频标签视频标签 HTML基本骨架综合案例->个人简介列表表格表单input标签单选框radio上传…

【AIGC】计算机视觉-YOLO系列家族

YOLO系列家族 (1)YOLO发展史(2) YOLOX(3) YOLOv6(4) YOLOv7(5) YOLOv8(6) YOLOv9(7)YOLOv10(8&…

The First项目报告:重塑 DeFi 流动性的革新者,ELX 即将登陆 The First

随着去中心化金融(DeFi)的持续发展,流动性问题一直是各类去中心化交易所(DEX)和项目方面临的核心挑战。传统的做市模式往往需要依赖中心化流动性提供者,而这些机构的资金控制能力可能影响代币价格波动&…

OpenCV连续数字识别—可运行验证

前言 ​ 文章开始,瞎说一点其他的东西,真的是很离谱,找了至少两三个小时,就一个简单的需求: 1、利用OpenCV 在Windows进行抓图 2、利用OpenCV 进行连续数字的检测。 3、使用C,Qt 3、将检测的结果显示出来 …

LiveGBS流媒体平台GB/T28181功能-海康大华宇视华为像头GB28181国标语音对讲语音喊话需要的摄像头设备及服务HTTPS准备

LiveGBS海康大华宇视华为像头GB28181国标语音对讲语音喊话需要的摄像头设备及服务HTTPS准备 1、背景2、准备2.1、服务端必备条件(注意)2.2、准备语音对讲设备2.2.1、 大华摄像机2.2.1.1、 配置接入示例2.2.1.2、 配置音频通道编号 2.2.2、 海康摄像机2.2…

第十五章:go package 包的管理

import f "fmt"   // 注意 这里 f 是包的别名 init初始化函数 在每一个Go源文件中,都可以定义任意个如下格式的特殊函数: func init(){// ... } package:声明包的关键字 packagename:包名,可以不与文…

deepseek的regflow安装mac版本

deepseek的ragflow部署安装 一:ollama安装,自行完成,我本地已安装 二:查看大模型情况oll::命令ollama list,我本地无ragflow 三:docker安装:命令docker version ,自行完成,我本地已安装 四:安装知识库软件ragflow: 简单科普下Ragflow 是一个基于深度学习模型的问答生成工具&…

文献分享: 对ColBERT段落多向量的剪枝——基于学习的方法

原论文 1. 导论 & \textbf{\&} &方法 1️⃣要干啥:在 ColBERT \text{ColBERT} ColBERT方法中,限制每个段落要保留的 Token \text{Token} Token的数量,或者说对段落 Token \text{Token} Token进行剪枝 2️⃣怎么干:注…

社交软件频繁更新,UI 设计在其中扮演什么角色?

在当今数字化时代,社交软件已成为人们日常生活中不可或缺的一部分。随着科技的飞速发展和用户需求的不断变化,社交软件更新频率日益加快。在这频繁更新的背后,UI 设计扮演着至关重要的角色,它如同社交软件的 “门面担当” 与 “交…

Gemini Robotics:Google DeepMind 让 AI 机器人真正“动”起来!

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

概率论的基本知识

逆概率还不懂,改天再想想。 联合概率 联合概率(Joint Probability) 是概率论中的一个重要概念,用于描述多个随机变量同时取某些值的概率。联合概率可以帮助我们理解多个变量之间的关系。

AI大数据挖掘的威力

通过AI挖掘大数据可以发现很多世界上用传统方法无法发现的潜在规律。 人类群体可以被精准的操控,这在AI发达的未来会越来越现实,甚至可以在社会动荡前夕精准清理权威节点。 基于AI与大数据的人类群体潜在规律发现 随着AI和大数据技术的深度结合&#xf…

使用服务器如何DNS呢

莱卡云服务器 DNS 配置指南 一、配置云服务器本地 DNS ‌修改网络配置文件‌ ‌Ubuntu/Debian‌: bashCopy Code sudo nano /etc/network/interfaces # 添加或修改 DNS 配置 dns-nameservers 8.8.8.8 8.8.4.4 *(保存后重启网络服务&#xf…

【SpringBoot】实现登录功能

在上一篇博客中,我们讲解了注册页面的实现。在此基础上会跳转到登录页面,今天给大家带来的是使用 SpringBoot,MyBatis,Html,CSS,JavaScript,前后端交互实现一个登录功能。 目录 一、效果 二、…

图论part3|101.孤岛的总面积、沉没孤岛、417. 太平洋大西洋水流问题

101. 孤岛的总面积 🔗:101. 孤岛的总面积思路:和昨天的岛的区别是:是否有挨着边的岛屿 所以可以先遍历四条边挨着的岛屿,把他们标记为非孤岛再计算其他岛屿当中的最大面积 代码:(深度搜索&…

江科大51单片机笔记【12】AT24C02(I2C总线)

写在前言 此为博主自学江科大51单片机(B站)的笔记,方便后续重温知识 在后面的章节中,为了防止篇幅过长和易于查找,我把一个小节分成两部分来发,上章节主要是关于本节课的硬件介绍、电路图、原理图等理论知识…

网络安全防护架构有哪些 网络安全防护措施包括

网络安全预防措施 网安措施 计算机网络安全措施主要包括保护网络安全、保护应用服务安全和保护系统安全三个方面,各个方面都要结合考虑安全防护的物理安全、防火墙、信息安全、Web安全、媒体安全等等。 (一)保护网络安全。 网络安全是为保护商务各方网络端系统之…