节点抽取与消解
节点提取与解析
相关源文件
以下文件为本 Wiki 页面的生成上下文:
examples/quickstart/dense_vs_normal_ingestion.pygraphiti_core/prompts/dedupe_edges.pygraphiti_core/prompts/dedupe_nodes.pygraphiti_core/prompts/extract_edges.pygraphiti_core/prompts/extract_nodes.pygraphiti_core/prompts/summarize_nodes.pygraphiti_core/utils/content_chunking.pygraphiti_core/utils/maintenance/edge_operations.pygraphiti_core/utils/maintenance/node_operations.pytests/utils/maintenance/test_edge_operations.pytests/utils/maintenance/test_node_operations.pytests/utils/test_content_chunking.py
本文档描述了从片段内容中提取实体节点,并针对现有图谱数据进行解析的过程。节点提取将非结构化内容转换为结构化的 EntityNode 对象,而解析则通过将实体与图谱中的现有节点进行匹配来去重。
关于边(关系)的提取与解析,请参阅边提取与解析。关于调用这些操作的更广泛片段处理工作流,请参阅片段处理。
概述
节点提取与解析是一个多阶段过程,它将原始片段内容转换为去重后的实体节点:
标题:节点提取与解析数据流
来源: 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_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 使用单次大语言模型调用。
标题:单次节点提取逻辑
_call_extraction_llm 函数根据 EpisodeType(message、text 或 json)从 prompt_library.extract_nodes 中选择合适的提示词。
来源: graphiti_core/utils/maintenance/node_operations.py:149-158, graphiti_core/utils/maintenance/node_operations.py:160-185
切分提取路径
对于高密度内容,提取过程会对内容进行切分,并并行处理各个片段:
标题:并行切分提取
每个片段由 _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_core/utils/maintenance/node_operations.py:493-548
候选收集
_collect_candidate_nodes 函数通过为每个提取的节点名称发起搜索查询来识别潜在匹配项。它使用混合搜索方法来检索具有相似名称或语义上下文的现有节点。
来源: graphiti_core/utils/maintenance/node_operations.py:309-341
多阶段解析策略
解析采用三层方法,以平衡速度和准确性:
- 精确匹配:标准化字符串比较(
_normalize_string_exact),用于名称完全相同的情况。 - 模糊相似度:使用 3-gram 分片(
_shingles)上的 Jaccard 相似度和 MinHash 签名(_minhash_signature)来识别潜在重复项,无需大语言模型开销。此步骤通过名称熵检查(_has_high_entropy)进行过滤,以避免对短/通用名称产生误报。 - 大语言模型推理:未解析的节点被发送到
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_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_pair 或 summarize_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_nodes | graphiti_core/utils/maintenance/node_operations.py:69 | 从片段中提取实体的主要入口点。 |
resolve_extracted_nodes | graphiti_core/utils/maintenance/node_operations.py:493 | 针对现有图谱对提取的实体进行去重。 |
extract_attributes_from_nodes | graphiti_core/utils/maintenance/node_operations.py:551 | 使用摘要、属性和嵌入向量丰富节点。 |
should_chunk | graphiti_core/utils/content_chunking.py:59 | 基于启发式的逻辑,用于判断内容是否过于密集,不适合单次提取。 |
_resolve_with_llm | graphiti_core/utils/maintenance/node_operations.py:344 | 使用大语言模型推理来解析模糊的实体重复项。 |
_resolve_with_similarity | graphiti_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