这个模块核心是把用户的原始问题处理成「更适合检索」的形式,从核心思路具体步骤代码示例三个层面讲清楚。

一、Query 理解模块的核心目标

简单说:把用户「口语化、碎片化、不完整」的问题,转化成「结构化、精准、能让检索模块高效匹配」的查询语句,最终提升检索准确率。

复杂点说,本质上要解决三个痛点:

1.用户查询的时候表述不规范,语义模糊

2.查询用于与知识库存在"语义鸿沟"

3.多轮对话上下文依赖断裂

二、Query 理解模块的具体实现步骤(从易到难)

1. 基础预处理(必做)

这是最基础的步骤,所有场景都适用,目的是清洗无效信息、统一格式。

  • 文本清洗:去除多余空格、特殊符号(比如 !!RAG怎么部署??RAG怎么部署)、emoji、敏感词;
  • 大小写 / 繁简转换:比如 What is RAG?what is rag?部署RAG的步驟部署RAG的步骤
  • 错别字修正:比如用拼音纠错、大模型纠错(RAG怎末部署RAG怎么部署)。

这里最容易忽略的但很重要的一步:否定词保留和实体初步过滤,前者会造成获取的结果和用户意图相反,后者会导致召回的信息不精准(LangChain的RAG-->处理为通用RAG,召回的结果就有偏差)

2. 意图与实体提取(核心)

目的是从问题中抠出「关键信息」,让检索聚焦核心。

  • 意图识别:判断用户想做什么(比如用户问「RAG 怎么部署到服务器」,意图是「RAG 部署方法」);
    • 实现方式:小模型分类(比如预设意图标签:查询 / 部署 / 故障排查)、大模型提取(用 Prompt 让 LLM 输出意图)---具体的问下AI都能给你落地方案和代码;
  • 实体提取:抠出问题中的核心名词(比如「RAG 怎么部署到阿里云服务器」,实体是「RAG、阿里云、服务器、部署」);
    • 实现方式:用分词工具(jieba、spaCy)+ 关键词权重排序(TF-IDF),或直接调用大模型提取。
3. 查询改写 / 优化(提升检索准确率的关键)

把口语化、模糊的查询输入,改成标准化、精准化表述,同时扩展核心语义(避免漏检)

方法有两种:

  • 规则驱动:同义词替换、句式转换
  • 模型驱动:用Seq2Seq或大模型做生成式改写

注意要避免“过度改写”:

核心是“保留核心意图+适配知识库风格”,改写后的东西不能丢失核心实体和意图、关键信息等,其次就是让改写的术语用知识库的语料风格,例如如果知识库是技术文档,就改写成技术化表达;若是客服FAQ这种,就简介通俗,避免为了标准化把简单问题复杂化。

4. 复杂查询分解(高级,复杂场景用)

针对专业领域、长问题场景,进一步提升精准度:如果直接检索长语句,会出现部分信息覆盖问题,拆解能确保全面召回,不遗漏关键维度信息。

  • 子问题拆分:把长问题拆成多个小问题(比如「RAG 的部署步骤和硬件要求是什么」→ 拆成「RAG 部署步骤」「RAG 硬件要求」);
  • 查询扩展:生成相关查询词(比如「RAG 部署」→ 补充「RAG 部署流程、RAG 部署教程、RAG 部署环境配置」);
  • 语义归一化:把不同表述的问题统一成标准说法(比如「RAG 怎么搭」「RAG 如何部署」→ 统一为「RAG 部署方法」)。

怎么判断一个查询是否需要分解?分解要遵循什么原则呢?

标准有几个:

  • 查询是否包含多个核心意图
  • 查询的长度和复杂度(字数或者核心词很多的)

原则是“不重叠、全覆盖、子查询独立可检索”,子查询之间没有冗余信息、合起来能覆盖原始查询所有意图,每个子查询单独检索都能拿到有用信息

5. 上下文融合(多轮场景专属)

在多轮对话中,把当前查询跟历史对话结合,补全确实信息、明确指代。核心就是实体状态追踪和对话历史摘要,用知识图谱或大模型记录历史实体和意图。能够避免回答孤立,保证形成连贯的对话体验。

融合中,怎么避免“历史信息冗余”?

核心是“动态筛选+权重分配”,不是全部历史都来拼接,是提取核心实体、关键意图和未解决的问题,过滤调冗余的寒暄和重复信息,同时注意给最近的对话更高的权重(时间衰减因子),给与当前查询语义相似度搞得历史信息更高权重,确保融合后完整不冗余。

三、可直接运行的 Python 代码示例(核心流程)

下面是一个极简但完整的 Query 理解模块实现,基于大模型(OpenAI API)+ 基础预处理,新手也能直接跑:

import re
import jieba
from openai import OpenAI

# 初始化客户端(替换成你的API Key和地址)
client = OpenAI(
    api_key="你的API Key",
    base_url="你的大模型地址(比如本地部署的LLM/OpenAI官方地址)"
)

class QueryUnderstandingModule:
    def __init__(self):
        # 停用词(无意义的词,比如“的、怎么、什么”)
        self.stop_words = {"的", "怎么", "什么", "是", "在", "到", "有"}

    # 1. 基础预处理
    def basic_preprocess(self, query):
        # 去除特殊符号和多余空格
        query = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9]', '', query)  # 保留中文、英文、数字
        query = query.strip()
        # 转小写(英文)
        query = query.lower()
        return query

    # 2. 提取关键词(实体)
    def extract_keywords(self, query):
        # 分词
        words = jieba.lcut(query)
        # 过滤停用词,保留核心关键词
        keywords = [word for word in words if word not in self.stop_words and len(word) > 1]
        return keywords

    # 3. 大模型改写查询(核心步骤)
    def rewrite_query(self, query, history=None):
        # 拼接多轮对话历史
        history_text = ""
        if history:
            history_text = "\n".join([f"用户:{h[0]},助手:{h[1]}" for h in history])
        
        # 构造Prompt,让大模型改写查询
        prompt = f"""
        你是RAG的Query理解模块,需要完成以下任务:
        1. 结合历史对话:{history_text}
        2. 把用户当前问题:{query}
        3. 改写成一个精准、完整、适合检索的查询语句,只输出改写后的内容,不要多余解释。
        """
        
        # 调用大模型
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",  # 也可以用本地模型比如Qwen、Llama
            messages=[{"role": "user", "content": prompt}],
            temperature=0.1  # 低温度,保证输出精准
        )
        rewritten_query = response.choices[0].message.content.strip()
        return rewritten_query

    # 4. 完整的Query理解流程
    def process(self, query, history=None):
        # 步骤1:基础预处理
        clean_query = self.basic_preprocess(query)
        # 步骤2:提取关键词
        keywords = self.extract_keywords(clean_query)
        # 步骤3:大模型改写
        final_query = self.rewrite_query(clean_query, history)
        return {
            "原始查询": query,
            "清洗后查询": clean_query,
            "核心关键词": keywords,
            "改写后查询(用于检索)": final_query
        }

# ------------------- 测试示例 -------------------
if __name__ == "__main__":
    # 初始化模块
    query_module = QueryUnderstandingModule()
    # 模拟多轮对话场景
    history = [["什么是RAG?", "RAG是检索增强生成,用于提升大模型回答准确率"]]
    # 用户当前的原始问题(口语化、不完整)
    user_query = "它怎么部署到阿里云服务器?!"
    
    # 处理查询
    result = query_module.process(user_query, history)
    # 输出结果
    for k, v in result.items():
        print(f"{k}:{v}")
代码运行效果示例:
原始查询:它怎么部署到阿里云服务器?!
清洗后查询:它怎么部署到阿里云服务器
核心关键词:部署、阿里云、服务器
改写后查询(用于检索):RAG怎么部署到阿里云服务器

四、不同场景的实现选择

场景 实现方式 优点 缺点
简单场景(小知识库) 基础预处理 + 关键词提取 成本低、速度快 准确率一般
通用场景(企业级) 基础预处理 + 大模型改写 准确率高、适配性强 依赖大模型、有调用成本
专业场景(垂直领域) 行业词库 + 意图分类 + 大模型改写 精准匹配专业知识 需定制词库 / 分类模型

总结

  1. Query 理解模块的核心是「清洗 + 提关键词 + 改写」,目的是让检索更准;
  2. 基础场景用「预处理 + 关键词」就能落地,复杂场景必须结合大模型做改写 / 重构;
  3. 多轮对话场景一定要做「上下文拼接」,解决问题不完整的问题。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐