大数跨境
0
0

用户查询太模糊?用查询扩展提升语义匹配能力

用户查询太模糊?用查询扩展提升语义匹配能力 二进制跳动
2026-02-09
3
导读:用户查询太模糊?用查询扩展提升语义匹配能力

在构建搜索或 RAG 系统时,我们经常遇到这种尴尬场景:

知识库里有:“企业差旅报销制度 V3.0.pdf”,里面详细规定了打车费用的上限。

用户搜:“打车钱”。

结果:搜不到,或者相关度极低。

原因在于:用户的查询和文档在语义空间中并不重叠。用户的输入是口语化的、短的;而文档是正式的、长的。

查询扩展的核心逻辑是:不要直接搜用户输入的词,而是搜“用户心里真正想找的内容”。

以下是三种最主流且高效的查询扩展技术方案:

一、 方案 A:LLM 多路改写

这是最直观的方法。利用大模型(LLM)将用户的短语扩充成多个不同角度的完整句子,然后并行搜索。

1. 原理

用户输入往往存在“词不达意”。通过 Prompt 让 LLM 充当“翻译官”,将一个模糊查询翻译成 3-5 个不同风格的精确查询。

2. 流程

用户输入:“连不上网”

LLM 改写指令:“请将上述问题改写为 3 个不同维度的搜索查询,包括技术术语、同义词变体。”

生成结果:

执行:将这 3 个句子分别做 Vector Search,然后对结果进行去重(Deduplication)和重排序(Rerank)

3. 优势与劣势

优点:极大地提高了召回率(Recall),解决了因关键词不匹配导致的漏搜。

缺点:增加了延迟(Latency),因为要调用一次 LLM,且后续要进行多次向量检索。

二、 方案 B:HyDE(假设文档嵌入)—— 这一招非常强

HyDE是目前向量检索领域的“杀手锏”。它的思路是逆向的:不扩充问题,而是直接“伪造”答案。

1. 痛点

向量模型通常在计算“问题”和“答案”的相似度时表现一般,但在计算“答案”和“答案”的相似度时表现极好。

2. 原理

在检索之前,先让 LLM 针对用户的问题写一篇幻觉答案(Hypothetical Document)。这个答案内容可能是不准确的,但它的句式、语气、关键词与真实文档库里的内容是高度相似的。

3. 流程

用户输入:“如何退货?”

LLM 生成假设文档:“如果您需要退货,请登录个人中心,点击订单详情,选择申请售后。由于商品属于...(注意:这是LLM瞎编的,但包含了'个人中心'、'售后'等关键语义)”

编码(Encoding):将这段“瞎编的答案”转化为向量。

检索:用这个向量去数据库里搜。

结果:因为“瞎编答案”和“真实政策文档”在语义上非常接近,检索精准度大幅提升。

4. 适用场景

非常适合跨域检索或用户问题极其简短的场景。

三、 方案 C:思维链/子问题分解

针对复杂、多跳的模糊问题。

1. 场景

用户问:“对比一下 iPhone 15 和 华为 Mate 60 的屏幕参数。”

如果直接搜这句话,可能只能搜到一些泛泛而谈的新闻。

2. 原理

利用 LLM 将复杂问题拆解为多个独立的原子问题。

3. 流程

拆解:

并行检索:分别搜索这两个子问题,获取精准的数据片段。

汇总:将两边的检索结果喂给 LLM,生成最终的对比回答。

四、 实战中的技术选型策略

并不是所有场景都要上最复杂的 HyDE。以下是推荐的组合拳:

用户查询特征 推荐技术 资源消耗 提升效果
拼写错误/同义词 传统 NLP 扩展   低 (无需 LLM)
短语/口语化 LLM 多路改写 
抽象概念/零样本 HyDE (假设文档) 高 (生成长文慢) 极高
逻辑复杂/对比类 子问题分解  高 (多次检索) 极高

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

如果你在使用 LangChain 或 LlamaIndex,逻辑大致如下:

def query_expansion_search(user_query):    

1. 调用 LLM 生成 3 个相关问题    augmented_queries = llm.generate([f"将 '{user_query}' 改写为3个更专业、详细的搜索查询。"    ])    # 加上原始查询     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)                  search_results.extend(results)                 # 3. 结果去重 (基于文档ID)                  unique_results = deduplicate(search_results)                   # 4. (可选) 重排序 Rerank                   # 使用 Cross-Encoder 对最终结果精排                     final_results = reranker.rank(user_query, unique_results)                      return final_results

总结

用户查询太模糊,本质是“意图"和“语料”之间的鸿沟。

如果是词汇鸿沟(不知道专业术语),用LLM 改写

如果是语义鸿沟(问题和答案长得不像),用HyDE

不要指望用户学会“提示词工程”,查询扩展就是系统主动帮用户完成提示词优化的过程。

【声明】内容源于网络
0
0
二进制跳动
15 年 + 技术老兵 架构师|技术总监|科技创业技术合伙人 曾任职苏宁科技、电讯盈科、联想云 专注架构设计与技术落地
内容 739
粉丝 0
二进制跳动 15 年 + 技术老兵 架构师|技术总监|科技创业技术合伙人 曾任职苏宁科技、电讯盈科、联想云 专注架构设计与技术落地
总阅读44
粉丝0
内容739