LangChain 与 Elastic 合作,加入向量数据库和语义重排序功能以增强 RAG

2024-08-11 21:36:34 浏览数 (3)

在过去的一年里,生成式 AI 领域发生了很多变化。许多新服务和库相继出现。LangChain 已成为构建大语言模型 (LLM) 应用程序(例如检索增强生成 (RAG) 系统)最受欢迎的库之一。这个库使得原型设计和实验不同模型及检索系统变得非常容易。

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

“过去12个月里,我们与 Elastic 的合作非常出色,尤其是在为开发者和最终用户建立从原型到生产的 RAG 应用程序方面,”LangChain 的联合创始人兼 CEO Harrison Chase 说。“LangChain-Elasticsearch 向量数据库的集成将帮助实现这一目标,我们期待在未来的功能和集成发布中看到这一合作关系的增长。”

Elasticsearch 是一个灵活且高性能的检索系统,包括可扩展的数据存储和向量数据库。我们的目标之一是成为最开放的检索系统。在生成式 AI 这样快速发展的领域,我们希望在开发者使用新兴工具和库时给予支持。这就是为什么我们与 LangChain 这样的库密切合作,并为 GenAI 生态系统添加原生支持。从使用 Elasticsearch 作为向量数据库到混合搜索以及协调完整的 RAG 应用程序。

今年,Elasticsearch 和 LangChain 紧密合作。我们将构建搜索工具的丰富经验融入到简化和增强您使用 LangChain 的体验中。让我们在这篇博客中深入探讨。

快速 RAG 原型设计

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

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

LangChain 集成包

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

代码语言:bash复制
pip install langchain-elasticsearch

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

代码语言:python代码运行次数:0复制
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 存储中。

代码语言:python代码运行次数:0复制
texts = [
    "LangChain 是一个用于开发大语言模型 (LLM) 驱动的应用程序的框架。",
    "Elasticsearch 是一个分布式的、RESTful 的搜索和分析引擎,能够解决越来越多的用例。",
    ...
]

es_store.add_texts(texts)

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

代码语言:python代码运行次数:0复制
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(api_key="sk-...") # 或者设置 OPENAI_API_KEY 环境变量

现在我们已经准备好将我们的 RAG 系统连接在一起。为了简单起见,我们使用一个标准的提示来指示 LLM。我们还将 Elasticsearch 存储转换为 LangChain 的检索器。最后,我们将检索步骤与将文档添加到提示并发送给 LLM 连接起来。

代码语言:python代码运行次数:0复制
from langchain import hub
from langchain_core.runnables import RunnablePassthrough

prompt = hub.pull("rlm/rag-prompt")  # 来自 LangChain hub 的标准提示
retriever = es_store.as_retriever()

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

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

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

代码语言:python代码运行次数:0复制
rag_chain.invoke("哪些框架可以帮助我构建 LLM 应用程序?")
代码语言:python代码运行次数:0复制
"LangChain 是一个专门为构建 LLM 驱动的应用程序而设计的框架。..."

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

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

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

假设我们想要在我们的检索步骤中添加语义重排序功能。通过添加一个 Cohere 重排序步骤,顶部的结果变得更加相关,而无需额外的手动调整。为此,我们定义一个 Retriever,它接收一个返回相应 Query DSL 结构的函数。

代码语言:python代码运行次数:0复制
def text_similarity_reranking(search_query: str) -> Dict:
    return {
        "retriever": {
            "text_similarity_reranker": {
                "retriever": {
                    "standard": {
                        "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 解决方案,同时提供深入调整结果质量所需的灵活性。

0 人点赞