【Langchain大语言模型开发教程】基于文档问答

 🔗 LangChain for LLM Application Development - DeepLearning.AI

Embedding: https://huggingface.co/BAAI/bge-large-en-v1.5/tree/main

学习目标

1、Embedding and Vector Store

2、RetrievalQA

引包、加载环境变量 

import os

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file


from langchain.indexes import VectorstoreIndexCreator
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
from langchain.document_loaders import CSVLoader
from langchain.vectorstores import DocArrayInMemorySearch
from langchain_huggingface import HuggingFaceEmbeddings
from IPython.display import display, Markdown

  加载一下我们的文件

file = 'OutdoorClothingCatalog_1000.csv'
loader = CSVLoader(file_path=file, encoding='utf-8')
docs = loader.load()

Embedding and vector Store 

大语言模型一次只能处理几千个单词,如果我们有一个非常大的文档的话,大语言模型不能一次全部处理,怎么办?

这时候就需要用到embeding和 vector store,先来看看embeding 

 embeding将一段文本转化成数字,用一组数字来表示这段文本。这组数字捕捉了这段文本表示的内容,内容相似的文本,将会有相似的向量值。我们可以在向量空间中比较文本片段来查看他们之间的相似性。

 我们使用智源实验室推出的BGE Embedding模型;

model_name = "bge-large-en-v1.5"
embeddings = HuggingFaceEmbeddings(model_name=model_name)

有了embedding模型后,我们还需要一个向量数据库, 创建向量数据库,首先需要将文档进行切片分割操作,把文档切分成一个个块(chunks),然后对每个块做embedding,最后再把由embedding生成的所有向量存储在向量数据库中;

我们使用DocArrayInMemorySearch作为向量数据库,DocArrayInMemorySearch是由Docarray提供的文档索引,它将会整个文档以向量的形式存储在内存中;

db = DocArrayInMemorySearch.from_documents(docs, embeddings)

当我们完成了向量数据库构建后,在用户提问时,用户的问题通过Embedding操作生成一组向量,接下来将该向量与向量数据库中的所有向量进行比较,找出前n个最相似的向量并将其转换成对应的文本信息。我们有这样一个问题,现在我们通过向量数据库来查找和该问题相似度最高的内容;

query = "Please suggest a shirt with sunblocking"

docs = db.similarity_search(query)

我们这里查看一下检索到的第一条数据 ,确实是跟防嗮有关的;

最后,我们将这些与用户问题最相似的文本信息输入到LLM,并由LLM生成最终的回复;

# 创建一个检索器
retriever = db.as_retriever()

# 初始化LLM
llm = ChatOpenAI(api_key=os.environ.get('ZHIPUAI_API_KEY'),
                         base_url=os.environ.get('ZHIPUAI_API_URL'),
                         model="glm-4",
                         temperature=0.98)

 刚刚我们输入了一个问题并在向量数据库中检索到了一些相关信息,接下来我们将这些信息和问题一起输入到大语言模型中,使用markdown的格式展示一下效果;

docs_str = "".join([docs[i].page_content for i in range(len(docs))])

response = llm.invoke(f"{docs_str} Question: Please list all your shirts with sun protection in a table in markdown and summarize each one.")

display(Markdown(response.content))

 这是智谱GLM4帮我们整理之后的答案,并且帮我们整理好了;

RetrievalQA

 当然,如果你觉得这很麻烦,我们可以创建一个RetrievalQA链,这样调用也是可以的;

qa_stuff = RetrievalQA.from_chain_type(
    llm=llm, 
    chain_type="stuff", 
    retriever=retriever, 
    verbose=True
)

query =  "Please list all your shirts with sun protection in a table in markdown and summarize each one."

response = qa_stuff.invoke(query)

该chain包含三个主要的参数,其中llm参数是我们的智谱GLM4, retriever参数设置设置为前面我们由DocArrayInMemorySearch创建的retriever,最后一个重要的参数为chain_type,该参数包含了四个可选值:stuff,map_reduce,refine,map_rerank,接下来我们简单了解一下这些选择的区别;

这种最简单粗暴,会把所有的 document 一次全部传给 llm 模型进行总结。如果document很多话,可能会报超出最大 token 限制的错。 

这个方式会先将每个 document 通过llm 进行总结,最后将所有 document 总结出的结果再进行一次总结。

这种方式会先总结第一个 document,然后在将第一个 document 总结出的内容和第二个document 一起发给 llm 模型再进行总结,以此类推。这种方式的好处就是在总结后一个 document 的时候,会带着前一个的 document 进行总结,给需要总结的 document 添加了上下文,增加了总结内容的连贯性。

这种方式会通过llm对每个文档进行一次总结,然后得到一个分数,最后选择一个分数最高的总结作为最终回复。 

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是饿梦啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值