Entity nodes. When the same real-world thing is extracted under several names (New York City and NYC), it becomes several Entity nodes and its edges are split across all of them — the consolidate_entities Memify pipeline detects those near-duplicates and collapses each group into a single canonical node.
Before You Start
- Complete Quickstart to understand basic operations
- Ensure you have LLM Providers configured — the script below builds a graph with
remember() - Ensure you have Embedding Providers configured — detection embeds every entity name at run time
- Have an existing knowledge graph with
Entitynodes, or let the script create one - The acting user needs write access to the target dataset. See Permissions
Code in Action
What Just Happened
Step 1: Build a Graph with Duplicates
remember() calls. That separation matters: when the texts are ingested together, the LLM sees both mentions at once, resolves the abbreviation during extraction, and emits a single entity, leaving nothing to merge. Ingested independently, the graph ends up with separate New York City and NYC entities — visible in the before visualization — each holding only its own edges.
Step 2: Preview the Merge Plan
dry_run=True runs detection and computes the full merge plan, then logs it — which clusters were found, which node becomes canonical, and how many edges would be re-pointed — without touching the graph. The threshold is lowered from the 0.85 default because an abbreviation like NYC is not embedding-close enough to New York City to clear it.
Step 3: Apply the Merge
dry_run to execute it. The after visualization shows a single canonical city node carrying the edges from both duplicates.
Options
consolidate_entities_pipeline() takes the following arguments:
Arguments are validated before anything runs. A
CogneeValidationError is raised when similarity_threshold is outside (0, 1], when top_k is not a positive integer, when protect_node_types is not a list of non-empty strings, or when the user has no write access to the requested dataset.
What the Merge Changes
- Each detected cluster collapses into one canonical
Entitynode; the rest are deleted. The canonical is the most connected member of the cluster, with ties broken by oldestcreated_atand then by normalized name. - The canonical keeps its existing graph id, so anything already pointing at it stays valid.
- Every edge on a duplicate is re-pointed onto the canonical with its direction preserved. Edges that would become a self-loop on the canonical are dropped.
- The canonical’s
descriptionbecomes the union of the distinct, non-empty descriptions across the cluster. - The canonical’s
belongs_to_setbecomes the union of every member’s tags, so a merge never narrows a node’s dataset / node-set scoping. - Duplicate nodes are detach-deleted (which removes their old edges) and their name embeddings are purged from the
Entity_namevector collection. - A merge report listing each
canonical_id,canonical_name, and themerged_fromduplicates is written to the logs on every run, including dry runs.
Additional Information
- Runnable guide script available on our GitHub
- Pipeline implementation: consolidate_entities.py
Tuning the matching
Tuning the matching
Raise
similarity_threshold to merge only very close names, exclude entity types you never want collapsed, and widen top_k if dense clusters of similar names are being missed.Under the hood
Under the hood
Two tasks run in sequence, both exported from
cognee.tasks.memify:detect_entity_duplicates(extraction) — loads everyEntitynode from the graph, embeds its name, and clusters near-duplicates by cosine similarity and, whenname_matchis on, by normalized-name equality. Similarities are scanned in row-blocks and only each node’stop_knearest neighbors are inspected, so the full N×N similarity matrix is never materialized.merge_entity_duplicates(enrichment) — picks the canonical for each cluster, re-points the duplicates’ edges onto it in one batched call, writes back the canonical with unioneddescriptionandbelongs_to_set, then deletes the duplicate nodes and their vectors.
get_graph_data, add_edges, add_nodes, delete_nodes, and the vector engine’s delete_data_points. No per-edge delete primitive is required.Troubleshooting
Troubleshooting
- Nothing was merged — the graph must contain at least two candidate
Entitynodes. Check the logs for the detected-cluster count, then lowersimilarity_thresholdor raisetop_k. - Entities that should match are not merging — by default only entities sharing the same
EntityTypeare merged. Setallow_cross_type=Trueif the duplicates were typed differently. - Too much was merged — restore from backup, then raise
similarity_thresholdand add the affected types toprotect_node_types. - Validation errors —
similarity_thresholdmust be in(0, 1],top_kmust be a positive integer, andprotect_node_typesmust be a list of non-empty strings. - Permission errors — the user must have write access to the target dataset. See Permissions.
Entity Consolidation
Rewrite fragmented entity descriptions with the LLM
Improve
Understand the current improvement workflow
Embedding Providers
Configure the embedder that duplicate detection relies on