diff --git a/graphiti_core/prompts/extract_edges.py b/graphiti_core/prompts/extract_edges.py index 21f68709..de581369 100644 --- a/graphiti_core/prompts/extract_edges.py +++ b/graphiti_core/prompts/extract_edges.py @@ -24,8 +24,12 @@ from .prompt_helpers import to_prompt_json class Edge(BaseModel): relation_type: str = Field(..., description='FACT_PREDICATE_IN_SCREAMING_SNAKE_CASE') - source_entity_id: int = Field(..., description='The id of the source entity of the fact.') - target_entity_id: int = Field(..., description='The id of the target entity of the fact.') + source_entity_id: int = Field( + ..., description='The id of the source entity from the ENTITIES list' + ) + target_entity_id: int = Field( + ..., description='The id of the target entity from the ENTITIES list' + ) fact: str = Field(..., description='') valid_at: str | None = Field( None, @@ -81,7 +85,7 @@ def edge(context: dict[str, Any]) -> list[Message]: -{context['nodes']} +{to_prompt_json(context['nodes'], ensure_ascii=context.get('ensure_ascii', False), indent=2)} @@ -107,7 +111,8 @@ You may use information from the PREVIOUS MESSAGES only to disambiguate referenc # EXTRACTION RULES -1. Only emit facts where both the subject and object match IDs in ENTITIES. +1. **Entity ID Validation**: `source_entity_id` and `target_entity_id` must use only the `id` values from the ENTITIES list provided above. + - **CRITICAL**: Using IDs not in the list will cause the edge to be rejected 2. Each fact must involve two **distinct** entities. 3. Use a SCREAMING_SNAKE_CASE string as the `relation_type` (e.g., FOUNDED, WORKS_AT). 4. Do not emit duplicate or semantically redundant facts. diff --git a/graphiti_core/utils/maintenance/edge_operations.py b/graphiti_core/utils/maintenance/edge_operations.py index a6760a40..a15a93de 100644 --- a/graphiti_core/utils/maintenance/edge_operations.py +++ b/graphiti_core/utils/maintenance/edge_operations.py @@ -181,7 +181,9 @@ async def extract_edges( target_node_idx = edge_data.target_entity_id if not (-1 < source_node_idx < len(nodes) and -1 < target_node_idx < len(nodes)): logger.warning( - f'WARNING: source or target node not filled {edge_data.relation_type}. source_node_uuid: {source_node_idx} and target_node_uuid: {target_node_idx} ' + f'Invalid entity IDs in edge extraction for {edge_data.relation_type}. ' + f'source_entity_id: {source_node_idx}, target_entity_id: {target_node_idx}, ' + f'but only {len(nodes)} entities available (valid range: 0-{len(nodes) - 1})' ) continue source_node_uuid = nodes[source_node_idx].uuid