前言
各位好久不见,我是久愿Y,自从上次换工作,已经很久没有更新文章了,现在技术圈一天一个样子,新技术层出不穷,希望能通过写文章的方式,让自己能吸纳更多知识,也欢迎一起交流。
一、知识图谱到底是为了解决什么问题
知识图谱本质上要解决的,不是"数据不够多",而是"数据之间明明有关系,但传统文本检索和普通表结构很难把这种关系表达清楚、追踪清楚、利用清楚"。
1.1 它解决的不是"存更多数据"
知识图谱真正擅长的是:
- 表达实体之间的关系:谁依赖谁,谁属于谁,谁影响谁,谁和谁相似
- 支持多跳推理:A 出问题,可能是因为 A 依赖 B,而 B 依赖 C
- 支持结构化记忆:用户学过什么、错过什么、偏好什么、哪些事实长期稳定
- 支持可解释召回:为什么推荐这个知识点,不是因为它"看起来像",而是因为它和当前问题存在依赖链、因果链、同类链
- 支持动态演化:记忆不是静态文档,而是不断增长、修正、衰减、关联
1.2 它最典型解决的几类问题
场景 1:关系复杂,靠关键词检索不够
比如教育场景:
- 知识点依赖:绝对值依赖正负数
- 实际问题依赖:某个学生反复在绝对值上出错,不一定是绝对值本身没学会,而可能是正负数理解不牢
这种问题,向量检索能找到"像"的内容,但很难天然给出:
这个知识点为什么要复习?
因为它是当前薄弱知识点的前置依赖节点。
场景 2:数据本身不是文档,而是"事实网络"
例如用户记忆:
- 用户是初一学生
- 最近 7 天主要学习有理数
- 绝对值掌握度 40%
- 错误模式:负负得正经常忘
这些东西如果全塞进长文本里,后续更新、去重、合并、追溯会很痛苦。
图谱更适合把它拆成:
- 用户
- 掌握知识点
- 错误模式
- 它们之间的关系
场景 3:需要可追踪、可增量更新、可长期积累的记忆系统
Agent 场景下,很多记忆不是一次性文档,而是长期沉淀:
- 某个事实什么时候第一次出现
- 后续有没有修正
- 哪条记忆和哪个任务结果相关
- 某个偏好是不是长期稳定
传统 RAG 更像"把一段文本找回来";图谱更像"把一张关系网络中的相关节点和边找回来"。两者都能用,但解决的问题重心不一样。
二、数据形式
知识图谱不是某一种固定存储格式,而是一种组织"实体---关系---属性"的方式。 怎么存只取决于对实际关系的描述。
2.1 最核心的数据抽象:实体 + 关系 + 属性
知识图谱最常见的抽象是三元组:
scss
(实体1, 关系, 实体2)
例如:
scss
(绝对值, DEPENDS_ON, 正负数)
(学生A, STUDIED, 绝对值)
(学生A, MADE_MISTAKE_IN, 绝对值)
但真实系统不会只停在三元组这一步。还会有很多其他属性:
json
{
"source": "studentA",
"relation": "STUDIED",
"target": "绝对值",
"properties": {
"mastery": 0.4,
"timestamp": "2026-05-17T14:00:00Z"
}
}
也就是说,实际存储一般是:
- 节点(Node) :实体
- 边(Edge) :关系
- 属性(Properties) :节点或边上的附加字段
2.2 数据库表设计
最小实现(3 张核心表)
- entity 表:存节点
- relation 表:存边
- entity_type / relation_type 表(可选):存类型定义
entity
| id | type | name | content | metadata |
|---|---|---|---|---|
| 1 | knowledge_point | 绝对值 | 数轴上... | {"grade":7} |
| 2 | knowledge_point | 正负数 | ... | {} |
| 3 | user | student-001 | null | {"grade":7} |
relation
| id | source_id | relation_type | target_id | properties |
|---|---|---|---|---|
| 1 | 1 | DEPENDS_ON | 2 | {} |
| 2 | 3 | STUDIED | 1 | {"mastery":0.4} |
如果想支持事件流、版本、来源追踪,通常还会加:
- event 表:存这条关系是怎么来的
- source 表:来源会话、来源文档、来源任务
- embedding 表:给节点或摘要做向量
2.3 不太适合的场景
1)纯全文检索
- 搜文档
- 问答召回
- FAQ 匹配
优先 ES / 向量库 / RAG。
2)高度事务化但关系价值低的业务
订单流水、支付流水、日志写入。这些更适合 OLTP 数据库,不值得硬上图谱。
3)结构完全不稳定、抽象边界极模糊的数据
实体定义都说不清楚,图谱很容易建成一锅粥。
三、工作流程
3.1 存储流程(Write Path)
Step 1:输入到来
来源可以是:
- 用户对话
- 文档
- 任务结果
- 表单 final 数据
- 系统事件
Step 2:抽取候选事实
通过规则或 LLM 提取:
- 识别了哪些实体
- 识别了哪些关系
- 哪些是稳定事实,哪些只是临时上下文
例如,用户对话的qeury输入:
用户:我初一,最近在学有理数,但绝对值老做错。
抽取:
- 用户年级 = 初一
- 用户学习主题 = 有理数
- 用户薄弱知识点 = 绝对值
Step 3:标准化 / 去重 / 冲突处理
解决:
- "绝对值" 和 "取绝对值" 是不是同一实体
- 用户说的旧偏好和新偏好冲突怎么办
- 这条事实是不是已经存在
Step 4:写入图谱
写入方式可能是:
- 新增节点
- 新增关系
- 更新关系属性
- 增加来源链
- 增加时间戳 / 置信度
Step 5:写入可追踪元数据
check后保留:
- source_session_ids
- source_document_ids
- timestamp
- confidence
- last_seen_time
最终存储内容
存事实 + 存关系 + 存来源 + 存时间 + 存置信度
教育 Agent 存储流程示例:
场景:学生小张(初一)在 Agent 辅导中问了一个问题:"老师,| -3 | 等于多少?为什么不是 -3?"
Step 1 → 输入到来
输入来源:用户对话
json
{
"role": "user",
"content": "老师,| -3 | 等于多少?为什么不是 -3?",
"session_id": "session_20260517_001"
}
Step 2 → 抽取候选事实
Agent 调用 LLM 抽取:
- 实体:绝对值(知识点)、-3(具体数值)
- 关系:学生提到了绝对值概念
- 事实类型:这是一个概念理解问题,不是错题
Step 3 → 标准化 / 去重
系统检查图谱中是否已有"绝对值"节点:
- 已有:
math-7-ch1-03 - 无需新增节点
- 检查小张是否已有 STUDIED 记录:无
Step 4 → 写入图谱
新增关系节点:
yaml
(source: student_001, relation: STUDIED, target: math-7-ch1-03)
→ 属性: { method: "agent_explain", duration: 120, timestamp: "2026-05-17T15:30:00Z" }
(source: student_001, relation: HAS_MASTERED, target: math-7-ch1-03)
→ 属性: { level: 25, confidence: 0.6 }
Step 5 → 写入元数据
json
{
"source_session_ids": ["session_20260517_001"],
"timestamp": "2026-05-17T15:30:00Z",
"confidence": 0.6,
"last_seen_time": "2026-05-17T15:30:00Z"
}
写入完成后,图谱状态变化:
- 小张的节点新增两条边(STUDIED + HAS_MASTERED)
- 绝对值节点的被学习次数 +1
- 来源链指向本次对话 session
3.2 召回流程(Recall Path)
召回一般不是只有一种方式,而是多路召回。
路 1:直接实体命中
用户提到"绝对值",直接命中该知识点节点。
路 2:关系扩展召回
命中"绝对值"后,沿边扩展:
- 前置依赖:正负数
- 相关错题
- 历史掌握记录
- 同章节知识点
路 3:语义召回
对节点摘要 / chunk 做 embedding,找到语义上相关的记忆。
路 4:时间 / 权重过滤
按以下关系做做 rerank。:
- 最近性
- 用户层级优先
- 置信度
- 业务权重
完整召回通常是:
Query → 实体识别 → 图谱命中 → 关系扩展 → 语义补充 → 排序 → 注入上下文
教育 Agent 召回流程示例:
场景:第二天,小张又问了一个题:"| a | + | b | = 10,a 和 b 都是整数,有多少种组合?"
路 1:直接实体命中
学生提到了"绝对值",系统命中 math-7-ch1-03。
路 2:关系扩展召回
从绝对值节点出发,沿边扩展:
scss
math-7-ch1-03 (绝对值)
→ DEPENDS_ON → math-7-ch1-01 (正负数) [掌握度: 20%]
→ DEPENDS_ON → math-7-ch1-02 (有理数) [掌握度: 35%]
→ BELONGS_TO → ch01 (第一章有理数)
→ COVERS → Q001, Q003, Q005 (相关题目)
路 3:语义召回
对"绝对值 整数 组合"做向量检索,命中:
- "绝对值的性质"文档 chunk
- "整数绝对值应用题"文档 chunk
路 4:时间 / 权重过滤
按掌握度排序(越低越优先):
- 正负数 (20%) --- 最高优先级
- 有理数 (35%) --- 次优先级
- 绝对值 (25%) --- 当前薄弱点
最终注入 System Prompt 的上下文:
markdown
## 学生知识状态
- 小张,初一学生
- 绝对值: 掌握度 25%(薄弱)
- 正负数: 掌握度 20%(更薄弱,是绝对值的前置依赖)
- 有理数: 掌握度 35%
## 相关错题记录
- 昨天在绝对值概念上提问(已解释,尚未练习)
## 前置依赖链
绝对值 → 正负数 → (根节点)
Agent 收到这个上下文后,会意识到:
- 小张基础薄弱,不适合直接做综合题
- 应该先从正负数开始复习
- 绝对值概念虽然解释过但还没通过练习巩固
3.3 Dreaming 流程
1)会话摘要
把一堆细碎对话压缩成 session summary。
2)事实蒸馏
从多条实例里抽出稳定事实。
3)经验归纳
把很多具体案例抽象成经验卡片。
4)冲突修正
旧记忆和新记忆冲突时,Dreaming 流程可以重新评估:
- 哪条更可信
- 哪条更近
- 是否应该替换或并存
冲突修正的三种策略:
- 覆盖:新信息置信度 > 旧信息 × 1.2 时,用新信息替换旧信息
- 并存(置信度并列) :新信息置信度 ≤ 旧信息 × 1.2 时,两条记忆同时保留,置信度各自独立
- 降级:旧记忆置信度降低,但不删除(保留历史痕迹)
5)图结构重构
比如:
- 合并重复实体
- 给孤立节点补连接
- 增加跨层关系
- 标记已失效记忆
教育 Agent 示例:Dreaming 流程
场景:小张连续 3 天使用 Agent 辅导,产生了大量细碎的学习记录。系统需要在凌晨离线整理。
Step 1:收集原始数据
sql
// 过去 3 天的原始记录
Day 1: 学习了绝对值 (mastery=25)
Day 2: 做了 3 道绝对值题,2 对 1 错
Day 3: 做了 5 道绝对值题,3 对 2 错;问了正负数问题
Step 2:会话摘要
diff
Session Summary:
- 学习主题: 有理数章节(绝对值 + 正负数)
- 核心问题: 绝对值掌握不稳定,正负数是前置薄弱点
- 错误模式: 符号混淆(-(-3) 答成 -3)
- 学习风格: 需要举例后抽象,不喜欢纯理论
Step 3:事实蒸馏
从多条实例中蒸馏出稳定事实:
ini
// 从 3 次交互中蒸馏
旧: (小张, PREFERS, 先举例后抽象) ×1
新: (小张, PREFERS, 先举例后抽象) ×3
→ 蒸馏: (小张, PREFERS, 先举例后抽象) confidence=0.9
// 从错题中蒸馏错误模式
Day2 错题: 符号混淆
Day3 错题: 符号混淆
→ 蒸馏: (小张, HAS_ERROR_PATTERN, 符号混淆) occurrence=2
Step 4:更新长期记忆图谱
yaml
// 更新掌握度(综合 3 天表现)
(小张, HAS_MASTERED, math-7-ch1-03)
→ level: 25 → 35 (有进步但还不稳定)
→ confidence: 0.5 (波动大)
// 新增错误模式节点
(小张, HAS_ERROR_PATTERN, 符号混淆)
→ occurrence: 2
→ last_occurred: Day3
→ is_resolved: false
// 新增学习偏好节点
(小张, PREFERS, 先举例后抽象)
→ confidence: 0.9
→ source_sessions: [session_001, session_002, session_003]
Step 5:清理
- 删除 3 天的原始 STUDIED 记录(已聚合到掌握度)
- 保留最近 1 条 session summary
- 标记过期的一次性上下文
Dreaming 前后对比:
| 维度 | Dreaming 前 | Dreaming 后 |
|---|---|---|
| 原始记录 | 3 天 × 多轮 = 大量碎片 | 已聚合 |
| 掌握度 | 多次独立记录 | 一条综合记录 (level=35) |
| 错误模式 | 散落在错题记录里 | 合并为 ERROR_PATTERN 节点 |
| 偏好 | 未显式记录 | 显式记录,confidence=0.9 |
| 图谱复杂度 | 高(大量冗余节点) | 低(干净、结构化) |
四、常见问题
4.1 图谱很容易建成垃圾场
原因通常是:
- 实体边界不清
- 关系类型过多
- 同义词没合并
- 冲突事实没处理
- 什么都往图里塞
结果就是:
- 节点很多
- 边更多
- 但根本不好用
原则:图谱不是越大越好,而是越干净越好。
4.2 抽取质量不稳定
如果靠 LLM 自动抽实体和关系,会遇到:
- 格式漂移
- 幻觉关系
- 过度抽取
- 漏抽关键事实
工程上必须加:
- schema 约束
- 白名单关系类型
- 结构化输出校验
- 人工 review 或规则兜底
4.3 更新比新增难得多
新增一条记忆不难,难的是:
- 这条是不是旧事实的修正
- 是覆盖还是并存
- 置信度怎么变
- 来源怎么保留
所以图谱系统真正难点通常不在"写入",而在:
去重、合并、冲突处理、版本管理
4.4 图谱查询性能未必天然好
如果:
- 图太大
- 查询模式太散
- 没有索引
- 到处多跳遍历
性能一样会烂。
所以现实里经常是混合架构:图数据库 + MySQL + ES + Milvus
-
图数据库:管关系结构和多跳遍历
-
MySQL:管事务、元数据、置信度、来源链
-
ES:管全文搜索和关键词召回
-
Milvus:管语义向量召回
五、与传统 RAG 的区别
5.1 传统 RAG 的核心思路
文档切块 → embedding → 向量检索 → 找回相似文本 → 塞给 LLM
它本质上擅长:
- 从大文本库里找相关片段
- 通过语义相似度做补充上下文
5.2 图谱型记忆 / Graph RAG 的核心思路
抽实体和关系 → 构建关系网络 → 基于实体命中和图遍历召回 → 再补充文本上下文
5.3 两者本质区别
| 维度 | 传统 RAG | 图谱 / Graph RAG |
|---|---|---|
| 基本对象 | 文本 chunk | 实体 + 关系 + chunk |
| 召回依据 | 语义相似度 | 关系结构 + 语义 |
| 擅长 | 文档问答、知识库检索 | 依赖分析、关系推理、长期记忆 |
| 可解释性 | 一般 | 更强,能解释召回链路 |
| 更新方式 | 重新切块 / 重建索引 | 可增量更新节点和边 |
| 多跳推理 | 弱 | 强 |
| 复杂度 | 低 | 高 |
| 典型场景 | 文档问答 / 知识库检索 / FAQ | 用户长期记忆 / 依赖分析 / 跨会话关系推理 |
六、市面上的主流方案
以下是主流图谱 / Agent Memory 方案的横向对比:
| 方案 | 关系推理 | 时序感知 | 是否轻量 | 适合 Agent Memory | 备注 |
|---|---|---|---|---|---|
| Neo4j | 强(Cypher 多跳查询) | 需自行实现(属性存时间戳) | 中(独立部署) | 需自建模+LLM集成 | 生态最成熟,社区最好,适合标准知识图谱 |
| JanusGraph | 强(分布式图遍历) | 需自行实现 | 重(依赖 Cassandra/HBase) | 不适合(面向超大图分析) | 适合超大规模图,运维成本高 |
| TigerGraph | 强(高性能图分析) | 需自行实现 | 重(企业级部署) | 不太适合(门槛高) | 企业级场景,成本和上手门槛高 |
| NebulaGraph | 强(原生分布式图) | 需自行实现 | 中(分布式部署) | 需自建模 | 国产开源,性能优秀,社区增长快 |
| Mem0 | 中(内置图谱结构) | 是(内置记忆时效) | 轻(SaaS/API) | 非常适合 | 面向 AI Memory,支持对话抽记忆,上手快 |
| GraphRAG(微软) | 强(社区摘要+实体图谱) | 弱(偏静态文档) | 中偏重 | 适合知识库问答 | 从大规模文档构建图谱,偏知识库而非个体记忆 |
| LlamaIndex GraphRAG | 中(与LlamaIndex生态结合) | 弱 | 轻 | 适合快速实验 | 适合已用LlamaIndex的团队做图谱检索实验 |
| Zep/Graphiti | 强(原生时序图谱) | 强(内置时序边) | 中(需自部署) | 非常适合 | 专为 Agent Memory 设计,内置会话级时序感知 |
| LightRAG | 中(轻量图谱+向量双检索) | 弱 | 轻(单机可用) | 适合快速落地 | 轻量级 GraphRAG,内置关系提取+向量召回,适合原型 |
| KAG | 强(知识增强+图推理) | 中 | 中 | 适合知识密集型场景 | 知识增强图谱,支持多源知识融合和逻辑推理 |
实践
小数 --- 初中数学智能辅导助手
基于 Next.js + LLM + Mem0 长期记忆 的初中数学辅导 Agent,具备知识点依赖追踪 、错题关联提醒 和学习记忆持久化能力。
核心能力
- 个性化对话辅导 --- "小数"老师身份进行启发式教学
- 长期学习记忆 --- 通过 Mem0 自动存储与召回学生历史学习记录
- 知识图谱驱动 --- 30 个有理数章节知识点及依赖关系,自动检测前置知识掌握情况
- 错题智能提醒 --- 关联 10 类常见错题模式,在相关知识点讲解时主动预警
git地址
欢迎交流~
总结
知识图谱是把"事实"和"关系"显式组织起来的系统,让存储不只是保存内容,让召回不只是搜相似文本,而是能沿着关系网络做可解释推理。
如果再粗暴一点:
RAG 解决"找得到",图谱解决"连得起来、讲得明白、能推下去"。
这才是它真正的价值。