一、它不是笨,是它只会猜下一个字二、RAG 说白了就是开卷考试三、拆开看,就两段五个动作四、四十行,把闭环跑通五、真正决定上限的,是那些脏活六、向量存哪?几千条 numpy 就够七、效果八成在检索,别把力气花错地方八、上线之前,四个容易被忽略的暗坑
前阵子帮朋友的公司看一个内部问答机器人。问到"出差住宿报销上限是多少",它张口就来:一线城市每晚 600,其余 450,还贴心地补了一句"含早餐"。
数字听着特别靠谱。可朋友把员工手册翻出来一查——上限 380,早餐另算,而且一线城市的名单里根本没有他们所在的杭州。
这就是大模型最让人头疼的地方:它不会说"我不知道",它会用最流畅的语气给你编一个最合理的答案。你越急着要结论,它编得越像真的。
解法其实不复杂,业内管它叫 RAG。这篇文章不聊概念,直接按真实开发的顺序走一遍:先用几十行代码把闭环跑通,再讲清楚哪几个地方最容易翻车。
大模型的本质是个巨大的概率机器。它生成每一个字,都是在算"接在这个字后面,最可能出现的是哪个字"。这个机制让它写文案、改邮件很在行,但也带来三个绕不开的短板。
- • 知识有截止日期。训练语料停在某个时间点,之后发生的事它一律不知道;
- • 你的私有资料它没有。员工手册、产品文档、项目复盘,全在它的视野之外;
- • 它不知道自己不知道。这一条最要命,也是幻觉的根源。
前两条还能靠常识避开,第三条只能靠工程手段兜住。
学生时代都懂:闭卷考拼记忆力,开卷考拼的是"翻书翻得快不快"。RAG(检索增强生成)干的事,就是给大模型配一本书,让它答题前先翻两页,照着资料说话。
![]()
这五项里,最容易被低估的是可追溯性。答错了,你能点开引用看一眼,立刻分清是"资料找错了"还是"总结说歪了"。一个能追责的答案,才是一个能被信任的答案,这也是 RAG 能在企业里活下来的根本原因。
整套系统看着唬人,其实可以切成泾渭分明的两半。
- • 离线建库:文档加载 → 切分 → 向量化 → 入库。慢一点无所谓,跑一次存下来就行;
- • 在线问答:提问 → 向量化 → 检索 TopK → 拼 Prompt → 生成。这一段必须快。
把这个界限搞清楚,能省掉一大半性能事故。我见过最典型的一例:每次用户提问,系统都把整个知识库重新向量化一遍,单次响应三十多秒——它把建库的活干到了问答里。
依赖清单其实短得可怜:文本处理 + 向量运算 + 接口调用,三件事。那为什么还有那么多人上框架?因为框架把五个动作封装成可串的模块,五分钟能出个 demo。但 demo 能跑,和系统能维护,是两码事——换个场景、换批文档,框架甩给你的往往是一层套一层的内部异常,你连从哪查都不知道。
所以第一版建议手写。手写能把每个中间结果打印出来,排错是线性的;等你用一百多行跑通了,再回头看框架文档,一眼就能看出它替你封装了什么、又在哪一层埋了雷。
下面这段是骨架,接口地址和 Key 换成你自己的就行。切分、向量化、提问检索,一条链全在里面。
![]()
四十行,一个能用的问答机器人。当然它还很粗糙:没有持久化、没有阈值过滤、没有关键词召回。但链路通了这件事,价值远大于它本身——后面所有优化都是在这条链上做局部替换,而不是推倒重来。有了参照系,你才知道效果变化到底来自哪一步。
企业文档的真实状态是脏乱差:PDF 带页眉页脚、表格被拍平成一行字、扫描件根本提不出文字。这些噪音会一路往下传,最后统一表现为一句话——"检索出来的全是废话"。
到这一步,换更强的模型、把 Prompt 改十遍,全是白费力气。数据质量排在模型前面,这条我反复验证过。
![]()
最后那行容易被忽略。PDF 解析出来的英文单词经常被换行劈成两半,embedd-ing这样直接喂进嵌入模型,语义就坏了。表格图片多的文档别拿正则硬扛,上 unstructured 或者 OCR——这块的投入产出比,比后面调十个参数都高。
切块大小是第二个高频坑。整篇文档直接 embedding 是最常见的错误:两万字压成一个向量,语义被彻底平均化,检索精度低到离谱。
![]()
默认从 500 字符 + 80 到 100 重叠起步。术语密集的规格书降到 400–500,叙述性长文可以放到 700–800。重叠的作用是防止一个知识点被切成两半,512 + 64 是性价比很高的组合。
实现上有个不报错但效果诡异的细节:硬切的步长必须等于 chunk_size 减去 overlap,否则你设多大的重叠都等于没设。另外每条 chunk 的 ID 建议用"来源 + 序号 + 内容摘要"的哈希,别用自增序号——文档一更新,增删段落会让后面所有序号整体错位,存好的向量全对不上。哈希 ID 是做增量更新的前提。
一说向量数据库,很多人下意识就去翻 Milvus 的文档。其实在几千到几万条这个量级,numpy 点积完全够用,四千条 768 维的向量也就 12MB 左右,全量检索几十毫秒。这个规模上分布式向量库,属于用航母打蚊子。
![]()
这里藏着一条必须记死的规则:建库和检索必须用同一个嵌入模型。换模型等于换了坐标系,新旧向量算出来的相似度全是噪音,而且它不报错,只是答得莫名其妙。稳妥的做法是在索引文件里连模型名和维度一起存,加载时校验,对不上直接抛异常。
还有一件必做的事:索引持久化。三千条 chunk 在 CPU 上向量化大概八分钟,要是每次调试都重建,一天时间就没了。存成 .npy 加 .json,启动时判断存在就加载——这一步做完,它才从"脚本"变成"能用的小服务"。
RAG 的效果,八成由检索质量决定。检索错了,后面接再强的模型也答不对。而裸向量检索有三个绕不开的毛病。
- 缺阈值。用户问的东西库里压根没有,相似度可能只有 0.5,TopK 照样把"矮子里拔高个"的塞给模型。得加分数过滤,让它有资格回答"没找到";
- 精确匹配失灵。问"设备 XK-2000 的防护等级",向量模型很可能召回一堆讲"防护等级通用要求"的文档——语义极像,答案全错。型号、错误码、SKU、人名,这些精确 token 恰恰是向量最不擅长的;
- 候选里混着"像但没用"的片段。排序依据是语义距离,不是"这条能不能回答这个问题"。
解法是双路召回,让两种检索各干自己擅长的事,再按权重融合。
![]()
0.7 比 0.3 是稳妥起点。语料里专名、编号多(设备手册、工单系统这类),把关键词那一路提到 0.4 到 0.5,效果提升很明显;纯叙述性文档就调回 0.2。
自己写 BM25 也就三十行,jieba 分词,k1 取 1.5、b 取 0.75。有个细节教程里经常漏:IDF 公式末尾那个+1必须加。不加的话,当一个词出现在超过一半的文档里,括号里会小于 1,对数变负,这个高频词反而开始惩罚排序——线下测不出来,线上会结结实实咬你一口。
如果对准确率要求高,还能再加一层重排。向量检索是双塔结构,问题和文档分开编码再算距离,快但精度有天花板;交叉编码器把"问题 + 片段"拼起来一起打分,准得多但慢,只能处理几十条。所以标准打法是两段式:召回 50 条,重排取前 5 条。库只有几百条、提问又简单的话,这层带来的一百来毫秒延迟可能不值,别硬加。
跑通 demo 只是开始。真正让系统能被人用起来的,是下面这几件不性感的事。
- 权限隔离。普通员工不能通过 AI 查到高管薪资。不处理这件事,RAG 会变成"越权查询加速器",比翻共享盘还方便。做法是在元数据里打部门和密级标签,检索时按角色注入过滤——注意要先多召回再过滤,否则过滤完凑不够 k 条;
- 评估。上线后最常听到的对话是"效果怎么样"——"感觉还行"。这不行。轻量方案半小时能搭:挑二三十个有明确答案的问题,标好答案在哪份文档哪一段,测检索命中率、答案正确率、引用准确率。命中率 0.8 是及格线,低于这条先回去调切分和阈值,别急着换模型;
- 增量更新。靠哈希 ID,索引里存每个 chunk 的内容哈希,启动时比对,一致的跳过。几十行代码,更新时间能从几分钟掉到几秒;
- 表格与多模态。表格被拍平成"一季度 100 200 300"这种字符串之后,向量化直接失效。折中办法是表格转 Markdown 保住行列关系,图片走 OCR 生成描述,把"描述 + 结构化内容"作为 chunk 正文,原图路径放元数据——检索走文本,展示走原图。
踩坑清单我也整理了一份,出问题时按现象对号入座,比乱改参数快得多。
![]()
至于改造顺序,我的建议很土:一次只改一个变量。
先跑最小可用版,能答对简单问题;再修检索,加阈值、加关键词召回,这一步通常提升最大而成本最低;最后修生成,强化 Prompt 约束、加引用、把 temperature 压到 0.1 到 0.3。每改一步,用那二三十道题验一遍,看得见变化,心里才踏实。
一上来就把混合检索、重排、多轮记忆、知识图谱全堆上去的人,最后往往得到一个"能跑但不知道为什么能跑"的系统——出了问题,四层里不知道是哪层坏的。
所以 RAG 到底难在哪?拆开看,它就是一个搜索系统加一层提示工程。你真正需要搞懂的只有四件事:向量怎么表示语义、相似度怎么算、Prompt 怎么约束、数据怎么治理。
模型负责说话,知识库负责内容。你不给资料,它只能猜;资料给得准,它才像个熟悉业务的老员工。等系统真跑起来你会发现,最有成就感的不是它答得多流畅,而是答案末尾那行「[来源:员工手册.pdf#12]」——点开,原文就在那儿。
你手上那份最想让 AI 读懂的文档,现在是什么格式?评论区聊聊,说不定你的坑我踩过。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.