# 基于关键词的知识图

# 基于关键词的知识图：核心思想

本文不涉及任何代码、接口或落地形式，只解释这套知识组织方式背后的**思想模型**。

---

## 一、要解决的问题

人类积累知识的过程不是堆数据，而是**给概念起名字、把概念挂到已有的概念体系上、再把零散的资料附在概念上**。

主流的"知识库"方案要么是：

- **关系型 / 文档库**：擅长存储事实，但不表达"概念之间的关系"；
- **向量库 / 嵌入检索**：擅长找"看起来相似"的内容，但相似不等于相关，更不等于"是同一个概念"；
- **传统知识图谱**：表达力强，但写入门槛高，且关系类型一旦多起来（"属于 / 派生 / 相似 / 引用 / 反义……"）就会陷入本体论争论。

这套设计选了一条更克制的路：

> **概念骨架 + 资料挂载 + 二态匹配 + 智能体导航**。
>
> 不让机器猜"像不像"，让它要么直接命中，要么沿着人类已经搭好的概念骨架一步步走过去。

---

## 二、核心抽象：两类关系，仅此而已

世界上的概念关系千变万化，但落到知识组织上，最有用的只有两种：

### 1. 包含 / 派生关系（有方向）

> "A 是 B 的上位概念" / "B 是从 A 派生出来的"。

- 有方向：`父 → 子`。
- 整体构成一张**有向无环图（DAG）**——一个概念可以挂在多个父节点下（"鲸鱼"既是"哺乳动物"也是"海洋生物"），但不允许成环。
- 这层结构是**人类心智的脚手架**：从顶层往下走，能定位到任何具体概念。

### 2. 关联关系（无方向）

> "A 和 B 相关，但说不清谁包含谁"。

- 无方向：`A ↔ B`。
- 表达"邻近性"——譬如"狗"和"狗粮"、"加密"和"哈希"，它们既不互相包含，也不互相派生，但提到一个就该想到另一个。

### 关键取舍

- **同一对概念可以同时挂这两种关系**，互不影响。"哺乳动物 → 狗"是包含；"狗 ↔ 猫"是关联——这两件事天然分层。
- **没有第三种、第四种边**。"相似""引用""反义"这些都被刻意排除：要么用关联表达，要么干脆不表达。语义类型越少，写入门槛越低，结构越稳定。
- **导航与展开走两套规则**：从上往下找概念时，只沿包含边下钻；找到概念后展示"周边"时，沿关联边横向铺开。两层互不干扰。

---

## 三、二态匹配哲学：要么命中，要么不命中

绝大多数检索系统都在试图回答"有多像"。这套设计反其道而行：

> **匹配只有两种状态：命中 / 不命中。不打分、不排序、不做模糊比较。**

具体到查询时：

- 用户给出一个查询词。
- 做最基础的归一化（大小写统一、标点空白剥离、全角半角拉平）。
- 在倒排索引里查：**有就是有，没有就是没有**。

这看起来过于简陋，但它换来三件事：

1. **结果可预期**——同一个查询永远返回同一组节点，不会因为模型版本、嵌入空间漂移而变。
2. **维护成本极低**——没有相似度阈值、没有 top-K、没有"调参"。
3. **真正的"找不到"信号**——倒排零命中是一个清晰的状态，可以触发完全不同的处理流程（见下一节）。

精确匹配的代价是**召回率低**——用户写"小猫"，库里只有"猫"，倒排不会命中。这正是下一节要解决的问题。

---

## 四、命中失败时：让智能体在概念骨架上"下钻"

倒排零命中不是终点，而是另一条路径的起点：

> **沿着包含树（DAG），让 LLM 一步步往下走，直到找到目标、否定所有候选、或者证明库里确实没有。**

### 工作直觉

想象一个图书管理员：

- 读者问"我想找一本关于深度伪造的书"。
- 管理员先看自己的目录卡片（倒排）——没有"深度伪造"这张卡。
- 但他知道目录的顶层分类（DAG 根节点），于是从"科技"一路往下走："科技 → 人工智能 → 计算机视觉 → ……"，每到一层就判断"是不是该往这下面找"。
- 走到某一层，他发现下面有"图像合成 / GAN / 视频生成"——他识别出"GAN"和读者要的东西最接近，匹配。

LLM 在这套系统里扮演的就是这位管理员：**它不评估相似度，它只做"该往哪里走"的导航选择**。

### 设计要点

#### 1. 起点（种子）的多路加权

下钻不是从根节点盲目展开，而是先构造一组**种子节点**作为起点，混合多种信号：

- **直接的语言信号**：查询词的子串出现在哪个节点的名字里？哪怕没精确命中，也是强信号。
- **最近访问偏置**：用户刚才碰过哪些节点？大概率仍在同一片话题区域。
- **重要性偏置**：度数高的节点（连接多）通常是话题枢纽，从它们出发更可能快速逼近目标。
- **结构兜底**：如果上面三路都没有信号，就把所有 DAG 根节点作为起点——保证 fuzzy 查询永远能从"图顶层"启动。

这套加权的目的不是排出"最像"的节点，而是给智能体一个**信息丰富的起跑线**：既不空手出发，也不被冗余候选淹没。

#### 2. LLM 视野的最小化

每一轮，智能体只看到极少量候选（默认不超过 10 个），每条候选只包含两件事：

- 节点的名字；
- 它距离起点走过几跳。

**不暴露内部 ID、不暴露描述、不暴露信息。** 原因有三：

- 节省 token；
- 防止 LLM 把 ID 字符串本身当成判断依据（幻觉的常见来源）；
- 强迫模型只用"语义"做决策，而不是"字符相似"。

#### 3. 跨轮次持久的探索队列

最关键的设计承诺：**没有节点会因为单轮容量限制被默默丢弃**。

- 探索过程维护一条全局的 BFS 队列；
- 每轮只从队首取少量候选喂给 LLM；
- 没看完的留在队列里，下一轮继续；
- 直到 LLM 明确判定"这个就是" / "都不是、给个建议名字" / "队列被完整走完"。

这样即使 LLM 一开始走偏了，只要兄弟分支还在队列里，最终仍能被探索到。**召回率由结构而非模型保证**。

#### 4. 智能体的四种动作

- **match**（找到了）：单目标 → 命中；多目标 → 歧义返回。
- **jump**（往下走）：把指定节点的子节点提到队首，但**不丢弃兄弟分支**。
- **missing**（不在这条路上）：可以软提示某个分支不要继续走，也可以彻底放弃并建议一个新名字。
- **ambiguous**（候选都对，但分不出主次）：返回一组候选给上层处理。

四种动作覆盖了"前进 / 后退 / 否决 / 终止"的全部决策面，没有第五种。

---

## 五、命中之后：沿关联边铺开"周边"

找到目标节点不是终点，用户往往还想知道**这个概念附近还有什么**。

设计上严格区分两个动作：

| 动作                | 沿什么走             | 给用户的语义       |
| ----------------- | ---------------- | ------------ |
| **下钻**（找到目标之前）    | 仅包含边（树结构）        | "我在分类体系中往下找" |
| **展开**（找到目标之后）    | 关联边 + 包含的子边（混合）  | "目标节点的周边有什么" |

为什么命中后也要走包含的子边？因为"狗"的"周边"理应包括"金毛 / 拉布拉多"等子类——它们和"狗"的关联性甚至比关联边更强。但**祖先方向不进入展开结果**——用户已经"在狗这里"，不必再被拉回"哺乳动物 → 动物"。要看祖先，得显式调用祖先子图的接口。

---

## 六、信息与关键词的解耦

知识不仅有"概念"，还有"事实 / 资料 / 引用"。这套设计把它们彻底分开：

- **关键词节点**：是概念骨架，名字唯一、有别名、有简短描述。
- **信息单元**：是真正的内容（一段文字、一份链接、一段笔记）。
- **挂载关系**：一条信息可以挂在多个关键词上；一个关键词可以收集多条信息。语义固定为"信息是关键词的来源 / 佐证 / 实例"，不再细分。

好处：

- 同一段资料不会被复制——它只存一份，多个相关关键词共享。
- 删除概念时，资料本身可以保留（因为别的概念可能还在引用它），只拆掉本节点和资料的链接。
- "什么是 X"和"X 这里有哪些资料"是同一次查询的两个层次：先命中节点，再列出该节点挂载的所有信息。

---

## 七、存储哲学：仅追加，软删，可重建

写入只允许两种动作：

- **新增一行**（创建）；
- **新增一行，标记为已删除**（删除）。

**永远不修改已有行**。要"改"一个节点，就追加一条版本号 +1 的新行。

启动时扫一遍所有行，按 ID 取最新版本，丢弃删除标记的，重建所有内存索引。这意味着：

- **崩溃恢复几乎免费**——文件本身就是事实来源，最多丢失最后一条未刷盘的记录。
- **变更日志天然存在**——每一次写都留痕，将来要做撤销 / 审计 / 合并是直接的。
- **没有"数据库"**——一组追加文件就是全部存储。没有 schema 迁移、没有索引重建脚本。

代价是文件会无限增长，需要定期压实（重写一次只保留最新版本）。但在概念量级是数千～数万的场景下，这点开销完全可以接受。

---

## 八、LLM 在这个系统中扮演的角色

理解这套设计的关键，是看清 LLM **做什么**和**不做什么**。

### LLM 做的事

1. **导航判断**——在概念骨架上选择往哪走、停在哪。
2. **缺失建议**——当库里确实没有目标时，给出一个建议名字，让用户决定要不要新建。
3. **关联挖掘**（可选）——给定一个节点，让模型推荐它可能"相关但还没连"的其他节点。

### LLM 不做的事

1. **不算相似度**——相似度由倒排和子串匹配处理。
2. **不打分排序**——没有 top-K 的概念。
3. **不感知 ID**——只看名字和跳数。
4. **不参与存储 / 写入**——LLM 的所有输出都要经过结构校验（动作合法、目标节点存在、非自环、不与现有边冲突）才会落盘；校验失败静默跳过，不污染图。

这条边界划得很清楚：**LLM 是导航员，不是裁判，更不是仓库管理员**。

---

## 九、与其他方案的取舍

| 维度       | 向量库 / 嵌入检索       | 传统知识图谱        | 本设计           |
| -------- | ---------------- | ------------- | ------------- |
| 召回方式     | 相似度排序            | 关系类型查询        | 精确命中 + 智能体下钻  |
| 关系建模     | 隐式（向量空间）         | 多种边类型 + 本体    | 仅两类边，最小本体     |
| 写入门槛     | 低（嵌入即可）          | 高（要选关系类型）     | 中（要起名、挂位置）    |
| 结果稳定性    | 随模型 / 数据漂移       | 稳定            | 完全稳定          |
| "找不到"的语义 | 模糊（永远能返回 top-K）  | 清晰            | 清晰，且能触发下钻流程   |
| 维护成本     | 中（嵌入要重算）         | 高（本体要维护）      | 低（追加文件）       |
| 适用规模     | 百万级以上            | 任意            | 千～十万级概念       |

这套设计的**舒适区**是：**中等规模、关系语义不需要细分、希望 LLM 增强但不希望被 LLM 主导**的知识组织场景。它不试图取代向量库或图数据库——它给"个人/团队的概念档案"提供了一个介于 wiki 和图谱之间的中间形态。

---

## 十、一句话总结

> **用最小的本体（两类边）+ 最严格的匹配（二态精确）+ 最克制的 LLM 用法（只做导航）+ 最朴素的存储（仅追加），换取一个能让人和模型协同维护、长期稳定演化的概念骨架。**