LangChain 与 Chroma 的大模型语义搜索应用

1,866 阅读4分钟

在人工智能原生应用领域,Chroma DB 和 LangChain 取得了重大进展。本文探索如何使用 LangChain 和 Chroma DB 进行语义搜索,讨论索引文档、检索语义相似的文档、实现持久化、集成大语言模型 (LLM) 以及使用问答和检索器链。

image.png

介绍

Chroma DB 是一个开源向量数据库,旨在提供高效、可扩展且灵活的方式来存储和搜索嵌入。LangChain 是一个用于开发由语言模型支持的应用程序的综合框架。

准备工作

加载 Python 环境库:

  • pip install openai langchain sentence_transformers chromadb unstructured -q

加载拆分文档:

from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import SentenceTransformerEmbeddings

directory = '/pets'

# 加载文档
def load_docs(directory):
  loader = DirectoryLoader(directory)
  documents = loader.load()
  return documents

# 拆分文档
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

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

# 嵌入文本
embeddings = SentenceTransformerEmbeddings(model_name="chinese-alpaca-2-7b-16k")

这个文本拆分器适合一般文本,基于特定的字符列表进行操作。它尝试按顺序划分这些字符上的文本,直到生成的块足够小。默认情况下,使用"\n\n", "\n", " ", ""等字符分割文本。目标是尽可能长时间地将段落以及随后的句子和单词保留在一起,因为这些通常构成文本中最有效的语义单元。

创建 Chroma DB 向量存储

向量存储是处理和搜索非结构化数据的有效方法,具体流程包括从非结构化数据创建嵌入、保存生成的向量、在查询期间嵌入非结构化查询以检索与该嵌入查询“最相似”的向量。向量存储的作用主要是促进嵌入数据的存储并执行相似性搜索。

LangChain 为多种向量存储提供支持,包括 Chroma、Pinecone 等。这种灵活性使用户能够根据自己的具体要求和偏好选择最合适的向量存储。

使用 Chroma DB 从加载和拆分的文档中创建一个向量存储:

from langchain.vectorstores import Chroma

db = Chroma.from_documents(docs, embeddings)

检索语义相似的文档

创建向量存储后,可以使用它来执行查询并检索语义相似的文档:

query = "人们通常拥有哪些不同种类的宠物?"
matching_docs = db.similarity_search(query)

matching_docs[0]

返回结果:

(Document(page_content='宠物有各种形状和大小,每种都适合不同的生活方式和家庭环境。狗和猫是最常见的,以陪伴和独特的个性而闻名......',metadata={'source': '/pets/Different Types of Pet Animals.txt''}), 0.7325009703636169)

Chroma DB 持久化

持久化存储是任何数据库的一个重要方面,现在创建一个持久 Chroma 数据库实例。如果想保存到磁盘,只需初始化 Chroma 客户端并传入想要保存数据的目录即可。

persist_directory = "chroma_db"

vectordb = Chroma.from_documents(
    documents=docs, embedding=embeddings, persist_directory=persist_directory
)

vectordb.persist()

LangChain、Chroma DB 与 OpenAI 结合

LangChain 中引入了一个称为“链”的抽象,用于表示对组件的调用序列。这些组件可以包含其他链,从而可以构建复杂的嵌套操作序列。一种特定类型的链是问答(QA)链。

QA 链专门用于根据提供的一组文档回答问题。它通过针对嵌入文档对输入问题执行相似性搜索,然后使用模型根据最相关的文档生成答案来实现此目的。

利用 LangChain 提供的问答链,可以从文档中提取答案:

from langchain.chains.question_answering import load_qa_chain
import os

os.environ["OPENAI_API_KEY"] = "key"

from langchain.chat_models import ChatOpenAI
model_name = "gpt-3.5-turbo"
llm = ChatOpenAI(model_name=model_name)

chain = load_qa_chain(llm, chain_type="stuff",verbose=True)

query = "“养宠物有什么情感上的好处?"
matching_docs = db.similarity_search(query)
answer =  chain.run(input_documents=matching_docs, question=query)
answer

返回结果:

拥有宠物可以提供情感支持,减轻压力和焦虑,甚至可以帮助主人过上更健康的生活……

应用与实践

使用 LangChain 中的 RetrieverQA 链来实现检索器查询。

from langchain.chains import RetrievalQA

query = "“养宠物有什么情感上的好处?"
retrieval_chain = RetrievalQA.from_chain_type(llm, chain_type="stuff", retriever=db.as_retriever())
retrieval_chain.run(query)

返回结果:

拥有宠物可以提供情感支持并减轻压力。宠物还可以提供舒适度和一致性......

结语

通过使用 LangChain 和 Chroma DB,可以创建由大型语言模型支持的复杂应用程序,这些模型可以处理复杂的信息检索任务,为创建可以利用向量数据库和语言模型的力量的人工智能原生应用程序打开了大门。