LangChain 与 Elastic 合作为 RAG 添加向量数据库和语义重排序

发布于:2024-06-13 ⋅ 阅读:(79) ⋅ 点赞:(0)

作者:来自 Elastic Max Jakob

在过去的一年中,我们看到了生成式人工智能领域的许多进展。许多新服务和库应运而生。LangChain 已成为使用大型语言模型 (LLM) 构建应用程序的最受欢迎的库,例如检索增强生成 (RAG) 系统。该库使原型设计和试验不同的模型和检索系统变得非常容易。

为了在 LangChain 中实现对 Elasticsearch 的一流支持,我们最近将我们的集成从社区包提升为官方 LangChain 合作伙伴包。这项工作使将 Elasticsearch 功能导入 LangChain 应用程序变得非常简单。Elastic 团队通过专用存储库管理代码和发布过程。我们将继续改进那里的 LangChain 集成,确保用户可以充分利用 Elasticsearch 的最新改进。

LangChain 联合创始人兼首席执行官 Harrison Chase 表示:“我们与 Elastic 在过去 12 个月的合作非常出色,特别是我们为开发人员和最终用户建立了更好的方式,从原型到生产构建 RAG 应用程序。”“LangChain-Elasticsearch 向量数据库集成将有助于实现这一目标,我们很高兴看到这种合作关系随着未来功能和集成版本的发布而不断发展。”

Elasticsearch 是最灵活、性能最高的检索系统之一,其中包括一个向量数据库。Elastic 的目标之一是成为最开放的检索系统。在像生成式人工智能这样快速发展的领域,我们希望在使用新兴工具和库时为开发人员提供支持。这就是我们与 LangChain 等库密切合作并为 GenAI 生态系统添加原生支持的原因。从使用 Elasticsearch 作为向量数据库到混合搜索和编排完整的 RAG 应用程序。

Elasticsearch 和 LangChain 今年密切合作。我们将利用我们在构建搜索工具方面的丰富经验,让你更轻松、更灵活地体验 LangChain。让我们在这篇博客中深入了解一下。

快速 RAG 原型设计

RAG 是一种为用户提供高度相关问题答案的技术。与直接使用 LLM 相比,其主要优势在于可以轻松集成用户数据,并可以最大限度地减少 LLM 的幻觉。这是通过添加为 LLM 提供相关上下文的文档检索步骤来实现的。

自成立以来,Elasticsearch 一直是相关文档检索的首选解决方案,并且一直是领先的创新者,提供多种检索策略。在将 Elasticsearch 集成到 LangChain 中时,我们可以轻松地在最常见的检索策略之间进行选择,例如密集向量、稀疏向量、关键字或混合。我们允许高级用户进一步定制这些策略。继续阅读以查看一些示例。(请注意,我们假设我们有一个 Elasticsearch 部署。)

LangChain 集成包

要使用 langchain-elasticsearch 合作伙伴包,你首先需要安装它:

pip install langchain-elasticsearch

然后,你可以从 langchain_elasticsearch 模块导入所需的类,例如 ElasticsearchStore,它为你提供了索引和搜索数据的简单方法。在此示例中,我们使用 Elastic 的稀疏向量模型 ELSER(必须先部署)作为我们的检索策略。

from langchain_elasticsearch import ElasticsearchStore

es_store = ElasticsearchStore(
    es_cloud_id="your-cloud-id",
    es_api_key="your-api-key",
    index_name="rag-example",
    strategy=ElasticsearchStore.SparseVectorRetrievalStrategy(model_id=".elser_model_2"),
),

一个简单的 RAG 应用程序

现在,让我们构建一个简单的 RAG 示例应用程序。首先,我们将一些示例文档添加到我们的 Elasticsearch 存储中。

texts = [
    "LangChain is a framework for developing applications powered by large language models (LLMs).",
    "Elasticsearch is a distributed, RESTful search and analytics engine capable of addressing a growing number of use cases.",
    ...
]
es_store.add_texts(texts)

接下来,我们定义 LLM。在这里,我们使用 OpenAI 提供的默认 gpt-3.5-turbo 模型,该模型也为 ChatGPT 提供支持。

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(api_key="sk-...") # or set the OPENAI_API_KEY environment variable

现在我们已准备好将 RAG 系统整合在一起。为简单起见,我们采用标准提示来指导 LLM。我们还将 Elasticsearch 存储转换为 LangChain 检索器。最后,我们将检索步骤与将文档添加到提示并将其发送到 LLM 链接在一起。

from langchain import hub
from langchain_core.runnables import RunnablePassthrough

prompt = hub.pull("rlm/rag-prompt")  # standard prompt from LangChain hub

retriever = es_store.as_retriever()

def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

通过这几行代码,我们现在已经有了一个简单的 RAG 系统。用户现在可以针对数据提出问题:

rag_chain.invoke("Which frameworks can help me build LLM apps?")
"LangChain is a framework specifically designed for building LLM-powered applications. ..."

就这么简单。我们的 RAG 系统现在可以回复有关 LangChain 的信息,而 ChatGPT(3.5 版)则无法做到这一点。当然,有很多方法可以改进这个系统。其中之一就是优化我们检索文档的方式。

通过 Retriever 实现完全的检索灵活性

Elasticsearch 存储提供开箱即用的常见检索策略,开发人员可以自由尝试最适合特定用例的策略。但是,如果你的数据模型比仅包含单个字段的文本更复杂,该怎么办?例如,如果你的索引设置包括一个网络爬虫,该爬虫会生成包含文本、标题、URL 和标签的文档,并且所有这些字段对于搜索都很重要,该怎么办?Elasticsearch 的 Query DSL 让用户可以完全控制如何搜索他们的数据。而在 LangChain 中,ElasticsearchRetriever 直接实现了这种完全的灵活性。所需的只是定义一个将用户输入查询映射到 Elasticsearch 请求的函数。

假设我们想在检索步骤中添加语义重新排名功能(semantic reranking)。通过添加 Cohere 重新排名步骤,顶部的结果会变得更加相关,而无需额外的手动调整。为此,我们定义了一个 Retriever,它接受一个返回相应查询 DSL 结构的函数。

def text_similarity_reranking(search_query: str) -> Dict:
    return {
        "retriever": {
            "text_similarity_rank": {
                "retriever": {
                    "semantic": {
                        "query": {
                            "match": {
                                "text_field": search_query
                            }
                        }
                    }
                },
                "field": "text_field",
                "inference_id": "cohere-rerank-service",
                "inference_text": search_query,
                "window_size": 10
            }
        }
    }

retriever = ElasticsearchRetriever.from_es_params(
    es_cloud_id="your-cloud-id",
    es_api_key="your-api-key",
    index_name="rag-example",
    content_field=text_field,
    body_func=text_similarity_reranking,
)

(请注意,相似性重新排序的查询结构仍在最终确定中。)

此检索器可以无缝插入上面的 RAG 代码。结果是我们的 RAG 管道的检索部分更加准确,从而导致更多相关文档被转发到 LLM,最重要的是,导致更多相关答案。

结论

Elastic 对 LangChain 生态系统的持续投资为最受欢迎的 GenAI 库之一带来了最新的检索创新。通过此次合作,Elastic 和 LangChain 使开发人员能够快速轻松地为最终用户构建 RAG 解决方案,同时提供必要的灵活性以深入调整结果质量。

准备好自己尝试了吗?开始免费试用
希望将 RAG 构建到你的应用程序中?想要使用向量数据库尝试不同的 LLM?
在 Github 上查看我们针对 LangChain、Cohere 等的示例笔记本,并立即加入 Elasticsearch Relevance Engine 培训

原文:LangChain and Elastic collaborate to add vector database and semantic reranking for RAG — Elastic Search Labs