【2024最全最细Langchain教程-6 】Langchain数据增强之加载、转换-CSDN博客
上一节课我们已经完成了数据的加载和转换,下面我们来看数据的词嵌入和存储是如何做的,我们来看代码:
import os
from langchain.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
api_key = os.getenv("OPENAI_API_KEY")
vectorstore = Chroma.from_documents(
pages_splitter,
embedding=OpenAIEmbeddings(openai_api_key=api_key,base_url = "https://apejhvxcd.cloud.sealos.io/v1"),
)
query = "需求总体思路是什么?"
docs = vectorstore.similarity_search(query)
print(docs[0].page_content)
词的嵌入和存储基本上是在一步里面就可以完成的,首先引入向量数据库Chroma:
from langchain.vectorstores import Chroma
引入openai的词向量工具,你也可以引入其他词向量工具,能找到很多:
from langchain_openai import OpenAIEmbeddings
然后构造一个Chroma向量数据库,将上一节课我们已经做好切分的pages_splitter传入,将词向量工具embedding传入,这样就构造出来了一个向量数据库,可以使用向量数据库的similarity_search方法进行向量搜索,就是寻找向量数据库里和查询问题语义最相近的向量值并返回结果,可以得到查询结果:
我们来看一个完整的数据增强业务过程,首先是引入所需的向量数据库和其他依赖库:
import os
#这个向量数据库有bug
# from langchain_community.vectorstores import DocArrayInMemorySearch
#换一个新的数据库, pip install chromadb
from langchain.vectorstores import Chroma
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
#这里不写chat_models ,直接从langchain_openai里调ChatOpenAI也OK
from langchain_openai import ChatOpenAI
from langchain_openai.embeddings import OpenAIEmbeddings
api_key = os.getenv("OPENAI_API_KEY")
这里要注意一下,langchain官网上给的DocArrayInMemorySearch 这向量数据库在实际应用里是有问题的,我把官网的案例给替换成了chromadb,效果是一样的。
vectorstore = Chroma.from_texts(
["harrison worked at kensho", "bears like to eat honey","jerry likes jenny","today is a good day"],
OpenAIEmbeddings(base_url = "https://apejhvxcd.cloud.sealos.io/v1"),
)
retriever = vectorstore.as_retriever()
本文上面的那个例子里,我们用的是from_documents方法,加载的是文件,这里我们使用from_texts方法,加载一组字符串,然后还是用openai的向量工具做embedding词嵌入,然后我们使用as_retriever()这个方法构造了一个检索器 retriever。下面我们看看这个retriever怎么用:
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI(openai_api_key=api_key,temperature=0.8)
output_parser = StrOutputParser()
setup_and_retrieval = RunnableParallel(
{"context": retriever, "question": RunnablePassthrough()}
)
chain = setup_and_retrieval | prompt | model | output_parser
response = chain.invoke("where did harrison work?")
print(response)
如何构建一个chain我们已经很熟了,之前的课程都已经讲过了,具体可以参考:【2024最全最细Langchain教程-5 】Langchain模型I/O之输出解析器-CSDN博客
唯一不一样的就是我们设置了一个检索器,而且是把这个检索器放在了一个并行方法RunnableParallel 里,RunnableParallel的输入呢是一个字典,里面有两个键值对,一个是context就是需要检索的内容,这里我们是用刚才我们构造的检索器retriever来获取;一个是question就是提出的问题,提出的问题是用RunnablePassthrough()来占位的,标识这个的输入是从模型的其他组件而来,这里只是占位。我们来看下代码运行的效果:
我们的问题是:"where did harrison work?"
我们检索的数据是:
["harrison worked at kensho", "bears like to eat honey","jerry likes jenny","today is a good day"]
我们获得结果:
这个过程可以简单的描述为,我们将四条事实向量化存储进了数据库,然后我们提了一个问题,langchain将向量化的数据库以检索器的形式和问题(同样向量化)一并送给了大模型进行匹配,大模型通过向量搜索发现针对我们的问题,“harrison worked at kensho”这条数据的相似度是最高的,他依据这条匹配结果正确地回答了我们的问题
本教学演示代码已上传github: https://github.com/jerry1900/jupyter
本教学有B站视频,欢迎大家捧场:【2024最全最细】langchain之数据增强RAG介绍(二)_哔哩哔哩_bilibili