AI 智能体的终极记忆方案?来认识一下 Graphiti
AI 智能体的终极记忆方案?来认识一下 Graphiti
在大模型时代,我们早已不再满足于问一句答一句的聊天机器人。真正聪明的 AI 助手,需要有记忆、能理解上下文、还能从海量信息中快速找到答案。
但传统技术如 RAG(检索增强生成)在面对频繁变化的数据时显得力不从心——它依赖批量处理和静态摘要,更新慢、响应迟、难以应对实时场景。
今天,我们要介绍一个正在悄然崛起的新一代图框架:Graphiti。它是 Zep 平台的核心引擎,也是目前公认的 Agent 记忆领域 SOTA(State-of-the-Art)解决方案之一。
如果你关心 AI 如何记住用户历史、如何高效管理动态知识、如何实现秒级精准检索,那这篇文章你一定不能错过!
开源地址:https://github.com/getzep/graphiti
什么是 Graphiti?
简单来说,Graphiti 是一个专为动态数据设计的开源图框架,它可以:
- 实时将文本或结构化数据转化为“知识片段”(Episode)
- 自动提取实体与关系,构建语义网络
- 支持超低延迟的混合检索(
语义+关键词+图路径) - 精确追踪事件发生时间和被记录的时间(双时间维度)
它不是传统的知识图谱工具,也不是简单的向量数据库,而是为 AI Agent 的大脑量身打造的记忆系统。
💡 为什么我们需要 Graphiti?传统 RAG 太“笨”了!
让我们先看一组对比,你就明白 Graphiti 到底强在哪👇
| 对比项 | 传统 GraphRAG | Graphiti |
|---|---|---|
| 主要用途 | 静态文档总结 | 动态数据管理 ✅ |
| 数据更新方式 | 批量处理 ❌ | 实时增量更新 ✅ |
| 检索速度 | 几秒到十几秒 ❌ | 通常 <1 秒 ✅ |
| 是否支持自定义实体 | 否 ❌ | 是 ✅ |
| 时间精度 | 基础时间戳 | 双时间模型(事件时间 & 录入时间)✅ |
| 矛盾处理 | 依赖 LLM 总结判断 | 自动失效旧边 ✅ |
| 扩展性 | 中等 | 高,适合企业级应用 ✅ |
举个例子:
假设你在做一个客服机器人,用户昨天说:我订了一张去北京的票。
今天又说:改成去上海。
传统的 RAG 可能还会把去北京当作有效信息返回,因为它只是做了静态存储和总结。
而 Graphiti 能识别这是修改行为,自动让去北京这条关系失效,并建立新的去上海连接 —— 这就是所谓的时间边失效机制。
🧠 它就像人的记忆一样,知道哪些信息已经过时了。
Graphiti 核心能力一览
1. 实时增量更新:新增数据无需重算
你每输入一句话,Graphiti 就能立即解析并加入图谱,不需要等待整批数据跑完。
👉 这句话会被自动拆解成:
- 实体:
小李(人)、心理咨询(服务)、2025-03-29 10:00(时间) - 关系:
小李 → 预约 → 心理咨询
所有这些都在后台悄悄完成,全程无需人工标注。
2. 双时间模型:记得什么时候发生的和什么时候记下的
这是 Graphiti 最独特的能力之一。
event_time:事件实际发生的时间(比如“预约是在3月28日提到的”)ingest_time:这条信息是什么时候被系统录入的
这意味着你可以做这样的查询:
“请告诉我截至2025年3月28日晚上8点,小李的所有预约安排。”
即使后来他改了时间,系统也能准确还原那一刻的历史状态。
📌 适用于医疗记录、法律证据、金融交易等对时间极其敏感的场景。
3. 混合检索:语义 + 关键词 + 图结构三合一
搜索不只是找相似句子,更是理解上下文关联。
# 示例:查找与“心理咨询”相关的所有关系(边)
results = await graphiti.search("关于心理咨询的信息", top_k=5)for result in results:print(f"UUID: {result.uuid}")print(f"Fact: {result.fact}")if hasattr(result, "valid_at") and result.valid_at:print(f"Valid from: {result.valid_at}")if hasattr(result, "invalid_at") and result.invalid_at:print(f"Valid until: {result.invalid_at}")
它不仅用到了语义匹配(embedding),还结合了关键词(BM25)和图中邻居节点的距离进行重排序,结果更准、更快!
4. 自定义实体类型:按你的业务建模
你可以用 Pydantic 定义自己的实体模型,比如:
from pydantic import BaseModel class Patient(BaseModel):name: str age: intmedical_history: list[str]class Appointment(BaseModel):date: strtype: strdoctor: str
然后告诉 Graphiti:“以后看到类似结构,就按这个模型提取!”
这样就能构建出高度定制化的专业知识图谱。
快速上手:三步搭建你的第一个 Graphiti 应用
第一步:安装依赖
确保你已安装 Python 3.10+,然后运行:
安装基础版本(使用 Neo4j)
pip install graphiti-core
第二步:配置环境变量
创建 .env 文件:
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=your_password_here
OPENAI_API_KEY=sk-xxxxxxxxxxxxx
💡 提示:也支持 Azure OpenAI、Google Gemini、Anthropic Claude、Groq 等主流模型。
第三步:写代码!
# 异步主函数,用于运行整个流程
async def main():# 导入所需的类和模块from graphiti_core.llm_client import LLMConfig, OpenAIClientfrom graphiti_core.embedder.openai import OpenAIEmbedder, OpenAIEmbedderConfigfrom openai import AsyncOpenAI# 创建一个异步 OpenAI 客户端实例(用于与 LLM 和嵌入模型交互)llm_client = AsyncOpenAI()# 配置大语言模型(LLM)的相关参数 llm_config = LLMConfig(model="qwen3", # 使用的主模型名称small_model="qwen3" # 使用的小型模型名称(用于轻量任务))# 初始化 Graphiti 实例,连接到 Neo4j 数据库并配置 LLM 和嵌入模型graphiti = Graphiti(neo4j_uri, # Neo4j 数据库 URIneo4j_user, # Neo4j 用户名neo4j_password, # Neo4j 密码llm_client=OpenAIClient(config=llm_config, client=llm_client), # 使用自定义 LLM 客户端embedder=OpenAIEmbedder( # 使用 OpenAI 嵌入器 config=OpenAIEmbedderConfig(embedding_model="text-embedding-ada-002" # 嵌入模型名称),client=llm_client, # 使用相同的 OpenAI 客户端),)try:# 导入用于清除图数据的工具函数from graphiti_core.utils.maintenance.graph_data_operations import clear_data # 清除 Neo4j 中已有的数据(可选,用于测试)await clear_data(graphiti.driver) # 构建 Neo4j 中的索引和约束(提升查询性能)await graphiti.build_indices_and_constraints() # 定义要添加到图中的 episodes(数据片段)episodes = [{"content": "卡玛拉·哈里斯是加利福尼亚州总检察长。她之前是旧金山地区检察官。","type": EpisodeType.text, # 文本类型的数据 "description": "podcast transcript",},{"content": "作为总检察长,哈里斯的任期为2011年1月3日至2017年1月3日","type": EpisodeType.text, "description": "podcast transcript",},{"content": {"name": "加文·纽瑟姆","position": "州长","state": "加利福尼亚州","previous_role": "副州长","previous_location": "旧金山",},"type": EpisodeType.json, # JSON 类型的数据"description": "podcast metadata",},{"content": {"name": "加文·纽瑟姆","position": "州长","term_start": "2019 年1月7日","term_end": "当前",},"type": EpisodeType.json, "description": "podcast metadata",},]# 遍历 episodes 并将其添加到图数据库中for i, episode in enumerate(episodes):await graphiti.add_episode( name=f"Freakonomics Radio {i}", # episode 名称 episode_body=(episode["content"] if isinstance(episode["content"], str)else json.dumps(episode["content"]) # 如果是字典则序列化为 JSON 字符串),source=episode["type"], # 数据类型(text 或 json)source_description=episode["description"], # 数据来源描述 reference_time=datetime.now(timezone.utc), # 当前时间作为参考时间)# 记录所有 episodes 已成功添加 logger.info("All episodes have been added.")# 可选:执行一次搜索测试,查询“谁是加州州长?”results = await graphiti.search( query="谁是加州州长?",search_config=NODE_HYBRID_SEARCH_RRF # 使用混合搜索配置(RRF))# 打印搜索结果(格式化为 JSON,便于阅读)print(json.dumps(results, indent=2, ensure_ascii=False))finally:# 确保在程序结束时关闭 Graphiti 连接await graphiti.close() # 程序入口点:使用 asyncio 运行主函数
if __name__ == "__main__":asyncio.run(main())
总结:为什么选择 Graphiti?
- 简化复杂度:将复杂的图谱构建过程抽象成简单的 API 调用,开发者可以专注于业务逻辑
- 实时响应:支持动态数据的实时更新,无需批量重算
- 时间感知:双时间模型让你能准确查询历史状态
- 高性能:混合检索技术实现毫秒级响应
- 高度可定制:支持自定义实体类型和业务模型
Graphiti真正做到了让复杂的知识图谱技术变得像初始化一个类一样简单,为 AI Agent 的记忆能力提供了强大的基础设施支持!
PS:都看到这里,来个点赞、推荐、关注吧。 您的支持是我坚持的最大动力!
