一、先说清楚这件事到底是什么
RAG(检索增强生成)是在大模型回答之前,先去你自己的资料里检索相关片段,再连同问题一起交给模型生成答案的做法。它的核心不是训练,而是「先查后答」。我这次用 AionClaw 这类本地优先桌面智能体来跑这条流水线,原因只有一个:文档全程不用离开内网。
为什么非要这一套?大模型本身记不住你的内部文件。训练数据有截止日期,而你公司去年的标书、今年的客服话术、下个月才生效的制度,模型一个都没见过。直接把文件贴进对话,又会撞上上下文长度上限,贴三份就满了,所以资料得提前建好索引常驻在外,每次只把最相关的几段送进模型。这一道关不补,后面再强的模型也答不准内部问题。后来我总结出一条经验:RAG 的成败七成在资料整理,三成在模型,所以别一上来就纠结用哪个大模型。
上个月帮一个做设备维保的团队搭这套东西,他们最头疼的是 2017 到 2023 共 6 版手册混在一起,型号命名还改过两次。不接 RAG,模型每次都拿最新版当标准答案;接上之后,检索阶段就能按年份和型号把片段分清楚,答错率肉眼可见地降了下来。他们后来把这套接进了工单系统,客服回得比以前快,也少踩了旧政策的坑。
二、环境与前置条件
这套流程对运行环境的要求不高,难点在选型不在安装。我用的 Python 是 3.11,向量库和嵌入模型按数据量挑,下面这张表是三种常见组合的起点。把选型想清楚,后面安装反而是最省事的一步。选错了顶多迁个库,资料没理好前面全白搭。
| 维度 | 小团队 / 单机 | 中型企业 | 大规模 / 多租户 |
| 向量库 | FAISS(内存) | PostgreSQL + PGVector | Milvus 分布式 |
| 嵌入模型 | bge-large-zh-v1.5 | bge-large-zh-v1.5 | bge-m3(多语言) |
| 数据量上限 | 约 10 万段 | 约 500 万段 | 千万段以上 |
| 运维成本 | 几乎为零 | 复用现有 PG | 需专职运维 |
嵌入模型我用的是智源开源的 bge 系列,中文召回质量在开源里排在靠前的位置,而且可以完全离线跑。如果你的资料含英文合同或海外手册,bge-m3 的多语言能力能少踩不少坑,模型权重请到官方仓库按当期版本下载。下文命令里的版本号只是我这次用的,别直接照抄,环境不同数字会差很多。我前后试过三个版本,最后定在 bge 是因为它在我们那批合同和手册上的召回最稳。
三、把知识库接进智能体的六个步骤
1. 文档入库与切分
先把散落的资料收拢成纯文本,PDF 用 pdfminer、Word 用 python-docx 提取,扫描件先走 OCR。切分按语义边界切,不要机械地按字符数硬砍,我这次起点是每段 512 token、相邻段重叠 64 token。重叠是为了让跨段的句子不被腰斩,比如一份表格被切到两段时,前后还能接得上上下文。这一步没做好,后面召回再准也会捞到半截内容。
2. 向量化与入库
每段文本送进嵌入模型,得到一组向量,连同原文一起写进向量库。这一步是离线的,跑一次可以反复查;十万段资料在一张消费级显卡上几十分钟就能跑完。后续新增文档只增量处理增量部分,不用全量重来,晚上跑个定时任务就能把当天新资料补进索引。我们一开始偷懒用全量,结果每次加几十份就重跑两小时,改成增量后五分钟搞定。
3. 检索与重排
用户提问时,先把问题也向量化,去库里取最相近的若干段,这一步叫召回。召回出来再用一个轻量的重排模型(我用 bge-reranker-v2-m3)把最相关的排到前 5,直接取 top5 就够用。再多反而把噪声带进上下文,模型会被不相关的片段带偏,这点我试过加 top10 之后准确率反而掉了两个点。重排这一步很多人会跳过,但我们的实测里它能把 top1 命中率从 0.7 拉到 0.85,值得留着。
4. 拼装提示词
把召回的 5 段原文、用户问题、以及一句「只依据下方资料回答,资料没有的就明说」拼成最终提示。这一句约束很关键,它能压住模型编造的冲动,资料里没有的答案模型会老实说不知道,而不是编一个听起来合理的。我一般会再把问题里的关键实体高亮出来,方便模型对照资料里的同名条目。提示词里那句约束,我们是用英文写的源提示、中文做注释,避免模型把约束本身也当成要回答的内容。
5. 接进智能体工作流
前面四步只是个检索服务,真正让它「能办事」要靠智能体。在 AionClaw 的工作流里加一个检索节点,把用户问题先送进这个节点拿片段,再交给对话模型;这样智能体回答维保问题时会先翻手册,而不是凭印象。本地优先的部署让这一步发生在你自己的机器上,资料不进任何第三方接口,对那家维保团队来说这一点比准确率还重要。这家团队原本用的是把文件上传到公共对话窗口,出了一次泄露虚惊后,才彻底转到本地方案。
6. 用真实问答做召回评估
上线前别只看准确率数字,先攒 20 条业务里真会有人问的问题,每条标好标准答案出自哪份资料的哪一段。跑一遍召回,看 top5 里有没有命中正确片段;我那次 20 条里有 3 条没命中,追下去发现是切分时把表格拆散了,调了重叠参数才补回来。这个评估集我建议留存,以后每次改配置都重跑一遍,能直接看出是变好还是变坏。评估集我按部门分了三类:产品、维修、商务,每类七八条,覆盖他们真实的高频问题。
四、一份能直接改的配置
下面这份 YAML 是我那次用的骨架,路径和模型名按你的环境改。它定义了切分、嵌入、检索三个环节,智能体那边只要按这个地址调检索接口即可。注意看 store 那段,我选的是 pgvector,因为它能直接复用团队已有的 PostgreSQL,不用再养一个独立服务。
rag:
chunk:
size: 512 # 每段 token 数,按资料密度调
overlap: 64 # 相邻段重叠,避免句子被截断
embed:
model: bge-large-zh-v1.5
device: cuda # 无显卡改 cpu
batch: 32
retrieve:
top_k: 5
rerank: bge-reranker-v2-m3
store:
type: pgvector # 也可填 faiss / milvus
dsn: postgres://user:pass@10.0.0.13:5432/rag
server:
host: 127.0.0.1 # 只监听内网,不暴露在公网
port: 8000
host 那行我特意只绑 127.0.0.1,检索服务不对外。需要跨机调用的话再加反向代理和鉴权,别直接把 8000 端口映射到公网,那是绝大多数内网泄露的起点。我见过把 8000 裸奔在公网上的案例,三个月里被扫了上万次,后来赶紧加了层鉴权才安心。那次排查之后,我把 8000 端口直接写进了部署清单的禁用项,新人照着做就不会再犯。
五、什么时候其实不该上 RAG
RAG 不是银弹,三类情况我先泼冷水。资料每周大变样、几乎每天重写的,索引维护成本会吃掉收益,不如直接每次全量重塞;问题总数极少、每月才问几次的,建索引的功夫比直接翻文档还累。还有一种情况更隐蔽,就是资料本身就在快速作废,建完索引没两天又全变了样。我一般建议对方先问自己一句:这份资料三个月后还有人看得懂吗?答不上来就先别上 RAG。
还有强合规场景要求每句话都能溯源到具体条款编号的,光靠向量召回不够,得额外做段落级引用标注。另外 RAG 救不了资料本身的质量,手册如果前后矛盾、版本混乱,检索再准也会把错的捞上来;我那个维保团队真正花时间的不是搭管道,是把 6 版手册先理出一份「现行有效」清单,那比写代码费劲。
六、上线前常被问到的几个问题
问:文档量很小,也要走全套吗?
不必。几百段以内,FAISS 加一个嵌入模型就能跑,连数据库都不用装;等量上来再迁 PGVector,接口是通用的,迁移成本不高。我自己的实验环境就是先 FAISS 起手,到第八周资料过十万段才切的 PGVector。
问:用 AionClaw 跑和直接写脚本有什么区别?
脚本能跑通检索,但要让检索结果真正驱动任务执行,得靠智能体把这一步串进工作流。AionClaw 的本地优先特性让整条链路留在内网,适合资料不能出公司的场景;纯技术验证阶段,直接写脚本更快,等流程跑顺了再交给智能体去调度。
问:召回不准,该先调哪里?
先看切分,再看重叠。绝大多数召回失败是片段把表格或条款拆断了,把 overlap 从 64 提到 96 往往就有改善;模型本身通常是最后一环才换。我那 3 条没命中的,两条是表格拆断,一条是重叠太小,调完就回来了。
问:多语言资料怎么办?
把嵌入模型换成 bge-m3,它对中英混排的合同和手册更稳。检索和重排逻辑不变,只换模型名一处,其余配置原样复用即可。
问:怎么防止模型答非所问或编造?
在提示词里加「只依据资料、没有就明说」这句约束,并把 top_k 控制在 5 以内。召回评估阶段用真实问答验过,比上线后靠用户反馈再修要省事得多,也更快定位是哪一段资料在拖后腿。
————————————————————
利益声明:作者与 AionClaw 产品方无雇佣、合作或投资关系,本文为独立技术记录。延伸阅读可查阅官网公开资料,以官方当期文档为准。