使用langchain及llama_index实现基于文档(长文本)的相似查询与询问

这篇具有很好参考价值的文章主要介绍了使用langchain及llama_index实现基于文档(长文本)的相似查询与询问。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前面的总结是半年前的知识与代码,但是框架不变,所以不再修改。
但是半年更新了不少内容,包括一些类都更换了不少,有同学问到,所以就又重新写一份,贴在下面。
考虑到这篇费了不少时间,关注一下不过分吧(❁´◡`❁)

2023.5.31

1. 引言

在调用ChatGPT接口时,我们常常受到4096个字符(token)的限制。这种限制对于处理长文本或者需要对文档进行相似查询和询问的场景来说是一个挑战。然而,通过结合使用langchain和llama_index这两个强大的工具,我们可以克服这个限制,实现对长文本的高效查询和询问。

2. 简介

langchain是一个功能强大的库,它为我们提供了许多方便的工具和模型,包括OpenAI模型。它通过链式调用的方式将这些组件连接在一起,创造出一个连贯的应用程序。同时,langchain还提供了内存组件Memory,可以帮助我们管理之前的聊天消息,以及Indexes和Agents等功能。

LlamaIndex(GPT Index)是一个用于LLM应用的数据框架,集成了langchain及chatgpt相关应用,更便于我们实现结构化数据和高级检索的相关功能。

3. 带关键字的查询方案

基于文档的查询场景有一种情况是,提问的内容与全部文档中的一小块相关,而其他内容无关。比如《百草园到三味书屋》中美女蛇的故事。

若询问中带有关键字,我们推荐使用相似匹配的方式进行筛选有关内容。

  • 拆分文档:首先,我们将长文本拆分成较小的块,并使用OpenAI的Embeddings功能将每个块向量化。
  • 相似性匹配:当用户提出查询时,我们将用户的查询文本也进行向量化。
  • 相似查询:然后,我们遍历已拆分并向量化的文档块,将其与向量化后的查询文本进行相似性比较。通过计算相似度,我们可以找到最相似的文档块
  • 传递上下文:根据之前的映射关系,我们找到与最相似文档块相对应的原始文档内容。将这个内容作为上下文传递给ChatGPT模型。
  • 询问与回答:最后,ChatGPT(LLM)根据这个上下文,对用户的查询进行回答。

总体langchain的内容如下:
使用langchain及llama_index实现基于文档(长文本)的相似查询与询问

对于文本的处理流程如下:
使用langchain及llama_index实现基于文档(长文本)的相似查询与询问

看上去很复杂,但是langchain都替我们做好了。

使用langchain及llama_index实现基于文档(长文本)的相似查询与询问

我们在库源码里面一层层输出中间变量,可以验证它确实是一种相似匹配。

使用langchain及llama_index实现基于文档(长文本)的相似查询与询问
如果不想使用OpenAI的API接口,也可以使用Hugginface上的模型来做相似匹配,从而传入自身的llm模型中。

使用langchain及llama_index实现基于文档(长文本)的相似查询与询问

4. 不带关键字的总结询问

如果用户询问的是“这篇文章写了什么”,这种无关键字的询问,这时候我们不能使用相似查询了,这样会有上下文的缺失。

这里我们推荐使用tree_summarize的方式进行询问。它的工作原理如下:

使用langchain及llama_index实现基于文档(长文本)的相似查询与询问
例如可以生成如下结果:
使用langchain及llama_index实现基于文档(长文本)的相似查询与询问

当然,除此之外还有其他的响应方式,比如简单总结simple_summarize、轮询迭代的refine等等,我们修改下方的response_mode即可。

不同的响应类型ResponseMode可见下篇博客:llama_index中query_engine的response_mode详解

5. 实现代码

import re
import os
from langchain import OpenAI

os.environ["OPENAI_API_KEY"] = 'sk-xx(apikey)'

from llama_index import SimpleDirectoryReader,LLMPredictor,ServiceContext
from llama_index import GPTListIndex, SimpleDirectoryReader
from llama_index.indices.response.type import ResponseMode

from llama_index import SimpleDirectoryReader
from llama_index.readers.schema.base import Document

# 可以直接输入文本
def textToDocuments(text):
    documents = [Document(text)]
    return documents

# 输入目录后将目录下的所有文件转成Documents对象数组,同上
def fileToDocuments(filePath):
    documents = SimpleDirectoryReader(filePath).load_data()
    return documents


# 模型名称参数
model_name = "text-davinci-003"
"""
其他模型名称及对应可接收每段的最大token数
    "gpt-4": 8192,
    "gpt-4-0314": 8192,
    "gpt-4-32k": 32768,
    "gpt-4-32k-0314": 32768,
    "gpt-3.5-turbo": 4096,
    "gpt-3.5-turbo-0301": 4096,
    "text-ada-001": 2049,
    "ada": 2049,
    "text-babbage-001": 2040,
    "babbage": 2049,
    "text-curie-001": 2049,
    "curie": 2049,
    "davinci": 2049,
    "text-davinci-003": 4097,
    "text-davinci-002": 4097,
    "code-davinci-002": 8001,
    "code-davinci-001": 8001,
    "code-cushman-002": 2048,
    "code-cushman-001": 2048,
"""

llm_predictor = LLMPredictor(llm=OpenAI(temperature=0, model_name=model_name,max_tokens=1800))

service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)

query_str = "美女蛇的故事是什么?"

response_mode = "compact"
"""
    REFINE = "refine"
    COMPACT = "compact"
    SIMPLE_SUMMARIZE = "simple_summarize"
    TREE_SUMMARIZE = "tree_summarize"
    GENERATION = "generation"
    NO_TEXT = "no_text"
"""

documents = fileToDocuments("./data")
# documents2 = textToDocuments("不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树,紫红的桑椹;也不必说鸣蝉在树叶里长吟,肥胖的黄蜂伏在菜花上,轻捷的叫天子(云雀)忽然从草间直窜向云霄里去了。单是周围的短短的泥墙根一带,就有无限趣味。油蛉在这里低唱,蟋蟀们在这里弹琴。翻开断砖来,有时会遇见蜈蚣;还有斑蝥,倘若用手指按住它的脊梁,便会拍的一声,从后窍喷出一阵烟雾。何首乌藤和木莲藤缠络着,木莲有莲房一般的果实,何首乌有拥肿的根。有人说,何首乌根是有象人形的,吃了便可以成仙,我于是常常拔它起来,牵连不断地拔起来,也曾因此弄坏了泥墙,却从来没有见过有一块根象人样。如果不怕刺,还可以摘到覆盆子,象小珊瑚珠攒成的小球,又酸又甜,色味都比桑椹要好得远。")

index = GPTListIndex.from_documents(documents,service_context=service_context)

query_engine = index.as_query_engine(
    response_mode=response_mode
)

response = query_engine.query(query_str)
print(response)

2024.1.24 更新

其实直接看llamaIndex的官网就可以了,现在的示例代码已经比较丰富了。

1. 基于文档的query代码(需openai api-key)

from llama_index import (
    VectorStoreIndex,
    get_response_synthesizer,
)
from llama_index.retrievers import VectorIndexRetriever
from llama_index.query_engine import RetrieverQueryEngine
from llama_index.postprocessor import SimilarityPostprocessor
from llama_index import SimpleDirectoryReader
import os

os.environ["OPENAI_API_KEY"] = 'sk-xxx'


# 输入目录后将目录下的所有文件转成Documents对象数组,同上
def fileToDocuments(filePath):
    documents = SimpleDirectoryReader(filePath).load_data(show_progress=True)
    return documents


documents = fileToDocuments("./data-test")
# build index
index = VectorStoreIndex.from_documents(documents)

# configure retriever
retriever = VectorIndexRetriever(
    index=index,
    similarity_top_k=10,
)

# configure response synthesizer
response_synthesizer = get_response_synthesizer()

# assemble query engine
query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=response_synthesizer,
    node_postprocessors=[SimilarityPostprocessor(similarity_cutoff=0.7)],
)

# query
response = query_engine.query("summarize the rapeseed traits mainly studied by the authors, the technologies employed,rapeseed genes mainly studied by the authors,relations between rapeseed genes,relations between rapeseed genes and rapeseed raits from the article.")
print(response)

2. 基于query搜索相似文档(huggingface embedding + faiss)

基于huggingface embedding后做相似度匹配文章来源地址https://www.toymoban.com/news/detail-485006.html

# pip install sentence-transformers
# pip install -U langchain-community
# pip install faiss-cpu 或者 pip install faiss-gpu
# pip install unstructured
# pip install "unstructured[pdf]"

# 1. 文档加载器 Document Loader
# from langchain.document_loaders import TextLoader,DirectoryLoader
from langchain_community.document_loaders import TextLoader, DirectoryLoader
# loader = TextLoader('data-test/xx.txt',encoding="utf-8")
loader = DirectoryLoader('data-test') # 直接读整个目录内的文件
documents = loader.load()

# 2. 分词器 Text Splitter
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

# 3. 嵌入向量 Embeddings
# from langchain.embeddings import HuggingFaceEmbeddings
from langchain_community.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings()
# from langchain.vectorstores import FAISS
from langchain_community.vectorstores import FAISS
db = FAISS.from_documents(docs, embeddings)

# 4. 相似性搜索
query = "summarize the rapeseed traits mainly studied by the authors, the technologies employed,rapeseed genes mainly studied by the authors,relations between rapeseed genes,relations between rapeseed genes and rapeseed raits from the article."
docs = db.similarity_search(query)
print("=========")
print(docs[0].page_content) # 输出结果页面内容


# 5. 保存和加载 Save and load
# 保存之后(后续可以单独调用load这块,就不用再嵌入一次了):
db.save_local("faiss_index")
query = "summarize the rapeseed traits mainly studied by the authors, the technologies employed,rapeseed genes mainly studied by the authors,relations between rapeseed genes,relations between rapeseed genes and rapeseed raits from the article."
new_db = FAISS.load_local("faiss_index", embeddings)
docs = new_db.similarity_search(query)
# print(docs[0].page_content)

到了这里,关于使用langchain及llama_index实现基于文档(长文本)的相似查询与询问的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 本地搭建【文档助手】大模型版(LangChain+llama+Streamlit)

    本文的文档助手就是:我们上传一个文档,然后在对话框中输入问题,大模型会把问题的答案返回。 先下载代码到本地 LangChain调用llama模型的示例代码:https://github.com/afaqueumer/DocQA(代码不是本人写的,尊重原创) 环境安装 如果没反应可能是缺少环境,打开控制台手动执行

    2024年02月04日
    浏览(47)
  • 自然语言处理从入门到应用——LangChain:索引(Indexes)-[文档加载器(Document Loaders)]

    分类目录:《大模型从入门到应用》总目录 LangChain系列文章: 基础知识 快速入门 安装与环境配置 链(Chains)、代理(Agent:)和记忆(Memory) 快速开发聊天模型 模型(Models) 基础知识 大型语言模型(LLMs) 基础知识 LLM的异步API、自定义LLM包装器、虚假LLM和人类输入LLM(

    2024年02月11日
    浏览(43)
  • 在本地使用CPU运行Llama 2模型来实现文档Q&A

    第三方商业大型语言模型(LLM)提供商,如OpenAI的GPT4,通过简单的API调用使LLM的使用更加容易。然而,由于数据隐私和合规等各种原因,我们可能仍需要在企业内部部署或私有模型推理。 开源LLM的普及让我们私有化部署大语言模型称为可能,从而减少了对这些第三方提供商

    2024年02月13日
    浏览(50)
  • 使用Llama index构建多代理 RAG

    检索增强生成(RAG)已成为增强大型语言模型(LLM)能力的一种强大技术。通过从知识来源中检索相关信息并将其纳入提示,RAG为LLM提供了有用的上下文,以产生基于事实的输出。 但是现有的单代理RAG系统面临着检索效率低下、高延迟和次优提示的挑战。这些问题在限制了真实世

    2024年02月07日
    浏览(43)
  • llama-index调用qwen大模型实现RAG

    llama-index在实现RAG方案的时候多是用的llama等英文大模型,对于国内的诸多模型案例较少,本次将使用qwen大模型实现llama-index的RAG方案。 llamaindex需要预装很多包,这里先把我成功的案例里面的pip包配置发出来,在requirements.txt里面。       llamaindex实现RAG中很关键的一环就是知

    2024年04月09日
    浏览(42)
  • LLMs之RAG:基于LangChain框架利用ChatGPT的API实现一个与在线网页交互的对话机器人—五大思路步骤—加载文档WebBaseLoader网址文件→文档分割(chunk_size=50

    LLMs之RAG:基于LangChain框架利用ChatGPT的API实现一个与在线网页交互的对话机器人—五大思路步骤—加载文档WebBaseLoader网址文件→文档分割(chunk_size=500)→文本嵌入化(OpenAIEmbeddings)并存储到向量库(Chroma)→构造Prompt(拉取一个对象并将其返回为 LangChain对象)→定义LLMs(ChatOpenAI)→输入

    2024年02月08日
    浏览(51)
  • 基于Llama2和LangChain构建本地化定制化知识库AI聊天机器人

    参考: 本项目 https://github.com/PromtEngineer/localGPT 模型 https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML 云端知识库项目:基于GPT-4和LangChain构建云端定制化PDF知识库AI聊天机器人_Entropy-Go的博客-CSDN博客          相比OpenAI的LLM ChatGPT模型必须网络连接并通过API key云端调用模型,担心

    2024年02月08日
    浏览(63)
  • 通过Llama Index实现大模型的SQL生成的三种方法详解

    文中使用了chatglm的llm和embedding modle,利用的智谱的免费token Text2SQL其实就是从文本到SQL,也是NLP中的一种实践,这可以降低用户和数据库交互的门槛,无需懂SQL就可以拿到数据库数据。Text2SQL实现了从自然语言到SQL语言的生成,更加进一步的是直接给出数据中的结果。在开始

    2024年04月14日
    浏览(47)
  • TS版LangChain实战:基于文档的增强检索(RAG)

    LangChain是一个以 LLM (大语言模型)模型为核心的开发框架,LangChain的主要特性: 可以连接多种数据源,比如网页链接、本地PDF文件、向量数据库等 允许语言模型与其环境交互 封装了Model I/O(输入/输出)、Retrieval(检索器)、Memory(记忆)、Agents(决策和调度)等核心组件

    2024年02月05日
    浏览(57)
  • 【LangChain学习】基于PDF文档构建问答知识库(三)实战整合 LangChain、OpenAI、FAISS等

    接下来,我们开始在web框架上整合 LangChain、OpenAI、FAISS等。 因为项目是基于PDF文档的,所以需要一些操作PDF的库,我们这边使用的是PyPDF2 传入 pdf 文件路径,返回 pdf 文档的文本内容。 首先我们需要将第一步拿到的本文内容拆分,我们使用的是 RecursiveCharacterTextSplitter ,默认

    2024年02月13日
    浏览(73)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包