agentic_huge_data_base / wiki
页面 Graphiti · 5.2 节点抽取与消解·DeepWiki 中文全文译文

5.2 · 节点抽取与消解(Node Extraction and Resolution)

时序知识图谱与动态事实记忆 · 聚焦本章的模块关系、源码依据与实现要点。

项目Graphiti 章节5.2 状态全文译文 模块图谱与关系、测试、发布与运维、入库与解析、界面与交互
源码线索
  • examples/quickstart/dense_vs_normal_ingestion.py
  • graphiti_core/prompts/dedupe_edges.py
  • graphiti_core/prompts/dedupe_nodes.py
  • graphiti_core/prompts/extract_edges.py
  • graphiti_core/prompts/extract_nodes.py
  • graphiti_core/prompts/summarize_nodes.py
  • graphiti_core/utils/content_chunking.py
  • graphiti_core/utils/maintenance/edge_operations.py
  • graphiti_core/utils/maintenance/node_operations.py
  • tests/utils/maintenance/test_edge_operations.py
模块标签
  • 图谱与关系
  • 测试、发布与运维
  • 入库与解析
  • 界面与交互
  • 模型调用与提供方适配

章节正文

节点抽取与消解

节点提取与解析

相关源文件

以下文件为本 Wiki 页面的生成上下文:

  • examples/quickstart/dense_vs_normal_ingestion.py
  • graphiti_core/prompts/dedupe_edges.py
  • graphiti_core/prompts/dedupe_nodes.py
  • graphiti_core/prompts/extract_edges.py
  • graphiti_core/prompts/extract_nodes.py
  • graphiti_core/prompts/summarize_nodes.py
  • graphiti_core/utils/content_chunking.py
  • graphiti_core/utils/maintenance/edge_operations.py
  • graphiti_core/utils/maintenance/node_operations.py
  • tests/utils/maintenance/test_edge_operations.py
  • tests/utils/maintenance/test_node_operations.py
  • tests/utils/test_content_chunking.py

本文档描述了从片段内容中提取实体节点,并针对现有图谱数据进行解析的过程。节点提取将非结构化内容转换为结构化的 EntityNode 对象,而解析则通过将实体与图谱中的现有节点进行匹配来去重。

关于边(关系)的提取与解析,请参阅边提取与解析。关于调用这些操作的更广泛片段处理工作流,请参阅片段处理

概述

节点提取与解析是一个多阶段过程,它将原始片段内容转换为去重后的实体节点:

标题:节点提取与解析数据流

Graphiti · 概述 · 图 1
Graphiti · 概述 · 图 1

来源: graphiti_core/utils/maintenance/node_operations.py:69-148, graphiti_core/utils/maintenance/node_operations.py:493-548, graphiti_core/utils/maintenance/node_operations.py:551-581

自适应片段切分的实体提取

extract_nodes 函数从片段内容中提取实体,当内容具有高实体密度时,会使用自适应片段切分。

片段切分决策逻辑

标题:自适应片段切分决策树

Graphiti · 片段切分决策逻辑 · 图 2
Graphiti · 片段切分决策逻辑 · 图 2

graphiti_core/utils/content_chunking.py 中的 should_chunk 函数根据内容大小和实体密度阈值来判断是否需要切分。高密度内容(每个 Token 包含多个实体)存在大语言模型上下文溢出或提取遗漏的风险,因此会将其拆分为重叠的片段,并使用 semaphore_gather 进行并行处理。

来源: graphiti_core/utils/maintenance/node_operations.py:124-127, graphiti_core/utils/content_chunking.py:59-83, graphiti_core/helpers.py:25-30

提取过程
单次提取路径

对于正常密度的内容,提取通过 _extract_nodes_single 使用单次大语言模型调用。

标题:单次节点提取逻辑

Graphiti · 单次提取路径 · 图 3
Graphiti · 单次提取路径 · 图 3

_call_extraction_llm 函数根据 EpisodeTypemessagetextjson)从 prompt_library.extract_nodes 中选择合适的提示词。

来源: graphiti_core/utils/maintenance/node_operations.py:149-158, graphiti_core/utils/maintenance/node_operations.py:160-185

切分提取路径

对于高密度内容,提取过程会对内容进行切分,并并行处理各个片段:

标题:并行切分提取

Graphiti · 切分提取路径 · 图 4
Graphiti · 切分提取路径 · 图 4

每个片段由 _extract_from_chunk 独立处理。_merge_extracted_entities 函数在转换为 EntityNode 对象之前,使用标准化名称匹配来跨片段去重实体。

来源: graphiti_core/utils/maintenance/node_operations.py:183-210, graphiti_core/utils/maintenance/node_operations.py:213-222, graphiti_core/utils/maintenance/node_operations.py:253-270

实体类型分类

提取的实体使用带有数字 ID 的实体类型系统进行分类。_build_entity_types_context 函数创建 ID 与类型名称之间的映射,该映射会在提取时提供给大语言模型。

实体类型 ID名称描述
0实体未类型化实体的默认分类
1+自定义类型来自 entity_types 字典映射到 Pydantic 模型的用户定义实体类型

来源: graphiti_core/utils/maintenance/node_operations.py:151-180, graphiti_core/prompts/extract_nodes.py:28-33

EntityNode 创建

_create_entity_nodes 函数将 ExtractedEntity 对象(大语言模型响应模式)转换为 EntityNode 对象。每个节点会获得:

  • 一个 UUID(自动生成)
  • 标签,包括 Entity 和具体的类型名称
  • 用于多租户的片段的 group_id
  • 来自 utc_now()created_at 时间戳

来源: graphiti_core/utils/maintenance/node_operations.py:188-210

实体解析与去重

resolve_extracted_nodes 函数执行多阶段去重,将提取的实体映射到现有的图谱节点。

解析架构

标题:多层解析逻辑

Graphiti · 解析架构 · 图 5
Graphiti · 解析架构 · 图 5

来源: graphiti_core/utils/maintenance/node_operations.py:493-548

候选收集

_collect_candidate_nodes 函数通过为每个提取的节点名称发起搜索查询来识别潜在匹配项。它使用混合搜索方法来检索具有相似名称或语义上下文的现有节点。

来源: graphiti_core/utils/maintenance/node_operations.py:309-341

多阶段解析策略

解析采用三层方法,以平衡速度和准确性:

  1. 精确匹配:标准化字符串比较(_normalize_string_exact),用于名称完全相同的情况。
  2. 模糊相似度:使用 3-gram 分片(_shingles)上的 Jaccard 相似度和 MinHash 签名(_minhash_signature)来识别潜在重复项,无需大语言模型开销。此步骤通过名称熵检查(_has_high_entropy)进行过滤,以避免对短/通用名称产生误报。
  3. 大语言模型推理:未解析的节点被发送到 dedupe_nodes.nodes 提示词。大语言模型返回一个 NodeResolutions 对象,其中包含 NodeDuplicate 条目,将提取的 ID 映射到现有的 candidate_id 值。

来源: graphiti_core/utils/maintenance/dedup_helpers.py:39-141, graphiti_core/utils/maintenance/dedup_helpers.py:215-263, graphiti_core/prompts/dedupe_nodes.py:25-38

属性与摘要丰富

解析后,extract_attributes_from_nodes 使用摘要和结构化属性来丰富节点。

丰富工作流

标题:节点丰富管线

Graphiti · 丰富工作流 · 图 6
Graphiti · 丰富工作流 · 图 6

来源: graphiti_core/utils/maintenance/node_operations.py:551-581

属性提取

如果节点的实体类型定义了自定义 Pydantic 模型,_extract_entity_attributes 会提取结构化数据。它使用 extract_nodes.extract_attributes 提示词,从片段上下文中填充字段。

来源: graphiti_core/utils/maintenance/node_operations.py:607-639, graphiti_core/prompts/extract_nodes.py:61

摘要生成

_extract_entity_summary 生成自然语言摘要。如果存在现有摘要,大语言模型会使用 summarize_pairsummarize_context 提示词,将其与新信息进行综合。结果会使用 truncate_at_sentence 截断至 MAX_SUMMARY_CHARS(1000 个字符)。

来源: graphiti_core/utils/maintenance/node_operations.py:642-671, graphiti_core/utils/text_utils.py:29-59, graphiti_core/prompts/summarize_nodes.py:54-116

嵌入向量生成

create_entity_node_embeddings 使用配置的 EmbedderClient 为每个节点的名称生成向量嵌入,以支持后续的语义搜索。

来源: graphiti_core/nodes.py:33, graphiti_core/utils/maintenance/node_operations.py:579

函数参考

函数位置用途
extract_nodesgraphiti_core/utils/maintenance/node_operations.py:69从片段中提取实体的主要入口点。
resolve_extracted_nodesgraphiti_core/utils/maintenance/node_operations.py:493针对现有图谱对提取的实体进行去重。
extract_attributes_from_nodesgraphiti_core/utils/maintenance/node_operations.py:551使用摘要、属性和嵌入向量丰富节点。
should_chunkgraphiti_core/utils/content_chunking.py:59基于启发式的逻辑,用于判断内容是否过于密集,不适合单次提取。
_resolve_with_llmgraphiti_core/utils/maintenance/node_operations.py:344使用大语言模型推理来解析模糊的实体重复项。
_resolve_with_similaritygraphiti_core/utils/maintenance/dedup_helpers.py:215使用字符串标准化和 LSH 进行快速、确定性的解析。

来源: graphiti_core/utils/maintenance/node_operations.py:69-671, graphiti_core/utils/content_chunking.py:59-83, graphiti_core/utils/maintenance/dedup_helpers.py:39-263