2 分钟阅读
用低成本搭建一座私有知识图谱
绝大多数「知识图谱」产品,优化的是一场 Demo,而不是接下来的十年。当目标是一座能比任何单一厂商活得更久的个人第二大脑时,最便宜、最耐久的底座,依旧是一块你自己掌控的磁盘上的纯文本。这篇笔记记录了我在淘汰两套托管方案之后,最终落地的架构。
架构
这套系统把托管工具往往揉在一起的三件事彻底拆开:事实来源(Markdown)、索引(派生出的图)、以及查询界面(任何读取索引的东西)。让每一层解耦,意味着任意一层都能从它下面那一层重建出来。
// 在解析期、而非查询期,从仓库构建链接图。
interface Node {
id: string; // slug 化的文件路径
title: string;
outbound: string[]; // [[wikilinks]] 解析为节点 id
backlinks: string[]; // 第二趟回填
}
function buildGraph(files: VaultFile[]): Map<string, Node> {
const graph = new Map<string, Node>();
for (const f of files) {
graph.set(f.id, { id: f.id, title: f.title, outbound: f.links, backlinks: [] });
}
for (const node of graph.values()) {
for (const target of node.outbound) {
graph.get(target)?.backlinks.push(node.id);
}
}
return graph;
}
这张图完全是派生的:删掉它,对仓库扫描一遍就能重新生成。正是这个性质让整套方案变得廉价 —— 没有需要备份、迁移、付费的有状态数据库。
存储层
存储层刻意做得很无聊。下面每一项要么免费,要么摊薄到接近于零:
- 放在 git 仓库里的 Markdown 文件(事实来源,顺带免费拿到版本历史)
- 每晚一个 cron,把派生图重建成单个 JSON 产物
- 可选:用于语义检索的向量索引(仅当召回确有需要时)
- 可选:托管在 CDN 上、供公开笔记使用的只读副本
跑了一年下来最大的体会是:真正的约束从来不是存储成本,而是过渡摩擦 —— 一个松散的念头,多快能变成一个被链接、可被检索的节点。把这一点优化好,图谱自己就会复利式生长。
评论