论文说老办法赢了,可它真正的结论在后半句

哈喽,我是飞飞。
前两天刷到一篇论文,标题挺挑衅:BM25 Wins at Scale。
BM25 是个上世纪的关键词检索算法,说人话就是按词频给文档打分排序。它跟现在流行的那套「把文字变成向量再按语义相似度捞」完全是两条路。一个老古董标题里写着「在规模上赢了」,我头一眼以为是开倒车。
看完发现不是。而且真正让我坐直的东西在结论的后半句,那半句被大部分转述都吃掉了。
我还顺手拿它量了一下自己那个知识库,量出个有点尴尬的结果。
那把尺子怎么做的
先说这研究怎么做的,因为它的价值全在方法上。
这类比较以前最大的毛病是各测各的。这个范式在这个数据集上测,那个范式在另一个数据集上测,语料规模还各不相同。测完谁也说服不了谁。
这次他们在一个叫 EnterpriseRAG-Bench 的基准上,把语料规模做成了一架梯子。28 级严格嵌套,每级比上一级大 1.25 倍,从 1144 篇文档一路爬到 511959 篇,token 数从 170 万涨到 6 亿零 100 万,整体跨度约 450 倍。
严格嵌套的意思是,小规模那一级的文档,在大规模那一级里全都还在。题目不变,相关文档和干扰文档的底座也不变,变的只有周围塞了多少无关内容。
这样一来,不同范式的分数曲线就能画在同一张图上了。
结果很干脆。大约在一千万语料 token 那个位置出现了交叉点。过了这条线,BM25 在每一个更大的层级上都领先,到满规模时领先接近 20 分。
我的库过线三倍多
看到一千万这个数,我立刻去数了自己的。
我那个 Obsidian 库现在有 9812 篇 markdown,8234 万个字符,其中中文字 1624 万。按中文一字约一个 token、其余四字符约一个 token 粗算,大概是 3280 万语料 token。
过线了,而且是那个交叉点的三倍多。
这个数字让我有点意外,因为我以前从没往这个方向想过。我一直觉得知识库的问题是「资料够不够干净」「问题问得够不够具体」,这两条我写过。规模本身会翻转「哪种检索更好」这件事,我没意识到。
顺带说个巧合。我写 Karpathy 那套 LLM Wiki 的时候引过他一句话。他说在约 100 篇资料、40 万字的规模下,靠一个目录文件加一个日志文件导航就够了,用不着向量数据库。当时我把它当成一条经验记下来了。
现在回头看,那其实是一句关于规模的判断,只是当时没人把整条曲线测出来。而我今天这个库,是他说那个规模的两百倍。
真结论不是老办法赢了
这才是我说被吃掉的那半句。
论文里还比了一种叫 File-System Agent 的范式,就是让 agent 自己在文件系统里翻,一层层找下去。它在最小的那几级上表现不错,能追平甚至略微超过 BM25。
但它有两个问题。一个是贵,光是这种一步步往下探的方式,在底座那一级就要多烧 39 倍的查询 token。另一个是不扛规模,到满规模时落后接近 20 分。
到这儿为止,故事听着像「花哨的新玩意输给了朴素的老办法」。
然后论文做了一件事,把结论整个翻了过来。
他们把 agent 自己翻文件那套换掉,改成先用 BM25 排好序再交给 agent。同样 150 道题,满规模下这个组合拿了 69.4 分。裸 BM25 是 54.8,agent 自己翻文件是 36.9。
翻文件那套之所以输,跟 agent 笨不笨没关系。输在它找东西的方式上。
摘要最后那句话我照原文译过来。语料变大会越来越偏向全局候选排序,词汇检索是最强的可扩展默认项。而 agent 的推理最好用在排好序之后,而非取代排序本身。
三天前我写过同一句话
看到这儿我去翻了自己的东西,然后有点说不出话。
我那份写作规则库现在是 57 万字节、129 条规则。这么大一个文件,agent 每次写文章不可能通读,所以我给它定的取法写在 skill 里,原话是:任何时候都不要试图通读全文。
硬规则那部分靠 grep 查,说白了就是关键词检索,跟 BM25 是一条路上的东西。这部分一直很好用。
出问题的是另一部分。我那里面攒了三十几条按选题类型分的写作范式,是几十篇一点点磨出来最值钱的东西。可有一次五连测复盘发现,这批范式连续五篇一条都没被用上。写稿时 grep 命中的全是硬规则,范式区成了只写不读的死内存。
七月二十八号我给这个问题写了个诊断,原话是:
症结不在规则本身,在没有入口。
然后我建了一张索引,35 行,每行写「选题长这样,跳到第几行」。agent 现在的流程是先读那张索引,找到对应的一两条,再照行号跳过去读全文。
三天后,这篇论文用 28 级语料阶梯,把我那句话测了出来。
我建的那张索引,就是论文说的 ranked discovery。我让 agent 先查索引再去读,就是论文说的「推理用在排好序之后」。而我之前让它在 57 万字节里 grep 碰运气,就是那个 36.9 分的 File-System Agent。
这套东西我不是照着论文搭的。我是被那 34 条范式没人用逼出来的。
而且那张索引建起来之后,效果是能看见的。最近几篇写稿,它连着命中了好几次。有一篇同时命中三条,正好覆盖了那篇最大的三个坑。还有一次更有意思。命中的那条范式自带一句文体预警,说这类文章的对仗最容易超标。我因此动笔就散句化,初稿的违规数比上一次同类文章少了一多半。
同样一批规则,之前躺了五篇没人读,之后连着几篇都用上了。中间没改过一个字,只是加了个入口。
我那个向量层只盖了一成三
再说个更尴尬的。
我给这个库配了一套检索后端,向量和关键词两层。向量那层现在索引了 1216 篇文档、4672 个片段。关键词那层是 9066 篇。
也就是说,向量那层只覆盖了整个库的一成三左右。
我一直把这当成一个待办事项,觉得哪天该把向量索引补全。今天读完这篇我改主意了。
在我这个规模上,论文说词汇检索本来就是更强的那个默认项。我那个覆盖一成三的向量层,与其说是没建完的工程,不如说是它本来就不该是主力。真正该补的是把关键词那层用好,再给上面加一层排序。
当然得说清边界。这篇论文测的是企业文档问答,我这是个人知识库,语料形态不一样,结论不能照搬。而且我没在自己的库上做过 A/B 对照,没有实测数字。所以上面这段是判断,不是测出来的结论。
你的库在哪一级
所以这篇给你的东西很具体。
如果你也攒了个喂给 AI 的知识库,今天可以做两件事。
一件是去数一下你的库有多大。找到那个目录,把所有文本文件的字符数加起来,中文按一字一个 token、英文按四字符一个 token 粗估。数出来跟一千万比一比,你就知道自己在交叉点的哪一侧。低于这条线,agent 自己翻文件还行;高过这条线,先做排序再让它推理。
一件是看看你给 AI 留的入口长什么样。你那堆资料,它是怎么知道该看哪几份的?如果答案是「它自己找」,那你大概率就是那个 36.9 分。
我自己接下来要做的,是把 grep 那一层再往上抬一格。现在硬规则靠关键词碰,范式靠索引查,可这两条路是分开的。论文那个 69.4 分的组合提示我,它们应该是一条路:先排序,再让 agent 从排好的候选里挑。
最后想问问你:你那个知识库,AI 每次是怎么找到该看的那几份的?是你给它建了目录,还是让它自己在文件夹里翻?
评论区说说你的做法,我挺想知道大家的入口都长什么样。