Elasticsearch:没有 “AG” 的 RAG?

作者:来自 Elastic Gustavo Llermaly

了解如何利用语义搜索和 ELSER 构建一个强大且视觉上吸引人的问答体验,而无需使用 LLMs。

想要获得 Elastic 认证?查看下一期 Elasticsearch Engineer 培训的时间!

Elasticsearch 拥有众多新功能,帮助你为你的用例构建最佳搜索解决方案。深入学习我们的示例笔记本,了解更多信息,开始免费云试用,或立即在本地机器上尝试 Elastic。


你可能听说过 RAG(Retrieval Augmented Generation - 检索增强生成),这是一种将你自己的文档与 LLM 结合,以生成类人回答的常用策略。在本文中,我们将探讨如果不使用 LLM,仅依靠语义搜索和 ELSER,能实现多大的效果。

如果你是 RAG 新手,可以阅读这篇关于 Azure 和 AI 上 RAG 的文章,这篇关于使用 Mistral 的 RAG 的文章,或这篇关于使用 Amazon Bedrock 构建 RAG 应用的文章。

大语言模型的缺点

虽然 LLM 能提供类人语言的回答,而不仅仅是返回文档,但在实现它们时需要考虑以下几点:

  • 成本:使用 LLM 服务会按 token 收费,或者如果你想在本地运行模型,则需要专用硬件
  • 延迟:增加 LLM 步骤会增加响应时间
  • 隐私:在使用云端模型时,你的信息会被发送给第三方,涉及到各种隐私问题
  • 管理:引入 LLM 意味着你需要处理一个新的技术组件,包括不同的模型提供商和版本、提示词工程、幻觉等问题

只需要 ELSER 就够了

如果你仔细想想,一个 RAG 系统的效果取决于背后的搜索引擎。虽然搜索后直接读到一个合适的答案比得到一串结果要好,但它的价值体现在:

  • 可以用问题来查询,而不是关键词,这样你不需要文档中有完全相同的词,因为系统 “理解” 意思

  • 不需要读完整篇文本就能获取所需信息,因为 LLM 会在你提供的上下文中找到答案并将其展示出来。

考虑到这些,我们可以通过使用 ELSER 来进行语义搜索获取相关信息,并对文档进行结构化,使用户在输入问题后,界面能直接引导他们找到答案,而无需阅读全文,从而实现非常好的效果。

为了获得这些好处,我们会使用 semantic_text 字段、文本分块 和 语义高亮。想了解最新的 semantic_text 特性,推荐阅读这篇文章。

我们会用 Streamlit 创建一个应用,把所有内容整合起来。它应该看起来像这样:

目标是提问后,从原始文档中获取回答问题的句子,并通过一个按钮查看该句子的上下文。为了提升用户体验,我们还会添加一些元数据,比如文章缩略图、标题和来源链接。这样,根据不同的文章,展示答案的卡片也会有所不同。

要求:

  • Elastic Serverless 实例。可以在这里开始试用

  • Python

关于文档结构,我们会索引 Wikipedia 页面,使每篇文章的每个部分成为一个 Elasticsearch 文档,然后每个文档再被分割成句子。这样,我们就能精准定位回答问题的句子,并能参考该句子的上下文。

以下是创建和测试应用的步骤:

  1. 配置 Inference endpoint

  2. 配置 mappings

  3. 上传文档

  4. 创建应用

  5. 最终测试

本文只包含主要模块,你可以在这里访问完整的代码仓库。

配置推理端点

导入依赖项

from elasticsearch import Elasticsearch
import osos.environ["ELASTIC_ENDPOINT"] = ("your_es_endpoint"
)
os.environ["ELASTIC_API_KEY"] = ("your_es_key"
)es = Elasticsearch(os.environ["ELASTIC_ENDPOINT"],api_key=os.environ["ELASTIC_API_KEY"],
)INDEX_NAME = "wikipedia"

首先,我们将配置推理端点,在这里我们将定义 ELSER 作为我们的模型,并建立分块设置:

  • strategy:可以是 “sentence” 或 “word”。我们选择 “sentence” 以确保所有分块都有完整的句子,因此高亮会作用于短语而不是单词,使答案更流畅。
  • max_chunk_size:定义每个分块的最大单词数。
  • sentence_overlap:重叠的句子数。范围从 1 到 0。我们将其设置为 0,以提高高亮精度。当你想捕捉相邻内容时,建议使用 1。

你可以阅读这篇文章了解更多关于分块策略的内容。

es.options(request_timeout=60, max_retries=3, retry_on_timeout=True).inference.put(task_type="sparse_embedding",inference_id="wiki-inference",body={"service": "elasticsearch","service_settings": {"adaptive_allocations": {"enabled": True},"num_threads": 1,"model_id": ".elser_model_2",},"chunking_settings": {"strategy": "sentence","max_chunk_size": 25,"sentence_overlap": 0,},},
)

配置映射

我们将配置以下字段来定义我们的映射:

mapping = {"mappings": {"properties": {"title": {"type": "text"},"section_name": {"type": "text"},"content": {"type": "text", "copy_to": "semantic_content"},"wiki_link": {"type": "keyword"},"image_url": {"type": "keyword"},"section_order": {"type": "integer"},"semantic_content": {"type": "semantic_text","inference_id": "wiki-inference",},}}
}# Create the index with the mapping
if es.indices.exists(index=INDEX_NAME):es.indices.delete(index=INDEX_NAME)es.indices.create(index=INDEX_NAME, body=mapping)

确保将内容字段复制到我们的 semantic_content 字段中,以便进行语义搜索。

上传文档

我们将使用以下脚本上传来自关于 Lionel Messi 的 Wikipedia 页面上的文档。

# Define article metadata
title = "Lionel Messi"
wiki_link = "https://en.wikipedia.org/wiki/Lionel_Messi"
image_url = "https://upload.wikimedia.org/wikipedia/commons/b/b4/Lionel-Messi-Argentina-2022-FIFA-World-Cup_%28cropped%29.jpg"# Define sections as array of objects
sections = [{"section_name": "Introduction","content": """Lionel Andrés "Leo" Messi (Spanish pronunciation: [ljoˈnel anˈdɾes ˈmesi] ⓘ; born 24 June 1987) is an Argentine professional footballer who plays as a forward for and captains both Major League Soccer club Inter Miami and the Argentina national team. Widely regarded as one of the greatest players of all time, Messi set numerous records for individual accolades won throughout his professional footballing career such as eight Ballon d'Or awards and eight times being named the world's best player by FIFA. He is the most decorated player in the history of professional football having won 45 team trophies, including twelve Big Five league titles, four UEFA Champions Leagues, two Copa Américas, and one FIFA World Cup. Messi holds the records for most European Golden Shoes (6), most goals in a calendar year (91), most goals for a single club (672, with Barcelona), most goals (474), hat-tricks (36) and assists (192) in La Liga, most assists (18) and goal contributions (32) in the Copa América, most goal contributions (21) in the World Cup, most international appearances (191) and international goals (112) by a South American male, and the second-most in the latter category outright. A prolific goalscorer and creative playmaker, Messi has scored over 850 senior career goals and has provided over 380 assists for club and country.""",},{"section_name": "Early Career at Barcelona","content": """Born in Rosario, Argentina, Messi relocated to Spain to join Barcelona at age 13, and made his competitive debut at age 17 in October 2004. He gradually established himself as an integral player for the club, and during his first uninterrupted season at age 22 in 2008–09 he helped Barcelona achieve the first treble in Spanish football. This resulted in Messi winning the first of four consecutive Ballons d'Or, and by the 2011–12 season he would set La Liga and European records for most goals in a season and establish himself as Barcelona's all-time top scorer. The following two seasons, he finished second for the Ballon d'Or behind Cristiano Ronaldo, his perceived career rival. However, he regained his best form during the 2014–15 campaign, where he became the all-time top scorer in La Liga, led Barcelona to a historic second treble, and won a fifth Ballon d'Or in 2015. He assumed Barcelona's captaincy in 2018 and won a record sixth Ballon d'Or in 2019. During his overall tenure at Barcelona, Messi won a club-record 34 trophies, including ten La Liga titles and four Champions Leagues, among others. Financial difficulties at Barcelona led to Messi signing with French club Paris Saint-Germain in August 2021, where he would win the Ligue 1 title during both of his seasons there. He joined Major League Soccer club Inter Miami in July 2023.""",},{"section_name": "International Career","content": """An Argentine international, Messi is the national team's all-time leading goalscorer and most-capped player. His style of play as a diminutive, left-footed dribbler, drew career-long comparisons with compatriot Diego Maradona, who described Messi as his successor. At the youth level, he won the 2005 FIFA World Youth Championship and gold medal in the 2008 Summer Olympics. After his senior debut in 2005, Messi became the youngest Argentine to play and score in a World Cup in 2006. Assuming captaincy in 2011, he then led Argentina to three consecutive finals in the 2014 FIFA World Cup, the 2015 Copa América and the Copa América Centenario, all of which they would lose. After initially announcing his international retirement in 2016, he returned to help his country narrowly qualify for the 2018 FIFA World Cup, which they would exit early. Messi and the national team finally broke Argentina's 28-year trophy drought by winning the 2021 Copa América, which helped him secure his seventh Ballon d'Or that year. He then led Argentina to win the 2022 Finalissima, as well as the 2022 FIFA World Cup, his country's third overall world championship and first in 36 years. This followed with a record-extending eighth Ballon d'Or in 2023, and a victory in the 2024 Copa América.""",},# Add more sections as needed...
]# Load each section as a separate document
for i, section in enumerate(sections):document = {"title": title,"section_name": section["section_name"],"content": section["content"],"wiki_link": wiki_link,"image_url": image_url,"section_order": i,}# Index the documentes.index(index=INDEX_NAME, document=document)# Refresh the index to make documents searchable immediately
es.indices.refresh(index=INDEX_NAME)

创建应用

我们将创建一个应用,用户输入问题后,应用会在 Elasticsearch 中搜索最相关的句子,并使用高亮显示展示最相关的答案,同时显示该句子来自的章节。这样,用户可以正确阅读答案,然后通过类似 LLM 生成的答案中包含引文的方式深入了解。

安装依赖

pip install elasticsearch streamlit st-annotated-text

让我们首先创建一个运行问题语义查询的函数:

# es.py
from elasticsearch import Elasticsearch
import osos.environ["ELASTIC_ENDPOINT"] = ("your_serverless_endpoint"
)
os.environ["ELASTIC_API_KEY"] = ("your_search_key"
)es = Elasticsearch(os.environ["ELASTIC_ENDPOINT"],api_key=os.environ["ELASTIC_API_KEY"],
)INDEX_NAME = "wikipedia"# Ask function
def ask(question):print("asking question")print(question)response = es.search(index=INDEX_NAME,body={"size": 1,"query": {"semantic": {"field": "semantic_content", "query": question}},"highlight": {"fields": {"semantic_content": {}}},},)print("Hits",response)hits = response["hits"]["hits"]if not hits:print("No hits found")return Noneanswer = hits[0]["highlight"]["semantic_content"][0]section = hits[0]["_source"]return {"answer": answer, "section": section}

ask 方法中,我们将返回第一个对应完整章节的文档作为完整上下文,并将来自高亮部分的第一个片段作为答案,按 _score 排序,也就是说,最相关的将是最优先的。

现在,我们将所有内容组合在一个 Streamlit 应用中。为了突出显示答案,我们将使用 annotated_text,这是一个组件,可以更容易地为高亮文本添加颜色并进行标记。

# ui.py
import streamlit as st
from es import ask
from annotated_text import annotated_textdef highlight_answer_in_section(section_text, answer):"""Highlight the answer within the section text using annotated_text"""before, after = section_text.split(answer, 1)# Return the text with the answer annotatedreturn annotated_text(before,(answer, "", "rgb(22 97 50)"),after)def main():st.title("Wikipedia Q&A System")question = st.text_input("Ask a question about Lionel Messi:")if question:try:# Get response from elasticsearchresult = ask(question)if result and "section" in result:section = result["section"]answer = result["answer"]# Display article metadatacol1, col2 = st.columns([1, 2])with col1:st.image(section["image_url"],caption=section["title"],use_container_width=True,)with col2:st.header(section["title"])st.write(f"From section: {section['section_name']}")st.write(f"[Read full article]({section['wiki_link']})")# Display the answerst.subheader("Answer:")st.markdown(answer)# Add toggle button for full contexton = st.toggle("Show context")if on:st.subheader("Full Context:")highlight_answer_in_section(section["content"], answer)else:st.error("Sorry, I couldn't find a relevant answer to your question.")except Exception as e:st.error(f"An error occurred: {str(e)}")st.error("Please try again with a different question.")if __name__ == "__main__":main()

最终测试

要进行测试,我们只需要运行代码并提出我们的提问:

streamlit run ui.py

不错!答案的质量将取决于我们的数据以及问题与可用句子之间的相关性。

结论

通过良好的文档结构和优秀的语义搜索模型如 ELSER,能够构建一个无需 LLM 的问答体验。尽管它有一些局限性,但它是一个值得尝试的选项,帮助我们更好地理解数据,而不仅仅是将一切交给 LLM 并寄希望于它。

在本文中,我们展示了通过使用语义搜索、语义高亮和一些 Python 代码,如何在不使用 LLM 的情况下接近 RAG 系统的结果,而没有其缺点,如成本、延迟、隐私和管理等。

文档结构和用户界面中的用户体验等元素有助于弥补你从 LLM 合成答案中获得的 “人性化” 效果,专注于向量数据库找到回答问题的确切句子的能力。

一个可能的下一步是补充其他数据源来创建更丰富的体验,其中 Wikipedia 只是用于回答问题的多个数据源之一,类似于 Perplexity 的做法。

这样,我们可以创建一个应用,利用不同的平台提供你搜索的人或实体的 360° 视图。

你准备好试试吗?

原文:RAG without “AG”? - Elasticsearch Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/79099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux下安装ollama网不好怎么办?

文章目录 前言kkgithub下载脚本,而不是直接运行修改脚本修改权限还是不行?前言 今天想在linux上面更新一下ollama,于是去到官网: https://ollama.com/download/linux linux下安装ollama还是挺简单的: curl -fsSL https://ollama.com/install.sh | sh我也是特别嗨皮地就…

相机-IMU联合标定:相机-IMU外参标定

文章目录 📚简介🚀标定工具kalibr🚀标定数据录制🚀相机-IMU外参标定📚简介 在 VINS(视觉惯性导航系统) 中,相机-IMU外参标定 是确保多传感器数据时空统一的核心环节,其作用可概括为以下关键点: 坐标系对齐(空间同步),外参误差会导致视觉特征点投影与IMU预积…

基于 Java 的实现前端组装查询语句,后端直接执行查询方案,涵盖前端和后端的设计思路

1. 前端设计 前端负责根据用户输入或交互条件,动态生成查询参数,并通过 HTTP 请求发送到后端。 前端逻辑: 提供用户界面(如表单、筛选器等),让用户选择查询条件。将用户选择的条件组装成 JSON 格式的查询参数。发送 HTTP 请求(如 POST 或 GET)到后端。示例: 假设用…

[STM32] 4-2 USART与串口通信(2)

文章目录 前言4-2 USART与串口通信(2)数据发送过程双缓冲与连续发送数据发送过程中的问题 数据接收过程TXE标志位(发送数据寄存器空)TC标志位(发送完成标志位)单个数据的发送数据的连续发送 接收过程中遇到的问题问题描述&#xf…

Qt多线程TCP服务器实现指南

在Qt中实现多线程TCP服务器可以通过为每个客户端连接分配独立的线程来处理&#xff0c;以提高并发性能。以下是一个分步实现的示例&#xff1a; 1. 自定义工作线程类&#xff08;处理客户端通信&#xff09; // workerthread.h #include <QObject> #include <QTcpSo…

详细介绍Python-pandas-DataFrame全部 *功能* 函数

Python-pandas-DataFrame全部 功能 函数 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是pandas的使用语法。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性。【帮帮志系列文章】&#xff1a;每个知识点…

香港科技大学广州|可持续能源与环境学域博士招生宣讲会—四川大学专场

香港科技大学广州&#xff5c;可持续能源与环境学域博士招生宣讲会—四川大学专场 时间&#xff1a;2025年5月8日&#xff08;星期四&#xff09;16:30开始 地点&#xff1a;四川大学基础教学楼A座504 宣讲嘉宾&#xff1a;肖殿勋 助理教授 一经录取&#xff0c;享全额奖学金…

装饰器设计模式(Decorator Pattern)详解

装饰器设计模式(Decorator Pattern)详解 装饰器模式是一种结构型设计模式,它允许动态地向对象添加额外行为,而无需修改其原始类。这种模式通过包装对象的方式提供灵活的扩展功能替代继承。 1. 核心概念 (1)模式定义 装饰器模式:动态地给一个对象添加一些额外的职责,就…

【SpringMVC】详解参数传递与实战指南

目录 1.前言 2.正文 2.1基础参数传递 2.1.1单参数 2.1.2多参数 2.2对象参数绑定 2.2.1自动封装对象 2.2.2参数别名处理 2.3集合类型处理 2.3.1数组接收 2.3.2List集合接收 2.4JSON参数处理 2.4.1介绍JSON 2.4.2传递JSON参数 2.5RESTful风格参数 2.6文件上传处理…

mysql-窗口函数一

目录 一、感受一下分组与窗口函数的区别 二、滑动窗口&#xff08;子窗口&#xff09;大小的确认 2.1 分组函数下order by使用 2.2 窗口子句 2.3 执行流程 三、函数使用 窗口函数需要mysql的版本大于等于8才行&#xff0c;可以先检查一下自己的mysql版本是多少 select ve…

解决在Mac上无法使用“ll”命令

在 macOS 上&#xff0c;ll 命令是一个常见的别名&#xff0c;它通常是指向 ls -l 的。但是&#xff0c;如果你看到 zsh: command not found: ll&#xff0c;这意味着你当前的 zsh 配置中没有设置 ll 作为别名。 解决方法&#xff1a; 1. 使用 ls -l 命令 如果只是想查看目录…

GTA5(传承/增强) 13980+真车 超跑 大型载具MOD整合包+最新GTA6大型地图MOD 5月最新更新

1500超跑载具 1000普通超跑 1500真车超跑 各种军载具1000 各种普通跑车 船舶 飞机 1000 人物1500 添加式led载具1000 超级英雄最新版 添加添加式武器MOD1000 添加地图MOD500 添加超跑载具2000 当前共计1.2wMOD 4月2日更新 新增770menyoo地图 当前共计12770 新增48款超级英雄最新…

初学Vue之记事本案例

初学Vue之记事本案例 案例功能需求相关Vue知识案例实现1.实现方法及代码2.演示 案例收获与总结 案例功能需求 基于Vue实现记事功能&#xff08;不通过原生JS实现&#xff09; 1.点击保存按钮将文本框的内容显示在特定位置&#xff0c;且清空文本框内容 2.点击清空按钮&#x…

一个linux系统电脑,一个windows电脑,怎么实现某一个文件夹共享

下载Samba linux主机名字不能超过15个字符 sudo dnf install samba samba-client -y 创建共享文件夹 sudo mkdir /shared 配置文件 vim /etc/samba/smb.conf [shared] path /shared available yes valid users linux电脑用户 read only no browsable yes p…

树莓派5+edge-tts 语音合成并进行播放测试

简介 Edge-TTS 是一个基于微软 Edge 浏览器的开源文本转语音(TTS)工具,主要用于将文本转换为自然流畅的语音。它利用了微软 Azure 的 TTS 技术,支持多种语言和声音,同时具备高质量的语音合成能力。这里简单演示在树莓派中安装该项目进行简单测试。 开源仓库地址:https:/…

多模态革命!拆解夸克AI相机技术架构:如何用视觉搜索重构信息交互?(附开源方案对比)

一、技术人必看&#xff1a;视觉搜索背后的多模态架构设计 夸克「拍照问夸克」功能绝非简单的OCRQA拼接&#xff0c;而是一套多模态感知-推理-生成全链路系统&#xff0c;其技术栈值得开发者深挖&#xff1a; 视觉编码器&#xff1a;基于Swin Transformer V2&#xff0c;支持4…

论文阅读:2024 ICLR Workshop. A STRONGREJECT for Empty Jailbreaks

总目录 大模型安全相关研究&#xff1a;https://blog.csdn.net/WhiffeYF/article/details/142132328 A STRONGREJECT for Empty Jailbreaks 对空越狱的 StrongREJECT https://arxiv.org/pdf/2402.10260 https://github.com/dsbowen/strong_reject https://strong-reject.re…

AI生成Flutter UI代码实践(一)

之前的杂谈中有提到目前的一些主流AI编程工具&#xff0c;比如Cursor&#xff0c;Copilot&#xff0c;Trea等。因为我是Android 开发&#xff0c;日常使用Android Studio&#xff0c;所以日常使用最多的还是Copilot&#xff0c;毕竟Github月月送我会员&#xff0c;白嫖还是挺香…

计网分层体系结构(包括OSI,IP,两者对比和相关概念)

众所周知&#xff0c;就像我们计算机领域中的任何东西一样&#xff0c;计算机网络也是个分层的体系结构&#xff0c;现代提出的结构就两种——OSI和TCP/IP&#xff0c;我们先来剖析并对比一下这两种模型&#xff0c;然后总结一下分层思想中的一些共性。 TCP/IP与OSI结构对比图 …

面向对象的XML综合练习

快递包裹配送管理 需求描述 构建一个快递包裹配送管理系统&#xff0c;完成以下操作&#xff1a; 记录每个快递包裹的信息&#xff0c;包括包裹编号、收件人姓名、收件地址和是否已配送。可以添加新的快递包裹到系统中。标记某个包裹为已配送状态。统计所有已配送和未配送的…