LangChain是一个开源的框架,本身不提供 LLM,但是它可以让AI开发人员把像chatgpt这样的大型语言模型(LLM)和外部数据结合起来。LangChain 提供通用的接口访问 LLM,支持OpenAI, HuggingFace, 自定义api等多种LLM。听起来很复杂,但其实它很容易上手。下面我们就用LangChain+chatgpt搭建一个简单的本地知识库。
pip install langchain
在这个例子中,我们将使用 OpenAI 的 API,因此我们需要安装OpenAI的SDK:
pip install openai
其他用到的python库:
pip install unstructured
pip install pdf2image
pip install chromadb
pip install tiktoken
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain import OpenAI,VectorDBQA
from langchain.document_loaders import DirectoryLoader
from langchain.chains import RetrievalQA
import os
os.environ["OPENAI_API_KEY"] = 'Your openai key'
#从指定的abc目录中加载文件所有的txt文件
loader = DirectoryLoader('abc', glob='**/*.txt')
# 将数据转成 document 对象,每个文件会作为一个 document
documents = loader.load()
# 初始化加载器
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0)
# 切割加载的 document
split_docs = text_splitter.split_documents(documents)
# 初始化 openai 的 embeddings 对象
embeddings = OpenAIEmbeddings()
# 将 document 通过 openai 的 embeddings 对象计算 embedding 向量信息并临时存入 Chroma 向量数据库,用于后续匹配查询
docsearch = Chroma.from_documents(split_docs, embeddings)
# 创建问答对象
qa = VectorDBQA.from_chain_type(llm=OpenAI(), chain_type="stuff", vectorstore=docsearch,return_source_documents=True)
# 进行问答
result = qa({"query": "这里是要提问的问题"})
print(result)
DirectoryLoader:加载目录中的所有文档,默认情况下使用UnstructuredLoader
loader = DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader)
docs = loader.load()
len(docs)
TextLoader:txt文本加载器
from langchain.document_loaders import TextLoader
# 定义文本加载器,指定读取的文件路径
loader = TextLoader("test.txt")
loader.load()
CSVLoader:csv文件加载器
from langchain.document_loaders.csv_loader import CSVLoader
# 定义csv加载器,加载指定csv文件
loader = CSVLoader(file_path='./example_data/test.csv')
UnstructuredHTMLLoader:HTML文档加载
from langchain.document_loaders import UnstructuredHTMLLoader
# 定义html加载器
loader = UnstructuredHTMLLoader("test.html")
UnstructuredMarkdownLoader:Markdown文档加载
from langchain.document_loaders import UnstructuredMarkdownLoader
loader = UnstructuredMarkdownLoader(path)
PyPDFLoader:PDF加载器
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("test.pdf")
因为大模型提示词有最大token限制,我们不能把太多的文档内容传给AI,通常是把相关的文档片段穿过去就行,所以这里需要对文档切片处理。
Langchain提供了很多文本切割的工具,其中langchain默认使用RecursiveCharacterTextSplitter:
为了能够根据问题查询相关的文档片段,我们需要把前面拆分的文档片段,分别使用embedding(嵌入模型)计算文本特征向量,然后存储到向量数据库中。
这里我们使用langchain默认的向量数据库chroma。
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 初始化 openai 的 embeddings 对象
embeddings = OpenAIEmbeddings()
# 将 document 通过 openai 的 embeddings 对象计算 embedding 向量信息并临时存入 Chroma 向量数据库,用于后续匹配查询
docsearch = Chroma.from_documents(split_docs, embeddings)