Skip to main content

基于类型化认知单元的认知图

基于类型化认知单元的认知图:核心思想

本文不涉及代码与接口,只解释这套认知存储方式背后的思想模型,以及推导过程中关键的论点取舍。


一、要解决的问题

存储所有的认知,并让"思考"这件事能在它上面机械地发生。

主流的方案各有缺陷:

  • 关系型 / 文档库:擅长存事实,不会判断;
  • 向量库 / RAG:擅长找"看起来像"的内容,相似 ≠ 相关,更不等于"在说同一件事";
  • 传统知识图谱:表达力强,但写入门槛高,关系类型一旦多起来就陷入本体论争论;
  • 关键词图谱(姊妹设计 基于关键词的知识图):解决了"概念骨架",但概念骨架本身不承载主张、推理、因果,没法做思考。

这套设计补上的是:概念之间承载了什么主张、这些主张之间是什么逻辑关系


二、本质目的(一句话)

建立一个认知的底层物质(substrate),让"思考"这件事能在它上面发生。

思考 = 比较 + 推理 + 整合 + 自洽 的混合体,不是单纯的查找。

输入:自然语言(充满冗余、歧义、修辞) 输出:固定形式的认知单元(让上述操作可机械化进行)

后面所有设计都是从这一句直接推出来的。


三、几次否决与它们背后的判断

设计的过程比结果重要。下面是几次关键否决,记录"为什么不那样做"——这些是这套设计真正的根据。

否决 1:不是"切分原文",是"对原文做转换"

第一直觉是把原文切成命题,再入库。但这是错的框架:

  • "切分" 受原文形式约束(句子边界、修辞、语序)
  • 它把一段文本想成"由几片可拆出来的命题组成",但原文其实是刺激/材料,本身没有义务对应到我们的存储形式

正确的框架是 转换(transformation)

原文进来 → LLM 识别其中承载的认知信息 → 重新编码成我们事先定义的标准形式 → 入库

原文的句子边界、修辞、语序,对最终入库的形式没有任何约束力

旧框(切分) 新框(转换)
受原文形式约束 不受原文形式约束
切错 vs 切对 编码完整 vs 残缺、合规 vs 不合规
关心"在哪刀下手" 关心"目标形式长什么样"

否决 2:不是 SMO 风格的语言学形式化

参考过 SMO(Semantic Meta Operator)这种把自然语言投影为类型化图的形式系统。它做得很完整——5 个 scope × ~70 关系,覆盖了情态、时体、极性、量化、焦点、传闻、转折……

但 SMO 的最高检验是回译保真:投出来的算式让 LLM 写回中文要跟原句近似。这意味着它必须保留语言表达层的所有细节("显然"、"了"、"还"、被动语态……)。

我们不需要回译保真。 思考和逻辑判断不需要这些表达层的差异:

  • "他错了" 和 "显然,他错了" 在认知图里是同一条认知
  • "猫吃了鱼" 和 "鱼被猫吃了" 在认知图里是同一条认知

SMO 解决的是 NL ↔ 形式化 的双向无损转换; 我们解决的是 存储认知,让思考成为可能——可以是单向的、有信息丢失的(丢的是表达层)。

否决 3:不是"自然语言句子 + 元数据"

中间一度倾向于:节点是规范化的自然语言句子,加上 mentions / source / time 等元数据。

但这违反了"事先定义的标准形式"——句子的形式是软的,不是 schema。后果是:

  • 检索时还要靠 LLM 在线判断语义
  • 比较两条认知没有定义良好的对象(句子 vs 句子是模糊的)
  • 不同表达的同一认知会反复以不同字符串出现

正确方向:标准形式必须是结构化的、可机械操作的。 自然语言只是入库前的输入用户阅读时的渲染输出

否决 4:不是从"语言里有什么"反推 type 集合

错误做法:列出语言里所有的修饰、连接、句式,想办法都装进图里(这就回到 SMO 的复杂度)。

正确做法:从"思考时操作的对象类型"反推。

  • 比较两件事 → 需要"事"是清晰的对象
  • 沿因果链推理 → 需要"因果"是显式的关系
  • 找谁主张了 X → 需要"主张"是带主体的二元结构
  • ...

每一种思考操作要求一种结构。把所有思考操作覆盖完,type 集合就出来了——大约 ~16 个,远少于 SMO 的 70。


四、三条内在性质(标准形式必须满足)

不是从需求列表来的,是从"思考的本质"来的。

性质 1:原子化——操作必须有明确的对象

比较、推理、整合都是对单元做的操作。如果单元边界模糊(比如一段自然语言),就没法定义"比较 A 和 B"——A 是哪一段?B 是哪一段?

单元必须是离散的、独立可指认的、有 ID 的。

性质 2:类型化——不同操作适用于不同认知

  • "判断 A 矛盾 B" 只对断言型认知有意义
  • "沿因果链回溯" 只对因果型认知有意义
  • "找谁主张了 P" 只对信念型认知有意义

没有类型,就不知道一条认知能被怎么用、能跟谁比、能进什么推理流程。

单元必须带类型,类型决定了适用的操作集合。

性质 3:可组合——复杂认知能用简单认知拼出来

"X 反驳了 Y 主张 Z" 是嵌套的:反驳 ⊃ 主张 ⊃ Z。

如果不能嵌套,就只剩两条路:

  • 塞进一个扁平字符串 → 丢结构
  • 硬展开成 N 条独立断言 → 丢"它们之间是嵌套关系"这件事

单元必须支持引用其他单元做参数——通过 ID 引用即可,自动获得无限深度的嵌套。


五、推出的标准形式

认知单元 = {
  type:      <预定义的认知类型>            // 性质 2
  args:      { 角色名: 概念ID or 单元ID }  // 性质 1(边界清晰)+ 性质 3(可嵌套)
  modifiers: { polarity, certainty, time, scope }
  meta:      { id, source, asserted_at }
}

关键:没有 statement 字段、没有自然语言。 LLM 在入库时把语义全部翻译进 args,这就是"重新编码到标准形式"。原文最多作为 source 留作出处证据回溯,不参与检索和判断

args 的取值

每个角色名(role)对应一个 value,value 必须是:

  • 一个概念节点 ID(指向关键词图中的某个概念),或
  • 另一个认知单元 ID(实现嵌套)

不允许直接放字符串——所有"内容"必须先成为概念或认知单元。这迫使语义被显式化,而不是藏在自由文本里。

唯一的例外是数值/单位/时间这种字面量(如 100°C2026-05-04),这些有专门的 literal 处理。


六、type 集合(认知的最小切分)

这 ~16 种 type 不是穷举语言现象,而是穷举思考时操作的对象类型。分六大类:

A. 关于"是什么"——概念结构

type args
IS_A (实例, 类别) 狗 ∈ 哺乳动物
HAS_PROPERTY (实体, 属性, 值, 单位?) 水 沸点 100℃
PART_OF (部分, 整体) 心脏 ⊂ 循环系统
DEFINED_AS (术语, 释义) AGI 定义为...
IDENTITY (A, B) 卡帕西 = Karpathy

B. 关于"发生了什么"——事件结构

type args
EVENT (主体, 动作, 客体?, 时间?, 地点?) 1997 年深蓝击败卡斯帕罗夫

C. 关于"怎么关联"——关系结构

type args
RELATES (A, B, 关系描述) Karpathy 曾任职 Tesla

RELATES 是兜底:上面 A 类塞不下的二元关系都用它。关系描述 是一个概念节点(如"曾任职"),不是字符串。

D. 关于"谁怎么认为"——认知态度(元层)

type args
CLAIMS (主体, 单元ID, 时间?) Karpathy 主张 P_001
PREDICTS (主体, 单元ID, 目标时间) Karpathy 预测 P_001 在 2036
DOUBTS (主体, 单元ID) Hinton 怀疑 P_001
DENIES (主体, 单元ID) LeCun 否认 P_001

关键设计:args 里的 单元ID 指向另一个认知单元。这就把"主张者"和"被主张内容"分开存——同一个 P_001 可以被多个主张者引用,自动聚合"对同一断言有哪些不同立场"。

E. 关于"为什么 / 会怎样"——逻辑结构

type args
CAUSES (因ID, 果ID, 强度?) 经济下行 → 消费萎缩
IMPLIES (前件ID, 后件ID) 若 X 则 Y
COMPARES (A, B, 维度, 方向) GPU 比 CPU 快(在并行计算上)

关键设计:CAUSES 和 IMPLIES 的 args 也是单元 ID,意味着逻辑关系本身也是认知单元——它们既能查询(沿因果链遍历),也能被讨论("我怀疑这条因果"= DOUBTS(我, 那条 CAUSES 单元))。

F. 关于"何时"——时序结构

type args
BEFORE (事件A_ID, 事件B_ID) 微芯片诞生 < 个人电脑普及
DURING (事件ID, 时段) 战争发生在 1939-1945

七、modifiers(4 维认知修饰)

只保留对判断真有影响的修饰,其他(焦点、口吻、强调、传闻语气)一律不要。

modifier 取值 影响什么操作
polarity pos / neg 是否互相矛盾的判断
certainty certain / likely / possible / unlikely / refuted 推理强度
time 时间锚点(绝对/相对/永真) 在某时刻是否成立
scope all / most / some / none 量化推理

为什么只要这 4 个? 因为后续的"思考操作"只用得到这 4 个:

  • 比较时要看 polarity 是否相反 → 矛盾
  • 推理时要看 certainty 是否够高 → 链条强度
  • 时间查询要看 time → 在 t 时刻成立吗
  • 量化推理要看 scope → 全称 vs 存在的差别

其他修饰("显然"、"据说"、"的确"、"也"、"还"、"特别")不影响这些操作,故意丢弃


八、边(认知单元 ↔ 认知单元)

只有 4 种关系,呼应关键词图的"二态匹配"哲学——不打分、不算相似度、不排序。

含义 怎么得到
等价表达 LLM pairwise 判定(在小候选集上)
矛盾 LLM 判定 + modifier 自动派生(同 type 同 args 反 polarity)
相关但说不清逻辑(兜底) 实体共现自动建议 + LLM 确认
取代(旧版本被新版本取代) 用户/agent 显式标注,带时间戳

注意:→(蕴含)和 因果 不是边,是 type(IMPLIES / CAUSES)——因为它们本身是可被讨论的认知,必须是有 ID 的单元。

边只用于**"对图本身的判断"**:是否等价、是否冲突、是否取代。这些不是认知内容,是元结构。


九、思考如何在这套形式上机械化

思考操作 在这套形式上怎么做 复杂度
比较两条认知 同 type → 逐 arg 比对;不同 type → 先看 args 是否有交集 O(args 数)
判断矛盾 同 type 同 args 但 polarity 相反 / certainty 极端冲突 O(1) per pair
找因果链 沿 CAUSES 单元的 (因→果) 索引遍历 O(链长)
找谁主张了 X 反查 args 包含 X 的 CLAIMS 单元 O(候选数)
整合一条新认知 抽 args 中的概念 → 反查共享概念的旧单元 → LLM 在小集合上判 ≡/⊥/相关 O(邻居数)
自洽扫描("睡眠整理") 对所有 IMPLIES 链做传递闭包,检测是否推出 ⊥ O(图大小),离线
回答开放问题("AGI 何时实现?") 抽问题里的概念 → 反查带这些概念的 PREDICTS 单元 → 列出所有候选 + 对应主张者 O(候选数)

所有操作都不需要在线对自然语言做语义判断——判断已经在入库时完成并固化到 type/args/modifier 里。

这是这套设计最重要的工程性质:把昂贵的"理解语义"动作集中在一次性入库,让常态的"使用认知"全部退化为指针追逐和集合操作。


十、与关键词图的关系

两套图不是替代,是分层互补

节点 回答的问题
概念层(关键词图) 概念名("AGI"、"Karpathy") "X 是什么 / X 旁边有什么"
认知层(本设计) 类型化认知单元 "关于 X,被主张了什么?这些主张如何互相关联?"

每个认知单元的 args 都引用概念层的节点。也就是说:

  • 关键词图为认知图提供"实体词典"——args 里的"概念ID"就是关键词图的节点 ID
  • 认知图通过共享概念聚合相关认知——查询某概念时,能拉出所有引用它的认知单元(mentions 反查)
  • 关键词图的导航能力可以复用——用户问 "AGI 还需多久",先在关键词图上命中或下钻到 "AGI" 节点,再列出所有引用它的 PREDICTS 单元

两层各自最小本体、各自二态化,避免了传统知识图谱的本体爆炸。


十一、关键的 trade-off

设计是有代价的。下面是显式接受的几个:

1. 接受语言表达层的信息损失

入库时丢掉焦点、口吻、修辞、时体、被动语态。

为什么可接受:这些是给人听的,不是给思考用的。我们不做回译,不做"原汁原味重述",所以丢得起。

2. 依赖 LLM 做关系判定

≡、⊥ 边的认定靠 LLM pairwise,不靠形式逻辑求解。

为什么可接受:LLM 的语义判断对自然语言已经足够;引入形式逻辑会回到 SMO 那种复杂度,而且要预设公理体系,迁移性差。 风险控制:LLM 不会 100% 准。漏判等价 → 多一个节点(可事后加边修复);误判等价 → 几乎不可逆(所以选 Y 方案:独立节点 + ≡ 边,而不是合并)。

3. 不做严格的形式推理

这套图不能证明定理、不能做完整一阶逻辑推导。

为什么可接受:我们的目标是"组织和检索认知",不是"形式化推理引擎"。如果以后真要做形式推理,可以在这套抽象上叠加一层专门的形式化命题层,针对那部分内容。

4. type 集合需要演化

~16 种 type 是起点,不是穷举。新认知形态出现时可能要加 type。

为什么可接受:加 type 是"加一种思考维度"的事,不是日常工作;频率低、影响可控。 控制方式:遇到塞不进任何现有 type 的输入 → 暂存 type: unknown + 原文;离线 worker 看 unknown 堆积,达到一定数量时引入新 type。

5. 入库代价比 RAG 高

一篇文档要经过:实体抽取 → 类型识别 → args 填充 → 邻居查询 → 关系判定 → 落盘。比单纯切 chunk + embed 贵多了。

为什么可接受:一次入库换长期可推理;常态使用不再付 LLM 成本。本质是把成本前置。


十二、入库流水线(概要)

原文
  ↓ LLM:识别其中的认知信息
认知单元草稿(type + args 候选)
  ↓ 实体对接到关键词图(命中或新建概念节点)
完整的认知单元(args 全部解析为 ID)
  ↓ 通过 args 中的概念反查"邻居单元"(O(邻居数))
候选邻居集合(通常 < 几十条)
  ↓ LLM pairwise 判 ≡ / ⊥ / ↔
关系边
  ↓ 全部追加到日志
落盘完成

离线"睡眠整理" worker(呼应大脑做的事):

  • 全局自洽扫描:发现新冲突、推导传递闭包
  • 抽象/归纳:发现一组同主题单元 → LLM 总结一条更高层的认知单元
  • 遗忘:长期未访问 + 已被高层单元覆盖 → 软删

十三、存储哲学(沿用关键词图)

  • 仅追加:写入只允许"新增一行"和"新增一行标记为已删除",永不修改已有行
  • 软删:版本号 +1 标记替代物理删除
  • 启动重建:扫所有日志,按 ID 取最新版本,重建内存索引
  • 崩溃恢复几乎免费:日志文件就是事实来源
  • 变更日志天然存在:每次写都留痕,将来要做撤销 / 审计 / 演化分析直接可用

新增的日志文件:

keyword_graph/             ← 已有:关键词图
cognition_units.log        ← 新:认知单元(追加)
cognition_edges.log        ← 新:≡ / ⊥ / ↔ / ⇒ 边
cognition_mentions.log     ← 新:单元 ↔ 概念 的引用关系(也可由 args 派生,缓存用)

十四、一句话总结

以最少的本体(~16 type + 4 modifier + 4 边)把所有认知压成可机械操作的离散单元,让思考退化为指针追逐 + 集合操作;用 LLM 一次性付清"理解语义"的成本,换取常态使用零语义负担。