# 召回即联想 > **「召回是针对节点的,然后召回的是节点与 n 层 bfs 结果」** > —— 这个机制就是在模仿人类的联想能力。 ## 为什么这个类比比技术描述准确 技术上说"命中节点 + N 层 BFS"只是描述了**做法**; 而"联想"说清了**为什么必须这样做**: ``` 人听到「值班室分机号是多少」时真的发生的事: ① 想起 "值班室分机号" ← 命中节点 ② 想起 "4324" ← 沿边一步 ③ 想起 "旧号 4379 停用了" ← 沿边两步(4324 --停用于--> 4379) ④ 想起 "老周值班" ← 沿边一步(反向可达) ★ 人不会只答 ② —— ② 单独说出来没有意义(「4324」是什么?) 联想里 ③④ 是**自动附带**的,不是被问到的。 ``` 而"只召回主语块"(我上一条列为选项 1)恰恰是**切断联想**: 宾语块 `4324` 孤立召回时不知道自己来自哪里,于是要么丢它、 要么给它加"来源标注"这种特判——**都是在模拟"人不会联想"**。 ## 三条由此推出的设计约束 ### ① 召回对象是节点,不是"事实" 节点是记忆的载体。一条事实(`值班室分机号 --是--> 4324`)是 **两个节点 + 一条边**,不是三个字符串。 ⇒ 任何把事实当原子值处理的实现(把 `<主语>|<关系>=<宾语>` 存成 一个块的属性图形态)都丢掉了"边可以独立演进"这件事。 ### ② 不做"来源标注"这类特判 联想不需要标注"这个值从哪来"——它天然在图里。 要标注,说明图结构没建对。 ⇒ 判据 `TestBFS_节点加N层邻居` 直接检查"孤立命中的宾语块能否 通过 BFS 找回主语",而不是检查标注字段是否为空。 ### ③ 层数(N)是**上下文预算**,不是图算法参数 人回忆时不会无限联想——想起第三个无关的东西就停了。 所以 N 应该由**召回预算**决定,而不是"遍历完整张图"。 ⇒ 与实测对齐:今天的召回预算是 `blockRecallTopK = 8`、 `blockRecallMinScore = 0.5`;N 定 1~2 层, 否则一个高频主语会把整张网拖出来(实测实体网会织成"全连通", 那样 BFS 就退化成全表扫描)。 ★ **这是还没验证的部分**:N=1 时已经能带出 4 个节点(含两个方向的 邻居),但"织成网"之后的实际连通度与噪声率没有实测过。 判据 `TestBFS_节点加N层邻居` 钉的是形态,不是规模。 ## 与已完成工作的关系 ``` ① 边升格(52e4596) 边成为独立单位(可并存多条、承载属性) ← 这是联想的**前提**:边不是标签才有"沿边一步" ② 节点形态回滚 主语块/宾语块(B 方案) ④ BFSBlocks 联想的实现 ``` 顺序不能反:没有 ①,「沿边一步」就是查一个字符串标签; 没有 ②,图里只有名字节点,联想织不出有意义的网。 ## 一条反面记录 我第一次实现 `Commit` 块化时(cdf0726)做成了 `主语块 --是--> 宾语块` 的属性图形态 —— **节点形态对、但块内容错了** (块内容是纯名字,而不是 `<主语>|<维度>=<值>` 的字段块)。 ⇒ 形态对不等于设计对。**节点装什么内容,与节点之间怎么连,是两件事。**