大语言模型知识库
以下为自译中文版本。
最近我发现了一个有用的方法:用大语言模型(LLM)为各种感兴趣的研究主题构建个人知识库。如此很大一部分 token 用量不再用于操作代码,而是操作知识(以 Markdown 和图片形式存储)。最新模型对此已相当擅长。具体做法是:
数据摄入(Data Ingest)
将源文档(文章、论文、代码仓库、数据集、图片等)索引到 raw/ 目录下,然后使用大语言模型增量式「编译」出 wiki —— 其实就是一堆按目录结构组织的 .md 文件。此 wiki 包含 raw/ 中所有数据的摘要、反向链接,并把数据归类成各种概念,为它们撰写文章,并相互链接。为了将网页文章转换成 .md 文件,我喜欢使用 Obsidian Web Clipper 扩展,另外用快捷键把所有相关图片下载到本地,以便模型能方便地引用它们。
IDE
使用 Obsidian 作为「前端」IDE,可以在里面查看原始数据、编译完成的 wiki 以及衍生出的可视化内容。特别说明,wiki 里的所有数据都是由模型撰写和维护的,我很少直接去动它。我也尝试了其他几个 Obsidian 插件,用其他方式来渲染、查看数据(比如用 Marp 做幻灯片)。
问答(Q&A)
真正有意思的地方在于一旦 wiki 足够大(比如关于某项近期研究的 wiki 有约 100 篇文章,40 万字),就可以针对这个 wiki 向智能体提出各种复杂的问题,它会自己去检索、得出答案。我原以为需要动用花哨的 RAG 技术,但事实证明 LLM 相当擅长自动维护索引文件和所有文档的简要摘要,在这种「小」规模下,它能轻松读取所有重要的相关数据。
输出(Output)
比起在文本 / 终端里得到答案,我更喜欢将其渲染为 Markdown 文件、幻灯片或者 Matplotlib 图片,然后我再通过 Obsidian 查看这些内容。可以想象,根据不同查询还能得到很多其他可视化输出格式。我会随后将这些输出「归档」回 wiki 中来增强它,方便后续查询。如此,探索和查询总能在知识库里「积累叠加」起来。
检查整理(Linting)
我在 wiki 上跑过一些 LLM「健康检查」,比如找出不一致数据、补全缺失数据(借助网络搜索)、发现有意思的关联作为新文章的候选等等,从而逐步清理 wiki 并提升其整体的数据完整性。LLM 相当擅长建议可继续深入探究的问题。
额外工具(Extra Tools)
我自己会开发一些额外的工具来处理数据,比如一个针对 wiki 的朴素搜索引擎。我会直接使用它(在一个网页 UI 里),但更多时候我通过 CLI 将它作为工具交给 LLM,用于更大规模的查询。
进一步探索(Further Explorations)
随着仓库不断扩大,一个很自然的想法是使用合成数据生成(synthetic data generation)和微调(finetuning)让 LLM 将数据「记」在其权重内,而不仅仅位于上下文窗口。
TLDR
先从若干来源收集原始数据,再由 LLM 编译成 .md 的 wiki,之后用 LLM 通过各种 CLI 工具对其进行操作来进行问答并增量式增强 wiki,而所有这些内容都可以在 Obsidian 中查看。几乎从不手动撰写或编辑此 wiki,它是 LLM 的领地。我认为此处有空间做出一款了不起的新产品,而非只是一堆临时拼凑的脚本。
该推文下的一些有趣讨论:
我已经在此设置上使用了大约一年,最大的突破是能够在任意 k 个主题上跨任意 k 个领域进行综合,此时连接的可能性变成了 个之多。 你可以连接比如「斯多葛哲学 - SaaS 定价 - 病毒式内容 - 育儿」,而代理实际上可以遍历此路径并找到连贯内容。
我在 PAI 算法的 Learn 阶段中判断某个内容是否应该成为 Knowledge 文章,并在 MEMORY/KNOWLEDGE 下为我们创建它。因此,我们在一次会话中处理的任何内容都会被收集为 Knowledge 文章,并且始终保存在文件系统中。随后,PAIUpdate 和其他任何 PAI 技能都可以看到这些内容,了解我们学到的东西,并在新内容出现时与之对比。我之所以不使用 Obsidian,是因为觉得它的 UI 很重。实际上只需使用高质量的 Markdown 并引用其他 Knowledge 文章即可。
OriginTrail 项目提出了 DAG(Decentralized Knowledge Graph,去中心化知识图谱)这个概念。目前影响力不算大。
从个人研究 wiki 到企业运营的跳跃才是真正残酷的。一个人的 Markdown 仓库尚能管理,但成千上万员工、数百万工单和部落式知识在团队之间激荡,此时根本无法用 vibe code 来处理。
我将其称之为「氛围研究」… 一个关键问题是,知识库缺乏测试、评估、基准等手段,你基本上只能相信 LLM 已经正确摄取、摘要并转化了已有信息。
实现这个 Idea 的指南文章。
该评论提到他们使用相似的设置训练了一个记忆模型用于长文本处理。
构建了一个受该模式启发的开源实现:llm-wiki-compiler,与此同时也找到了另一个开源实现:agentmemory 。
我目前正在寻找一种 LLM 之外的方法来让 LLM 知道何时停止「获取」信息,有时 LLM 在获取信息太少后就决定回答,有时又会「浪费」时间获取超过实际需要的信息。 我猜这也取决于知识库的规模,但就单一项目而言,LLM 在跨越大约 5 层(水平和垂直)链接的知识上出现失败。 而且这是在使用 Claude Opus 4.6 时的情况下。希望有更好的方法帮助 LLM 进行遍历… 或许在 LLM 对问题进行推理之前,就先将数据布局在关系型和图数据库中(或许由另一个代理,或者仅仅是一个工具来完成?)。
这深有共鸣,我已经使用 Claude Code 运行一个拥有 1w+ 笔记的 Obsidian Vault 长达三年,得出完全相同的模式… 我想补充的经验是:除了 schema 之外系统文件还能携带「规则」和「上下文」。我的 CLAUDE.md 包含优先级、STATIC / DYNAMIC 标记(缓存感知)以及 Essential(在上下文压缩中仍然保留的核心规则)。当 AI 读取的不仅是「这里有什么」而是「在此应该如何行动」时,wiki 的质量会提升一个档次。
他的工作可以在此找到。
后续:Karpathy 在发表推文后立即发布了一份关于这个 Idea 的详细说明文档。
目前最具影响力的实现来自 agentmemory,目前在 Github 上已经有超过 25k Star,它声称:
The gist extends Karpathy's LLM Wiki pattern with confidence scoring, lifecycle, knowledge graphs, and hybrid search: agentmemory is the implementation.
#todo 目前尚未仔细研究该代码库。
该库的作者扩展了 Karpathy 的 LLM Wiki,提出了 LLM Wiki v2。
已经将以上两份说明文档存到本地:
#todo 仔细阅读说明文档下的评论。
LLM Wiki v2 相关评论:
来自 ChristopherA
我对这个方向很感兴趣,但相比推断出来的知识图谱,我更看重由人显式撰写的命名边(由人发起、但由 agent 协助完成)。
https://gist.github.com/ChristopherA/151aefa6a6bde1ce4fa6b1182656cebe
摘要:一份实用指南,讲的是仅用两条约定就能把一堆 markdown 文件变成真正的知识图谱:用 wikilinks 表示连接,用类似
derived_from::[[Source]]这样的命名边表示连接的含义。不需要数据库或其他特殊工具,只需在文本文件添加少许规则。如果你在 Obsidian 之类的工具里记笔记、在构建需要遍历结构化知识的 AI agent,或者关心协作者如何在不把自己的词汇体系交给别人的 schema 的前提下共享同一张图谱,那么这份指南值得一读。
来自 gnusupport
@ttaskippythemagnificent-coder
- 「置信度评分」从未被定义:是浮点数,还是枚举值?谁来计算?如何更新?
- 「自动将会话蒸馏为知识」纯属魔法:没有提取算法、没有去重机制、没有触发条件
- 582 个节点少得可怜:这不是知识图谱,只是周二下午随手就能做完的东西
- 混合搜索没有融合策略,不过是把三样缓慢方法拼凑在一起
- 没有延迟目标:100 毫秒?10 秒?谁知道?
- 没有准确性指标:NDCG?MRR?什么都没有
- 「3A+3B 需要 8-10 小时」简直不切实际:那只是笔记本试验性技巧,不是生产系统
- 假定组件能够自然组合:它们做不到;集成本身才是工作
- 每次写入都做矛盾检测是一个 AI 完备问题:它们还没准备好面对这种复杂度
- 没有访问控制:任何 agent 都可以写入任何内容
- 没有版本控制:无法回滚一次糟糕的蒸馏
- 没有溯源机制:是哪一个 agent 写下这条事实?来自哪个来源?
- 没有一致性模型:ACID?最终一致性?多 agent 同步需要这些
- 没有备份或恢复策略:一旦损坏就全盘皆输
- 没有评估框架:如何判断它是否奏效?
- 把 LLM 当成可靠的:它们会悄无声息地污染图谱,而你永远不会知道
- 没有针对 LLM 失败的 human-in-loop 回路机制
- LLM API 宕机时没有后备方案
- 没有人类可读的地址:无法在邮件或文档中引用一条事实
- 没有反向链接:缺少「什么指向这个节点?」这一问题的答案
- 没有时间戳:无法审计一条事实何时发生变化
- 没有签名或身份验证:无法信任内容由谁写入
- 没有外部文档链接(XDoc):Slack、邮件和 PDF 都被排除在外
- 假设不存在 bug、测试、安全和回滚问题
- 这是一份披着架构文档外衣的产品愿景
方向很好,蓝图却很糟。不要按这个去构建。借鉴这些 想法,而不是照搬 计划。
参考:
技术模板项目 OHS 框架:
https://www.dougengelbart.org/content/view/110/460/
来自 ghost
乍看材料很扎实,但有张力之处值得指出:「schema 才是真正产品」这句话和那一整套精巧的生命周期机制(置信度衰减、自动蒸馏、遗忘曲线)其实在朝反方向拉扯。如果 schema 真的做好了本职工作,过滤就应该发生在摄入(ingest)环节 —— 大部分后处理机制会沦为在解决本该被 schema 提前避免掉的问题。
以下是几点具体顾虑,来自我在生产环境中运行一套类似但更保守的模式的经验:
1. 把遗忘曲线套用到错误和被取代的决策上恰恰导致你重复犯同一个错误。 旧不等于过时。半年前记录的 bug 往往比上周的更有价值,因为它恰恰是你即将遗忘的那个。一份被取代的 ADR 依然解释了当前的 ADR(架构决策记录) 为何存在。艾宾浩斯(Ebbinghaus)曲线是一个与容量限制绑定的生物学模型,而 wiki 根本没有这种限制。正确原语应当是 显式取代(explicit supersession),而非衰减:旧文档保留下来,只在头部加一个指向替代它的新文档的标记。什么都不会消失。未来的读者在三秒内就能知道哪些是现行的、哪些是历史。Git 也可以顺理成章地成为审计轨迹。
2. 数值化的置信度分数是一种虚假的精确。 真正好的信号是主张所携带的证据链 —— 来源、相关 ADR、提交历史。置信度分数无法被验证。「在一份 ADR、对应的 commit 以及两份来源文档中都得到确认」才是可验证的。为主张生成置信度分数就等于给它披上了一层它并未从证据中赢得的权威外衣。
3. 事件驱动的自动录入假设了 LLM 是可靠的。 但它们并不可靠,即便是前沿规模的模型也一样,本地小模型更是如此。我在一个 2B Q5 模型上测试过创造性综合任务:它会凭空捏造出上下文里根本没有的依赖项,会无视作为输入喂给它的 ADR 中明确记录的架构约束。让模型在 hook 触发时写入知识库,会悄无声息地污染它。把「人在回路中」作为写入闸门不是一种落后,而是质量控制」 —— 当写入者是一个随机过程时尤其如此。我运行的这套系统里有一个独立的写入 agent,受一份正式契约约束,只有在明确的人工交接之后才会写入,并以带前缀的 commit 作为审计轨迹。虽然慢一些,但保证了每条记录都可逆且有动因。
我的行之有效的替代哲学是:在录入环节过滤,而非在保留环节过滤;用取代替代衰减;用 git 做审计;先手动,再自动。 schema(一份 CLAUDE.md 加上一套有文档记录的工作方法)大约完成了 90% 的工作。其余一切只有在手动循环跑过数十个真实周期、模式明显稳定下来之后,才会被自动化。
这份 gist 里的各个想法作为一套词汇(vocabulary)是有价值的。但作为一份蓝图,gnusupport 的批评依然成立。
来自 ahumanft
V2 提供了机制层(mechanism layer)。以下文章则是对分段层(segmentation layer)的一次尝试 —— 它从架构层面回答了:为什么当 V2 的各项机制被堆叠到一个不加区分的 schema 和一堆不加区分的数据之上时会失效。分段之后,V2 的机制就能完全按预期工作。文中还涵盖了用于检索的 librarian 模式,以及面向显式触发(而非隐式配置)的 schema 设计。它把分段配置留作尚未解决的开放问题。
https://gist.github.com/ahumanft/6c96385be6ca4af578cc9b20e0f79e66
来自 nunezb
GCP 最近提出的 Open Knowledge Format 或许可以作为一种 schema,用于把 agent 的「记忆」当作一个动态演化的知识图谱来处理,尤其是它针对这里提到的结构化数据缺失问题:它把概念 —— 也就是图谱的基本单元或节点 —— 视为带类型、以 YAML 作前言(YAML-prefaced)的 Markdown 文件,而不是像这里提议的那样去处理带类型的关系 —— 他们在 §5.3 中似乎明确否定了这一想法。当然它目前还是非常早期的草案(v0.1),所以我会用一个个人 fork 来做实验,或者等这份 spec 足够成熟之后再说(如果它真能成熟的话)。
就这份 gist 而言,我很欣赏它对模块化的强调 —— 严格按需添加复杂度的层次,而不是过早优化、把事情搞得过于复杂。(这正是我建议大家使用诸如 Obsidian 来记个人笔记的方式:先禁用所有插件,把工具用起来,只在真正需要时才去折腾插件。)
来自 Firsgith
建议:若 V2 停留在记忆工程层,将面临 5 种系统性退化风险
你好 @rohitg00 —— 你在 Karpathy 的原始版本之上扩展出生命周期管理、混合检索和整合分层,做得很棒。但当我把 V2 模式推进到复杂的长期推理场景(多 agent 研究、跨领域分析、跨月项目)时,我观察到:纯粹停留在记忆工程层会导致 5 种可预测的系统性退化模式:
1. 跨实体推断污染(幻觉合法化)
V2 的实体抽取会创建带类型的节点,但没有 证据范围(Evidence Scope) 约束。混合检索会把所有语义相关的记忆一并拉出来 —— 于是 LLM 会乐此不疲地用 A公司的行业事实去推断 B公司的战略。举例:问「Kimi 为什么不做百万 token 上下文?」,它会把 Gemini 的长上下文文档和 DeepSeek 的文档一起拉进来;系统于是推理出「Gemini 占据了长上下文的生态位,所以 Kimi 要做差异化」—— 听起来合情合理、置信度很高,却完全是跨领域污染凭空捏造出来的。
建议: 在知识图谱中加入实体绑定的证据范围。每条边 / 事实都携带一个范围标签:
entity_only | local_generalizable | global。检索在推断之前先按范围过滤,从而防止跨实体泄漏。2. 猜想固化为事实(认知僵化)
置信度 0.85 这种设计无法区分「从官方文档中核实过的」和「agent 上一轮 session 里瞎猜的"」。也就是缺少 认知层(Epistemic Layer)。被回写进记忆的推断与有来源的事实无法区分。随着时间推移,早期的猜测会自我强化成不可撼动的「知识地基」—— 形成一个封闭的认知回路,系统再也无法质疑自己的假设。
建议: 加入离散的认知状态:
fact | verified_inference | hypothesis | speculation(事实 | 已验证推断 | 假设 | 推测)。追踪主张的溯源(Claim Provenance,即来源链)。置信度退居为次要信号;认知状态才是首要的。系统应当能够说出「我知道 X」与「我怀疑 Y」的区别。3. 矛盾被当作噪声,而非研究机会
V2 通过按时间加权的取代来化解矛盾 —— 较新的主张胜出。这对清理数据是高效的,但对认知成长是破坏性的。真正的研究恰恰诞生于矛盾之中:「为什么双方都有证据?边界条件是什么?」自动化解矛盾,等于消除了驱动知识扩张的关键信号。
建议: 加入一种 矛盾即研究(Conflict-as-Research) 机制。当两条高置信度的主张彼此矛盾时取消自动取代,而是生成一个结构化的研究任务:去探究边界条件、适用场景,以及为什么双方都有支撑。把化解过程连同其推理一起存下来,这样未来同一领域的矛盾就能更快化解。
4. 决策存储时未记录推理路径(知识复利中断)
蒸馏能很好地提炼出结论,却不记录做出该决策的原因 —— 权衡过什么、否决了哪些备选方案、当时的环境约束,以及当时的置信度。三个月后,agent 面对一个类似问题时,只能检索到旧的结论,检索不到当初的推理。它不得不从零开始重新推导一切。
建议: 加入 决策记忆(Decision Memory):记录完整的推理路径、加权的利弊、被否决的备选方案,以及决策当时的情境上下文。当条件发生变化时,agent 就能对旧决策做增量修正,而不必重新发明轮子。
5. 规模化时缺少路由器或时间线
在 10 万以上对象上做混合检索,意味着每一次查询都会触发全范围的 BM25 + 向量 + 图遍历 —— 这既昂贵又缓慢。应当有一个 路由器/规划器(Router/Planner) 在检索之前先对意图分类、选定合适的检索层,而不是每次都做全量扫描。
另外,V2 没有面向时间查询的 时间线(Timeline) 视图。「我们在 2024 年初对 Agent 架构是怎么看的?」要么返回最新版本(错误答案),要么返回零散片段(不连贯的答案)。一个感知时间的索引能实现对某一时间点知识状态的重建。
TL;DR V2 出色地解决了记忆质量问题。而这 5 项补充(证据范围、认知层、矛盾即研究、决策记忆、路由器 + 时间线)能把它从一个知识渊博却盲目的存储柜提升为一个知道自己知道什么、不知道什么、以及下一步该往哪探索的认知系统。