ChatGPT 人工智能 GPT4 伦理 生成式 医疗 监管 安全 机器学习 深度学习 神经网络 计算机视觉 强化学习 模型 算法 应用 开发 研究 工具 平台 框架 数据集 训练 部署 安全 合规 培训 投资 LLM,llm AI,ai,Ai 大模型 大语言模型 制图 生图 绘图 文生图 文生视频 生成式AI AGI 世界模型 sora chatGPT,chatgpt,ChatGpt claude openai Llama deepseek midjourney 红熊猫模型 Red panda,panda Stable Diffusion,StableDiffusion,stable DALL- E 3 DALL E DALL Flux,flux 扩散模型 混元大模型 文心一言 通义千问 可灵 Pika PixelDance 豆包 月之暗面 零一万物 阶跃星辰 搜索增强 MiniMax Talkie Agent prompt fastai LangChain TTS 微调 提示词 知识库 智能体
# 热门搜索 #
搜索
RAG 高效应用指南 03:Query 理解
7687点击    2024-08-03 10:57

在这篇文章中,笔者将讨论以下几个问题:


  • • 为什么要进行 query 理解


  • • query 理解有哪些技术(从 RAG 角度)


  • • 各种 query 理解技术的实现(基于 LangChain)


为什么要进行 query 理解


在 RAG 系统中,进行 query 理解是非常关键的一步。query 理解指的是对用户提出的问题进行深入分析,提取出关键信息,从而更准确地从知识库中检索出与用户查询最相关的信息,进而生成高质量的回答。


在 RAG 系统中,对用户 query 进行理解,包括但不限于以下原因:


1、用户表达的模糊性


由于自然语言的复杂性,相同的词汇在不同的上下文中可能有不同的含义,query 理解可以帮助系统识别并纠正这些错误,确保准确地理解用户的真正需求。


比如,用户输入「我想知道子龙是谁?」这里的「子龙」可能指代多种含义,如历史人物赵子龙或者某个昵称。又比如,用户输入 「book」,而 book 有多种含义,可能指一本书,也可能指预订一个座位。


通过 query 理解,系统可以分析上下文,判断用户的意图,从而检索到相关的正确信息。


2、query 和 doc 不在同一个语义空间


用户的 query 通常是非结构化的,可能使用非正式或口语化的语言进行自由表达,而文档则可能采用正式的书面表达。query 理解可以帮助将用户的表述转换为文档中术语,从而提高召回率。


比如,用户输入「手机坏了怎么办」,而文档中可能使用的是「手机维修步骤」这样的表述。又比如,用户可能问「如何让网站更快」,而文档内容可能是「提高网站性能的方法」。


当用户的 query 和文档不在同一个语义空间时,这增加了检索系统的复杂性,因为它需要在不同的表达方式、术语使用、上下文信息等方面建立联系。


3、用户的 query 可能比较复杂


用户的 query 有时可能涉及多个子问题或包含多个步骤,需要将复杂的 query 分解成更易处理的部分,逐一进行处理,以便提供准确和完整的答案。


比如,用户 query:「如何用 Python 分析数据,并生成预测报告?」,而文档内容可能是「使用 Python 分析股票数据的方法包括数据获取、数据清洗、特征提取等步骤」、「生成预测报告的方法包括建立预测模型、进行模型训练和测试、生成报告」。在这个例子,用户的 query 涉及数据分析和报告生成两个主要部分。通过 query 理解,系统可以将复杂的 query 分解为两个子问题:「如何用 Python 分析数据?」和「如何生成预测报告?」,然后分别进行处理和回答。


处理复杂 query 时,RAG 系统需要能够识别并分解用户的查询,将其拆分为更小、更具体的子问题。这样不仅可以提高检索的准确性,还可以使生成的回答更加精确和相关。


query 理解有哪些技术


在 RAG 系统中,query 理解技术是提高信息检索效率和准确性的关键。我把当前常用的 query 理解技术分为三大类:query 改写、query 增强和 query 分解,如图所示。当然,也还有很多其他技术,这里先介绍下面这几种。


上下文信息补全


在多轮对话中,用户的当前输入往往包含隐含的指代关系和省略的信息。例如,用户在对话中提到的「它」可能指代之前对话中提到的某个具体事物。如果缺乏这些上下文信息,系统无法准确理解用户意图,从而导致语义缺失,无法有效召回相关信息。


在这种情况下,我们可以使用上下文信息补全,这里的上下文不仅仅是指多轮对话的信息,还包含当前对话的背景信息,比如时间、地点等。我们可以通过使用大型语言模型(LLM),对当前的 query 进行重写,将上下文中隐含的信息纳入到新生成的 query 中。


下面是一段多轮对话的示例:

User:最近有什么好看的电视剧?
Bot:最近上映了《庆余年 2》,与范闲再探庙堂江湖的故事
User:我想看第一季
Bot:


在这个例子,用户的问题「我想看第一季」包含了隐含的指代信息,没有上下文信息的补全,系统无法知道具体指的是哪部电视剧。通过采用上下文信息补全,我们把前面的对话信息也纳入其中,对 query 进行改写,可以生成类似「我想看庆余年第一季」的完整 query,从而提高后续检索的清晰度和相关性。


上下文信息补全可以提高 query 的清晰度,使系统能够更准确地理解用户意图,不过,因为需要多调用一次 LLM,会增加整体流程的 latency 问题。因此,我们也需要权衡计算复杂度和延迟的问题。


RAG-Fusion


RAG Fusion 旨在提升搜索精度和全面性,它的核心原理是根据用户的原始 query 生成多个不同角度的 query ,以捕捉 query 的不同方面和细微差别。然后通过使用逆向排名融合(Reciprocal Rank Fusion,RRF)技术,将多个 query 的检索结果进行融合,生成一个统一的排名列表,从而增加最相关文档出现在最终 TopK 列表的机会。


RAG Fusion 的整体流程如图所示,工作流程如下


1、多查询生成:直接使用用户输入的 query 进行查询,查询结果可能太窄导致无法产生较为全面的结果。通过使用 LLM 将原始查询扩展成多样化的查询,从而增加搜索的视野和深度。 


2、逆向排名融合(RRF):RRF 是一种简单而有效的技术,用于融合多个检索结果的排名,以提高搜索结果的质量。它通过将多个系统的排名结果进行加权综合,生成一个统一的排名列表,使最相关的文档更有可能出现在结果的顶部。这种方法不需要训练数据,适用于多种信息检索任务,且在多个实验中表现优于其他融合方法。 


3、生成性输出:将重新排名的文档和查询输入到 LLM ,生成结构化、富有洞见的答案或摘要。


拓展阅读


  • • https://towardsdatascience.com/forget-rag-the-future-is-rag-fusion-1147298d8ad1

• •  https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf


  • • https://github.com/Raudaschl/rag-fusion


Multi-Query


跟 RAG Fusion 类似,MultiQuery 是一种通过生成多种视角的查询来检索相关文档的方法。它使用 LLM 从用户输入的查询生成多个不同的查询视角,然后为每个查询检索一组相关文档,并合并这些结果以获得更全面的文档集合。


跟 RAG Fusion 不同的是,MultiQuery 没有使用 RRF 来融合多个搜索结果列表的排名,而是将多个搜索结果放到 context 中。这样做的好处是能够在上下文中保留更多的检索结果,提供更丰富的信息源,同时减少了在排名融合上的复杂性。通过这种方法,用户可以获得更加多样化和全面的信息集合,有助于更好地理解和回答复杂的问题。

拓展阅读


  • • https://python.langchain.com/v0.2/docs/how_to/MultiQueryRetriever/


  • • https://github.com/langchain-ai/rag-from-scratch


HyDE


通常,RAG 向量检索通过使用内积相似度来度量查询(query)和文档(doc)之间的相似性。事实上,这里存在一个挑战:query 和 doc 不在同一个语义空间(前面已经介绍),通过将 query 和 doc 向量化,然后基于向量相似性来检索,检索的精度有限而且噪声可能比较大。为了解决这个问题,一种可行的方法是通过标注大量的数据来训练 embedding 函数。


而 HyDE(假设性文档嵌入,Hypothetical Document Embeddings)技术是一种无监督的方法,它基于这样一个假设:与 query 相比,假设性回答(LLM 直接对 query 生成的答案)与文档共享更相似的语义空间。


HyDE 具体是怎么工作的呢?


首先,HyDE 针对 query 直接生成一个假设性文档或者说回答(hypo_doc)。然后,对这个假设性回答进行向量化处理。最后,使用向量化的假设性回答去检索相似文档。


经过这么一顿操作,以前的 query - doc 检索就变成了 query - hypo_doc - doc 的检索,而此时 hypo_doc 和 doc 可能在语义空间上更接近。因此,HyDE 可以在一定程度上提升文档检索的精准度和相关度。


举个例子,假设用户提问「如何提高睡眠质量?」,HyDE 首先生成一个假设性回答,比如「提高睡眠质量的方法包括保持规律的睡眠时间、避免咖啡因和电子设备等。」,这个假设回答经过编码后,可能与提供的知识库中的文档内容(如不喝咖啡,不玩手机等电子设备)更接近,从而更容易找到相关文档。

HyDE 的核心优势在于:


  1. 1. 避免了在同一向量空间中学习两个嵌入函数的复杂性。


  1. 2. 利用无监督学习,直接生成和利用假设文档。


  1. 3. 在缺乏标注数据的情况下,仍能显著提高检索的准确性和效率。


然而,因为 HyDE 强调问题的假设性回答和查找内容的相似性,因此也存在着不可避免的问题,即,假设性回答的质量取决于大型语言模型的生成能力,如果模型生成的回答不准确或不相关,会影响检索效果。例如,如果讨论的主题对 LLM 来说比较陌生,这种方法就无效了,可能会导致生成错误信息的次数增加。


拓展阅读


  • • https://arxiv.org/pdf/2212.10496


  • • https://docs.llamaindex.ai/en/stable/examples/query_transformations/HyDEQueryTransformDemo/#failure-case-1-hyde-may-mislead-when-query-can-be-mis-interpreted-without-context


  • • https://github.com/langchain-ai/rag-from-scratch


Step-back prompting


Step-back prompting 技术旨在提高 LLM 进行抽象推理的能力,它引导 LLM 在回答问题前进行深度思考和抽象处理,将复杂问题分解为更高层次的问题。


Step-Back Prompting 包含两个主要步骤:


  1. 1. 抽象(Abstraction):不是直接针对问题进行回答,而是首先促使 LLM 提出一个更高级别的「回溯问题」(step-back question),这个问题涉及更广泛的高级概念或原则,并检索与这些概念或原则相关的相关事实。


  1. 2. 推理(Reasoning):在高级概念或原则的基础上,利用语言模型的内在推理能力,对原始问题进行推理解答。这种方法被称为基于抽象的推理(Abstraction-grounded Reasoning)。


研究者在多个挑战性推理密集型任务上测试了 Step-Back Prompting,包括 STEM、知识问答(Knowledge QA)和多跳推理(Multi-Hop Reasoning)。实验涉及 PaLM-2L、GPT-4 和 Llama2-70B 模型,并观察到在各种任务上的性能显著提升。例如,在 MMLU(物理和化学)上,PaLM-2L 的性能分别提高了 7% 和 11%,在 TimeQA 上提高了 27%,在 MuSiQue 上提高了 7%。


Step-Back Prompting 适用于需要复杂推理的领域,如:


  • • STEM 领域:涉及物理和化学等科学原理的应用问题。


  • • 知识问答:需要大量事实性知识的问题回答。


  • • 多跳推理:需要通过多个步骤或信息源进行推理的问题。

拓展阅读


  • • https://arxiv.org/pdf/2310.06117


  • • https://blog.langchain.dev/query-transformations/


  • • https://github.com/langchain-ai/rag-from-scratch


IR-CoT


IR-CoT(Interleaving Retrieval with Chain-of-Thought Reasoning),是一种用于解决多步骤问题(Multi-Step Questions)的技术。IR-CoT 通过交替执行检索(retrieval)和推理(reasoning)步骤来提高大型语言模型(LLMs)在处理复杂问题时的性能,如图所示。


IR-CoT 的核心思想是将检索步骤与推理步骤相结合,以指导检索过程并反过来使用检索结果来改进推理链(Chain-of-Thought, CoT)。论文作者认为,对于多步 QA 任务,单纯基于问题的一次性检索是不够的,因为后续检索的内容取决于已经推导出的信息。


IR-CoT的工作流程如下:


  1. 1. 初始化检索:使用问题作为查询,从知识库中检索一组相关段落。


  1. 2. 交替执行两个步骤


  • • 扩展 CoT:利用问题、到目前为止收集的段落和已经生成的 CoT 句子来生成下一个 CoT 句子。


  • • 扩展检索信息:使用上一个 CoT 句子作为查询来检索额外的段落,并将它们添加到已收集的段落集中。


  1. 3. 重复上述步骤:直到 CoT 报告答案或达到最大允许的推理步骤数。


  1. 4. 终止:返回所有收集的段落作为检索结果,并使用这些段落作为上下文,通过直接 QA 提示或CoT 提示来回答原始问题。

这里,我们以论文中的一个例子来进行说明:


如图所示,


  1. 1. 初始问题:Lost Gravity 是在哪个国家制造的?


  1. 2. CoT 生成与检索步骤交替:


  • • 第一步检索:系统首先进行一次检索,获得相关信息,结果发现「Lost Gravity 是由 Mack Rides 制造的」。


  • • 第二步检索:基于之前的结果,系统进行进一步的检索,发现「Mack Rides 是一家来自德国的公司」。


  • • 第三步检索:继续累积文档,确认这一信息。


  1. 3. 最终回答:根据累积的信息做出回答:「答案是德国」。


IR-CoT 通过交替进行 CoT 生成和检索步骤,使得每一步的检索过程都受到前一步的推理结果指导,从而可以更精确地定位相关信息。


这相比于传统的单次检索方法,即只使用初始问题作为查询的方式,能够获得更多相关且精确的信息,提高了最终答案的准确性。


拓展阅读


  • • https://arxiv.org/pdf/2212.10509


• https://github.com/langchain-ai/rag-from-scratch


Least-to-Most


Least-to-Most prompting 也可以用于解决多步推理的问题,它将复杂问题分解为一系列更简单的子问题,并按顺序解决这些子问题。


Least-to-Most prompting 包括两个主要阶段:


  1. 1. 分解(Decomposition):在这个阶段,将复杂问题分解为更简单的子问题。


  1. 2. 子问题解决(Subproblem Solving):在这个阶段,使用之前解决的子问题的答案来帮助解决当前子问题。


这种方法的核心思想是将问题分解为可管理的步骤,并利用逐步构建的答案来指导模型解决更复杂的问题。

这里,我们以论文中的一个例子来进行说明:

如图所示,展示了如何通过两阶段的方法使用 LLM 解决一个数学题。


问题:Amy 爬到滑梯顶部需要4分钟,从滑梯滑下需要1分钟。水滑梯将在15分钟后关闭。她在关闭之前可以滑多少次?


阶段 1:将问题分解为子问题


LLM 将复杂问题分解为更小的子问题:为了回答「她在关闭之前可以滑多少次?」,我们需要先解决「每次滑行需要多长时间?」的问题。


阶段 2:依次解决子问题


子问题1: 问:每次滑行需要多长时间?答:Amy 爬上滑梯需要4分钟,滑下来需要1分钟。因此每次滑行需要5分钟。


子问题2: 问:她在关闭之前可以滑多少次?答:水滑梯将在15分钟后关闭。每次滑行需要5分钟。因此 Amy 可以滑15 ÷ 5 = 3次。


拓展阅读


  • • https://arxiv.org/pdf/2205.10625


  • • https://github.com/langchain-ai/rag-from-scratch


各种 query 理解技术的实现


知道了各种 query 理解技术的原理,我们就可以尝试使用 LangChain 来实现了。笔者将所有实现代码放在jupyter notebook 中了,需要的读者,请关注公众号,然后发消息 query 获取 notebook 代码


在代码中,我使用了 bge-m3 向量模型和 DeepSeek 大模型,它们都可以很方便地获取到。在使用上述 notebook 代码之前,大家需要先安装如下 python 依赖库:

langchain
langchain-openai
langchain_community
tiktoken
langchainhub
chromadb
beautifulsoup4
unstructured
lxml
sentence-transformers


另外,读者还需要去 DeepSeek 官网(https://platform.deepseek.com/usage)申请 API Key,刚注册的时候,会送 500 万 token。


这里,给大家展示下上下文信息补全的实现,更多代码可以参考笔者的 notebook(关注公众号,然后发消息 query 进行获取)。


上下文信息补全代码如下:

from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate

llm = ChatOpenAI(
    model="deepseek-chat", 
    temperature=0, 
    api_key=your_api_key,
    base_url="https://api.deepseek.com",
    streaming=False
)

system_prompt = """
使用聊天对话中的上下文重新表述用户问题,使其成为一个独立完整的问题,不要翻译聊天历史和用户问题。
<conversation></conversation> 标签中的内容属于聊天对话历史。
<question></question> 标签中的内容属于用户的问题。
省略开场白,不要解释,根据聊天对话历史和当前用户问题,生成一个独立完整的问题。
将独立问题放在 <standalone_question> 标签中。
"""

user_prompt = """
<conversation>
User:最近有什么好看的电视剧?
Bot:最近上映了《庆余年 2》,与范闲再探庙堂江湖的故事
</conversation>

<question>
User:我想看第一季
</question>
"""

messages = [
    {"role": "system", "content": system_prompt},
    {"role": "user", "content": user_prompt},
]

response = llm.invoke(messages)

结果如下:



总结


构建一个高效的 RAG 系统,不仅仅是技术上的挑战,更是对我们理解和应对信息复杂性的考验。本文详细阐述了 Query 理解的重要性、原理和技术实现,揭示了在 RAG 系统中,精确的 Query 理解是提升信息检索与生成质量的关键。


Query 理解作为连接用户需求和知识库的桥梁,其核心在于能够准确捕捉用户的意图,并在海量信息中找到最相关的内容。


一个性能优良的 RAG 系统,离不开对 Query 理解的持续优化。这一过程不仅是技术的迭代,更是对用户需求的深刻理解。还是那句话:提高 RAG 系统性能是一个持续的过程,需要不断地评估、优化和迭代


文章来源微信公众号“AI花果山”


关键词: AI , RAG , 搜索增强 , LLM , Query , 模型训练
AITNT资源拓展
根据文章内容,系统为您匹配了更有价值的资源信息。内容由AI生成,仅供参考
1
AI工作流

【开源免费】n8n是一个可以自定义工作流的AI项目,它提供了200个工作节点来帮助用户实现工作流的编排。

项目地址:https://github.com/n8n-io/n8n

在线使用:https://n8n.io/(付费)


【开源免费】DB-GPT是一个AI原生数据应用开发框架,它提供开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及优化、Multi-Agents框架协作、AWEL(智能体工作流编排)等多种技术能力,让围绕数据库构建大模型应用更简单、更方便。

项目地址:https://github.com/eosphoros-ai/DB-GPT?tab=readme-ov-file



【开源免费】VectorVein是一个不需要任何编程基础,任何人都能用的AI工作流编辑工具。你可以将复杂的工作分解成多个步骤,并通过VectorVein固定并让AI依次完成。VectorVein是字节coze的平替产品。

项目地址:https://github.com/AndersonBY/vector-vein?tab=readme-ov-file

在线使用:https://vectorvein.ai/(付费)

2
知识库

【开源免费】FASTGPT是基于LLM的知识库开源项目,提供开箱即用的数据处理、模型调用等能力。整体功能和“Dify”“RAGFlow”项目类似。很多接入微信,飞书的AI项目都基于该项目二次开发。

项目地址:https://github.com/labring/FastGPT

3
RAG

【开源免费】graphrag是微软推出的RAG项目,与传统的通过 RAG 方法使用向量相似性作为搜索技术不同,GraphRAG是使用知识图谱在推理复杂信息时大幅提高问答性能。

项目地址:https://github.com/microsoft/graphrag

【开源免费】Dify是最早一批实现RAG,Agent,模型管理等一站式AI开发的工具平台,并且项目方一直持续维护。其中在任务编排方面相对领先对手,可以帮助研发实现像字节扣子那样的功能。

项目地址:https://github.com/langgenius/dify


【开源免费】RAGFlow是和Dify类似的开源项目,该项目在大文件解析方面做的更出色,拓展编排方面相对弱一些。

项目地址:https://github.com/infiniflow/ragflow/tree/main


【开源免费】phidata是一个可以实现将数据转化成向量存储,并通过AI实现RAG功能的项目

项目地址:https://github.com/phidatahq/phidata


【开源免费】TaskingAI 是一个提供RAG,Agent,大模型管理等AI项目开发的工具平台,比LangChain更强大的中间件AI平台工具。

项目地址:https://github.com/TaskingAI/TaskingAI

4
prompt

【开源免费】LangGPT 是一个通过结构化和模板化的方法,编写高质量的AI提示词的开源项目。它可以让任何非专业的用户轻松创建高水平的提示词,进而高质量的帮助用户通过AI解决问题。

项目地址:https://github.com/langgptai/LangGPT/blob/main/README_zh.md

在线使用:https://kimi.moonshot.cn/kimiplus/conpg00t7lagbbsfqkq0