掘金 人工智能 9小时前
RAG 每日一技(十三):检索一次不够?学习查询改写与迭代式检索!
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了优化RAG(检索增强生成)系统检索流程的两种关键技术:查询分解和HyDE。针对用户原始查询可能存在的宽泛、多子问题或风格不匹配等问题,查询分解能将复杂问题拆解为多个子问题分别检索,提高覆盖率;HyDE则通过生成高质量的“假设性答案”来优化查询向量,从而提升检索精度。这两种技术都能让RAG系统更像一个经验丰富的侦探,能够从失败中学习并优化检索策略,从而显著提升信息检索的准确性和效率。

RAG系统在检索过程中面临“一锤子买卖”的局限,即第一次检索失败可能导致整个流程的失败。为解决此问题,核心思想是将用户的原始问题视为可优化的对象,通过“查询转换”技术进行改写和优化。

查询分解技术通过将一个包含多个子问题或复杂概念的原始问题,拆解成一系列更简单、独立的子问题。随后对每个子问题进行单独检索,最后汇总所有检索结果,以应对需要多方面信息的问题,显著提高检索的全面性和准确性。

HyDE(Hypothetical Document Embeddings)技术是一种创新方法,它不直接对用户问题进行向量化检索,而是先利用LLM生成一个“假设性的、完美的”答案,然后对这个答案进行向量化处理,并以此作为查询探针在向量数据库中进行搜索。其核心在于利用高质量的虚构答案来匹配更相关的文档。

这两种查询转换技术都能帮助RAG系统规避原始查询的不足,例如过于宽泛、包含多重意图或与文档库语言风格不符等问题,从而提升检索的精准度,使系统表现得更加智能和鲁棒。

前情回顾

到目前为止,我们构建的RAG系统,其检索流程本质上是“一锤子买卖”:用户提问 -> 系统检索 -> 返回结果。如果第一次检索返回的都是不相关的垃圾信息,整个流程就宣告失败。

这就像一个经验不足的侦探,跟丢了第一条线索后,就直接放弃了整个案件。而一个经验丰富的老侦探,则会重新审视案情,分析失败原因,然后从一个新的、更巧妙的角度再次切入。

我们能让我们的RAG系统也成为一名“老侦探”吗?答案是肯定的。核心思想就是:不要把用户的原始问题当成一成不变的“圣旨”,而是要授权给RAG系统,让它在检索前或检索失败后,对原始问题进行“改写”和“优化”。

这项技术,统称为查询转换(Query Transformation)

为什么要改写用户的查询?

用户的原始查询可能存在以下问题:

    过于宽泛或模糊:“请谈谈人工智能。”包含多个子问题:“对比一下Refine和Map-Reduce策略的优缺点。”语言风格与文档库不匹配:用户用口语提问,而文档库是专业术语。

对这些查询进行改写,可以大大提高检索的精准度。下面我们介绍两种强大且常用的查询改写技术。

技术一:查询分解 (Query Decomposition)

当一个问题包含多个方面时,一次性检索很难找到一个“完美”的文档能覆盖所有方面。查询分解的思想就是将一个复杂问题,拆解成多个独立的、更简单的子问题,然后对每个子问题分别进行检索,最后将所有结果汇总。

我们可以用一个LLM来自动完成这个分解任务。

分解Prompt模板示例:

DECOMPOSITION_PROMPT_TEMPLATE = """你是一个查询分析专家。请将用户提出的复杂问题,分解成一系列更简单的、可以独立回答的子问题。请直接返回一个Python列表(List)格式的字符串。复杂问题: "{question}"分解后的子问题列表:"""

工作流程:复杂问题 -> LLM(分解) -> [子问题1, 子问题2, ...] -> 分别检索 -> 汇总结果 -> LLM(最终生成)

技术二:假设性文档嵌入 (HyDE)

HyDE (Hypothetical Document Embeddings) 是一种脑洞大开、但效果惊人的技术。

我们之前的思路是:计算“问题”和“文档”的向量相似度。但问题通常很短,而文档很长,这种不对称性有时会影响相似度计算的准确性。

HyDE反其道而行之,它的流程是:

    拿到用户的问题后,不直接去检索。而是先让一个LLM凭空想象并生成一个“假设性的、完美的”答案。这个答案是模型“猜”出来的,很可能是错的。我们不关心这个答案内容的对错,而是将这个长长的、包含丰富上下文的“假设性答案”进行向量化(Embedding)。用这个“假设性答案的向量”去向量数据库里进行搜索。

核心思想:一个“完美的答案”的向量,在向量空间中,理应与存储着“真实答案”的文档块的向量,极为接近。我们通过生成一个虚构的答案,来创造一个更优质的“查询探针”。

HyDE Prompt模板示例:

HYDE_PROMPT_TEMPLATE = """请根据以下问题,生成一个理想中的、详细的回答。请注意,这个回答是用于后续检索的,不需要保证事实的绝对正确性,但需要包含可能的相关信息和关键词。问题: "{question}"生成的理想回答:"""

工作流程:问题 -> LLM(生成假设性答案) -> Embedding(假设性答案) -> 用新向量进行检索 -> LLM(用真实文档生成最终答案)

上手实战:两种改写策略的代码逻辑

我们用代码逻辑来展示这两种策略如何实现。

# 模拟函数def call_llm(prompt):    print("--- 调用LLM ---")    print(f"Prompt: {prompt[:150]}...")    if "分解" in prompt:        return "['RAG中Refine策略的优缺点是什么?', 'RAG中Map-Reduce策略的优缺点是什么?']"    if "理想回答" in prompt:        return "RAG(检索增强生成)是一种将大语言模型与外部知识库结合的技术。它通过检索相关文档来为生成提供依据,从而减少幻觉并提高答案的准确性和时效性。这在问答、内容创作等领域有广泛应用。"    return "..."def retrieve(text_for_embedding):    print(f"--- 正在对文本进行Embedding并检索 ---")    print(f"文本: {text_for_embedding[:100]}...")    return ["检索到的文档1", "检索到的文档2"]# --- 策略一:查询分解 ---def run_decomposition(question):    print("\n=== 运行查询分解策略 ===")    prompt = DECOMPOSITION_PROMPT_TEMPLATE.format(question=question)    sub_questions_str = call_llm(prompt)    sub_questions = eval(sub_questions_str) # 将字符串格式的列表转为真实的列表    all_retrieved_docs = []    for sub_q in sub_questions:        docs = retrieve(sub_q)        all_retrieved_docs.extend(docs)        print("--- 所有子问题检索到的文档 ---")    print(list(set(all_retrieved_docs))) # 去重# --- 策略二:HyDE ---def run_hyde(question):    print("\n=== 运行HyDE策略 ===")    prompt = HYDE_PROMPT_TEMPLATE.format(question=question)    hypothetical_answer = call_llm(prompt)        retrieved_docs = retrieve(hypothetical_answer)    print("--- HyDE检索到的文档 ---")    print(retrieved_docs)complex_question = "对比一下Refine和Map-Reduce策略的优缺点,并简述RAG是什么。"run_decomposition(complex_question)run_hyde(complex_question)

总结与预告

今日小结:

    优秀的RAG系统不应满足于“一次性”检索,而应具备查询改写迭代检索的能力。查询分解:将复杂问题拆分为简单的子问题,分别检索,再汇总结果,适合处理多方面的问题。HyDE:通过生成一个“假设性答案”来创造一个更优质的查询向量,适合处理较短或较模糊的问题。这些技术让RAG系统变得更“聪明”,能从失败的检索中自我恢复,并主动优化检索路径。

经过这几天的学习,我们已经探索了混合搜索、Refine、Map-Reduce、查询改写等多种高级组件和策略。现在,我们的工具箱里已经装满了各种强大的“乐高积木”。

问题来了:我们该如何高效、优雅地将这些复杂的组件和逻辑流(比如先做查询改写,再做混合搜索,最后用Refine策略生成答案)串联起来,构建成一个稳定、可维护的应用呢?手动编写大量的“胶水代码”显然是一场噩梦。

明天预告:RAG 每日一技(十四):化繁为简,统揽全局——用LangChain构建高级RAG流程

明天,我们将把目光从“造零件”转向“搭框架”。我们将正式介绍大名鼎鼎的AI应用开发框架LangChain,学习它是如何通过“链(Chain)”的概念,将我们学过的所有RAG组件和策略,像搭乐高一样轻松地编排和组合在一起的。这将是提升你RAG开发效率的革命性一步!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

RAG 查询转换 查询分解 HyDE LLM
相关文章