使用 Elasticsearch、Ollama、Llama 3.1 和 LangChain 构建自定义多文档

在这里插入图片描述

在这篇博客中,我们将探讨构建一个基于文档的自定义虚拟代理所涉及的步骤和组件,使用强大的工具组合: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)

输出:

img

第 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_namees_api_keyes_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:

img

第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

输出:

img

我们可以通过使用 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大模型是一项有前景且值得投入的时间和精力的重要选择。

### RAG (Retrieval-Augmented Generation) with Llama3 and LangChain Integration #### Overview of Retrieval-Augmented Generation (RAG) Retrieval-Augmented Generation combines the strengths of retrieval-based models and generative models to improve response quality by leveraging external knowledge sources. This approach allows systems to retrieve relevant information from a corpus before generating responses, ensuring that outputs are both accurate and contextually appropriate[^1]. #### Introduction to Llama3 Model The Llama3 model represents an advanced iteration within transformer architectures designed specifically for language understanding tasks. It excels at processing large volumes of text data efficiently while maintaining high accuracy levels across various NLP benchmarks. Key features include enhanced parameter optimization techniques and improved pre-training methodologies which contribute significantly towards better performance metrics compared to its predecessors. #### Utilizing LangChain Framework LangChain is a powerful toolset aimed at simplifying interactions between different components involved in building conversational AI applications. By abstracting away complex implementation details associated with integrating multiple services like Elasticsearch, it enables developers to focus more on crafting meaningful user experiences rather than worrying about underlying infrastructure concerns. The framework supports seamless integration with popular libraries such as Hugging Face Transformers, making it easier to deploy sophisticated models into production environments without sacrificing flexibility or scalability options available through cloud providers. #### Integrating RAG Using Llama3 and LangChain To integrate RAG using Llama3 alongside LangChain involves several key steps: For setting up environment variables required by both frameworks: ```bash export ELASTICSEARCH_URL="http://localhost:9200" export MODEL_NAME_OR_PATH="./models/llama3" ``` Creating a custom retriever class compatible with LangChain's API specifications: ```python from langchain.retrievers import BaseRetriever class CustomElasticSearchRetriever(BaseRetriever): def __init__(self, es_client): self.es_client = es_client def get_relevant_documents(self, query): results = self.es_client.search(index="documents", body={"query": {"match": {"content": query}}}) return [hit["_source"]["text"] for hit in results["hits"]["hits"]] ``` Implementing generation logic utilizing retrieved documents along with input queries passed onto Llama3 instance via LangChain pipeline configuration: ```python from transformers import AutoModelForCausalLM, AutoTokenizer import torch from langchain.pipelines import Pipeline tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME_OR_PATH) model = AutoModelForCausalLM.from_pretrained(MODEL_NAME_OR_PATH).to('cuda' if torch.cuda.is_available() else 'cpu') pipeline = Pipeline( tokenizer=tokenizer, model=model, device=-1 if not torch.cuda.is_available() else 0, ) def generate_response(query, retriever_instance): contexts = retriever_instance.get_relevant_documents(query)[:5] # Limit number of docs used during inference prompt_text = f"Context:\n{'\n'.join(contexts)}\n\nQuestion:{query}\nAnswer:" output_sequences = pipeline(prompt_text, max_length=256, do_sample=True, top_k=50, num_return_sequences=1) generated_answer = output_sequences[0]['generated_text'].split('\n')[-1].strip() return generated_answer ``` This setup demonstrates how one can effectively combine these technologies to create intelligent question answering systems capable of delivering precise answers based on indexed document collections accessed through Elasticsearch searches performed internally within this architecture. --related questions-- 1. How does the performance of Llama3 compare against other state-of-the-art models when applied in RAG scenarios? 2. What specific advantages does LangChain offer over alternative solutions for implementing RAG workflows? 3. Can you provide examples where combining Elasticsearch with machine learning algorithms has led to significant improvements in search relevance scores? 4. Are there any best practices recommended for fine-tuning Llama3 parameters tailored explicitly toward optimizing retrieval-augmented generation processes?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值