我把知识库当成了硬盘
No English version yet — here is the Chinese original.
我这个知识库,硬盘那一半做得很好,知识那一半停在开局。
那张二十四行空白的待压缩清单,上一篇已经交代过,这里不重讲。这篇讲它底下那套东西:工作台、知识库、技能层,还有你正在看的这个网站——它们怎么咬合,为什么坏掉的偏偏是最不出声的那层。不是使用说明,是一次对账。
分三层,是因为它们坏掉的方式不一样
执行层是一套叫 FPI-X 的流程:准入、契约冻结、并行、集成、验证,五道闸。它管的是活怎么派出去、怎么收回来。最硬的一条是契约先行——接口、类型、数据形状没定死就开并行,几个 agent 各按各的假设写,集成那天一起爆。还有一条反直觉的:默认单线,并行是例外。编码任务里真正能并行的线程,往往比看上去少得多。
知识层是一个 LLM Wiki。查的时候走三层渐进检索:先读极简索引定位候选,再读摘要筛掉不相关的,最后才读全文,永远从第一层开始。为什么不直接上 RAG——五百页以内、需要反复深入同一个领域的场景,预编译的库比向量检索省约 84% 的 token;RAG 更适合上千页、一次性查询。所以顺序是先 wiki,撑不住再加向量层。检索流程里我还钉死了一条:第一层筛下来候选数是零,就停下报知识缺口,不许往下猜。报一句"库里没有",比端出一个像模像样的错答案便宜得多。
能力层是技能库,按需加载。不常驻,因为常驻等于每次开工都在为用不上的东西付钱。
执行层的错误是急性的——契约漏了一个字段,集成当场爆给你看。能力层的错误是"该触发的没触发",跑一次就知道。知识层的错误是慢性的:一个页面写错了、过期了、悄悄把你带偏,它不报错,可以静静躺半年。
三层混在一起管,慢性病会被急性病的噪音盖住。后来真发生了。
一开始我的直觉是,存下来就是赚到
四月初建的库,骨架是照着 Karpathy 那套 LLM Wiki 模式抄的:结论要编译进页面、别留在对话里;有价值的决策必须回写;wiki 优先于 RAG;不绑定任何工具;知识高于代码。第二天我就升了一版,加上三层检索、按访问频率的衰减分级、token 计量。
然后订阅源接上,每天往里倒。
那阵子很上头。六月里我把一批写作范本拆成了一个可复用的文风库,又联网扒了一整套类型谱系补进去;索引一天比一天长,每次打开都有新东西冒出来。我当时就一个判断:存下来就是赚到,反正总有一天用得上。
这个判断错在哪儿,我隔了两个月才看明白。
工具都在,只是没在跑
建那张待压缩清单的同一天,我坐下来盘了一次账,结论就写在它的页尾,不好看。
囤积与提炼的比例,一度是 9:1。原料页一大堆,真正提炼出来的模式页、决策页加起来是个零头,而且几乎全是四月初开局那一轮的产物。failures 目录零个文件。decisions 和 failures 两份台账各只有一行标题。决策日志里只有模板。度量层更离谱——统计页自报的总页数比实际少了一个数量级,那个数字从四月起就没动过。
而衰减机制的公式我早写好了:按访问频率和入站链接算分,分 Hot / Warm / Cold / Archive 四档,冷了不删只归档。compile 和 lint 两条命令也都在。
写好了,从来没周期性跑过。
这不是懒。这是我把"建好了"当成了"在运行"。写一条规则,比执行它便宜得多;而写下它的那一刻,感觉最像进步。
后来我给自己补过一条更难受的解释。我在别处定过一条规矩:一道门禁必须比绕开它更省力,否则它迟早变成墙纸。compile 和 lint 恰好是这条规矩的反例——往库里倒一篇原料,一条命令的事;把一批原料压成一页结论,得我坐下来读、判、取舍。倒进去比提炼出来便宜太多,于是我天天倒,一次没提。规矩没有拦住我,因为那条规矩当时管的是别人写的代码,没管我自己的知识库。
八月那次补抓更能说明问题。订阅断更了 34 天,补的时候我在日志里写了一整段 degraded 记录:有一路中文源整条没抓到,三层故障连着来——容器没起;起来了发现凭据过期;重新登录之后第一个请求就撞上频控锁,锁约二十四小时。静置三分钟、十分钟各探一次,都还锁着,按"同一条通道失败两次即降级"停手,没有硬刷。后果我也照写了:那一轮的候选全来自英文源,中文长文那半边是空的。
同一轮还揪出一个更阴的。抓榜单的脚本,正则只认 "N stars today",而周榜月榜写的是 this week、this month。于是星数被静默解析成空值——不报错、不告警,就是没有。修完实测七十八行全部解析出星数,修之前是零行。
这两件事其实是同一件事:不报错的失败最贵。
顺手重算统计的时候还撞上一个岔子:索引页脚上的数,和磁盘上数出来的数对不上,差了将近一倍。我一个都没动——索引数的是逐条列进索引的条目,而有两个大分区本来就挂在各自的子索引底下、不逐条列;统计页数的是磁盘上的真实文件。两个数都对,改任一个去凑另一个都是错的。这段说明我原样写进了页面。给以后的自己留一句:数字对不上的时候,先问它们量的是不是同一件事,再决定改谁。
后来我动了两个地方
第一个,不再对所有大牛文章一视同仁。我做了一张来源权重表,判高低只看一条:对我这套工作台有没有能直接用上的东西。给出 checklist 或 rubric 的加分,能改到某条具体规则的加分,一手实测比转述加分,自带反例和边界的比单边断言可信。纯发布、纯营销、纯观点的减分。
要紧的是高权重不等于免检。有个作者我给到最高的锚点级,连着几轮都是源码级的一手实测;但他有一篇是在某个模型发布前抢跑评论,本人没有访问权,能力数据全靠转引早期玩家。那一篇我按二手处理了。作者权重决定我先读谁,不决定我信什么。
第二个,给知识记战绩。现有的衰减只量"被召回过多少次",不量"召回了到底有没有用"。一个天天被召回、每次都把我带偏的页面,会一直待在 Hot 层——它比一个冷页面有害得多。设计是这样:每次召回注入落一行快照,任务收尾时按成败记账;再加三道抑噪闸——累计三次以上才允许影响排名,权重只做有界的乘法微调,账本满了淘汰最久没用的。最要紧的一条纪律写在最后一行:战绩是结论之后的副作用,永远不驱动结论本身。
这套设计七月初写完,到今天没接线。页面标题里我把"未接线"三个字写在了明处。因为接线之前得先有一把尺子——拿一段真实的查询历史干跑一遍,确认它不会把好页面错杀。尺子没做,就不接。
这一条我不后悔。设计好了不上线,比上线了没人验要诚实。
编译这个动作,没法外包
这个网站是这套东西的产物之一。项目、文章、翻车记录,都是从那三层里长出来的;你现在读到的每一句,背后都有一条能追回去的出处。
五条铁律里排第一的是 compile-first:把结论编译进页面,不要留在对话里。每次重新给模型喂一遍背景是线性成本,编译过一次之后就是查表。这条我到现在还信,它是整套东西唯一真实的收益来源——不是我攒了多少页,是下一个任务能不能直接吃掉上一个任务的结论。
但铺料和压缩是两回事。铺料可以委派,agent 铺得比我快、比我全、比我耐心。压缩不行。把二十四条压成真正承重的六到八条,还得是合上出处、凭记忆说出来的那种压——这个动作没法外包,因为它的产物不在文件里,在我脑子里。委派它,等于委派了自己的理解。
所以这次对账只剩一条:库建好了,不等于我懂了。
我为什么又开始写,上一篇交代完了,这里不重复。这篇的账只记到这儿:清点完了,压缩还没开始。写这一篇,顶多算把要压的东西自己先数了一遍。
Comments
…