找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1239

积分

0

好友

157

主题
发表于 2 小时前 | 查看: 1| 回复: 0

在构建搜索或者 RAG(检索增强生成)系统时,咱们是不是经常遇到下面这种让人挠头的场景?

知识库里明明有一份《企业差旅报销制度 V3.0.pdf》,里面白纸黑字写着打车费用的报销上限。可用户偏偏只输入“打车钱”三个字来搜索。结果呢?要么搜不到,要么搜出来的结果相关度极低,根本对不上号。

这背后的根本原因在于,用户的查询语句和文档内容在语义空间里没有产生有效重叠。用户的输入往往是口语化、碎片化的短句;而文档则是正式、结构化的长文本。这就造成了一道“意图鸿沟”。

查询扩展(Query Expansion)要解决的,就是这道鸿沟。它的核心逻辑很聪明:咱们别傻傻地直接去搜用户输入的那几个字,而是要想办法去搜“用户心里真正想找的那个东西”。下面,咱们就来聊聊三种主流且高效的查询扩展技术方案,看看它们是怎么各显神通的。

一、方案 A:LLM 多路改写 —— 让模型当“翻译官”

这是最直观、最容易想到的方法。既然用户“词不达意”,那就利用大语言模型(LLM)的能力,把用户那个简短的短语,扩充、改写成多个不同角度、不同表达方式的完整句子,然后并行地进行搜索。

1. 原理

用户输入的查询往往是模糊、不完整的。这个方案的思路是,通过设计特定的 Prompt,让 LLM 充当一个“翻译官”或“扩展器”。它的任务是把一个模糊的查询,“翻译”成 3-5 个风格各异但意图明确的精确查询。

2. 典型流程

  1. 用户输入:例如,“连不上网”。
  2. LLM 改写指令:Prompt 可以这样设计:“请将上述用户问题,改写成 3 个不同维度的、更专业的搜索查询,可以包含技术术语、同义词变体、具体场景描述等。”
  3. 生成结果:LLM 可能会输出:
    • “网络连接故障诊断与排除方法”
    • “无法连接互联网的可能原因及解决方案”
    • “Wi-Fi 或以太网连接失败如何处理”
  4. 执行检索:将原始查询“连不上网”和这 3 个改写后的句子,一共 4 个查询,分别进行向量检索(Vector Search)。
  5. 结果聚合:收集所有检索返回的文档,然后进行去重(Deduplication)重排序(Rerank),最终呈现给用户或交给后续的生成环节。

3. 优势与劣势

  • 优点:能极大地提高召回率(Recall)。只要用户的意图落在任何一个改写后的查询范围内,相关文档就能被找出来,有效解决了因关键词不匹配导致的“漏搜”问题。
  • 缺点:增加了系统延迟(Latency) 和成本。因为需要额外调用一次 LLM API 来生成改写查询,并且后续要执行多次向量检索,计算开销变大。

当你的系统主要依赖 LLM 来处理复杂语义时,多路改写是一个平衡效果与复杂度的不错起点。

二、方案 B:HyDE(假设文档嵌入)—— “以假乱真”的杀手锏

HyDE(Hypothetical Document Embeddings)是目前向量检索领域公认的一个“大招”。它的思路非常巧妙,是逆向思维的典范:不去扩充问题,而是直接“伪造”一个答案

1. 要解决的痛点

一个被观察到的现象是:像 BERT 这类经过对比学习训练的向量模型,在计算“问题”和“答案”的相似度时,表现可能一般;但在计算“答案”和“答案”的相似度时,表现却出奇地好。也就是说,模型更擅长识别两段文本是不是在说同一件事(都是答案),而不是识别一个问题和一个答案是否匹配。

2. 核心原理

在正式检索之前,先让 LLM 针对用户的查询,“脑补”一篇答案文档。这篇文档是 LLM “幻想”出来的,内容可能不准确,甚至包含事实错误(Hallucination)。但关键在于,它幻想出来的这篇文档,其句式结构、语气风格、核心关键词,都与真实知识库里的文档高度相似。
然后,我们不去编码用户的问题,而是编码这篇“伪造”的答案文档,用它的向量去知识库里搜索。由于“假答案”和“真答案”在语义和风格上高度接近,检索精准度(Precision)往往会大幅提升。

3. 工作流程

  1. 用户输入:例如,“如何退货?”
  2. LLM 生成假设文档:Prompt 可以是:“请针对‘如何退货?’这个问题,生成一段假设性的、详细的答案文档。” LLM 可能会生成:

    “如果您需要办理退货,请首先登录您的个人中心,找到对应的订单详情页面,点击‘申请售后’按钮。请注意,商品需满足七天无理由退货条件,且包装完好……(注:这是LLM根据常识‘瞎编’的,但其中包含了‘个人中心’、‘订单详情’、‘申请售后’、‘七天无理由’等关键语义和词汇)”

  3. 编码:将这段“瞎编的答案”文本,通过嵌入模型(Embedding Model)转化为向量。
  4. 检索:用这个“答案向量”去向量数据库里进行相似度搜索。
  5. 结果:因为“瞎编的答案”和知识库里真实的《退货政策文档》在语义和行文上非常接近,所以能精准地将其检索出来。

4. 适用场景

这种方法特别适合跨域检索,或者用户问题极其简短、模糊的场景。当用户的查询与文档库的“语言体系”完全不同时,HyDE 能架起一座高效的桥梁。

三、方案 C:思维链/子问题分解 —— 破解复杂查询

这个方案专门用来对付那些复杂、包含多步逻辑(多跳)的模糊问题。

1. 典型场景

用户问:“对比一下 iPhone 15 和华为 Mate 60 的屏幕参数。”
如果直接用这句话去检索,很可能只能搜到一些泛泛而谈的对比新闻或评测视频,而找不到具体、精确的屏幕参数规格表。

2. 原理

利用 LLM 的推理能力,将复杂的母问题(Parent Query)拆解成若干个独立的、原子化的子问题(Child Queries)。每个子问题都更简单、指向性更强,更容易被精确检索。

3. 流程

  1. 拆解
    • 子问题 1: “iPhone 15 的屏幕参数有哪些?例如尺寸、分辨率、刷新率、亮度等。”
    • 子问题 2: “华为 Mate 60 的屏幕参数有哪些?”
  2. 并行检索:分别用这两个子问题去向量数据库或全文搜索引擎中检索,获取最精准的数据片段(可能是规格表的一行,或技术文档的一段)。
  3. 汇总合成:将检索到的关于 iPhone 15 和华为 Mate 60 屏幕参数的信息片段,一并喂给 LLM,让它来组织语言,生成最终的对比性回答。

四、实战技术选型:对症下药,组合出拳

并不是所有场景都需要祭出最复杂的 HyDE。在实际工程中,我们需要根据用户查询的特征来选择最合适(性价比最高)的技术。下表是一个简单的选型参考:

用户查询特征 推荐技术 资源消耗 预期效果提升
拼写错误/近义词/词干变化 传统 NLP 扩展(如:同义词库、词干还原、拼写校正) 低(无需调用LLM) 中等
短语简短/口语化/意图单一 LLM 多路改写 中等(1次LLM调用+多次检索)
抽象概念/零样本/跨域查询 HyDE(假设文档嵌入) 高(LLM生成长文本较慢) 极高
逻辑复杂/多跳/对比类查询 子问题分解 高(多次检索与合成) 极高

通常,一个健壮的工业级 RAG 系统会采用混合策略。例如,先判断查询复杂度,简单查询走同义词扩展,中等复杂度走多路改写,高复杂度则启用 HyDE 或子问题分解。

五、核心代码逻辑示例(Python 伪代码)

如果你在使用 LangChain 或 LlamaIndex 这类框架,查询扩展的逻辑大致可以这样实现(以下是概念性伪代码):

def query_expansion_search(user_query):
    # 1. 调用 LLM 生成 N 个相关的扩展问题
    prompt = f"将 '{user_query}' 改写为3个更专业、更详细的搜索查询。"
    augmented_queries = llm.generate([prompt])

    # 加上原始查询,组成查询集合
    all_queries = [user_query] + augmented_queries

    search_results = []
    # 2. 并行执行向量检索
    for q in all_queries:
        vector = embedding_model.encode(q) # 将查询编码为向量
        results = vector_db.search(vector, k=5) # 检索最相似的5个文档
        search_results.extend(results)

    # 3. 结果去重 (基于文档ID或内容哈希)
    unique_results = deduplicate(search_results)

    # 4. (可选) 使用重排序器(Reranker)进行精排
    # 例如使用 Cross-Encoder 模型,综合考虑原始查询与每个文档的相关性
    final_results = reranker.rank(user_query, unique_results)

    return final_results

总结

用户查询太模糊,本质是“用户意图”和“系统语料”之间的语义鸿沟。这道鸿沟有不同的表现形式,也需要不同的“桥梁”来跨越:

  • 如果是词汇鸿沟(用户不懂专业术语),用 LLM 多路改写来丰富查询表达。
  • 如果是语义鸿沟(“问题”和“答案”文本形态差异太大),用 HyDE 来“伪造”答案,实现同质匹配。
  • 如果是逻辑鸿沟(问题复杂,包含多个子意图),用子问题分解来化繁为简。

我们不可能指望所有用户都去学习“提示词工程”。查询扩展,就是系统在后台主动为用户完成提示词优化的智能过程。 它让搜索和 RAG 系统变得更聪明、更贴心,也更强大。

希望这些方案能为你优化搜索系统带来一些启发。在实际应用中,如何组合、调试这些策略,并将其无缝集成到你的架构中,是更值得深入探讨的工程问题。欢迎在 云栈社区 分享你的实战经验或遇到的挑战。




上一篇:Git提交前拦截慢SQL:基于Qoder与RDS Copilot的自动审查实践
下一篇:OpenClaw全量记忆机制解析:基于本地存储与混合检索的Agent持久化方案
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-10 04:50 , Processed in 0.402614 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表