跳到主要内容

Cognee — 架构与原理

30 秒导读: Cognee 是给 AI agent 用的开源记忆平台。你把文档/文本喂给它,它用 LLM 把内容抽成一张知识图谱(谁是谁、谁和谁有什么关系),同时存成向量;之后 agent 提问时,它不是简单做向量 RAG,而是「先用向量找到相关节点,再沿图扩展出三元组事实」喂给 LLM 回答。一句话:把 agent 的「记性」做成一张会长大的图。

1. 这是什么(零基础也能懂)

一句话定义: Cognee 是一个 Python 库,把「原始数据 → 知识图谱 + 向量索引 → 可检索的记忆」这条链路打包好,让 AI agent 跨会话拥有持久长期记忆

解决什么问题 / 给谁用。 假设你在做一个 AI 助手,它读了你公司 200 篇文档。下次对话时,模型早忘了——上下文窗口装不下,而普通向量 RAG 只会捞回「字面相似」的段落,捞不出「A 公司收购了 B,B 的 CTO 是 C」这种跨段落的关系。Cognee 的用户就是这类需要「记住事实之间的连接」的 agent 开发者。

它和普通 RAG 的区别。 官方把核心流程称作 ECL 流水线(Extract, Cognify, Load:抽取、认知化、装载),用来替代传统 RAG(CLAUDE.md:7):

传统向量 RAGCognee
存什么文本块 + 向量文本块 + 向量 + 实体/关系图
怎么召回找最相似的块向量找种子节点 → 沿图扩展三元组
能答的问题「文档里怎么说 X」「X 和 Y 之间有什么关系」

它能做什么(功能):

  • 吃多种格式:文本、PDF、图片(OCR/视觉)、音频(转写)、代码、Office 文档(cognee/api/v1/add/add.py 的 docstring「Supported File Formats」)。
  • 自动用 LLM 抽实体和关系,建成知识图谱。
  • 多种检索模式:图补全、向量块、摘要、Cypher、时序等(SearchType 枚举共 17 种,cognee/modules/search/types/SearchType.py)。
  • 可插拔后端:图库(Ladybug/Kuzu/Neo4j…)、向量库(LanceDB/pgvector…)、关系库各司其职。

用起来什么样。 整个库的「主线」就是三个 await 调用(三步结构仿照 cognee/api/v1/add/add.py 的 docstring;下面的 Einstein 文本是为演示自拟的,非 docstring 原文):

import cognee

# 第 1 步:喂数据(一段文本或一个文件路径)
await cognee.add("Einstein was born in Ulm. He developed relativity.")

# 第 2 步:认知化——抽实体/关系,建知识图谱
await cognee.cognify()

# 第 3 步:检索——基于图上下文让 LLM 回答
results = await cognee.search("Where was Einstein born?")

新一点的 v2「记忆语义」API 把 add+cognify 合成了一个 remember()(cognee/api/v1/remember/remember.py:623),但底层还是同一条流水线。

一句话直觉/类比。 把 Cognee 想成 agent 的「海马体」:add 是看到信息,cognify 是把信息理解成概念之间的连接(而不是死记字面),search 是被问到时顺着连接回忆出相关事实。

2. 顶层全景(它大概怎么转)

一张主线图

怎么读:从左到右是数据的一生。上排是三个对外函数,下排是它们各自跑的任务流水线,最右是三类数据库。

add() cognify() search()
│ │ │
┌──▼─────────┐ ┌───────────▼───────────────┐ ┌─────────────▼──────────────┐
│ 解析路径 │ │ ① 分类文档(Document) │ │ 选一个 Retriever │
│ 抽取文本 │ │ ② 切块(DocumentChunk) │ │ (默认 GraphCompletion) │
│ 存原始数据 │ │ ③ LLM 抽实体/关系 + 摘要 │ │ 1. 向量找种子节点 │
└──┬─────────┘ │ ④ 落库:节点/边/向量 │ │ 2. 图投影 + 扩展三元组 │
│ └───────────┬───────────────┘ │ 3. 三元组打分排序 top-k │
│ │ │ 4. 拼上下文 → LLM 回答 │
▼ ▼ └─────────────┬──────────────┘
┌───────────────────────────────────────────────────────────▼──────────┐
│ 关系库(Data/Dataset/User 元数据) · 图库(节点+边) · 向量库(嵌入) │
└───────────────────────────────────────────────────────────────────────┘

三步全部由同一个任务流水线引擎 run_pipeline 驱动,只是任务列表不同(详见第 1 章)。

部件一句话职责

部件干什么在哪个文件
add()把原始数据解析、抽文本、存为 Data 记录cognee/api/v1/add/add.py
cognify()切块→LLM 抽图→落库,构建知识图谱cognee/api/v1/cognify/cognify.py
search()路由到某个 Retriever,召回并(可选)让 LLM 生成答案cognee/api/v1/search/search.py
run_pipeline / Task通用流水线引擎,串起一串可组合任务cognee/modules/pipelines/operations/run_tasks_base.py
DataPoint所有图节点的统一基类(Entity、DocumentChunk… 都继承它)cognee/infrastructure/engine/models/DataPoint.py
GraphCompletionRetriever默认召回器:向量种子 + 图三元组cognee/modules/retrieval/graph_completion_retriever.py
数据库适配层图/向量/关系三类库的统一接口 + 多后端实现cognee/infrastructure/databases/

主线走一遍(高层)

  1. add: cognee.add(text) 跑一个两步流水线 resolve_data_directories → ingest_data,把内容存成关系库里的 Data 行,并给用户授予该 dataset 的读写权限(cognee/api/v1/add/add.py,tasks 列表)。
  2. cognify: cognee.cognify() 跑默认五步流水线:分类 → 切块 → 「LLM 抽图 + 摘要」 → 落库 → DLT 外键边(get_default_tasks,cognee/api/v1/cognify/cognify.py:289)。这一步把文本变成实体节点 + 关系边
  3. search: cognee.search(q) 默认走 GRAPH_COMPLETION:用查询向量在向量库里找最近的节点当「种子」,把图投影成一个内存子图,扩展出三元组,按距离打分取 top-k,渲染成文本喂给 LLM 生成答案(graph_completion_retriever.py)。

3. 阅读地图(建议顺序)

这是个大项目,按由浅入深拆成四章。建议顺序:

  1. 01-pipeline-engine.md — 先懂「任务流水线」这个贯穿全局的骨架:Task 怎么定义、run_tasks_base 怎么递归把任务串起来、批处理和 provenance 盖章。读完你能看懂任何一条 add/cognify 流水线。
  2. 02-cognify-graph.md — 核心价值所在:一段文本如何被 LLM 抽成知识图谱,以及确定性节点 id 如何让「Einstein」在不同文档里自动合并成同一个节点。
  3. 03-recall-retrieval.md — 召回为什么强:brute_force_triplet_search 的「向量找种子 + 图扩展 + 三元组打分」三段式,以及十几种 SearchType 的分工。
  4. 04-data-model-and-storage.md — 底座:DataPoint 统一模型、三类数据库的分工、节点 id 与落库去重。

4. 巧妙之处(先记住这几条)

  • 一套引擎跑三件事。 add/cognify/search 不是三套代码,而是同一个 run_pipeline 喂不同的 Task 列表。新增能力 = 写个新 Task 插进列表(第 1 章)。
  • 确定性节点 id 实现「免费去重」。 Entity.id_for("Einstein")uuid5(NAMESPACE_OID, "Entity:einstein") 算 id,所以同名实体在任何文档、任何运行里都落到同一个节点,天然合并、可幂等重建(DataPoint.id_for,第 2/4 章)。
  • 召回是「向量 + 图」混合,不是纯向量。 向量只负责找入口节点,真正的上下文靠图扩展出来的三元组,这才是它比传统 RAG 能答「关系类问题」的原因(第 3 章)。

5. 边界与局限(诚实)

  • 强依赖 LLM。 抽图、摘要、最终回答都要调 LLM,LLM_API_KEY 是硬前置(add.py docstring「Prerequisites」)。抽取质量 = 模型质量,代码里看不出对抽错实体的纠错。
  • 本文未深挖的部分: memify()(图增强/规则)、SessionManager 会话缓存、ontology 解析器内部、distributed/eval_framework/。这些在仓库里存在但不在本组文档的核心主线上,需要时请按代码地图自行下钻。

6. 横向对比(ai-agent-reference 兄弟)

Cognee 在 memory-context 区,和同区做「agent 记忆」的项目相比,它的取舍是:把记忆显式建成知识图谱(实体+关系),而不是只存对话历史或向量块。代价是每条数据都要过一遍 LLM 抽取,换来的是「关系可检索」。具体兄弟对比留给 shelf 总库文档。

7. 代码地图(导航索引)

主题文件路径符号名
公开 API 入口cognee/__init__.pyadd, cognify, search, remember, recall
add 流水线cognee/api/v1/add/add.pyadd
cognify 流水线 + 默认任务cognee/api/v1/cognify/cognify.pycognify, get_default_tasks
流水线引擎(递归串任务)cognee/modules/pipelines/operations/run_tasks_base.pyrun_tasks_base, handle_task
Task 定义cognee/modules/pipelines/tasks/task.pyTask, TaskSpec, BoundTask
统一节点模型cognee/infrastructure/engine/models/DataPoint.pyDataPoint, id_for
实体抽图cognee/tasks/graph/extract_graph_from_data.pyintegrate_chunk_graphs
实体去重/扩展cognee/modules/graph/utils/expand_with_nodes_and_edges.pyexpand_with_nodes_and_edges
默认召回器cognee/modules/retrieval/graph_completion_retriever.pyGraphCompletionRetriever
混合召回核心cognee/modules/retrieval/utils/brute_force_triplet_search.pybrute_force_triplet_search, get_memory_fragment
三元组打分cognee/modules/graph/cognee_graph/CogneeGraph.py_calculate_query_top_triplet_importances
检索类型枚举cognee/modules/search/types/SearchType.pySearchType