把知识库注入你的LLM,一次查询节省6倍Token。
LLM领域的传奇大牛 Karpathy ,这次带来了全新的知识库。
就在一个多月前,Andrej Karpathy(没错,就是那个OpenAI创始团队成员,刚刚加入 Anthropic 的LLM研究员)发布了他日常使用的知识库形态。
“实体”、“概念”,这一套逻辑没变,区别是让LLM全面接手知识库的管理,包含三重目录和三种操作:
• raw目录:存储原始文档• wiki目录:存储各个wiki页面,包括摘要、实体、概念等• schema目录:存储各种规则、提示词、约束• Ingest 操作:将新的文档加入知识库 • Query 操作:用户向知识库发起提问 • Linter 操作:知识库健康检查,清理过时知识

如果说基于向量召回的知识库是知识的“解释器”,那么基于LLM的知识库就是知识的“编译器”。
LLM Wiki不会每次都读取原始知识,而是将知识“编译”成wiki摘要,并基于摘要回答。
而他的开源方式更加特立独行:没有完整的项目仓库,也没有可供复现的demo,而是直接在GitHub上开源了一个“llm-wiki.md”的文件。
将代码塞入知识库Karpathy的方案一经提出便获得千万阅读,相关的复现实践更是层出不穷。但绝大部分的复现都局限于文本数据,例如学术论文、技术文档、学习笔记。
LLM Wiki能够取得巨大效果的核心原因在于,能够轻松将整篇文档放入上下文,直接理解文档内容并执行后续的抽取知识、总结wiki操作。
恰好我们的工作流需要频繁地调研竞品代码并对比,于是便有了一个新的idea:为什么不把代码直接塞进知识库?
怎么让 LLM 读透代码仓库?先来看看需要分析的三个仓库:
MySQL - 6.36GB
PostgreSQL - 958 MB
NeuG - 38MB
再长的上下文也塞不进这么多信息。
因此,我们全面重构了LLM Wiki的数据管理逻辑,确保LLM不会遗漏每一个细节。
三层目录
在 raw 目录中,我们不再存储原始代码,而是直接通过 Submodule 关联到远程仓库。
默认情况下,Submodule 只是一个指向特定仓库特定分支的链接,只有LLM确实需要检查原始代码时才会下载代码。
通过submodule管理的代码仓库,天然支持增量更新,只需要直接对比两个分支的diff即可。
在 wiki 目录中,我们会将代码仓库划分成多个模块,每个模块都会生成一个独立的wiki页面,各自描述对应的功能。
每个模块对应的wiki页面和其他类型的wiki页面(如实体,对话等)一致,同样包含丰富的引用链接,并且可以关联到特定的概念页面。
在 schema 目录中,所有的提示词和流程规范都会永久保存,确保可复用性和一致性。
三重操作
LLM Wiki提供了三种核心操作:摄入、查询、健康检查。
其中查询和健康检查的操作都建立在wiki之上,可以直接复用,而如何在知识摄入阶段建立准确的wiki则是一个难题。
我们广泛调研并扩展了现有的工具,例如DeepWiki和RepoWiki,设计了一套两阶段生成方案:
• 架构生成阶段。LLM扫描仓库的元信息,例如README文件和项目目录,了解整个仓库的架构,并划分模块。 • 细节生成阶段。LLM针对每一个模块阅读具体的代码,并生成详细的wiki内容。
这种解析方式可以让LLM自主决定模块的划分,确保每个模块对应的代码规模适中,不会受到上下文规模的影响。
而将两阶段操作分开,便于用户快速观测划分的模块是否合理,在昂贵的wiki细节生成环节之前提前审查划分的质量。
怎么对齐概念和模块的名称?“从原始文档中抽取特定的概念”是将数据存入知识库的核心操作,不同的文档可以通过相同的概念建立关联,实现知识的图谱化。
在LLM出现之前,概念的抽取与对齐是一个颇具挑战的任务:例如“数据修改”和“数据更新”其实对应相同的操作,而“量化交易”和“量化压缩”中的“量化”概念完全不同。
而现在强大的LLM借助对上下文的理解,几乎能够完全确保概念的对齐。具体来说,概念的抽取总结为下面三条规则:
阅读LLM wiki中已有的所有概念;
从该文档中总结3~5个概念;
最多只允许出现一个新的概念。
这样做的好处在于鼓励LLM匹配并更新已有的概念,而不是新建,确保wiki的结构不会过于发散。
受到这个概念的抽取过程启发,我们在解析代码仓库之前,提前将其他仓库的wiki目录注入上下文,并且要求LLM在划分模块时必须参考已有的模块标题。
这样,划分模块的过程就从“填空题”变成了“选择题”,确保最终抽取的模块能够尽量对齐。
实践案例:一个查询节约6倍token在本案例中,我们选取两个知名数据库产品 MySQL 和 PostgreSQL,以及我们团队的开源数据库产品 NeuG,要求LLM wiki能够横向对比三个数据库在事务管理方面的能力。
回答质量对比
可以看到在事务处理的重点模块上(MVCC、并发控制、隔离级别、WAL)两组都可以精准提取。
差别在于对照组由于使用了原始代码,加入更多的代码逻辑,而实验组由于使用wiki就可以得到足够完整的结果,更倾向于介绍整体架构设计。
从“技术方案总结”的角度来看,两者的回答质量都较高。

资源开销对比
接下来我们对比两组实验所耗费的资源。由于单个上下文窗口中可能包含多轮对话,且不同类型的token计费也不同,因此我们统一采用最后出账的credit为基准作为对比数据。
可以看到在使用wiki之后,通过极少的token就可以解答问题,整体提升率在6倍左右。
此外,由于token生成的速度比较固定,token的消耗和整体执行时间大致成正比,这就导致整体的执行时间同样存在高达4倍以上的差异。
一个更省token的方案,节约的不仅是你的金钱,还有你的时间。

这次LLM Wiki + Code的实践案例,是我们尝试将wiki这一数据管理方式扩展到多模态场景的一次尝试。
我们认为,LLM管理的wiki就应该和LLM本身一样,能够接收并输出任意格式的数据。
同时,知识库的管理方式也打破了数据的边界,借助LLM的理解能力,所有的数据都可以在一个统一的知识库下管理。
下一步,我们会把这套流程整合进 CodeGraph [1](基于NeuG[2]),让 coding Agent 在调研源码、跨仓库对比时,直接用上预编译好的代码知识库。
