LLM 系列 | 15:如何用LangChain做长文档问答?

11 篇文章 1 订阅
4 篇文章 1 订阅

简介

西塞山前白鹭飞,桃花流水鳜鱼肥。
在这里插入图片描述
小伙伴们好,我是微信公众号《小窗幽记机器学习》的小编:卖酱猪蹄的小女孩。今天新开一个专题:LangChain实践。前文ChatGPT Prompt 工程和应用系列文章可以如下自取,预告一下该系列还有2篇小作文,后续补下。

本文作为LangChain专题的开篇,以长文档问答为例介绍如何使用LangChain。完整代码请在微信公众号:小窗幽记机器学习上添加小编微信。

加载数据

本次测试数据来源于百度百科画江湖之不良人的词条数据,并以pdf格式保存到本地(右键->打印->另存为pdf)。

在这里插入图片描述

# load document
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("test_data.pdf")
documents = loader.load()

补充说下,如果是多个文档可以如下类似方式进行加载:

loaders = [....]
documents = []
for loader in loaders:
    documents.extend(loader.load())

短文本问答

load_qa_chain是LangChain中最通用的问答接口,用户可以对输入的文档进行问答。需要注意:load_qa_chain默认使用文档中的全部文本。如果将整个文档全部输入的话,可能会报错,所以本章节先只将带有答案的文档页面输入,后文补充介绍如何做整个文档的问答。

text-davinci-003

以下使用text-davinci-003模型(该模型是OpenAI接口的默认模型)进行问答:

from langchain.chains.question_answering import load_qa_chain
llm = OpenAI() # model_name="text-davinci-003"
chain = load_qa_chain(llm=llm)
query = "李星云会哪些武功?"
chain.run(input_documents=documents[1:2], question=query)

输出结果如下:

' Li Xingyun can perform the following martial arts techniques: Qinglian Sword Song, Huayang Needle Method, and Longquan Seven Star Scripture.'

可以看出,回答的内容是正确的。如果想要以中文形式回答,可以通过设计Prompt作为额外输入。

ChatGPT

改用ChatGPT模型进行问答:

from langchain.chains.question_answering import load_qa_chain
model_name = "gpt-3.5-turbo"
llm = OpenAI(model_name=model_name, temperature=0)
chain = load_qa_chain(llm=llm)
query = "李星云会哪些武功?"
chain.run(input_documents=documents[1:2], question=query)

输出结果如下:

'李星云的武功包括青莲剑歌、华阳针法、龙泉七星诀。'

与原文查找确认相同:

在这里插入图片描述

长文档问答

以上通过人工指定候选文本范围,但真实场景我们希望基于全部文档自动搜索答案。

向量召回

为此,改变思路先进行召回,缩小文档范围:

from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma

text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings() # 默认的model="text-embedding-ada-002"
docsearch = Chroma.from_documents(texts, embeddings, metadatas=[{"source": str(i)} for i in range(len(texts))]).as_retriever()
# 可以在 as_retriever 指定参数 search_kwargs={"k": 1},从而实现Top K的召回
query = "李星云会哪些武功?"
docs = docsearch.get_relevant_documents(query)
print("docs len=", len(docs))

为此,召回了4个docs片段。

text-davinci-003

from langchain.chains.question_answering import load_qa_chain

llm = OpenAI(temperature=0)

chain = load_qa_chain(llm=llm, chain_type="map_reduce")
query = "李星云会哪些武功?"
chain.run(input_documents=docs, question=query)

运行结果如下:

" Li Xingyun's martial arts include the Qinglian Sword Song, the Shock Rainbow, the Zhisheng Qiankun Gong, the Five Thunder Heart Sutra, and the Illusion Sound Sutra. He also wields the Suxin Sword."

可以看出,回复内容多数是胡说八道,比如竟然出现"至圣乾坤功"和"五雷天心诀"。效果整体比较差。以下将QA部分的模型更换为ChatGPT。

ChatGPT

from langchain.chains.question_answering import load_qa_chain

model_name = "gpt-3.5-turbo-16k"
llm = OpenAI(model_name=model_name, temperature=0)

chain = load_qa_chain(llm=llm)
query = "李星云会哪些武功?"
chain.run(input_documents=docs, question=query)

输出结果如下:

'李星云会青莲剑歌、惊虹、天罡诀、华阳针法等武功。'

可以看出,这种召回+ChatGPT的方式容易受到召回数据的干扰。所以,这种方式很大程度上依赖于召回阶段的质量,特别是当上述问题的答案分布于多处的情况。

综合整个长文档,其实上述答案其实很接近真实的答案,但是玩了一个trick:用等武功这类话术。其实还缺了了一个龙泉七星诀

小结

今天这篇小作文作为LangChain实践专题的首篇,主要介绍如何基于load_qa_chain接口做长文档问答。后续会持续介绍其他的问答接口和其他的向量化方案,感兴趣的小伙伴们可以留意关注下。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值