构建向量索引数据库

我们上个案例里面有一步是将 document 信息转换成向量信息和embeddings的信息并临时存入 Chroma 数据库。

因为是临时存入,所以当我们上面的代码执行完成后,上面的向量化后的数据将会丢失。如果想下次使用,那么就还需要再计算一次embeddings,这肯定不是我们想要的。

那么,这个案例我们就来通过 Chroma 和 Pinecone 这两个数据库来讲一下如何做向量数据持久化。

因为 LangChain 支持的数据库有很多,所以这里就介绍两个用的比较多的,更多的可以参看文档:https://python.langchain.com/en/latest/modules/indexes/vectorstores/getting\_started.html

Chroma

chroma 是个本地的向量数据库,他提供的一个 persist_directory 来设置持久化目录进行持久化。读取时,只需要调取 from_document 方法加载即可。

  1. from langchain.vectorstores import Chroma
  2. # 持久化数据
  3. docsearch = Chroma.from_documents(documents, embeddings, persist_directory="D:/vector_store")
  4. docsearch.persist()
  5. # 加载数据
  6. docsearch = Chroma(persist_directory="D:/vector_store", embedding_function=embeddings)

Pinecone

Pinecone 是一个在线的向量数据库。所以,我可以第一步依旧是注册,然后拿到对应的 api key。https://app.pinecone.io/

免费版如果索引14天不使用会被自动清除。

然后创建我们的数据库:

Index Name:这个随意

Dimensions:OpenAI 的 text-embedding-ada-002 模型为 OUTPUT DIMENSIONS 为 1536,所以我们这里填 1536

Metric:可以默认为 cosine

选择starter plan

image-20230405184646314

持久化数据和加载数据代码如下

  1. # 持久化数据
  2. docsearch = Pinecone.from_texts([t.page_content for t in split_docs], embeddings, index_name=index_name)
  3. # 加载数据
  4. docsearch = Pinecone.from_existing_index(index_name, embeddings)

一个简单从数据库获取 embeddings,并回答的代码如下

  1. from langchain.text_splitter import CharacterTextSplitter
  2. from langchain.document_loaders import DirectoryLoader
  3. from langchain.vectorstores import Chroma, Pinecone
  4. from langchain.embeddings.openai import OpenAIEmbeddings
  5. from langchain.llms import OpenAI
  6. from langchain.chains.question_answering import load_qa_chain
  7. import pinecone
  8. # 初始化 pinecone
  9. pinecone.init(
  10. api_key="你的api key",
  11. environment="你的Environment"
  12. )
  13. loader = DirectoryLoader('/content/sample_data/data/', glob='**/*.txt')
  14. # 将数据转成 document 对象,每个文件会作为一个 document
  15. documents = loader.load()
  16. # 初始化加载器
  17. text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=0)
  18. # 切割加载的 document
  19. split_docs = text_splitter.split_documents(documents)
  20. index_name="liaokong-test"
  21. # 持久化数据
  22. # docsearch = Pinecone.from_texts([t.page_content for t in split_docs], embeddings, index_name=index_name)
  23. # 加载数据
  24. docsearch = Pinecone.from_existing_index(index_name,embeddings)
  25. query = "科大讯飞今年第一季度收入是多少?"
  26. docs = docsearch.similarity_search(query, include_metadata=True)
  27. llm = OpenAI(temperature=0)
  28. chain = load_qa_chain(llm, chain_type="stuff", verbose=True)
  29. chain.run(input_documents=docs, question=query)

image-20230407001803057