使用LangChain和LLM模型构建基于文档的问答系统。

在LangChain框架下使用LLM模型作为AzureOpenAI和Vector Store作为Pincone。

1. 简介

这篇博客文章提供了一个深入的探索,介绍了创建高效文档问答系统所涉及的逐步过程。通过利用LangChain和Pinecone这两种前沿技术,我们发挥了大语言模型(LLMs)的最新进展,包括AzureOpenAI GPT-3和ChatGPT。

LangChain是一个专门设计用于开发语言模型驱动应用程序的强大框架,为我们的项目提供了基础。它为我们提供了必要的工具和能力,以创建一个智能系统,可以根据特定的文档准确回答问题。

为了增强我们的问答系统的性能和效率,我们集成了松鼠数据库Pinecone,这是一个以构建高性能向量搜索应用程序而知名的高效向量数据库。通过利用它的功能,我们可以显著提高我们的系统搜索和检索过程的速度和准确性。

我们在这个项目中的主要重点是通过仅依赖于目标文档中包含的信息来生成精确且具有上下文意识的答案。通过将语义搜索的能力与GPT等LLM的卓越特性相结合,我们实现了一个先进的文档问答系统。

通过这篇博客文章,我们旨在指导读者建立自己的前沿文档问答系统的过程。通过利用最新的人工智能技术,我们展示了将语义搜索和大型语言模型相结合的强大力量,最终实现了一种高度准确和高效的系统,用于根据具体文档回答问题。

ChatGPT中文站
Q&A Architecture using LangChain and VectorStore.

2. 特定背景下的答案:

语义搜索+GPT QnA能够通过将回答与相关文件中的特定段落联系起来,生成更加与上下文相关和精确的答案。然而,精细调整的GPT模型可能基于模型中嵌入的常规知识生成答案,这可能不够精确,或者与问题的上下文无关。

3. LangChain模块

LangChain提供几个主模块的支持:

  • 模型:LangChain支持的各种模型类型和模型集成。
  • 索引:当语言模型与您自己的文本数据结合时,通常会更加强大——该模块介绍了实现此目标的最佳实践。
  • 链:链不仅仅是一个LLM调用,而是调用序列(无论是对LLM还是其他实用程序)。 LangChain为链提供了标准界面,与其他工具的大量集成以及常见应用的端到端链。

4. 让我们深入实际实施:

导入库:

import os
import openai
import pinecone
from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Pinecone
from langchain.llms import OpenAI
from langchain.chains.question_answering import load_qa_chain

加载文档:

首先,我们需要使用LangChain的DirectoryLoader从目录中加载文档。在此示例中,我们假设文档存储在名为“data”的目录中。

directory = '/content/data'   #keep multiple files (.txt, .pdf) in data folder.

def load_docs(directory):
loader = DirectoryLoader(directory)
documents = loader.load()
return documents

documents = load_docs(directory)
len(documents)

拆分文件:

现在,我们需要将文档分成更小的块以便处理。我们将使用LangChain中的RecursiveCharacterTextSplitter,默认情况下会尝试在字符[“\n\n”,“\n”,“ ”,“”]上进行拆分。

def split_docs(documents, chunk_size=1000, chunk_overlap=20):
text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
docs = text_splitter.split_documents(documents)
return docs

docs = split_docs(documents)
print(len(docs))

使用OpenAI嵌入文件:

文档分割后,我们需要使用OpenAI的语言模型进行嵌入。首先,我们需要安装tiktoken库。

!pip install tiktoken -q

现在,我们可以使用LangChain的OpenAIEmbeddings类来嵌入文档。

embeddings = OpenAIEmbeddings(model_name="ada")

query_result = embeddings.embed_query("Hello world")
len(query_result)

Pinecone 的向量搜索:

Pinecone 是一个高性能的向量数据库。它能够快速准确地搜索高维向量的相似度。通过其用户友好的API,可扩展性和先进的算法,开发人员可以轻松处理大量向量数据,实现实时检索,并构建高效的推荐系统和搜索引擎。

!pip install pinecone-client -q

然后,我们可以初始化 Pinecone 并创建 Pinecone 索引。

pinecone.init(
api_key="pinecone api key",
environment="env"
)

index_name = "langchain-demo"

index = Pinecone.from_documents(docs, embeddings, index_name=index_name)

我们正在使用Pinecone.from_documents()方法创建一个新的松果矢量索引。此方法需要三个参数:

  1. 文档:使用递归字符文本分割器将拆分为较小块的文档列表。这些较小的块将在Pinecone中进行索引,以便稍后更轻松地搜索和检索相关文档。
  2. 嵌入:OpenAIEmbeddings类的一个实例,其负责使用OpenAI的语言模型将文本数据转换为嵌入(即数字表示)。这些嵌入将存储在Pinecone索引中,并用于相似度搜索。
  3. 索引名称:一个表示Pinecone索引名称的字符串。该名称用于在Pinecone数据库中识别该索引,应该是唯一的,以避免与其他索引发生冲突。

The Pinecone.from_documents() 方法会处理输入文件,使用提供的 OpenAIEmbeddings 实例生成嵌入信息,并创建一个新的 Pinecone 索引,其名称已指定。生成的索引对象可以执行相似度搜索,并根据用户查询检索相关文件。

5. 查找相似文件:

现在,我们可以定义一个函数来根据给定的查询找到相似的文档。

def get_similiar_docs(query, k=2, score=False):  # we can control k value to get no. of context with respect to question.
if score:
similar_docs = index.similarity_search_with_score(query, k=k)
else:
similar_docs = index.similarity_search(query, k=k)
return similar_docs

6. 使用LangChain和OpenAI LLM进行问答:

有了必要的组件,我们现在可以使用LangChain的OpenAI类和预先构建的问答链来创建问答系统。

from langchain.llm import AzureOpenAI
model_name = "text-davinci-003"
llm = AzureOpenAI(model_name=model_name)

chain = load_qa_chain(llm, chain_type="stuff") #we can use map_reduce chain_type also.

def get_answer(query):
similar_docs = get_similiar_docs(query)
print(similar_docs)
answer = chain.run(input_documents=similar_docs, question=query)
return answer

7. 示例查询和答案:

最后,让我们用一些示例查询来测试我们的问题回答系统。

query = "How is India's economy?"
answer = get_answer(query)
print(answer)

query = "How have relations between India and the US improved?"
answer = get_answer(query)
print(answer)

我们将使用特定的查询来获取上下文,然后将查询和上下文作为提示传递给LLM模型,以获取响应。

8. 结论:

在本博客文章中,我们展示了使用LangChain和Pinecone构建基于文档的问答系统的过程。通过利用语义搜索和大型语言模型的能力,这种方法为从大量文档收集中提取有价值信息提供了强大且灵活的解决方案。此外,该系统可以轻松定制和适应个人需求和特定领域,为用户提供高度适应和个性化的解决方案。

愿这段美妙的文字之旅能够振奋你的精神,给你带来微笑,让你的心充满喜悦和积极性。愉快的阅读,祝你快乐如影随形!

2023-10-20 17:00:25 AI中文站翻译自原文