RAG 检索环节:关键词检索完整落地讲解(附可运行 TF-IDF 代码)

我们先来搞清楚,检索增强生成(RAG)到底是什么。 前面我们已经确定,要搭建一套企业政策智能助手系统:员工提出问题后,系统会检索相关资料、扩充提示词,再生成对应答复。接下来我们拆解这套流程每一步的工作原理,先从检索环节讲起。 检索,顾名思义就是调取匹配的相关资料。 但具体该怎么实现?企业内部可能有成百上千份政策文件,如何精准定位到和用户问题语境匹配的文档?又该在文件里检索哪些内容? 第一步,我们会从用户的提问中提取若干关键词。举个例子,假设用户问居家办公报销相关问题,系统就会提取出报销、居家办公这两个核心关键词。 最简单的一种办法,是使用 GREP 命令,在所有文件中检索 “报销” 或 “居家办公” 这类特定词汇,寄希望于能匹配到包含关键词的文档。 另一种方式:如果文件存储在数据库中,我们可以编写数据库查询语句进行检索。 但以上两种方式,只会返回完全精准匹配关键词的内容,很难每次都拿到准确有效的信息。 这种依靠精确文字匹配检索文档的方式,叫做关键词检索,也是各大搜索引擎广泛采用的基础技术。简单解释它的逻辑:程序遍历全部文档,提取关键词,并根据关键词出现频次对文档排序。 举个简化例子:系统统计所有文档里 “报销” 一词的出现次数,第一份文档出现 3 次,中间两份无相关内容,第三份同样出现 3 次;随后再统计 “居家办公”,发现该词仅出现在居家办公配置说明文档中。将两组统计结果结合对比,就能筛选出两个关键词总出现次数最多的文档,以此判定这份文档和用户问题最相关。 以上只是极度简化的原理说明。关键词检索本身是一套完整技术体系,背后包含大量复杂运算,业界也衍生出多种成熟落地算法,其中最主流的两种就是 TF-IDF 与 BM25。 我们不深入拆解底层运算逻辑,只演示实操使用方式,分别看下两种算法的运行效果。 首先从开源 Python 库 scikit-learn 中导入 TF 向量转换器。你可以把 scikit-learn 库理解成一个算法工具箱,内置封装好的成熟算法,无需从零手写实现。 接着我们定义三份样例文档(这里先用简短句子演示,实际项目中可以读取本地完整文件内容); 然后实例化 TF-IDF 分析器; 调用 transform 方法计算各个词汇对应的权重分值; 最后将计算结果打印输出到控制台。

RAG 检索环节:关键词检索完整落地讲解(附可运行 TF-IDF 代码)

1. 回顾核心定位

整套企业政策智能助手的 RAG 流程: 员工提问 → 检索企业政策文档 → 拼接检索到的文档 + 用户问题构造 Prompt → 大模型生成合规回答 检索是整套系统的信息来源,检索不准,后面大模型回答必然失真。 关键词检索是检索层最基础、低成本的第一阶段方案,核心只匹配字面文字,不理解语义。

2. 关键词检索核心缺陷

  1. 字面不匹配但语义相关的文档完全丢失 例:用户问「远程办公补贴」,文档写「居家办公报销标准」,无重合关键词,检索不到;
  2. 无法区分词语重要程度,纯靠词频容易产生噪音;
  3. 同义词、近义词、简称、书面口语无法互通匹配。

主流关键词检索算法:TF-IDF、BM25

  • TF-IDF:词频 - 逆文档频率,衡量单个词在当前文档重要性
  • BM25:在 TF-IDF 基础上优化,增加文档长度、关键词位置加权,企业知识库检索效果普遍优于原生 TF-IDF。

3. Python TF-IDF 完整可运行演示代码(基于 scikit-learn)

场景说明

3 份企业政策文档,用户查询:居家办公报销标准

python

运行

# 导入TF-IDF工具包 from sklearn.feature_extraction.text import TfidfVectorizer import pandas as pd # 1. 模拟企业政策文档库 docs = [ "公司居家办公报销标准:每月网络补贴100元,凭缴费凭证每月15号提交申请", "外勤出差交通补贴、餐饮补贴报销规则,出差需提前线上报备审批", "员工考勤管理制度,上下班打卡、请假流程、加班调休相关规定" ] # 用户查询问句 query = "居家办公报销多少钱" # 2. 初始化TF-IDF转换器 tfidf = TfidfVectorizer() # 对全部文档计算TF-IDF权重矩阵 doc_tfidf = tfidf.fit_transform(docs) # 把用户问句转为相同向量空间 query_tfidf = tfidf.transform([query]) # 3. 计算查询与每篇文档的相似度(余弦相似度) from sklearn.metrics.pairwise import cosine_similarity similarity_scores = cosine_similarity(query_tfidf, doc_tfidf)[0] # 4. 整理输出结果 result = pd.DataFrame({ "文档内容": docs, "匹配相似度得分": similarity_scores }).sort_values("匹配相似度得分", ascending=False) print("=== TF-IDF 检索匹配结果 ===") print(result) print("\n最匹配文档:", result.iloc[0]["文档内容"])

代码运行结果解读

  1. 工具会自动拆分文本词汇:居家、办公、报销、补贴、出差、考勤等;
  2. TF(词频):某词在单篇文档出现越多,分值越高;
  3. IDF(逆文档频率):词在全部文档里越稀有,权重越高;
    • “居家办公” 只出现在第一篇文档,IDF 权重极高;
    • “报销” 出现在第一篇、第二篇,IDF 权重会被稀释;
  4. 余弦相似度用来衡量用户提问向量和文档向量重合度,分数越高代表关键词重合越多。

4. TF-IDF 检索的局限(企业政策场景痛点)

  1. 纯文字匹配,无语义理解 若文档写「远程工作费用补贴」,提问「居家办公报销」,无重叠关键词,相似度趋近 0,检索失效;
  2. 长文档干扰大 长篇政策里零星出现一次关键词,会被误判为高相关;
  3. 无法处理行业简称、同义替换 文档:线上办公补助 | 用户提问:居家办公报销 → 完全匹配失败

5. 补充:BM25 简单对比

TF-IDF 仅计算词权重 + 余弦相似度; BM25 额外优化两点:

  1. 惩罚过长文档,避免长篇无关文档因偶然出现关键词排名靠前;
  2. 关键词多次连续出现会大幅加分,更贴合政策文档短句匹配场景; 企业知识库落地时,一般先用 BM25 做关键词检索兜底,再搭配向量语义检索,组成混合检索

6. 企业 RAG 检索层进阶思路(解决关键词检索短板)

关键词检索只能作为基础兜底方案,完整企业政策助手检索流程通常分层:

  1. 第一层:关键词检索(BM25/TF-IDF),快速召回字面高度匹配文档;
  2. 第二层:向量语义检索(Embedding 嵌入),捕捉同义、近义、不同表述的相关政策;
  3. 重排序层:将两层召回的文档统一打分筛选,只保留 Top3-Top5 高相关文档送入大模型。