在本文中,我们将使用 LlamaIndex 来索引数据,为常见问题实现一个搜索引擎。Elasticsearch 将作为我们的矢量数据库,实现矢量搜索,而 RAG(Retrieval-Augmented Generation,检索增强生成)将丰富上下文,提供更准确的响应。

什么是 LlamaIndex?
LlamaIndex 是一个框架,可帮助创建由大型语言模型(LLM)驱动的代理和工作流,以便与特定或私人数据进行交互。它可以将各种来源(应用程序接口、PDF、数据库)的数据与 LLM 集成,从而完成研究、信息提取和生成上下文化回复等任务。
关键概念:
- 代理:使用 LLM 执行任务的智能助手,任务范围从简单的响应到复杂的操作。
- 工作流程:将代理、数据连接器和高级任务工具结合起来的多步骤流程。
- 语境增强:利用外部数据丰富 LLM 的技术,克服其训练局限性。
LlamaIndex 与 Elasticsearch 集成:
Elasticsearch 可以通过各种方式与 LlamaIndex 配合使用:
- 数据源:使用 Elasticsearch 阅读器提取文档。
- 嵌入模型:将数据编码为向量,用于语义搜索。
- 矢量存储:将 Elasticsearch 用作搜索矢量化文档的存储库。
- 高级存储:配置文档摘要或知识图谱等结构。
使用 LlamaIndex 和 Elasticsearch 创建常见问题搜索
数据准备
我们将以Elasticsearch 服务常见问题解答为例进行说明。每个问题都是从网站上提取的,并保存在一个单独的文本文件中。您可以使用任何方法来组织数据;在本例中,我们选择将文件保存在本地。
文件示例:
保存所有问题后,目录将如下所示:

安装依赖项
我们将使用 Python 语言实现摄取和搜索,我使用的版本是 3.9。作为前提条件,有必要安装以下依赖项:
Elasticsearch 和 Kibana 将使用 Docker 创建,并通过 docker-compose.yml 配置为运行 8.16.2 版本。这样就能更容易地创建本地环境。
使用 LlamaIndex 进行文件摄取
文件将使用 LlamaIndex 索引到 Elasticsearch 中。首先,我们使用SimpleDirectoryReader 加载文件,它允许从本地目录加载文件。加载文档后,我们将使用VectorStoreIndex 对其进行索引。
LlamaIndex 中的矢量存储负责存储和管理文档嵌入。LlamaIndex 支持不同类型的向量存储,在本例中,我们将使用 Elasticsearch。在 StorageContext 中,我们配置 Elasticsearch 实例。由于上下文是本地的,因此不需要额外的参数。有关其他环境中的配置,请参阅文档检查必要的参数:ElasticsearchStore 配置。
默认情况下,LlamaIndex 使用 OpenAItext-embedding-ada-002模型生成嵌入。不过,在本例中,我们将使用文本嵌入-3-小模型。需要注意的是,使用该模型需要一个 OpenAI API 密钥。
以下是完整的文件摄取代码。
执行后,文件将被编入faq索引,如下图所示:

使用 RAG 搜索
要执行搜索,我们需要配置ElasticsearchStore客户端,用 Elasticsearch URL 设置index_name和es_url字段。在retrieval_strategy 中,我们为向量搜索定义了AsyncDenseVectorStrategy。还提供其他策略,如AsyncBM25Strategy(关键词搜索)和AsyncSparseVectorStrategy(稀疏向量)。更多详情,请参阅官方文档。
接下来,我们将创建一个VectorStoreIndex对象,并使用 ElasticsearchStore 对象配置vector_store。通过as_retriever方法,我们可以搜索与查询最相关的文档,并通过similarity_top_k参数设置返回结果的数量为 5。
下一步是 RAG。矢量搜索的结果被纳入本地语言管理器的格式化提示中,从而能够根据检索到的信息做出符合具体情况的响应。
在 PromptTemplate 中,我们定义了提示格式,其中包括
- Context ({context_str}):检索器检索到的文件。
- Query ({query_str}): 用户的问题。
- 说明:指导模型根据环境做出反应,而不依赖外部知识。
最后,LLM 会处理提示,并根据上下文返回准确的回复。
完整代码如下:
现在,我们可以执行搜索,例如"Elastic services are free?" ,并根据常见问题数据本身获得符合上下文的回复。
为了做出这一回应,我们使用了以下文件:
结论
我们使用 LlamaIndex 演示了如何创建一个高效的常见问题搜索系统,并将 Elasticsearch 作为向量数据库提供支持。使用嵌入法对文件进行摄取和索引,从而实现矢量搜索。通过 PromptTemplate,搜索结果被纳入上下文并发送给 LLM,LLM 会根据检索到的文件生成精确且符合上下文的回复。
该工作流程将信息检索与根据上下文生成回复整合在一起,以提供准确、相关的结果。
参考资料
https://www.elastic.co/guide/en/cloud/current/ec-faq-getting-started.html
https://docs.llamaindex.ai/en/stable/api_reference/readers/elasticsearch/
https://docs.llamaindex.ai/en/stable/module_guides/indexing/vector_store_index/
https://docs.llamaindex.ai/en/stable/examples/query_engine/custom_query_engine/
常见问题
什么是 LlamaIndex?
LlamaIndex 是一个框架,可帮助创建由大型语言模型(LLM)驱动的代理和工作流,以便与特定或私人数据进行交互。
LlamaIndex 能否与 Elasticsearch 集成?
是的,Elasticsearch 可以多种方式与 LlamaIndex 配合使用,包括作为数据源(使用 Elasticsearch 阅读器提取文档)、作为嵌入模型(将数据编码为向量,用于语义搜索)、作为向量存储(将 Elasticsearch 用作存储库,用于搜索向量化文档),以及用于高级存储(配置文档摘要或知识图谱等结构)。




