mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-12 20:15:26 +00:00
fix(graphrag): drop entities whose name normalizes to nothing
``canonical_name`` answers "" for a punctuation-only name, which callers are meant to read as "no entity" -- ``_resolve_endpoint`` already does. Entity extraction did not, and nodes merge on that key, so every such entity in a source collapsed onto one shared node that belonged to none of them.
This commit is contained in:
1 parent
2b6d4d509e
commit
ef5b718f37
2 files changed
+29
-2
No files matched your search
@@ -424,7 +424,7 @@ def extract_graph_for_source(
|
||||
|
||||
|
||||
def _build_entities(raw_entities: Any) -> List[Dict[str, Any]]:
|
||||
"""Normalize the LLM's entity dicts (drop nameless ones)."""
|
||||
"""Normalize the LLM's entity dicts (drop the ones with no usable name)."""
|
||||
entities = []
|
||||
for e in raw_entities:
|
||||
if not isinstance(e, dict):
|
||||
@@ -432,10 +432,16 @@ def _build_entities(raw_entities: Any) -> List[Dict[str, Any]]:
|
||||
name = str(e.get("name", "")).strip()
|
||||
if not name:
|
||||
continue
|
||||
normalized_name = normalize_entity_name(name)
|
||||
if not normalized_name:
|
||||
# A punctuation-only name normalizes to nothing, and nodes merge on
|
||||
# that key: keeping it collapses every such entity onto one shared
|
||||
# node. The relationship side already drops them.
|
||||
continue
|
||||
entities.append(
|
||||
{
|
||||
"name": name,
|
||||
"normalized_name": normalize_entity_name(name),
|
||||
"normalized_name": normalized_name,
|
||||
"type": str(e.get("type") or "") or None,
|
||||
"description": str(e.get("description") or "") or None,
|
||||
}
|
||||
|
||||
@@ -1085,6 +1085,27 @@ class TestSummaryCountFailure:
|
||||
assert store.count_nodes.call_args.kwargs.get("strict") is True
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestEntityNormalization:
|
||||
"""An entity whose name normalizes to nothing is not an entity.
|
||||
|
||||
``canonical_name`` answers "" for a punctuation-only name, and nodes are
|
||||
merged on that key, so keeping them collapses every such entity onto one
|
||||
shared node. ``_resolve_endpoint`` already drops them on the relationship
|
||||
side.
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize("name", ["!!!", "--", "?", " *** "])
|
||||
def test_a_name_that_normalizes_to_nothing_is_dropped(self, name):
|
||||
assert extraction_module._build_entities([{"name": name}]) == []
|
||||
|
||||
def test_real_names_survive(self):
|
||||
built = extraction_module._build_entities(
|
||||
[{"name": "Quill Store"}, {"name": "!!!"}, {"name": "Alder"}]
|
||||
)
|
||||
assert [e["normalized_name"] for e in built] == ["quill store", "alder"]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestParsing:
|
||||
def test_parses_embedded_json(self):
|
||||
|
||||
Reference in new issue
Block a user