【RAG-六-检索增强技术之查询改写】
D, I = index.search(embedding, k=2) # 检索最相关的两个文档print(f"-
·
📄 查询增强技术(Query Rewriting)文档:提升信息检索性能的关键策略
📘 一、引言
在现代搜索引擎、问答系统和推荐系统中,用户查询的质量直接影响检索系统的性能。然而,现实中的用户问题往往存在以下问题:
- 表达不清晰(如“帮我找点资料”)
- 语言措辞不当(如“这个东西怎么用?”)
- 缺少关键信息(如没有限定时间、地点、领域等)
这些问题会导致传统检索模型难以准确理解用户意图,从而影响召回率和相关性。
为了解决这一挑战,查询改写(Query Rewriting)技术应运而生。其核心思想是:
利用大语言模型(LLM),根据原始模糊或低质量的查询,生成多个语义一致但表达更清晰、信息更丰富的重写版本,以提高后续检索系统的匹配效果。
🧠 二、问题背景与挑战
✅ 问题描述
当用户输入一个表达不清的问题时,直接用于检索可能导致以下问题:
| 问题 | 描述 |
|---|---|
| 检索偏差 | 返回结果偏离用户真实需求 |
| 召回不足 | 无法命中高质量的相关内容 |
| 多义歧义 | 用户问题可能有多种解释,导致模型误判 |
❗ 示例说明
原始查询:
“帮我查一下那个病毒”
该问题缺乏关键信息(如病毒名称、时间、地域、用途等),直接检索可能返回大量无关结果。
🔧 三、解决方案:多角度查询改写
🎯 解决思路
- 利用大语言模型(如 Qwen、ChatGPT、Llama3 等)对原始查询进行解析
- 从不同维度(如目的、场景、对象、限制条件)生成多个改写后的查询
- 将这些改写后的查询分别用于检索,汇总所有结果后进行排序或融合
⚙️ 四、技术流程图
🧪 五、代码实现(使用 LangChain + Qwen)
以下是一个使用 Qwen 模型 实现查询改写,并结合 Sentence Transformers 和 FAISS 进行检索增强的完整示例。
✅ 安装依赖
pip install langchain transformers faiss-cpu sentence-transformers torch
✅ 导入模块
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.llms import HuggingFacePipeline
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
from sentence_transformers import SentenceTransformer
import faiss
import numpy as np
✅ 加载 Qwen 模型
请确保你已经下载并本地部署了 Qwen 模型(如 Qwen/Qwen-7B 或其他版本)。
model_name = "Qwen/Qwen-7B" # 根据实际情况替换为你本地部署的模型路径
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
pipe = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
max_new_tokens=100,
device=0 if torch.cuda.is_available() else -1
)
llm = HuggingFacePipeline(pipeline=pipe)
✅ 构建查询改写 Chain
prompt_template =PromptTemplate(
input_variables=["question"],
template="""You are an AI language model assistant. Your task is to generate five
different versions of the given user question to retrieve relevant documents from a vector
database. By generating multiple perspectives on the user question, your goal is to help
the user overcome some of the limitations of the distance-based similarity search.
Provide these alternative questions separated by newlines.
Original question: {question}
Output format:
- Rewritten Query 1: [rewritten query]
- Rewritten Query 2: [rewritten query]
- Rewritten Query 3: [rewritten query]
"""
prompt = PromptTemplate.from_template(prompt_template)
rewrite_chain = LLMChain(llm=llm, prompt=prompt)
✅ 示例查询与改写
original_query = "帮我查一下那个病毒"
rewritten_queries_response = rewrite_chain.run(original_query).strip()
print("Rewritten Queries Response:\n", rewritten_queries_response)
# 解析出改写后的查询列表
rewritten_queries = [line.split(": ")[1] for line in rewritten_queries_response.split('\n') if ": " in line]
print("\nRewritten Queries:")
for q in rewritten_queries:
print(f"- {q}")
输出示例:
Rewritten Queries:
- 如何预防新冠病毒的传播?
- 最新关于埃博拉病毒的研究进展有哪些?
- 常见的流感病毒类型及其防治方法是什么?
✅ 将改写后的查询转化为嵌入并检索
我们模拟一个文档库并构建 FAISS 索引。
doc_texts = [
"新冠疫苗接种可有效预防病毒感染和重症发生。",
"埃博拉病毒主要通过体液传播,致死率高达90%。",
"流感分为甲型、乙型和丙型,每年流行的主要是甲型H1N1。",
"病毒是一种非细胞生物,只能寄生在宿主细胞内复制。",
"SARS-CoV-2 是引起新冠疫情的主要病原体。"
]
encoder = SentenceTransformer('all-MiniLM-L6-v2')
doc_embeddings = encoder.encode(doc_texts)
dimension = doc_embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(np.array(doc_embeddings).astype('float32'))
✅ 对每个改写后的查询进行检索并汇总结果
retrieved_docs = set()
for q in rewritten_queries:
embedding = encoder.encode([q])
D, I = index.search(embedding, k=2) # 检索最相关的两个文档
for i in I[0]:
retrieved_docs.add(doc_texts[i])
print("\nRetrieved Docs from Rewritten Queries:")
for d in retrieved_docs:
print(f"- {d}")
输出示例:
Retrieved Docs from Rewritten Queries:
- 新冠疫苗接种可有效预防病毒感染和重症发生。
- SARS-CoV-2 是引起新冠疫情的主要病原体。
- 流感分为甲型、乙型和丙型,每年流行的主要是甲型H1N1。
- 埃博拉病毒主要通过体液传播,致死率高达90%。
📊 六、适用场景分析
| 场景 | 描述 |
|---|---|
| 📚 教育问答系统 | 学生提问“这道题怎么做?” → 改写为具体知识点问题 |
| 🏥 医疗咨询系统 | 用户询问“头疼怎么办?” → 改写为症状+建议的组合问题 |
| 🌐 通用搜索引擎 | “查一下那个新闻” → 改写为“最近一周国际重大新闻” |
| 🛒 电商推荐系统 | “给我推荐点好东西” → 改写为“高性价比家用电器推荐” |
🧩 七、进阶优化建议
| 技术方向 | 描述 |
|---|---|
| 动态扩写数量 | 根据查询复杂度动态决定生成多少个改写版本 |
| 权重加权检索 | 给不同改写版本分配不同权重,影响最终排序 |
| 多路召回融合 | 每个改写版本对应不同的召回通道(如 BM25 + DPR) |
| 答案合成 | 使用 LLM 对多个改写版本的检索结果进行整合,生成统一答案 |
| 领域定制提示词 | 在医疗、法律、教育等领域中加入专业术语提示词 |
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)