实体与关系抽取(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/getzep/graphiti/3.3-entity-and-relationship-extraction
翻译时间:2026-05-27T08:44:56.629Z
翻译模型:deepseek-chat
原文字符数:14000
项目:Graphiti (graphiti)
---
实体与关系提取
相关源文件
以下文件为本维基页面的生成提供了上下文:
graphiti_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/maintenance/edge_operations.pygraphiti_core/utils/maintenance/node_operations.pygraphiti_core/utils/ontology_utils/entity_types_utils.pytests/utils/maintenance/test_edge_operations.pytests/utils/maintenance/test_node_operations.py
本文介绍 Graphiti 如何使用大语言模型(LLM)从非结构化片段内容中提取结构化知识。提取过程将原始文本、对话或 JSON 数据转换为带有类型分类、时间元数据和自定义属性的实体节点与关系边。
本文涵盖初始提取阶段。关于已提取实体和边如何与现有图谱进行去重和解析的信息,请参见去重与解析。关于完整片段处理工作流的详细信息,请参见片段处理工作流。
概述
实体与关系提取是从片段构建知识图谱的基础步骤。该过程包括:
- 实体提取:识别片段内容中提到的实体(人物、地点、对象)。
graphiti_core/utils/maintenance/node_operations.py:69-148 - 实体类型分类:基于可配置的模式和整数 ID 映射分配实体类型。
graphiti_core/utils/maintenance/node_operations.py:151-180 - 属性提取:使用自定义 Pydantic 模型填充类型特定属性。
graphiti_core/utils/maintenance/node_operations.py:440-472 - 关系提取:识别实体之间的事实性连接。
graphiti_core/utils/maintenance/edge_operations.py:116-181 - 时间解析:使用参考时间提取关系的
valid_at和invalid_at时间戳。graphiti_core/utils/maintenance/edge_operations.py:249-276
所有提取操作均通过结构化的大语言模型提示完成,提示内容根据片段类型和实体/边模式的不同而变化。
实体提取管线
片段类型路由
Graphiti 支持三种片段类型,每种类型都有专门的提取提示。系统根据 episode.source 属性在 _call_extraction_llm 中路由提取调用。
| 片段类型 | 提示函数 | 使用场景 | 关键特性 |
|---|---|---|---|
EpisodeType.message | extract_message() | 对话式交流 | 消歧代词、识别说话者、处理对话行。 |
EpisodeType.json | extract_json() | 结构化数据 | 从 JSON 键和值中提取实体。 |
EpisodeType.text | extract_text() | 原始文档 | 从散文和非结构化文本中进行通用实体提取。 |
来源: graphiti_core/prompts/extract_nodes.py:83-255,graphiti_core/utils/maintenance/node_operations.py:220-255
提取流程示意图
下图连接了自然语言空间(片段内容)与代码实体空间(EntityNode 对象)。
graph TB
Episode["EpisodicNode<br/>(内容,来源)"]
Router["_call_extraction_llm()<br/>node_operations.py:220"]
MessagePrompt["extract_message()<br/>extract_nodes.py:83"]
JSONPrompt["extract_json()<br/>extract_nodes.py:216"]
TextPrompt["extract_text()<br/>extract_nodes.py:248"]
LLM["LLMClient.generate_response()<br/>response_model=ExtractedEntities"]
Response["ExtractedEntities.extracted_entities<br/>list[ExtractedEntity]"]
Filter["过滤空名称<br/>node_operations.py:134"]
Convert["_create_entity_nodes()<br/>node_operations.py:258"]
Nodes["list[EntityNode]<br/>(名称,标签,group_id)"]
Episode --> Router
Router -->|"EpisodeType.message"| MessagePrompt
Router -->|"EpisodeType.json"| JSONPrompt
Router -->|"EpisodeType.text"| TextPrompt
MessagePrompt --> LLM
JSONPrompt --> LLM
TextPrompt --> LLM
LLM --> Response
Response --> Filter
Filter --> Convert
Convert --> Nodes
来源: graphiti_core/utils/maintenance/node_operations.py:69-148,graphiti_core/prompts/extract_nodes.py:28-42
实体类型分类
实体类型使用 Pydantic 模型字典定义。系统构建一个 entity_types_context 数组,将整数 ID 映射到实体类型定义,以减少提示中的 Token 使用量。graphiti_core/utils/maintenance/node_operations.py:151-180
# 来自 _build_entity_types_context()
entity_types_context = [
{
'entity_type_id': 0,
'entity_type_name': 'Entity',
'entity_type_description': '一个特定的、可识别的实体...'
},
{
'entity_type_id': 1,
'entity_type_name': 'Person',
'entity_type_description': Person.__doc__
}
]
大语言模型返回带有 entity_type_id 字段的 ExtractedEntity 对象。_create_entity_nodes 将这些 ID 映射回标签,并创建 EntityNode 对象。graphiti_core/utils/maintenance/node_operations.py:258-306
来源: graphiti_core/utils/maintenance/node_operations.py:151-180,graphiti_core/prompts/extract_nodes.py:28-38
属性提取
实体分类后,如果实体类型定义了自定义字段,Graphiti 会提取类型特定的属性。extract_attributes_from_nodes 函数使用实体的名称、现有属性和片段内容调用大语言模型。响应在合并到 node.attributes 之前,会根据实体类型的 Pydantic 模式进行校验。graphiti_core/utils/maintenance/node_operations.py:440-472
来源: graphiti_core/utils/maintenance/node_operations.py:440-472,graphiti_core/prompts/extract_nodes.py:348-362
实体摘要
实体摘要会批量生成或更新,以优化大语言模型的使用。_extract_entity_summaries_batch() 函数每次大语言模型调用最多处理 30 个实体(由 MAX_NODES = 30 控制)。graphiti_core/utils/maintenance/node_operations.py:62-62,graphiti_core/utils/maintenance/node_operations.py:674-682
来源: graphiti_core/utils/maintenance/node_operations.py:62-62,graphiti_core/utils/maintenance/node_operations.py:674-682
关系提取管线
边提取过程
关系提取识别片段中发现的实体之间的事实性连接。extract_edges() 函数构建边类型上下文,并调用大语言模型识别涉及提供的列表中两个不同实体的事实。graphiti_core/utils/maintenance/edge_operations.py:116-247
graph TB
Input["episode: EpisodicNode<br/>nodes: list[EntityNode]<br/>edge_type_map: dict"]
BuildContext["构建 edge_types_context<br/>包含 fact_type_signatures<br/>edge_operations.py:151"]
BuildMap["构建 name_to_node 映射<br/>用于校验<br/>edge_operations.py:167"]
Prompt["prompt_library.extract_edges.edge()<br/>extract_edges.py:94"]
LLM["LLMClient.generate_response()<br/>response_model=ExtractedEdges"]
Response["ExtractedEdges.edges<br/>list[Edge]"]
Validate["校验 source_entity_name<br/>和 target_entity_name<br/>是否存在于 nodes 中<br/>edge_operations.py:205"]
CreateEdges["创建 EntityEdge 对象<br/>包含时间字段<br/>edge_operations.py:249"]
Output["list[EntityEdge]"]
Input --> BuildContext
Input --> BuildMap
BuildContext --> Prompt
Prompt --> LLM
LLM --> Response
Response --> Validate
Validate --> CreateEdges
CreateEdges --> Output
来源: graphiti_core/utils/maintenance/edge_operations.py:116-247,graphiti_core/prompts/extract_edges.py:94-141
时间信息提取
边提取提示指示大语言模型使用片段的时间戳作为锚点来提取时间元数据。graphiti_core/prompts/extract_edges.py:108-110
| 字段 | 描述 | 格式 | 示例使用场景 |
|---|---|---|---|
valid_at | 关系何时变为真 | ISO 8601(UTC) | "John 于 2024-03-15 开始在 Acme 工作" |
invalid_at | 关系何时结束 | ISO 8601(UTC) | "John 于 2024-12-01 离开 Acme" |
提取提示包含时间解析的具体规则,例如使用 REFERENCE_TIME 解析"上周"等模糊表达。graphiti_core/prompts/extract_edges.py:127-129
来源: graphiti_core/prompts/extract_edges.py:40-47,graphiti_core/utils/maintenance/edge_operations.py:252-276
边类型映射
边类型使用签名定义,指定它们适用于哪些节点类型对。提取过程构建一个 edge_type_signatures_map,为每种边类型保留所有有效签名,确保大语言模型了解有效的关系约束上下文。graphiti_core/utils/maintenance/edge_operations.py:144-150
来源: graphiti_core/utils/maintenance/edge_operations.py:144-164
提示系统架构
提示函数接口
所有提取提示遵循由 PromptFunction 类型定义的一致接口。提示库按类别组织提示,例如 extract_nodes 和 extract_edges。
graph TB
Library["PromptLibrary<br/>lib.py:44"]
ExtractNodes["extract_nodes<br/>extract_nodes.py"]
ExtractEdges["extract_edges<br/>extract_edges.py"]
DedupeNodes["dedupe_nodes<br/>dedupe_nodes.py"]
DedupeEdges["dedupe_edges<br/>dedupe_edges.py"]
ENMessage["extract_message()"]
ENJSON["extract_json()"]
ENText["extract_text()"]
ENAttrs["extract_attributes()"]
ENSummary["extract_summaries_batch()"]
EEEdge["edge()"]
EEAttrs["extract_attributes()"]
Library --> ExtractNodes
Library --> ExtractEdges
Library --> DedupeNodes
Library --> DedupeEdges
ExtractNodes --> ENMessage
ExtractNodes --> ENJSON
ExtractNodes --> ENText
ExtractNodes --> ENAttrs
ExtractNodes --> ENSummary
ExtractEdges --> EEEdge
ExtractEdges --> EEAttrs
来源: graphiti_core/prompts/extract_nodes.py:72-80,graphiti_core/prompts/extract_edges.py:87-92
结构化输出校验
所有提取提示使用 Pydantic 模型进行结构化输出,以确保一致性和类型安全。
关键响应模型包括:
ExtractedEntities:包含list[ExtractedEntity],带有name和entity_type_id。graphiti_core/prompts/extract_nodes.py:41-42ExtractedEdges:包含list[Edge],带有源/目标名称、事实和时间字段。graphiti_core/prompts/extract_edges.py:55-56SummarizedEntities:包含list[SummarizedEntity],带有实体名称和更新后的摘要。graphiti_core/prompts/extract_nodes.py:54-58
来源: graphiti_core/prompts/extract_nodes.py:28-58,graphiti_core/prompts/extract_edges.py:25-56
完整提取管线
端到端流程
以下序列展示了提取如何集成到整体片段处理管线中。
sequenceDiagram
participant Graphiti
participant NodeOps as node_operations.py
participant EdgeOps as edge_operations.py
participant LLM as LLMClient
participant Embedder
Note over Graphiti: 阶段 1:实体提取
Graphiti->>NodeOps: extract_nodes(episode, previous_episodes, entity_types)
NodeOps->>NodeOps: _build_entity_types_context()
NodeOps->>LLM: _call_extraction_llm()<br/>→ ExtractedEntities
LLM-->>NodeOps: extracted_entities
NodeOps->>NodeOps: _create_entity_nodes()<br/>(过滤与分类)
NodeOps-->>Graphiti: list[EntityNode](未解析)
Note over Graphiti: (此处进行解析 - 参见 3.4)
Note over Graphiti: 阶段 2:属性丰富
Graphiti->>NodeOps: extract_attributes_from_nodes(nodes, episode)
loop 对于每个节点
NodeOps->>LLM: extract_attributes()<br/>→ entity_type model
LLM-->>NodeOps: attributes dict
NodeOps->>NodeOps: node.attributes.update()
end
NodeOps->>NodeOps: _extract_entity_summaries_batch()<br/>(每次调用最多 30 个节点)
NodeOps->>LLM: extract_summaries_batch()<br/>→ SummarizedEntities
LLM-->>NodeOps: summaries
NodeOps->>Embedder: create_entity_node_embeddings()
NodeOps-->>Graphiti: list[EntityNode](已填充)
Note over Graphiti: 阶段 3:边提取
Graphiti->>EdgeOps: extract_edges(episode, nodes, edge_type_map)
EdgeOps->>EdgeOps: 构建 edge_type_signatures_map
EdgeOps->>LLM: edge()<br/>→ ExtractedEdges
LLM-->>EdgeOps: 带有时间信息的边
EdgeOps->>EdgeOps: 校验实体名称<br/>解析 valid_at/invalid_at
EdgeOps->>EdgeOps: 创建 EntityEdge 对象
EdgeOps-->>Graphiti: list[EntityEdge](未解析)
来源: graphiti_core/utils/maintenance/node_operations.py:69-148,graphiti_core/utils/maintenance/edge_operations.py:116-247,graphiti_core/utils/maintenance/node_operations.py:440-472,graphiti_core/utils/maintenance/node_operations.py:674-730