Elasticsearch 与行业领先的生成式 AI 工具和提供商实现了原生集成。请观看我们的网络研讨会,了解如何超越 RAG 基础功能,或使用 Elastic 向量数据库构建生产就绪型应用。
在本博客中,我们将讨论如何使用 RAG 技术(检索增强生成)和作为向量数据库的 Elasticsearch 来实现 Q&A 体验。我们将使用 LlamaIndex 和本地运行的 Mistral LLM。
在开始之前,我们先来了解一些术语。
术语
LlamaIndex是用于构建 LLM(大型语言模型)应用程序的领先数据框架。LlamaIndex 为构建 RAG(检索增强生成)应用程序的各个阶段提供了抽象概念。像 LlamaIndex 和 LangChain 这样的框架提供了抽象,因此应用程序不会与任何特定 LLM 的应用程序接口紧密耦合。
Elasticsearch由Elastic 提供。Elastic 是 Elasticsearch 背后的行业领导者,Elasticsearch 是一个搜索和分析引擎,支持精确的全文搜索、语义理解的矢量搜索以及两全其美的混合搜索。Elasticsearch 是一种可扩展的数据存储和矢量数据库。我们在本博客中使用的 Elasticsearch 功能在 Elasticsearch 的免费开放版本中提供。
检索增强生成(RAG)是一种人工智能技术/模式,它为 LLM 提供外部知识,以生成对用户查询的回复。这样,法律硕士的答复就可以根据具体情况量身定做,答复也更加具体。
Mistral提供开源和优化的企业级 LLM 模型。在本教程中,我们将使用可在笔记本电脑上运行的开源模型mistral-7b。如果你不想在笔记本电脑上运行模型,也可以使用他们的云版本,在这种情况下,你必须修改本博客中的代码,以使用正确的 API 密钥和软件包。
Ollama可帮助您在笔记本电脑上本地运行 LLM。我们将使用 Ollama 在本地运行开源的 Mistral-7b 模型。
嵌入是文本/媒体意义的数字表示。它们是高维信息的低维表示。
使用 LlamaIndex、Elasticsearch& Mistral 构建 RAG 应用程序:场景概述
场景
我们有一个样本数据集(JSON 文件),内容是一家虚构的家庭保险公司的座席人员与客户之间的呼叫中心对话。我们将建立一个简单的 RAG 应用程序,它可以回答以下问题
Give me summary of water related issues.
高位流量

我们使用 Ollama 在本地运行 Mistral LLM。
接下来,我们以Documents 的形式将 JSON 文件中的对话加载到ElasticsearchStore(由 Elasticsearch 支持的 VectorStore)中。在加载文档时,我们使用本地运行的 Mistral 模型创建嵌入。我们将这些嵌入和对话一起存储在 LlamaIndex Elasticsearch 向量存储(ElasticsearchStore)中。
我们配置一个 LlamaIndex IngestionPipeline,并向其提供我们使用的本地 LLM,在本例中是通过 Ollama 运行的 Mistral。
当我们提出 "请简要介绍与水有关的问题 "这样的问题时、Elasticsearch 可进行语义搜索,并返回与水问题有关的对话。这些对话与原始问题一起发送给本地运行的 LLM,以生成答案。
建立 RAG 应用程序的步骤
本地运行 Mistral
下载并安装Ollama。安装 Ollama 后,运行此命令下载并运行mistral
首次下载并在本地运行模型可能需要几分钟时间。通过提出类似下面 "写一首关于云的诗 "的问题来验证 mistral 是否在运行,并验证诗歌是否符合您的要求。保持 ollama 运行,因为我们稍后需要通过代码与 mistral 模型交互。
安装 Elasticsearch
通过创建云部署(在此说明)或在 docker 中运行(在此说明),启动并运行 Elasticsearch。您也可以从这里开始创建生产级的 Elasticsearch 自托管部署。
假设您使用的是云部署,请按照说明中的要求获取部署的 API 密钥和云 ID。我们稍后将使用它们。
RAG 申请
整个代码可在此Github 代码库中找到,以供参考。克隆 repo 是可选项,因为我们将在下文中介绍代码。
在您最喜欢的集成开发环境中,用以下 3 个文件创建一个新的 Python 应用程序。
index.py与索引数据有关的代码的位置。query.py与查询和 LLM 交互相关的代码都放在这里。.env配置属性(如 API 密钥)的位置。
我们需要安装一些软件包。首先,我们要在应用程序的根文件夹中创建一个新的 python虚拟环境。
激活虚拟环境并安装以下所需软件包。
索引数据
下载conversations.json文件,其中包含客户与我们 fictionaly 房屋保险公司呼叫中心座席之间的对话。将该文件与 2 个 python 文件和 .env 文件一起放在应用程序的根目录中。文件。下面是该文件内容的示例。
我们在index.py 中定义了一个名为get_documents_from_file 的函数,用于读取 json 文件并创建文档列表。文档对象是 LlamaIndex 处理信息的基本单位。
创建摄取管道
首先,将在Install Elasticsearch 部分获得的 Elasticsearch CloudID 和 API 密钥添加到.env 文件中。.env 文件应如下所示(使用真实值)。
通过 LlamaIndexIngestionPipeline,您可以使用多个组件组成一个管道。在index.py 文件中添加以下代码。
如前所述,LlamaIndex IngestPipeline 可由多个组件组成。我们将在pipeline = IngestionPipeline(... 行的管道中添加 3 个组件。
- SentenceSplitter:从
get_documents_from_file()的定义中可以看出,每个文档都有一个文本字段,用来保存 json 文件中的对话内容。该文本字段是一段较长的文本。为了使语义搜索工作顺利进行,需要将其分解成小块文本。SentenceSplitter类可以帮我们做到这一点。这些块在 LlamaIndex 术语中称为节点。节点中的元数据指向它们所属的文档。或者,也可以使用 Elasticsearch Ingestpipeline 进行分块,如本博客所示。 - OllamaEmbedding:嵌入模型可将一段文字转换成数字(也称为向量)。有了数字表示法,我们就可以进行语义搜索,搜索结果与词义相匹配,而不仅仅是进行文本搜索。我们为 IngestionPipeline 提供
OllamaEmbedding("mistral")。使用 SentenceSplitter 分割的语块会通过 Ollama 发送到本地机器上运行的 Mistral 模型,然后 mistral 会为这些语块创建嵌入。 - ElasticsearchStoreLlamaIndex ElasticsearchStore 向量存储会将正在创建的嵌入式内容备份到 Elasticsearch 索引中。ElasticsearchStore 负责创建和填充指定 Elasticsearch 索引的内容。在创建 ElasticsearchStore(由
es_vector_store引用)时,我们提供要创建的 Elasticsearch 索引的名称(本例中为calls)、索引中要存储嵌入的字段(本例中为conversation_vector)以及要存储文本的字段(本例中为conversation)。总之,根据我们的配置ElasticsearchStore在 Elasticsearch 中创建了一个新索引,并将conversation_vector和conversation作为字段(以及其他自动创建的字段)。
将这一切联系起来,我们通过调用pipeline.run(documents=documents) 运行管道。
运行 index.py 脚本执行摄取管道:
管道运行完成后,我们应该会在 Elasticsearch 中看到一个名为calls 的新索引。使用开发控制台运行一个简单的 elasticsearch 查询,就能看到数据和嵌入式内容一起加载。
概括地说,我们从 JSON 文件创建了文档,将文档分割成块,为这些块创建了嵌入,并将嵌入(和文本对话)存储在向量存储(ElasticsearchStore)中。
查询
llamaIndexVectorStoreIndex可以让你检索相关文档和查询数据。默认情况下,VectorStoreIndex 会将嵌入存储在SimpleVectorStore 的内存中。不过,也可以使用外部向量存储(如ElasticsearchStore)来使嵌入持久化。
打开query.py 并粘贴以下代码
我们定义了一个本地 LLM (local_llm) 来指向在 Ollama 上运行的 Mistral 模型。接下来,我们从之前创建的 ElasticssearchStore 向量存储中创建一个 VectorStoreIndex (index),然后从索引中获取一个查询引擎。在创建查询引擎时,我们会引用本地 LLM 来进行响应,我们还会提供 (similarity_top_k=10) 来配置应从向量存储中检索并发送给 LLM 以获得响应的文档数量。
运行query.py 脚本执行 RAG 流程:
我们发送查询Give me summary of water related issues (可随意定制query ),法律硕士的回复应与提供的相关文件类似。
在所提供的背景下,我们看到客户询问与水有关的损害的承保范围。在两个案例中,洪水对地下室造成了破坏,在另一个案例中,屋顶漏水也是问题所在。代理商确认,这两种水渍都在他们各自的保险范围内。因此,与水有关的问题,包括洪水和屋顶漏水,通常都在房屋保险的承保范围之内。
注意事项
这篇博文是关于使用 Elasticsearch 的 RAG 技术的初学者介绍,因此省略了一些功能配置,而这些功能配置将使您能够将这一起点应用到生产中。在构建生产用例时,您需要考虑更复杂的方面,如使用文档级安全保护数据,将数据分块作为 ElasticsearchIngest 管道的一部分,甚至在用于 GenAI/Chat/Q&A 用例的相同数据上运行其他ML 作业。
您还可以考虑使用Elastic Connectors 从各种外部来源(如 Azure Blob Storage、Dropbox、Gmail 等)获取数据并创建嵌入。
Elastic 可实现上述所有功能,并为 GenAI 用例及其他应用提供全面的企业级解决方案。
接下来呢?
- 您可能已经注意到,我们正在将 10 个相关会话与用户问题一起发送给 LLM,以便制定回复。这些对话可能包含 PII(个人身份信息),如姓名、出生日期、地址等。在我们的案例中,LLM 是本地的,因此数据泄漏不是问题。但是,如果您想使用在云中运行的 LLM(例如 OpenAI),则不宜发送包含 PII 信息的文本。在后续博客中,我们将介绍如何在向 RAG 流程中的外部 LLM 发送 PII 信息之前完成屏蔽。
- 在本篇文章中,我们使用了本地 LLM,在接下来的文章 "在 RAG 中屏蔽 PII 数据 "中,我们将介绍如何轻松地从本地 LLM 切换到公共 LLM。
常见问题
什么是 LlamaIndex?
LlamaIndex 是用于构建 LLM(大型语言模型)应用程序的领先数据框架。
什么是 Mistral?
Mistral 是一家提供开源和优化的企业级 LLM 模型的公司。




