
你以为给 Agent 接上一个“知识图谱”就算有了记忆,其实大多数系统最后都退化成高级一点的向量库。抽取模型随意起名字、随便连边,图谱看起来很酷,却几乎查不出有用东西。想让 Agent 在真实业务里稳定工作,记忆模式本身就是核心产品设计,而不是一个“顺手加上的增强功能”。
当你给 Agent 一个知识图谱当记忆层,如果不加约束,负责抽取的 LLM 会自己发明结构。它会自由决定实体类型、关系标签和属性名,看起来很聪明,但结果往往极度泛化。大量节点被标成 Topic 或 Object,所有连接都叫 RELATES_TO,图谱结构被彻底抹平。等你想做一点复杂查询时,才发现几乎无事可做。
Zep 的开源项目 Graphiti(GitHub 超过 2.6 万星)走的是另一条路:通过预定义本体和模式,把抽取过程“框死”在一个合理空间里。你用 Pydantic 模型定义实体和边的类型,抽取模型只在这些类型里分类,而不是天马行空乱猜。下面就从一个常见误区讲起,再看抽取流程、模式代码示例,以及它在真实查询中的差异。
扁平向量检索为什么撑不起多跳推理
一个简单例子:三条事实,向量只看见两条
基于向量的记忆,把事实当成一块块文本,用语义相似度来检索。这种方式在“单点问答”里挺好用,一旦问题需要跨多条事实推理,就开始掉链子了。看一个关于项目的三条事实:

- Alice 管理项目 Atlas
- 项目 Atlas 运行在 PostgreSQL 上
- PostgreSQL 集群在周二宕机
当用户问:“Alice 的项目是否受到了周二宕机的影响”,真正需要的是三条事实一起出现。向量检索往往只会返回第 1 条和第 3 条,因为它们都提到了 Alice 或周二、宕机这类关键词。第 2 条是关键桥梁:它把 Alice 管理的项目和 PostgreSQL 连接起来,却既没提到 Alice,也没提到周二,于是被相似度搜索直接忽略。

知识图谱的做法完全不同:它把实体存成节点,把事实关系存成边。查询时不是“匹配文本”,而是“沿着连接走路”。在上面的例子里,图谱会有一条链:Alice → 管理 → 项目 Atlas → 运行于 → PostgreSQL。多跳推理就是顺着这条链走出来的,而扁平向量检索根本看不到这条路径。
据一些团队的内部评估数据,在需要 2 跳以上推理的场景里,单纯向量检索的召回率会掉到 40% 以下,而结构化图谱能稳定在 80% 左右。
没有模式的图谱,会悄悄退化成“伪向量库”
每个基于图谱的记忆系统,流程大致类似:LLM 接收原始对话或文档,抽取实体和关系,存成节点和边;查询时在图谱里检索,再把相关事实注入 Agent 的提示中。关键在于,抽取这一步几乎决定了后面的一切——图谱里到底有什么、结构长什么样、你能问出什么问题,全被它锁死。


假设有一段开发者对话,聊的是一个叫 Nexus 的 Web 应用,用 Python、TypeScript、React 和 Docker 构建。没有模式约束时,抽取出来的节点大概率都叫 Topic 或 Object,边一律是 RELATES_TO。看上去图谱很“通用”,但一落地就暴露两个大问题:
- 检索只能退回语义相似度,因为无法按类型过滤,所有东西都挂在同一个标签下面。
- 领域约束完全消失,没有结构化属性,比如
status、category,你没法区分“进行中 vs 已完成”“前端框架 vs 数据库”。
我自己在一个内部项目里踩过这个坑:图谱建得很勤快,节点数涨得飞快,但业务同事只会说一句——“我直接搜文档好像更快一点”。那一刻就很扎心。
用 Pydantic 把“记忆”变成可控的模式
模式思路:和 FastAPI、函数调用是同一套哲学
解决思路,其实在 AI 技术栈里已经被验证过很多次了。你可以把它理解成“给记忆加上类型系统”:
- FastAPI 的接口响应,用 Pydantic 模型定义结构。
- 函数调用工具,用 Pydantic 模式约束参数和返回值。
- Zep 的 Agent 记忆,也用同样的方式定义实体和边。
你可以基于 EntityModel(继承自 Pydantic 的 BaseModel)定义自定义实体类型,字段用 EntityText 并配上描述,指导抽取模型怎么填。描述写得越具体,抽取越稳定。


文档字符串和字段描述不是装饰品,它们是抽取器的“学习材料”。一段好的描述,外加 1~2 个具体示例,往往就能让模型稳定地区分“项目名称”和“项目类型”。上面的 Pydantic 描述,不只是分类指令,还在教抽取器它原本不懂的业务词汇。技术实体也可以用同样的模式来定义。

边类型则用 EdgeModel 定义,并且可以携带自己的属性,比如角色、熟练度、权重等:


最后,用 EntityEdgeSourceTarget 把图谱“接起来”,明确哪些实体类型可以通过哪些边类型连接:

约束带来的“安全感”:只允许合理的关系存在
通过上面的定义,代码会强制执行这些规则:
WORKS_ON只能连接User和ProjectUSES_TECHNOLOGY只能连接User和Technology- 不符合这些约束的关系,不会生成类型化边
有用户反馈,在引入这种源/目标约束后,图谱里“奇怪关系”的比例(比如人和日期之间的莫名其妙连边)下降了 70% 以上,调试时间也明显缩短。
这和类型化函数调用的逻辑一模一样:通过限制 LLM 的输出空间,避免生成无效参数。记忆模式则是在约束“Agent 允许记住什么”,把无意义或有风险的关系挡在门外。我也不太确定这个类比是不是完美,但在工程实践里确实挺好用。

Graphiti 抽取流程:从原始对话到可追溯事实
五步流水线:抽取、消歧、时间轴
当一段带模式的对话被导入时,Zep 的抽取流程大致分成五步:

- 实体抽取:识别文本中的命名实体,并根据你定义的实体类型进行分类。
- 实体消歧:合并重复实体,比如把“Nexus”和“the Nexus project”合并成一个节点。
- 事实抽取:识别实体之间的关系,并根据源/目标约束输出类型化边。
- 事实消歧:检测矛盾事实,作废过时信息,通过 Graphiti 的双时态模型保留历史,记录事件发生时间和导入时间。
- 时间抽取:解析“昨天”“上周二”这类时间引用,并映射到每条边的有效时间窗口。
前面定义的 Pydantic 模式,直接指导了第 1 步和第 3 步。实体类型告诉抽取器“要找什么”,边类型和源/目标约束告诉它“哪些关系是合法的”。消歧和时间处理则在后台自动完成。
每条边都会带上明确的有效时间区间(t_valid、t_invalid)。当信息发生变化,比如“Alex 从项目 Atlas 转到项目 Nexus”,旧事实会被标记为失效,而不是直接删除。这样一来:
- 你可以查询“当前真实状态”。
- 也可以重建“某个时间点的历史状态”。
在合规和审计越来越被重视的今天,这种“可回放”的记忆结构,已经不只是锦上添花,而是很多行业的硬性要求。

一个真实对话的输出长什么样
看一个更贴近实战的例子:导入一段开发者 Alex 的对话,他在聊自己的工作——一个活跃的 Web 应用 Nexus、技术栈,以及自己对不同技术的熟练度。

当你查询 Project 节点时,会返回 Nexus,并带有填充好的 project_status 和 project_type 属性:

节点不再是泛泛的“Topic”或“Object”,而是一个结构化的 Project,字段和含义都在模式里写得清清楚楚。边同样是有类型、有属性的:

WORKS_ON边上带着role: lead developer

USES_TECHNOLOGY边上,对 Python 和 Docker 标记为proficiency: advanced,对 TypeScript 标记为proficiency: intermediate

有了这些结构化信息,你就能做很多过去很难做的事:
- 按状态筛选项目,比如“所有活跃项目”。
- 按类别筛选技术,比如“后端数据库 vs 前端框架”。
- 精确查询“哪些活跃项目使用 PostgreSQL”。
这类查询在招聘匹配、内部专家搜索、SaaS 客户成功团队里都非常实用,有团队反馈用这种图谱后,内部“找对人”的时间从几天缩短到几小时。
把结构化事实重新拼成 Agent 能用的上下文
上下文模板:从图谱到提示的一座桥
图谱建好了,下一步是把这些结构化事实重新拼成 Agent 能理解的上下文文本。Graphiti 用的是“上下文模板”的方式:你定义要包含哪些实体类型、边类型,以及时间注释的格式,系统会自动把查询结果组装成一个字符串,注入到 Agent 的提示里。


效果大概是这样:

每一条上下文条目都有:
- 清晰的类型(比如 Project、Technology)。
- 时间注释(何时有效)。
- 已定义好的属性(状态、角色、熟练度等)。
模板只需要配置一次,之后在调用 Agent 时通过 ID 引用即可。对接不同业务线时,你甚至可以为同一套图谱准备多套上下文模板,让客服、销售、运营看到的“记忆视角”各不相同。

一个容易被忽略的风险点
上下文模板虽然好用,但也有坑。模板设计不当时,很容易把太多事实一次性塞给模型,导致:
- 提示长度暴涨,推理变慢、成本变高。
- 模型被无关信息干扰,回答开始“跑题”。
所以在设计模板时,建议:
- 控制实体和边的数量上限。
- 优先选择和当前任务强相关的类型。
- 对时间做裁剪,比如只保留最近 N 个月的事实。
10/10/10 约束:用模式给推理画边界
为什么要强行“少而精”
Zep 在 Graphiti 里强制了一个 10/10/10 约束:
- 最多 10 个自定义实体类型。
- 最多 10 个自定义边类型。
- 每种类型最多 10 个字段。

这个限制是刻意设计的,目的就是逼开发者认真想清楚:在你的领域里,真正重要的东西到底有哪些,而不是一股脑儿把所有概念都建成实体。很多团队一开始会觉得“10 个不够用”,但实践下来,能覆盖 80% 关键逻辑的实体类型往往不超过 4~5 个。

源/目标约束也在这里起到“护栏”的作用。如果模式里没有定义连接 Project 和 Competitor 的边类型,即便对话中频繁提到这两者,抽取模型也不会创建这种关系。模式定义的,其实就是“有效记忆的空间”。
有点像在给 Agent 画一块“思考的安全区”,让它在这块区域里自由联想,而不是到处乱跑。
从 3×3 起步:一个可复用的设计方法
如果你正准备给 Agent 设计记忆模式,可以用一个简单的起步策略:
- 先选 3~4 个实体类型:比如 User、Project、Document、Technology。
- 再选 3~4 个边类型:比如 WORKS_ON、OWNS、USES_TECHNOLOGY、MENTIONS。
- 每个类型只保留最关键的 5~7 个字段,其余先放在“以后再说”的列表里。
等这套模式在真实流量下跑顺了,再逐步增加复杂度。很多团队一上来就想建“完美本体”,结果半年过去还在改 schema,Agent 迟迟上不了线。说实话,能在两周内跑出一个可用的 3×3 模式,比纸面上完美的 30×30 模式有用多了。

把模式当成产品的一部分,而不是工程细节
没有模式约束的 Agent 记忆,本质上就是一个“长得像图谱的向量库”。你花了构建图谱的成本,却没拿到结构化检索、多跳推理、可审计时间轴这些真正的红利。模式设计,就是把这些红利兑现出来的关键步骤,而且基于 Pydantic,不需要你再学一门新 DSL。
如果你正在做 Agent 产品,或者准备把 LLM 接入现有业务系统,这套“先画模式,再谈记忆”的方法,值得反复拿出来对照。等哪天你发现团队开始在图谱上做复杂查询、回放历史状态、按角色和熟练度自动分配任务,大概率就是这套模式真正发挥价值的时候。
想要深入研究,可以直接去看 Zep 的 Graphiti 开源仓库,顺手点个星,后面有更新也方便跟进。
常见问题
Q:为什么我的 Agent 已经接了知识图谱,效果还是和向量检索差不多?
A:最常见原因是图谱缺乏清晰的模式设计,实体和边类型过于泛化,导致查询时只能按语义相似度“模糊搜索”。当所有节点都叫 Topic/Object、所有边都叫 RELATES_TO 时,你几乎无法按类型过滤,也没法利用结构化属性做精确筛选。建议先用 Pydantic 定义 3~4 个核心实体类型和 3~4 个关键边类型,给每个字段写清楚含义和示例,再让抽取模型按这个模式工作。等你能稳定跑出“按状态筛选项目”“按熟练度筛选技术”这类查询时,效果差异会非常明显。
Q:如何判断自己设计的记忆模式是不是“过度建模”了?
A:一个简单信号是:如果你在模式里定义了十几个实体类型,但日常查询只用到其中三四个,大概率就是建多了。过度建模会让抽取变慢、维护成本变高,还容易引入一堆几乎没人用的字段。更实用的做法是先用 10/10/10 约束自我克制:限制实体、边和字段数量,把注意力放在覆盖 80% 业务场景的那部分。每隔一段时间回顾一次查询日志,把几乎没被访问的类型和字段砍掉或合并,这样模式会越来越“贴身”。
Q:多跳推理一定要用知识图谱吗,能不能只靠向量和长上下文?
A:理论上可以用向量加长上下文硬撑,但在 2 跳以上推理、数据量较大时,成本和稳定性都会迅速恶化。向量检索对“桥接事实”非常不敏感,容易漏掉关键一跳,而长上下文会让模型在大量无关信息里迷路。知识图谱的优势在于显式的节点和边结构,可以精确控制遍历路径和过滤条件。更现实的做法是混合:用向量做初筛,再在筛出的实体上做图谱遍历,这样既能保持召回率,又能控制成本和延迟。
Q:时间维度真的有必要吗,我的业务好像不太需要回放历史?
A:很多团队一开始也这么想,等系统上线一段时间后,才发现“历史状态”在排查问题、合规审计、用户纠纷处理里非常关键。没有时间维度,你只能看到“现在的真相”,却解释不了“它是怎么变成这样的”。双时态模型通过记录事件发生时间和导入时间,让你既能查当前状态,也能回放任意时间点的图谱切片。实现成本并不高,却能在关键时刻帮你少掉很多扯皮和猜测,属于典型的“早做早安心”。
Q:如果业务在快速变化,模式会不会很快就过时?
A:模式确实会随着业务演进而调整,但这不意味着一开始就要设计得很复杂。更健康的节奏是:先用一个精简模式跑起来,定期根据真实对话和查询需求做小步迭代。Graphiti 这类系统通过源/目标约束和字段描述,让你在扩展模式时保持兼容性,同时避免引入太多“实验性字段”。每次扩展前,可以先问三个问题:这个新类型/字段是否会被频繁查询?是否能显著提升推理质量?是否能在两周内被真实使用?三问都过了,再加进模式里,演进会更稳。
如果你正打算给 Agent 上一层“真正有记忆的脑子”,不妨把这里的模式设计方法先收起来。等下次团队讨论“要不要接一个知识图谱”时,拿这套思路对照一下,往往比随口问几个人经验更有用。记忆这件事,做对一次,就能在后面的所有迭代里持续放大价值。


