我正参加‘启航计划’

ElasticSearch简介

Elasticsearch(opens in a new tab)是一个分布式、RESTful查找和分析引擎。它供给了一个分布式、多租户能力的全文查找引擎,具有HTTP网络接口和无形式JSON文档。之后咱们将简称ElasticSearch为Es.

一般咱们在项目中运用到的Es场景一般如淘宝查找,百度查找.这次咱们将结合Langchain+OpenAI使Es成为你本地向量存储库.

ElasticSearch装置

请查看Elasticsearch装置阐明(opens in a new tab)。 Es的装置在本文中不再赘述,感兴趣的能够先去官网先LookLook,后期会针对Es在Mac以及Linux装置单独出一篇文章

开始

准备工作

本文依据python3.11展开、 Es版本为7.17.4

#首要咱们装置一些必须的依靠
pip3 install elasticsearch
pip3 install openai
pip3 install langchain

话不多说上代码

请详细阅读代码注释

#引进环境变量
import os
#设置环境变量你的OpenAI秘钥用来之后实例化Embeddings
os.environ["OPENAI_API_KEY"] = "Your OpenAI key"
#设置Es地址用于之后LangChain链接Es
os.environ["ELASTICSEARCH_URL"] = "http://localhost:9200"
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import ElasticVectorSearch
#实例化一个OpenAIEmbedding用于为数据向量化操作
embeddings = OpenAIEmbeddings(openai_api_key=os.environ["OPENAI_API_KEY"])
# 链接一个Es实例,elasticsearch_url为Es的地址我这儿是本地无密码的Es所以直接就是http://localhost:9200,index_name就是Es的索引名称
elastic_vector_search = ElasticVectorSearch(
    elasticsearch_url="http://localhost:9200",
    index_name="test3",
    embedding=embeddings
)
#引进文字加载器
from langchain.document_loaders import TextLoader
#引进文字分词
from langchain.text_splitter import CharacterTextSplitter
#加载咱们准备好的txt文档
loader = TextLoader('./public/school.txt')
documents = loader.load()
#运用分词器将咱们的数据分割成一小段一小段的内容,separator指分隔符建议依据文本进行自定义,chunk_size指分割巨细,偶尔他分隔的内容也会比你设置的巨细要大
text_splitter = CharacterTextSplitter( separator = "<<===>>",
                                       chunk_size = 1000,
                                       chunk_overlap  = 20,
                                       length_function = len)
docs = text_splitter.split_documents(documents)
#将分隔好的document向量化持久化存储在Es中
res = elastic_vector_search.add_documents(docs)
#这儿打印咱们能够看到回来的Id串
print(res)

比如这样的成果

ElasticSearch 你的本地向量数据库
出现这个画面阐明你现已成功将数据向量化并存储在Es中了 假如你之前运用过Es那么你现已能够在Es中查看到存储的向量数据了

查找

q = "依据你供给的文档提问的问题"
#查找到相关的docs,默认搜素4个片段
docs = elastic_vector_search.similarity_search(q)
#打印你能够看到具体查找到了哪些文章片段
print(docs)
#将查找到的docs转换为向量
vectordb = elastic_vector_search.from_documents(docs,embeddings)
retriever = vectordb.as_retriever()
#创建Chain机器人
chain = ConversationalRetrievalChain.from_llm(ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo-16k-0613"),
                                              retriever=retriever,
                                              return_source_documents=True)
def get_answer(question):
    chat_history = []
    result = chain({"question": question, "chat_history": chat_history})
    return result["answer"]
#这时你就能够看到OpenAI输出的成果啦
print(get_answer(q))

总结

不得不说LangChain是一个很牛的依靠,之前有讲过ChormDb作为本地向量数据库、其实Redis也能够作为本地向量数据库,之后将会单独出一篇文章进行讲解。其实所谓的本地向量数据库异曲同工原理都是相同的。就像Mysql和MongoDB相同,尽管一个是联系型数据库,一个对错联系型数据库,但他们核心都相同,乃至Sql句子也类似。好了,期望这篇文章能协助你更好的了解向量数据库。