Agent记忆进阶——从一个实际例子学习知识图谱

前言

各位好久不见,我是久愿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 张核心表)

  1. entity 表:存节点
  2. relation 表:存边
  3. 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}

如果想支持事件流、版本、来源追踪,通常还会加:

  1. event 表:存这条关系是怎么来的
  2. source 表:来源会话、来源文档、来源任务
  3. 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:时间 / 权重过滤

按掌握度排序(越低越优先):

  1. 正负数 (20%) --- 最高优先级
  2. 有理数 (35%) --- 次优先级
  3. 绝对值 (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地址

github.com/AdolescentJ...

欢迎交流~

总结

知识图谱是把"事实"和"关系"显式组织起来的系统,让存储不只是保存内容,让召回不只是搜相似文本,而是能沿着关系网络做可解释推理。

如果再粗暴一点:

RAG 解决"找得到",图谱解决"连得起来、讲得明白、能推下去"。

这才是它真正的价值。

相关推荐
nix.gnehc10 小时前
agentic 源码深度拆解:启动流程与会话调用流程全解
人工智能·agent
一条泥憨鱼10 小时前
能够让AI做事的“Skill“有什么奥秘
人工智能·ai·agent·rag·skill·mcp
唐璜Taro11 小时前
LangChain与LangGraph多Agent实战:从工具链到工作流编排(上)
langchain·agent·langgraph
元思未来11 小时前
Hermes Agent 源码探秘 (5):System Prompt 组装 — Agent 的"灵魂"
源码·agent
冬奇Lab12 小时前
Agent系列(三):Plan-and-Solve——先想清楚,再动手
人工智能·llm·agent
冬奇Lab12 小时前
每日一个开源项目 #110:ai-engineering-from-scratch - 从零构建 AI 工程全栈能力
人工智能·深度学习·llm
deephub12 小时前
推理 → 行动 → 观察:用 LangChain + Python 实现一个智能体循环
人工智能·python·langchain·大语言模型·agent
格桑阿sir12 小时前
03-大模型智能体开发工程师:主流大模型家族与演进
ai·大模型·llm·openai·agent·ai agent·智能体
feasibility.12 小时前
Qwen3-VL-Seg 深度解读:当多模态大模型学会“像素级精准手术“
人工智能·深度学习·计算机视觉·llm·图像分割·多模态·vlm