游乐游手机版
首页/AI教程/文章详情

用LangChain搭建可落地的制度RAG系统

时间:2026-06-18 16:47
基于LangChain与FAISS构建企业制度RAG系统,采用数据增强将来源信息融入向量库以缓解召回漂移,通过gte-rerank-v2精排解决向量排序与语义排序偏差。实现增量同步、相似度过滤及CLI交互问答,以工程手段优先提升落地稳定性。

RAG(检索增强生成,Retrieval-Augmented Generation)技术在过去一年中迅速崛起,成为AI落地应用领域最受关注的热门词汇之一。然而,要让这一技术流程在企业制度问答这类实际场景中真正稳定运行并发挥价值,中间仍有许多细节值得深入推敲。本文将从建库到问答、从数据增强到精排重排的完整链路出发,逐层拆解,系统分享实践经验。

本次实践的核心目标是:以一份公司制度PDF为原始素材,在此基础上实现增量同步、相似度过滤、CLI交互式问答,并重点攻克两大常见难点——其一是“同义不同问法”引发的召回漂移问题,其二是“向量排序并不等同于语义排序”所导致的精度瓶颈。

首先,让我们整体了解所采用的技术路线:

维度 内容
主线 基于LangChain + FAISS + DashScope(Embedding/对话/精排),完整实现RAG全流程
场景 公司制度PDF,附带溯源元数据、增量同步、相似度过滤、CLI交互问答
今日加码① 数据增强:写入向量库前,把“身份”信息拼入page_content,有效缓解召回漂移
今日加码② Rerank:向量Top-K初筛后,调用gte-rerank-v2进行重排,将最贴合问意的文本块送入Prompt

RAG核心原理:检索与生成的两步接力

RAG的基本流程可以用一句话清晰概括:

数据入库:Load(读取)→ Split(分块)→ Embedding(向量化)→ Vector Store(存入向量库)
检索生成:Similarity Search(相似度检索,可设阈值或多取再过滤)→ Context + Prompt → LLM(生成答案)

分块参数的设定是调优过程中的第一个关键环节。在本次实践中,具体参数配置如下:

参数 取值 作用
Chunk Size ≈ 500 控制文本粒度,过大容易导致语义稀释
Chunk Overlap ≈ 50 减轻边界截断造成的语义断层

这一参数组合并非固定不变,针对不同领域的文档,可能需要做针对性调整。但对于制度类文本而言,这无疑是一个比较稳妥且高效的起步配置。

此外,典型问题及其应对策略同样值得提前梳理与关注:

问题 说明 方向
语义偏移/召不回 用户问法与正文表述不一致 数据增强、Query改写、混合检索
幻觉 检索能力弱时,模型仍会“编造”答案 相似度阈值、拒答式Prompt
排序不准 向量“形似”但并非最相关段落 Rerank精排

从“点状知识”到LangChain + FAISS的架构理解

很多初学者在接触RAG时,容易把向量库简单理解成一个“黑盒搜索引擎”。实际上,将其拆解开来看会非常清晰:

概念 一句话
FAISS 向量 → 邻居ID(寻找最相似的向量)
Docstore(pkl) ID → Document(page_content, metadata)
metadata 记录source_file、page_number、file_hash等,服务于溯源和按文件增量更新
增量 通过processed_files.json(MD5)管理;变更时先按source_file删除旧数据,再执行add_texts;源文件删除时清理孤儿向量
清洗 控制字符、多余换行等,有效降低PDF噪声对Embedding效果的干扰

这一“向量+文档”双存储结构,正是LangChain中FAISS集成的标准实现方式,也是企业场景下实现增量维护的核心基础。


企业级制度RAG:设计与实现要点

技术栈与代码一致性

选型
向量化 DashScope EMBEDDING_MODEL(例如text-embedding-v2)
对话 DashScope Generation(例如qwen-turbo)
精排 dashscope.TextReRank,采用gte-rerank-v2(独立API调用)
向量库 本地index.faiss + index.pkl;PDF解析使用PyPDF2,页码信息写入metadata

同步阶段的数据增强(写入向量前)

整个流程中,一个关键的操作为_enrich_page_content_for_embedding函数。其核心做法是:在写入向量库之前,将“来源信息”拼接到文本正文中。内容模板大致为:资料来源(source_file) + 可选所属部门页码 + 正文内容(原始分块正文)。而metadata依然保持为结构化字段。

这里需要特别留意几点:

  • 冷启动阶段,process_text_with_splitterFAISS.from_texts,使用的是增强后的字符串。
  • 增量同步时,sync_vector_store中的add_texts同样先进行增强再写入向量库。
  • index.pkl中的page_content是增强版,如果从FAISS导出JSON,可能会与“仅正文”的预期不一致,这一点要特别关注。

这样做的好处显而易见:当用户提问时,即使问法没有明确提到文件名,增强后的文本也能帮助模型锚定到具体的制度和所在位置。这在很大程度上缓解了“同义不同问法”带来的召回漂移问题。

向量召回与相似度阈值

说明
相似度标尺 similarity = 1 / (1 + distance),基于L2距离;非概率值,仅在同一索引内具有可比性
_DEFAULT_SIMILARITY_THRESHOLD 当前设置为0.3,可通过--no-min-score参数进行调试
_DEFAULT_TOP_K 设置为20,这个规模与后续Rerank的输入保持一致

Rerank精排:gte-rerank-v2

这一步是本次实践的重点加码内容。相关实现集中在rerank_retrieval_hits_call_dashscope_rerank中:

  • 输入:由similarity_search检索、经过阈值过滤后得到的候选列表。
  • 调用:TextReRank.call,模型指定为gte-rerank-v2top_n与候选条数对齐。
  • 输出:每条结果新增rerank_score,同时保留原有的similaritydistance,便于对照分析和调试。
  • 失败处理:网络原因或非200返回时,记录日志并回退到向量排序,不影响整体流程的稳定性。
  • 默认配置:generate_rag_answer(..., use_rerank=True);在ask时可以通过--no-rerank参数跳过精排。
  • 纯检索模式:search默认不执行精排,加--rerank参数才会触发一次DashScope调用。

为什么需要Rerank?向量的相似度检索本质上是“形似”,但语义层面的“最相关”并不一定排在检索结果的最前面。Rerank相当于在候选池中再做一次语义级别的精排,将最贴合用户问意的段落提升到最靠前的位置。

问答Prompt与CLI设计

System Prompt采用专业模板(PROFESSIONAL_SYSTEM_TEMPLATE),核心要求是:仅依据给定片段进行回答,遇到冲突信息时要并列呈现,涉及比例推算时需注明依据。在上下文展示时,如果存在rerank_score,则同时标注精排分和向量similarity,方便排查和定位问题。

CLI命令行工具的具体设计如下:

命令 作用
python langchain_rag.py 交互式RAG,默认使用Top-20 + Rerank
python langchain_rag.py sync PDF → FAISS 增量同步
python langchain_rag.py search … 纯检索模式,加--rerank开启精排
python langchain_rag.py ask … 单次问答模式,加--no-rerank跳过精排
python langchain_rag.py help 获取帮助信息

能力阶梯对照

不同阶段的RAG方案,在成本和稳定性方面各有差异,以下是一个可供参考的对照表:

阶段 方案 核心操作 主要解决的问题 成本 稳定性
1 原生RAG Chunking → 向量库 跑通基础流程
2 参数调优 Top-K、Chunk / Overlap 截断与粒度优化 ⭐⭐
3 数据增强 同步时拼接来源、页码再嵌入 召回漂移、出处弱化 ⭐⭐⭐⭐
4 查询改写 Pre-LLM转检索词 口语化表达、多轮指代 ⭐⭐⭐⭐⭐
5 Rerank Top-K → gte-rerank-v2 向量序≠语义最相关 中(API) ⭐⭐⭐⭐⭐
6 混合检索 + 长上下文 向量 + BM25 + 长窗口 长文、表格、复杂逻辑 极高 ?

数据增强 + Rerank:四层链路

存储层:头部带资料来源和页码,即使问法不提到文件名,也能锚定制度和具体位置。
检索层:在阈值内适度拉宽候选池,尽可能避免“正确答案进不了前K”的情况。
精排层:对同一批候选进行语义级重排,把最贴合问句的文本片段前置。
生成层:在相对干净的上下文基础上,进行合规表述和拒答边界的把控。

开发者避坑摘要

主题 要点
macOS OpenMP 设置KMP_DUPLICATE_LIB_OK=TRUE,缓解FAISS与libomp重复链接导致的崩溃问题
网络/SSL Embedding、Generation、Rerank均可能出现断连,dashscope_generation.py与Rerank侧均有退避重试机制
Pickle allow_dangerous_deserialization=True仅用于可信索引,注意安全性
索引与增强 如果先建库后改增强逻辑,需要sync重建或全量更新,否则仍是旧的向量文本

实操进展与仓库记录

模块 记录
langchain_rag.py 实现了_enrich_page_content_for_embedding、process_text_with_splitter/增量add_texts、rerank_retrieval_hits、_RERANK_MODEL、search --rerank / ask --no-rerank
增量与清理 MD5、processed_files.json、按source_file更新、孤儿清理、文本清洗
检索与问答 similarity_search、generate_rag_answer、相似度标尺、交互与help
公共模块 dashscope_generation.py等统一调用与重试
学习材料 本文Day10定稿,与练习代码、向量库一并纳入版本管理

今日收束

数据增强的核心价值在于夯实召回与溯源的地基,让模型在检索阶段就能“站在更有利的位置”。而Rerank则是在可控成本范围内,把“最应该让模型看到的段落”尽可能排到靠前位置。两者叠加使用,比单纯更换更大的对话模型,更能贴近工业级RAG常见的迭代节奏——先用工程手段解决性价比最高的瓶颈,再考虑引入更重的模型。


相关代码已更新至:
课程练习 RAG技术与应用 目录(含langchain_rag.py等):Cyning12/auto-gpt-work-demo · data/课程练习/RAG技术与应用

来源:https://cloud.tencent.com.cn/developer/article/2691198
上一篇第九天学习日志:深入理解嵌入与向量数据库 下一篇RAG从复读机到逻辑大脑:既找得准也说得清
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
RAG四标融合企业知识资产体系四库协同GEO优化实践
AI教程 · 2026-07-01

RAG四标融合企业知识资产体系四库协同GEO优化实践

生成式AI正在彻底改写信息检索的底层逻辑。传统SEO依赖关键词堆砌和外链建设的策略,在大模型的内容采信规则下已经基本失效。取而代之的,是生成式引擎优化(GEO)。它不再关注外链数量,而是重点衡量你的知识是否结构化、证据链是否坚实、信源是否可靠——这些维度才是RAG(检索增强生成)架构真正看重的核心指

一个普通上班人分享WorkBuddy使用心得与真实体验
AI教程 · 2026-07-01

一个普通上班人分享WorkBuddy使用心得与真实体验

前言 最近我开始使用WorkBuddy——这是腾讯推出的一款AI办公工作台。差不多用了一周时间,趁印象还新鲜,把真实的使用感受记录下来,给还在犹豫的朋友做个参考。不吹不黑,只说实际体验。 初印象:不只是聊天机器人 之前用过不少AI工具,大多数就是个对话框,你问它答,答完就结束了。WorkBuddy不

AI幻觉变真功能实战教程:App Inventor 2视频录制拓展一周开发实录
AI教程 · 2026-07-01

AI幻觉变真功能实战教程:App Inventor 2视频录制拓展一周开发实录

先讲一个颇具戏剧性的开端。 这件事的开端颇显荒诞——有用户前来咨询,称AI Pro版的介绍中提到我们有一款“视频录制拓展”。团队全体成员都感到困惑,翻遍产品列表,发现根本不存在该组件。AI那种“一本正经胡说八道”的能力,这次确实让我们陷入尴尬。 按常理,此事到此便可结束——一句“抱歉,暂时没有这个拓

别再混淆OLAP和SQL-on-Hadoop两者查询本质不同
AI教程 · 2026-07-01

别再混淆OLAP和SQL-on-Hadoop两者查询本质不同

OLAP和SQL-on-Hadoop虽都使用SQL查询数据,但本质不同。SQL-on-Hadoop负责海量数据批量计算与ETL,查询速度秒级至分钟级;OLAP通过预聚合实现毫秒级多维分析,适合BI报表。两者在数据平台分工协作,前者是后厨加工,后者是前台快速服务。

GEO优化深度解析:AI偏好FAQ还是长文内容?
AI教程 · 2026-07-01

GEO优化深度解析:AI偏好FAQ还是长文内容?

在GEO优化中,AI对内容形式无统一偏好:FAQ在简单查询中引用率41%,长文在复杂查询中达58%。内容应基于用户意图选择形式,FAQ适配简单事实类问题,长文建立主题权威,两者互补而非替代。