在这篇博客中,我们将探讨构建一个基于文档的自定义虚拟代理所涉及的步骤和组件,使用强大的工具组合:Elasticsearch、Ollama的LLaMA 3.1语言模型和LangChain的RetrievalQA
。该代理能够高效地从大型文档集中检索信息,提取有意义的答案,并为用户查询提供简明的响应。
介绍
在信息时代,企业和组织处理大量文档、数据和非结构化文本。从这些数据集中高效检索特定信息通常是一个挑战。这就是自定义文档代理发挥作用的地方。通过集成Elasticsearch实现可扩展的文档检索,并利用像LLaMA 3.1这样的高级语言模型,我们可以构建一个智能虚拟代理,能够理解自然语言查询并提供准确的答案。
在本教程中,我们将逐步介绍如何使用LangChain、Elasticsearch和Ollama的LLaMA模型构建自定义文档代理。在这个过程中,我们将讨论每个组件的好处以及它们如何协同工作以创建一个强大、可扩展的信息检索系统。
为什么选择 Elasticsearch?
Elasticsearch 是一个分布式搜索引擎,旨在快速、可扩展和全文搜索。它在索引和搜索大量文档集合方面非常高效,使其成为我们自定义文档代理的理想选择。通过对文档进行索引并利用 Elasticsearch 的搜索能力,我们可以快速根据与用户查询的相似性检索相关文本。
Elasticsearch 提供:
- 可扩展性: 能够高效处理大量数据。
- 快速检索: 设计用于近实时搜索,提供快速响应时间。
- 向量搜索: 能够进行基于向量的相似性搜索,与现代语言模型的嵌入相得益彰。
为什么选择 LangChain 和 RetrievalQA?
LangChain 是一个旨在构建由语言模型驱动的应用程序的框架。它提供了文档加载、分割、检索和查询回答的基本工具。使用 LangChain 的 RetrievalQA
,我们可以将文档存储与语言模型结合起来,创建一个将用户查询与最相关文档匹配的管道。
RetrievalQA
增强了:
- 问答系统: 它确保虚拟代理通过检索和处理相关文档直接响应用户查询。
- 上下文相关性: 该模型从上下文相关的文档中提取简洁的答案。
为什么选择 Ollama 的 LLaMA 3.1?
LLaMA 3.1 是一种大型语言模型 (LLM),以其准确性和处理复杂自然语言处理任务的能力而闻名。它旨在高效处理查询并提供类人响应。当与 Elasticsearch 集成时,LLaMA 在处理检索到的文档、理解其内容以及生成简洁、相关的答案方面表现出色。
第一步:安装必要的包
在深入代码之前,您需要安装必要的包。这些库包括文档处理、嵌入和检索系统本身的工具。
!pip install langchain -U langchain-community
!pip install langchain-elasticsearch
!pip install sentence-transformers
!pip install langchain-ollama
!pip install python-docx
!pip install PyMuPDF
第2步:加载和拆分文档
构建我们自定义文档代理的步骤是加载和预处理文档。为此,我们使用LangChain的DirectoryLoader
来加载文档,并使用RecursiveCharacterTextSplitter
将文本拆分为可管理的块。文档拆分对于高效处理和检索至关重要。
directory
变量表示一个包含多个文档的文件夹。
from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
directory = "/path/to/documents"
def load_docs(directory):
loader = DirectoryLoader(directory)
documents = loader.load()
return documents
def split_docs(documents, chunk_size=200, 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)
输出:
第 3 步:使用 SentenceTransformer 嵌入文档并索引到 Elasticsearch
在拆分文档后,我们需要生成嵌入。我们使用 SentenceTransformer
为每个文档块创建向量嵌入。这些嵌入使我们能够高效地执行相似性搜索。
from langchain.embeddings import SentenceTransformerEmbeddings
from langchain_elasticsearch import ElasticsearchStore
def embedding_vectordb(docs):
embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
vectordb = ElasticsearchStore.from_documents(
docs,
index_name="documents_index",
es_api_key="your_elasticsearch_api_key",
embedding=embeddings,
es_cloud_id="your_elasticsearch_cloud_id"
)
return embeddings, vectordb
embeddings, vectordb = embedding_vectordb(docs)
您可以用实际值替换
index_name
、es_api_key
和es_cloud_id
。要获取这些信息,您可以创建一个 Elastic Cloud 账户,部署一个项目,并生成所需的凭据,或者您可以使用 Docker 在本地设置 Elasticsearch 来获取这些值。Elastic cloud: https://cloud.elastic.co/login?redirectTo=%2Fhome
如果您已经将嵌入上传到 Elastic Cloud 作为向量数据库,请在下次使用以下代码以防止上传重复项。它将加载已上传的嵌入,而不是重新上传。
def embedding_vectordb():
embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
vectordb = ElasticsearchStore(
embedding=embeddings,
index_name="documents_index",
es_api_key="your_elasticsearch_api_key",
es_cloud_id="your_elasticsearch_cloud_id"
)
return embeddings, vectordb
embeddings, vectordb = embedding_vectordb()
第4步:集成LLaMA 3.1模型
我们从Ollama加载LLaMA模型以处理问答任务。LLaMA模型根据检索到的文档处理查询并生成响应。
from langchain_ollama import ChatOllama
def load_model():
llm = ChatOllama(
model="llama3.1",
temperature=0,
)
return llm
llm = load_model()
如果您的本地计算机或Google Colab中未安装Ollama,请按照此指南安装Ollama并下载LLaMA 3.1模型。或者,您可以从Ollama拉取任何可用的LLM模型。可用模型及其详细信息的完整列表可以在以下网址找到:https://ollama.com/library。
第5步:设置RetrievalQA链
在文档嵌入和模型加载完成后,我们设置RetrievalQA
链。该链将根据用户的查询检索最相关的文档,将其传递给LLM模型,并返回简明的答案。
from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQA
def setup_prompt_chain(llm, vectordb):
template = """You're Virtual Agent, name Genie.
{context}
Give answer what question you have. Answers will be max 50 words and concise, but you will always provide a full sentence. You will not provide extra out-of-context answers.
Question: {question}
Answer:"""
prompt = PromptTemplate(template=template, input_variables=["context", "question"])
chain_type_kwargs = {"prompt": prompt}
retriever = vectordb.as_retriever(search_kwargs={"k":3})
chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
chain_type_kwargs=chain_type_kwargs,
)
return chain
chain = setup_prompt_chain(llm, vectordb)
第6步:查询代理
设置好链条后,您现在可以查询代理并获得简明的答案。
import time
def get_response(chain, query):
start_time = time.time()
response = chain.run(query)
print(response)
end_time = time.time()
elapsed_time = end_time - start_time
print(f"Time taken to generate answer: {elapsed_time:.2f} seconds")
return response
question = "How old is John Anderson?"
response = get_response(chain, question)
Output:
第7步:额外:比较相似性搜索与上下文压缩
要根据查询检索相关文档,我们可以使用向量数据库中的 similarity_search
。该方法将搜索与查询语义相似的文档,并返回前 k
个匹配项。
question = "How old are John Anderson?"
docs = vectordb.similarity_search(question,k=3)
# Check the length of the document
len(docs)
# Check the content of the first document
docs[0].page_content
输出:
我们可以通过使用 LangChain 的 ContextualCompressionRetriever
进一步优化我们的检索过程,该方法根据文档与查询的相关性进行压缩。这将导致更高效的检索和处理。
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor
compressor = LLMChainExtractor.from_llm(llm)
compressed_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=vectordb.as_retriever()
)
compressed_docs = compressed_retriever.get_relevant_documents(question)
def display_relevant_documents(docs):
for i, doc in enumerate(docs, 1):
print(f"Document {i}:\n\n{doc.page_content}\n{'-' * 100}")
display_relevant_documents(compressed_docs)
输出:
摘要
在这篇博客中,我们探讨了通过结合Elasticsearch、Ollama的LLaMA 3.1模型和LangChain的RetrievalQA
来构建自定义文档代理的过程。我们首先加载并将文档拆分为更小、可管理的块。然后,我们使用SentenceTransformer
创建向量嵌入,这使得使用Elasticsearch进行高效的相似性搜索成为可能。我们集成了LLaMA 3.1进行自然语言处理,使代理能够从相关文档中生成简洁的答案。
我们还比较了两种检索方法:标准相似性搜索和ContextualCompressionRetriever
,后者通过压缩文档来提高检索效率。通过结合这些工具,我们创建了一个能够以简洁、上下文感知的方式回答来自大量文档集查询的虚拟代理。
结论
使用现代工具如 Elasticsearch 和大型语言模型构建自定义文档代理为处理大规模信息检索任务开辟了新的可能性。RetrievalQA
和 LLaMA 3.1 的集成使得响应更加精准、简洁且与上下文相关,使得该代理成为处理大量文档集合的组织的宝贵资产。
本教程展示了构建该代理的逐步方法,展示了将搜索、嵌入和语言模型结合的力量,以创建一个智能、可扩展的虚拟助手。无论是应用于法律文件、内部知识库还是学术研究,这种方法都为基于文档的查询回答提供了强有力的解决方案。
如何学习大模型
现在社会上大模型越来越普及了,已经有很多人都想往这里面扎,但是却找不到适合的方法去学习。
作为一名资深码农,初入大模型时也吃了很多亏,踩了无数坑。现在我想把我的经验和知识分享给你们,帮助你们学习AI大模型,能够解决你们学习中的困难。
下面这些都是我当初辛苦整理和花钱购买的资料,现在我已将重要的AI大模型资料包括市面上AI大模型各大白皮书、AGI大模型系统学习路线、AI大模型视频教程、实战学习,等录播视频免费分享出来
,需要的小伙伴可以扫取。

一、AGI大模型系统学习路线
很多人学习大模型的时候没有方向,东学一点西学一点,像只无头苍蝇乱撞,我下面分享的这个学习路线希望能够帮助到你们学习AI大模型。
二、AI大模型视频教程
三、AI大模型各大学习书籍
四、AI大模型各大场景实战案例
五、结束语
学习AI大模型是当前科技发展的趋势,它不仅能够为我们提供更多的机会和挑战,还能够让我们更好地理解和应用人工智能技术。通过学习AI大模型,我们可以深入了解深度学习、神经网络等核心概念,并将其应用于自然语言处理、计算机视觉、语音识别等领域。同时,掌握AI大模型还能够为我们的职业发展增添竞争力,成为未来技术领域的领导者。
再者,学习AI大模型也能为我们自己创造更多的价值,提供更多的岗位以及副业创收,让自己的生活更上一层楼。
因此,学习AI大模型是一项有前景且值得投入的时间和精力的重要选择。