大模型应用系列:Query 变换的示例浅析

【引】NLP中的经典组件在大模型应用中还有效么?大模型对自然语言处理中的典型任务有什么影响么?

RAG应用通过分割文档、嵌入向量化并检索高语义相似性的块来响应用户问题,但面临文档块不相关、用户用词不当及结构化查询需求等问题。若RAG无法找到必要信息,则无法正确回答。对此,可采用Query变换技术,包括Query改写以提高检索准确性、后退提示以获取背景信息及子查询分解以全面检索。这些方法常利用大模型生成新query,关键在于生成提示词的选择。

fe5e22f16f0494efe452c652664a13f6.jpeg

1. Query 变换及其所解决的问题空间

一般地,RAG应用通常将文档分割成块,然后嵌入向量化,并检索与用户问题具有高语义相似性的块。但是,这会带来一些问题: 

(1)文档块可能包含不相关的内容,这会降低检索效率; 
(2)用户提出的问题可能用词不当,不利于检索; 
(3)结构化查询可能需要从用户提出的问题中产生(例如,用元数据过滤或 SQL 数据库查询向量存储)。

也就是说,用户的query可能写得很糟糕,或者表达方式与我们预期的不同。而且,如果我们的 RAG 应用程序不能找到回答这个问题所需的信息,它就不会正确地回答。面对这些问题,一般会采用Query 变换的技术,主要有3种解决方案:

  • Query改写: 使查询更加具体和详细,提高检索最相关信息的可能性

  • 后退提示: 生成更广泛、更一般的查询,以帮助检索相关的背景信息

  • 子查询分解: 将复杂的查询分解为更简单的子查询,以获得更全面的信息检索。

具体而言,如果考虑一个简单的 RAG流水线,通常的流程是将用户提出的问题直接传递给嵌入模型。然后,将这种嵌入与存储在向量存储中的文档进行比较,返回top-k个最相似的文档,而query变换在传递到嵌入模型之前处理用户query的变换。

随着大模型的普及,这些Query变换的方法都乐意使用大模型来生成新的(或多个新的)query,主要区别在于它们使用的生成提示词。

本文会简述各种Query变换的实现方法示例,当然首先是环境搭建,导入必要的库并设置访问权限。

from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplateimport os
from dotenv import load_dotenv# Load environment variables from a .env file
load_dotenv()# Set the OpenAI API key environment variable
os.environ["OPENAI_API_KEY"] = os.getenv('OPENAI_API_KEY')

2. Query改写

简单地说,Query改写意味着我们将用自己的语言改写用户的query,以便于我们的 RAG 应用程序将知道如何最好地回答。我们将采用改写-检索-读取的方法,而不仅仅是检索-读取的模式。

from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain# LLM configuration
def get_rewriting_llm(model_name: str = "gpt-4o", temperature: float = 0, max_tokens: int = 4000) -> ChatOpenAI:return ChatOpenAI(temperature=temperature, model_name=model_name, max_tokens=max_tokens)# Prompt Template for Query Rewriting
def create_query_rewrite_prompt() -> PromptTemplate:template = """You are an AI assistant tasked with reformulating user queries to improve retrieval in a RAG system. Given the original query, rewrite it to be more specific, detailed, and likely to retrieve relevant information.Original query: {original_query}Rewritten query:"""return PromptTemplate(input_variables=["original_query"], template=template)# Build Query Rewriting Chain
def build_query_rewriting_chain(llm: ChatOpenAI) -> LLMChain:prompt_template = create_query_rewrite_prompt()return prompt_template | llm# Function to Rewrite the Query
def rewrite_query(original_query: str, query_rewriter_chain: LLMChain) -> str:response = query_rewriter_chain.invoke(original_query)return response.content.strip()if __name__ == "__main__":  llm = get_rewriting_llm()query_rewriter_chain = build_query_rewriting_chain(llm)original_query = "What are the impacts of climate change on the environment?"rewritten_query = rewrite_query(original_query, query_rewriter_chain)print("Original query:", original_query)print("\nRewritten query:", rewritten_query)

我们使用生成式人工智能模型来改写问题。这个模型是一个大模型,就像我们在最后一步用来回答问题的模型一样。或者,它也可以是一个较小的模型,专门训练来执行这项任务。

3. 后退提示

对基于 RAG 流水线的检索来说,许多问题可能有点过于复杂,以至于无法掌握回答这些问题所需的多层次信息。对于这些情况,生成用于检索的多个附加查询可能很有帮助。这些查询将比原始查询更通用。这将使 RAG 流水线能够在多个级别上检索相关信息。

from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain# LLM Configuration
def get_step_back_llm(model_name: str = "gpt-4o", temperature: float = 0, max_tokens: int = 4000) -> ChatOpenAI:return ChatOpenAI(temperature=temperature, model_name=model_name, max_tokens=max_tokens)# Step-Back Prompt Template
def create_step_back_prompt_template() -> PromptTemplate:template = """You are an AI assistant tasked with generating broader, more general queries to improve context retrieval in a RAG system.Given the original query, generate a step-back query that is more general and can help retrieve relevant background information.Original query: {original_query}Step-back query:"""return PromptTemplate(input_variables=["original_query"], template=template)# Build Step-Back Query Chain
def build_step_back_chain(llm: ChatOpenAI) -> LLMChain:prompt_template = create_step_back_prompt_template()return prompt_template | llm# Function to Generate Step-Back Query
def generate_step_back_query(original_query: str, step_back_chain: LLMChain) -> str:response = step_back_chain.invoke(original_query)return response.content.strip()if __name__ == "__main__":llm = get_step_back_llm()step_back_chain = build_step_back_chain(llm)original_query = "What are the impacts of climate change on the environment?"step_back_query = generate_step_back_query(original_query, step_back_chain)print("Original query:", original_query)print("\nStep-back query:", step_back_query)

4.子查询分解

如果用户Query包含多个问题,这会使上下文检索变得棘手。每个问题可能需要不同的信息,我们不会用所有的问题作为信息检索的基础。为了解决这个问题,我们可以将输入分解为多个子查询,并对每个子查询执行检索。

from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from typing import List# LLM Configuration
def get_subquery_llm(model_name: str = "gpt-4o", temperature: float = 0, max_tokens: int = 4000) -> ChatOpenAI:return ChatOpenAI(temperature=temperature, model_name=model_name, max_tokens=max_tokens)# Sub-query Decomposition Prompt Template
def create_subquery_decomposition_template() -> PromptTemplate:template = """You are an AI assistant tasked with breaking down complex queries into simpler sub-queries for a RAG system.Given the original query, decompose it into 2-4 simpler sub-queries that, when answered together, would provide a comprehensive response to the original query.Original query: {original_query}example: What are the impacts of climate change on the environment?Sub-queries:1. What are the impacts of climate change on biodiversity?2. How does climate change affect the oceans?3. What are the effects of climate change on agriculture?4. What are the impacts of climate change on human health?"""return PromptTemplate(input_variables=["original_query"], template=template)# Build Sub-query Decomposition Chain
def build_subquery_decomposer_chain(llm: ChatOpenAI) -> LLMChain:prompt_template = create_subquery_decomposition_template()return prompt_template | llm# Function to Decompose Query into Sub-queries
def decompose_query(original_query: str, subquery_chain: LLMChain) -> List[str]:response = subquery_chain.invoke(original_query).content# Parse the sub-queries by splitting lines and removing unwanted textsub_queries = [q.strip() for q in response.split('\n') if q.strip() and not q.strip().startswith('Sub-queries:')]return sub_queriesif __name__ == "__main__":llm = get_subquery_llm()subquery_chain = build_subquery_decomposer_chain(llm)original_query = "What are the impacts of climate change on the environment?"sub_queries = decompose_query(original_query, subquery_chain)print("\nSub-queries:")for i, sub_query in enumerate(sub_queries, 1):print(f"{i}. {sub_query}")

5.一句话小结

执行Query变换的方法有很多种,虽然这个概念本身并不新颖,并且在NLP中是一个基本组件,但创新之处在于大模型的应用,方法之间的关键区别往往在于所使用的提示词。

【关联阅读】

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

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

相关文章

【Oracle】空格单字符通配符查询匹配失败

问题 在进行模糊查询的时候,通过全局任意字符串匹配出含有两个字刘姓的人,但是通过刘_不能匹配出结果。 解决 检查后发现,姓名中包含空格 SELECT * FROM student WHERE TRIM(sname) LIKE 刘_;第一种解决方案就是查询的时候进行去空格处理&a…

讲讲⾼并发的原则?

大家好,我是锋哥。今天分享关于【讲讲⾼并发的原则?】面试题。希望对大家有帮助; 讲讲⾼并发的原则? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 高并发是指系统在同一时间内能够处理大量请求的能力。要有效地管理…

鸿蒙进阶-AlphabetIndexer组件

大家好,这里是鸿蒙开天组,今天我们来学习AlphabetIndexer组件,喜欢就点点关注吧! 通过 AlphabetIndexer 组件可以与容器组件结合,实现导航联动,以及快速定位的效果 核心用法 AlphabetIndexer不是容器组件…

ubuntu交叉编译expat库给arm平台使用

1.下载expat库源码: https://github.com/libexpat/libexpat/release?page=2 wget https://github.com/libexpat/libexpat/release/download/R_2_3_0/expat-2.3.0.tar.bz2 下载成功: 2.解压expat库,并进入解压后的目录: tar xjf expat-2.3.0.tar.bz2 cd expat-2.3.0 <…

【系统面试篇】进程和线程类(1)(笔记)——区别、通讯方式、同步、互斥、锁分类

目录 一、问题综述 1. 进程和线程的区别&#xff1f; 2. 进程的状态有哪些&#xff1f; 3. 进程之间的通信方式? &#xff08;1&#xff09;管道 &#xff08;2&#xff09;消息队列 &#xff08;3&#xff09;共享内存 &#xff08;4&#xff09;信号量 &#xff08…

nginx(四):如何在 Nginx 中配置以保留真实 IP 地址

如何在 Nginx 中配置以保留真实 IP 地址 1、概述2、nginx配置示例2.1、配置说明2.2、客户端获取真实IP2.2.1、代码说明 3、插曲4、总结 大家好&#xff0c;我是欧阳方超&#xff0c;可以我的公众号“欧阳方超”&#xff0c;后续内容将在公众号首发。 1、概述 当使用nginx作为…

C++《list的模拟实现》

在上一篇C《list》专题当中我们了解了STL当中list类当中的各个成员函数该如何使用&#xff0c;接下来在本篇当中我们将试着模拟实现list&#xff0c;在本篇当中我们将通过模拟实现list过程中深入理解list迭代器和之前学习的vector和string迭代器的不同&#xff0c;接下来就开始…

本篇万字,博客最细,oled多级菜单代码解析,与实现教程,指针实现(含源码)!!!

目录 教程前言 多级菜单基本知识 驱动文件创建 ​编辑 ​编辑 ​编辑 定义菜单数据类型代码解析 按键代码解析 菜单数据赋值代码解析 菜单按键切换显示代码解析 项目工程移植地址 教程前言 前言&#xff1a;编写不易&#xf…

华为HarmonyOS打造开放、合规的广告生态 - 贴片广告

场景介绍 贴片广告是一种在视频播放前、视频播放中或视频播放结束后插入的视频或图片广告。 接口说明 接口名 描述 loadAd(adParam: AdRequestParams, adOptions: AdOptions, listener: AdLoadListener): void 请求单广告位广告&#xff0c;通过AdRequestParams、AdOptions…

Leetcode137只出现一次的数字|| 及其拓展

简述&#xff1a; 虽然标题是这么描述的&#xff0c;但是我们不是一上来就解这道题&#xff0c;先看一下他的子题和扩展 子题&#xff1a;136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 扩展题&#xff1a; 所以我们由易到难&#xff0c;先来看第一道&#x…

【解决办法】无法使用右键“通过VSCode打开文件夹”

个人博客&#xff1a;苏三有春的博客 前言 作者的编程环境为VScode&#xff0c;工作时常使用VScode打开整个工程文件夹。如果先打开VScode再从VScode中选择文件夹打开效率太慢&#xff0c;作者一般使用的方式是右键文件夹&#xff0c;直接选择"通过code打开文件夹"…

数据揭秘:掌握K-means聚类算法的精髓与实践

数据揭秘&#xff1a;掌握K-means聚类算法的精髓与实践 在机器学习领域&#xff0c;聚类是一种探索性的数据挖掘技术&#xff0c;用于将数据集中的样本划分成若干个簇&#xff0c;使得同一簇内的样本相似度高&#xff0c;而不同簇之间的样本相似度低。本文将深入探讨聚类分析的…

ADNI蛋白质数据集下载

&#xff08;我发现这个网站最近又更新了界面&#xff0c;现在变得很好看很简洁&#xff0c;但是有一些入口变了&#xff09; 1.官网链接 https://ida.loni.usc.edu/home/projectPage.jsp?projectADNI 2.登录 选择ADNI&#xff08;其实PPMI数据也是这样下的&#xff09;&a…

【数据分享】2024年我国省市县三级的生活服务设施数量(46类设施/Excel/Shp格式)

人才市场、售票处、旅行社等生活服务设施的配置情况是一个城市公共基础设施完善程度的重要体现&#xff0c;一个城市生活服务设施种类越丰富&#xff0c;数量越多&#xff0c;通常能表示这个城市的公共服务水平越高&#xff01; 本次我们为大家带来的是我国各省份、各地级市、…

彻底解决idea不识别java项目

需求背景 下载了一个java swing的项目,通过idea导入后,项目无法识别。打开java文件,也不会报错,也不编译。 无法识别效果图 可以看到左侧的菜单,项目是没有被识别。 打开java文件,可以看到没有识别,java的图标也没有出现。 解决方法 1、打开Project Structure 2、修改…

HTMLCSS:打造酷炫下载安装模拟按钮

效果演示 这段代码通过HTML和CSS创建了一个具有交互效果的下载按钮&#xff0c;当复选框被选中时&#xff0c;会触发一系列动画和样式变化&#xff0c;模拟了一个下载和安装的过程&#xff0c;包括圆形的动画、文本的显示和隐藏等。 HTML <div class"container&quo…

Multi Agents协作机制设计及实践

01 多智能体协作机制的背景概述 在前述博客中&#xff0c;我们利用LangChain、AutoGen等开发框架构建了一个数据多智能体的平台&#xff0c;并使用了LangChain的Multi-Agents框架。然而&#xff0c;在实施过程中&#xff0c;我们发现现有的框架存在一些局限性&#xff0c;这些…

ML2001-1 机器学习/深度学习 Introduction of Machine / Deep Learning

图片说明来自李宏毅老师视频的学习笔记&#xff0c;如有侵权&#xff0c;请通知下架 影片参考 【李宏毅】3.第一节 - (上) - 机器学习基本概念简介_哔哩哔哩_bilibili 1. 机器学习的概念与任务类型 概念&#xff1a;机器学习近似于寻找函数&#xff0c;用于处理不同类型的任…

90%会展主办方都会用的6款数字化工具

在会展行业&#xff0c;数字化转型已成为提升竞争力的关键。面对日益增长的运营成本和收入增长的瓶颈&#xff0c;主办方需要借助数字化工具来实现效率提升和成本控制。 今天介绍几种常见的数字化工具和应用方式。 一、线上展览平台 构建线上展览平台是会展主办方拓展线上销…

JMeter快速造数之数据导入导出

导入数据 输入表格格式如下 创建CSV Data Set Config 在Body Data中调用 { "username": "${email}", "password": "123456", "client_id": "00bb9dbfc67439a5d42e0e19f448c7de310df4c7fcde6feb5bd95c6fac5a5afc"…