![]()
一个做HR系统的团队,用开源工具替换掉商业方案,检索准确率从"能用"变成"真香"。没人想到,瓶颈居然卡在PDF怎么拆。
这是RAG(检索增强生成,Retrieval-Augmented Generation)落地的第二阶段。第一阶段搭了个能跑的demo,第二阶段要解决一个扎心问题:用户上传的PDF,机器读不懂格式。
PDF是RAG的隐形杀手
做过文档AI的人都知道,PDF是格式黑洞。同样的文字,扫描版、文字版、表格混排版的解析难度天差地别。很多团队卡在第一步:花了大价钱买嵌入模型,结果喂进去的是断章取义的碎片。
IBM开源的Docling在这个节点杀出来。它不做嵌入,只做一件事——把各种格式(PDF、Word、HTML)洗成干净的Markdown或JSON。关键是保留版式:标题层级、表格结构、段落归属,全给你标清楚。
作者实测后的结论是:「这是我测过最有效的开源文档处理工具。」这句话的含金量在于,他对比过商业方案。
Docling的chunking(分块)策略叫"混合层级分块"。简单说,它按标题智能分组,把小碎片合并成有上下文的整块,同时给每块打上丰富的元数据。下游检索时,你能知道这段话属于哪个章节、前面讲了什么。
代码层面,调用很干净。一个DocumentConverter配置格式选项,一个HybridChunker执行分块,输出直接进向量库。作者贴出的Python函数不到20行,核心逻辑是:
converter.convert(file) → chunker.chunk(doc) → 拿到带上下文的文本块
![]()
这比很多"黑盒"商业方案透明得多。出问题的时候,你知道该调哪。
余弦相似度是个性能陷阱
文档处理升级后,作者盯上了检索层的计算效率。这里有个反直觉的发现:大家都在用的余弦相似度(cosine similarity),在现代嵌入模型场景下是冗余计算。
余弦相似度的公式里,归一化(normalization)是内置步骤。它只算向量夹角,无视长度。但现在的主流嵌入模型(比如OpenAI、Cohere、开源的BGE系列)输出的本身就是单位向量,已经归一化过了。
这时候再用余弦相似度,等于同一批数除两遍自己。换成点积(dot product),跳过冗余的归一化步骤,结果完全一致,计算量更少。
作者给了两个务实的提醒:
第一,点积的提速在端到端RAG链路里可能不明显。如果你的瓶颈在文档解析或大模型生成,检索快几倍也感知不到。别为了优化而优化。
第二,点积有个硬前提:向量必须预归一化。如果没做这个检查,向量长度会直接扭曲搜索结果。配置切换很容易,拿不准的时候跑个对比测试就行。
重排序是性价比最高的升级
![]()
架构图里还藏了一个新组件:重排序模型(re-ranker)。它的作用是让"粗排"变"精排"。
向量检索是速度优先的近似匹配,召回率高但精度有限。重排序模型用更复杂的交叉注意力机制,对召回的前K个结果做二次打分。代价是计算量更大,所以只跑少量候选。
这个设计在信息检索领域叫"召回-精排"两段式,Google搜素用了二十年。RAG场景下,它解决的是语义匹配的模糊性问题:用户问"年假怎么算",向量检索可能召回"加班调休政策",重排序模型能把真正相关的条款顶上去。
作者没展开讲具体用的哪个重排序模型,但从上下文推断是轻量级方案。太重的话,延迟优势就被吃光了。
下一步是"跑"起来
这篇是"Crawl-Walk-Run"三部曲的中篇。Crawl阶段验证了RAG能跑通,Walk阶段做了两件事:上游把文档解析做扎实,下游把检索效率抠干净。
作者预告下一篇会深入Docling的实现细节。从代码片段看,他对这个工具的研究还没放完。
一个值得留意的细节:整个优化过程没碰大模型本身。更好的效果来自数据工程——怎么切文档、怎么算相似度、怎么排优先级。这和很多团队"模型不够大就换更大的"思路正好相反。
如果你的RAG系统还在用正则表达式拆PDF,或者用余弦相似度跑预归一化向量,这两个改动可能是最低投入、最高回报的升级。问题是,你知道自己现在用的是哪种方案吗?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
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.