785 篇文章写给代理,而不是人:没有向量检索的知识库
作者: Anastasiia Butova, ComfyUI 与扩散模型工程师,贝尔格莱德 · 发布于 2026-04-22 · 更新于 2026-09-23
译自英文版: English
代理在一个陌生项目中开始工作时,会花掉前 30% 到 40% 的 token 去弄清周围发生了什么。不是在干活,而是在定位方向。这篇文章介绍 Happyin Knowledge Space:一个我为代理而非人写的参考卡片库。内容包括:卡片格式为什么是现在这个样子,快速变化的领域为什么要设定新鲜度阈值,为什么我手工链接卡片而不是把它们放进向量数据库,以及来自多个账号聊天的研究如何不经复制粘贴就进入这个库。2026 年 4 月 22 日俄文原文发布时,它包含 26 个领域的 785 张卡片。
代理学习项目的两个问题
README 讲动机,教程手把手带你做,API 参考列出参数。它们都没有回答代理真正带着来的那个问题:我的任务是这样的,该照搬哪种模式,哪里有地雷?
第二个问题更深,也更不容易察觉。模型"什么都知道",但这些知识在训练数据中的分布并不均匀。一项技术在互联网上存在得越久,关于它的帖子、Stack Overflow 回答和教程就越多,那种做法在模型内部的权重也就越大。当我让 Claude 训练一个 LoRA 时,它第一个给出的方案往往是五年前的配方。不是因为它更好,而是因为相关内容更多。对于稳定的技术,这没有问题。但对于变化很快的领域,比如模型训练、代理工具链或安全,结果就是代理悄悄地把我拽回过去。
显而易见的解法是每次都做深度研究,带入当前的上下文。我确实这么做。但深度研究代价很高:每月订阅要花几百美元,而额度几乎马上就用完。更糟的是,每次研究都随着会话一起消失。明天我会在同一主题上再搜一遍,把同样的 token 花在我已经知道的东西上。
由此得出两个想法。研究应该积累,而不是蒸发。格式应该向代理展示当下什么是最新的,使它一打开项目,就能直接进入"这里是通常的做法"。
格式:卡片,而不是文章
每张卡片都有相同的骨架。顶部是主题和一句话定义,让代理一眼就知道自己是否来到了正确的位置。接着是 Key Facts(关键事实):带有数字的简短陈述,比如版本号、阈值和依赖关系。然后是 Patterns(模式):可以直接复制粘贴、带语言标签的代码。最底下是 Gotchas(坑点),每条是一对:什么会出错,以及如何修复。
没有"我们来看一看"之类的开场白,也没有"本文中我们考察了"之类的结尾。Kafka 的 broker 架构卡片包含一张 ZooKeeper 与 KRaft 的对比表、一份带注释的配置、带告警阈值的 JMX 指标,以及一步一步的迁移过程。读起来并不顺滑。但代理搜索 "KRaft migration" 时,三步就能拿到一份可用的配方。
最后一块最有价值。一行"min.insync.replicas 只有在 acks=all 时才生效",能省下半小时的调试。代理读到了它,就没有犯这个错误,也没有浪费一轮重试去修复。
26 个领域,由工作生长而来
四月份最大的领域是图像生成,有 58 张卡片,紧随其后的是 LLM 代理 57 张,数据科学和安全各 56 张(安全是通过单独的文件夹、按 CWE 类别增长起来的)。之后是 Kafka 43 张、DevOps 38 张、Web 前端 36 张、数据工程 34 张,另有四个领域各 33 张:Python、SQL、架构和算法。其余十四个较小的领域包括:iOS、Linux CLI、C++、Java Spring、测试与 QA、BI、SEO、Rust、Node.js、PHP、LLM 记忆、音频与语音、写作,以及 Go。
这不是一份计划,而是一张地图,标出我和代理一起工作时时间真正花在哪里:训练 LoRA、调试 C++ 插件、做研究。每个领域都积累了一份"我的事情在这里出过错"的清单,而这些清单就成了骨架。
知识并非以同一速度老化
算法和数学是稳定的:三年前写的摊还分析或网络流卡片,今天依然正确。扩散模型训练、推理优化和 ComfyUI 节点每隔几个月就会变化,秋天有效的做法到了春天可能已经过时。我在 为什么扩散模型在 4000 万像素照片上画出接缝 中写过的超大照片分块扩散,就是这样一个快速变化的话题。
因此每个领域都有自己的新鲜度阈值。稳定的领域没有阈值。在快速变化的领域里,超过 60 天的卡片会被标记为需要复查,而每天运行一次的 hook 会把它放进"检查并更新"列表。这不是删除警报,而只是一个提醒:这个话题很可能已经变了,卡片需要对照当下的事实重新核对。过时的卡片会自行进入复查流程,而不是悄无声息地误导代理。
链接而不是向量
这类知识库显而易见的架构是向量数据库加 RAG。它能快速找到语义相近的文本,在生产环境中效果很好。我刻意没有采用,原因有三。
向量库对人不可读。 我可以用文本编辑器打开 Markdown,可以 grep、可以在 git 里 diff、可以粘贴到邮件里,也可以打印出来钉在墙上。今天如此,十年后任何电脑上也依然如此,不需要任何特殊工具。向量库则是只有它自己的客户端才能理解的二进制文件。换供应商、服务停掉、API 变动,数据就变成一堆没人读得懂的数字。我希望知识库能经得起工具更换,而不是依赖于某个工具。
向量化几乎是不可逆的。 嵌入是有损的单向压缩。如果不把原始文本块存在旁边,一堆嵌入毫无用处,因为几乎不可能还原出可读的文本。关于嵌入反演的研究确实存在,但它只在很短的片段上有效,需要相同的嵌入模型,还需要单独训练的解码器。而且它把你绑定在一个嵌入模型上:为了更好的质量换了模型,就得全部重新索引,因为旧向量在新空间里毫无意义。
还有对我最重要的一点:链接图记录的是哪些主题相邻,而不是哪些文本相似。 向量相似度找到的是在词汇和概念上有重叠的主题。而在真实工作中,最有价值的链接往往跨越相距很远的主题。我的 Kafka 复制卡片链接到一张内存剖析卡片,不是因为两个主题相似,而是因为调优消费者时发现了一个内存泄漏,经验让它们成了邻居。在嵌入空间里,"分布式队列中的复制"和"Python 中的内存剖析"相距甚远,语义搜索不会搭起这座桥。而手写的 wiki 链接可以,现在读 Kafka 的代理离内存剖析只有一步之遥。
机制很简单。卡片之间通过 [[flux-klein-9b-inference]]、[[two-phase-commit]]、[[saga-pattern]] 相互引用。构建时,一个 Python hook 把每个 slug 解析为相对路径。如果找不到某个 slug,日志会给出警告;在严格模式下构建直接失败,这样断掉的链接永远不会进入线上站点。四月时链接数超过 2,100 个。这就是整个知识图谱:没有嵌入,没有向量数据库,没有 RAG。只有 Markdown 和 grep。代理打开分布式事务的卡片,在 See Also(另见)下看到相邻的主题,跟着其中一个走下去,然后继续工作。从入口到可用模式,只需三步。
这与我代理记忆中的 [[filename]] 链接是同一种思路,在 我的 CLAUDE.md 有 582 行 中有介绍。
网站是仓库的一次构建
happyin.space 上的一切都是由开放仓库中的 Markdown 构建出来的静态站点。没有数据库,没有后端,没有隐藏层。文件 docs/kafka/broker-architecture.md 经过构建后变成页面 happyin.space/kafka/broker-architecture/,整个机制就是这样。
这意味着任何人都可以 fork 并在本地大约五分钟内运行:
git clone https://github.com/AnastasiyaW/knowledge-space.git
cd knowledge-space
pip install -r requirements.txt
mkdocs serve # then open http://localhost:8000
这会得到一份本地副本,包含每张卡片、完整的搜索和链接图。从这里开始,你可以清理掉我的领域,添加你自己的,然后让代理指向本地构建,而不是公开站点。我自己就是这样使用它的:大多数时候打开的是本地构建,公开站点只是一个镜像。
完整重建大约需要五秒,在老旧笔记本上和工作站上一样快,因为底层是业界用了十五年的那类静态站点生成器。针对本地副本工作的代理,不会把 token 耗费在网络往返或等待部署上:重新构建,打开卡片,取出配方即可。
同一个构建步骤也保证了链接的真实性。它遍历每个 [[slug]],找到对应卡片并写入相对路径;如果找不到,构建就失败。我在提交前就能在本地看到这一结果,CI 也会以严格模式运行同样的检查,任何断链都会阻止部署。四月时链接超过 2,100 个,没有一个是断的。而且因为站点就是仓库,一切都在 git 里:你可以看到一张卡片如何变化,哪些事实是在哪次研究之后出现的,以及它最后一次被修改是什么时候。对于一个按知识老化速度分类的库来说,这段历史很重要。
研究如何进入库中
这套流程的设计让我从不需要手动搬运数据。我有几个 Claude 账号,每个账号同时打开着几个对话,在其中任何一个对话里,某个时刻都可能启动一次深度研究:新模型、优化、故障,什么都可能。以前,结果只存在于对话结束之前。现在,这些对话都遵循同一条常设规则:深度研究完成后,把结果的一份副本放到一个集中的地方。
这个地方是一个绑定到 knowledge-space 仓库的 Claude Code 项目,它有自己的 research/inbox/ 文件夹,用来收集每个账号上每个对话的原始导出。没有复制粘贴,只有一条规则:每个对话在开始时读取它,在研究完成时遵循它。
接下来是第二遍处理。knowledge-space 项目中一个单独的会话会逐个处理收件箱:读取每份原始导出,提取具体的事实和坑点,把它们重新打包成卡片格式,并与该领域中已有的内容对照,让重复的内容去丰富已有卡片,而不是制造重复。然后它检查 wiki 链接,运行构建,阅读差异,再推送。一次这样的会话通常在几个小时内产出 20 到 40 张新卡片或丰富后的卡片。
模型分级是由此直接得出的,我也是在这里终于找到了 Sonnet 的用处。对我来说,它以前一直夹在"对简单的事情太聪明"和"对任何有意思的事情又太简单"之间。但"读取原始研究导出、提取事实、重新打包成卡片格式、与文件夹中的相邻卡片比对"恰好是它擅长的工作:机械,但需要语言能力。Sonnet 重组文本的能力与更大的模型不相上下,而成本明显更低,所以研究对话和收件箱处理都跑在它上面。检查 wiki 链接、判断两张卡片是否应该合并、或者解决两个来源之间的冲突,则属于需要理解、判断和设计的工作,交给更强的模型。成本差距是几倍,而质量没有损失。
结果是一条流水线。我做我的主要工作,同时在不同对话中顺带进行研究,而知识库在我不搬运、不排版的情况下不断充实。
使用与贡献
最简单的用法是让你的代理指向 happyin.space/llms.txt,然后需要时自己拉取卡片。仅此一点,就能减少过去用于定位的前三分之一 token。
下一个层次是贡献。仓库中有两份专门为此编写的文件:CONTRIBUTING.md,是准备页面和提交修改的通用指南;AGENTS.md,是给你的代理的说明。它们描述卡片格式、文字应有的密度、哪些内容应放在 Gotchas 下、如何编写 wiki 链接,以及如何为新卡片或更正发起 pull request。把指南和一份新的研究结果交给你的代理,它就能自己组装出卡片。你的研究进入了知识库,你不必再为它付第二次钱,其他人也一样。README 声明采用 MIT 许可证。
研究在库中越多,任何人需要重做的就越少。越多的人和代理提交卡片,领域之间意想不到的桥梁就越多,而这些桥梁恰恰最有价值。本站的项目页面是 happyin.space。
四月之后的变化
2026 年 9 月更新。仓库 README 现在报告 28 个领域中有 1,287 篇以上文章,以及 3,139 条以上的交叉引用。增长大多来自两类新页面:projects/,388 页,每个新闻流水线跟踪的工具、模型或产品一页;以及 organizations/,45 页,每家公司或实验室一页。新鲜度规则现在在 README 中是一个四步循环:稳定、每年、每半年、每月,其中图像生成和代理框架归入每月一次的一组。
上文中的四月数字(785 张卡片、26 个领域、2,100 多个链接、60 天阈值、五秒构建)在发布当天是真实的,我保留了原样。同样偏好普通文件而非服务的理念,应用到多个代理会话同时工作的场景,见 多个 Claude 共用一个仓库。
俄文原文发表于 Habr。