From 5274970be346516bb4df0262186a4848c43d14e9 Mon Sep 17 00:00:00 2001 From: Preston Rasmussen <109292228+prasmussen15@users.noreply.github.com> Date: Wed, 16 Apr 2025 19:09:25 -0400 Subject: [PATCH] reduce entity type attribute hallucinations (#365) * reduce entity type attribute hallucinations * reduce entity type attribute hallucinations * reduce entity type attribute hallucinations * mypy fix * mypy fix * mypy fix --- graphiti_core/prompts/summarize_nodes.py | 1 + .../utils/maintenance/node_operations.py | 17 +++++++++++++---- pyproject.toml | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/graphiti_core/prompts/summarize_nodes.py b/graphiti_core/prompts/summarize_nodes.py index 172cb001..a9475dc3 100644 --- a/graphiti_core/prompts/summarize_nodes.py +++ b/graphiti_core/prompts/summarize_nodes.py @@ -89,6 +89,7 @@ def summarize_context(context: dict[str, Any]) -> list[Message]: Guidelines: 1. Do not hallucinate entity property values if they cannot be found in the current context. + 2. Only use the provided messages, entity, and entity context to set attribute values. {context['node_name']} diff --git a/graphiti_core/utils/maintenance/node_operations.py b/graphiti_core/utils/maintenance/node_operations.py index b6bb5e29..337f8c26 100644 --- a/graphiti_core/utils/maintenance/node_operations.py +++ b/graphiti_core/utils/maintenance/node_operations.py @@ -17,6 +17,7 @@ limitations under the License. import logging from contextlib import suppress from time import time +from typing import Any import pydantic from pydantic import BaseModel @@ -324,16 +325,17 @@ async def resolve_extracted_node( else [], } - summary_context = { + summary_context: dict[str, Any] = { 'node_name': extracted_node.name, 'node_summary': extracted_node.summary, 'episode_content': episode.content if episode is not None else '', 'previous_episodes': [ep.content for ep in previous_episodes] if previous_episodes is not None else [], - 'attributes': [], } + attributes: list[dict[str, str]] = [] + entity_type_classes: tuple[BaseModel, ...] = tuple() if entity_types is not None: # type: ignore entity_type_classes = entity_type_classes + tuple( @@ -344,8 +346,15 @@ async def resolve_extracted_node( ) for entity_type in entity_type_classes: - for field_name in entity_type.model_fields: - summary_context.get('attributes', []).append(field_name) # type: ignore + for field_name, field_info in entity_type.model_fields.items(): + attributes.append( + { + 'attribute_name': field_name, + 'attribute_description': field_info.description or '', + } + ) + + summary_context['attributes'] = attributes entity_attributes_model = pydantic.create_model( # type: ignore 'EntityAttributes', diff --git a/pyproject.toml b/pyproject.toml index e7bc154c..16a0fb2f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "graphiti-core" description = "A temporal graph building library" -version = "0.10.1" +version = "0.10.2" authors = [ { "name" = "Paul Paliychuk", "email" = "paul@getzep.com" }, { "name" = "Preston Rasmussen", "email" = "preston@getzep.com" },