improve() for the standard self-improvement flow; use this guide when you specifically want entity-description consolidation.
The pipeline runs in three stages:
- Rewrite entities — each
Entitydescription is regenerated from that entity’s neighbors and edges. - Summarize types — each
EntityTypedescription is regenerated from its actual member entities (their rewritten descriptions and the total member count), not from the type name alone. - Write
is_aedge text — every member gets one short line blending its own facts with the finished type summary, stored asedge_texton itsis_aedge.
This pipeline only rewrites text — it never creates or deletes nodes. It updates
Entity descriptions, EntityType descriptions, and the text on existing is_a edges, all in place. To merge near-duplicate Entity nodes into one, see Entity Deduplication.Before You Start
- Complete Quickstart to understand basic operations
- Ensure you have LLM Providers configured
- Have an existing knowledge graph with
Entitynodes — the script below builds one withremember()
Code in Action
What Just Happened
Step 1: Clear Existing Data
Step 2: Build and Visualize the Graph
The entities and types from a real run, before consolidation. Hover a node: every description is a single-chunk fragment such as “Person mentioned in the text.”, and every is_a edge says only “alice is a person.”
Entity and EntityType nodes and the edges between them are shown — the document, chunk, and summary nodes are not touched by this pipeline.
Step 3: Consolidate and Visualize Again
- Each
Entitynode’sdescriptionis rewritten in place from that entity’s neighbors and edges, so descriptions become more coherent than the single-chunk text they came from. - Each
EntityTypenode’sdescriptionis rewritten from its member entities. The summary always states the total member count; at or below 5 members it names them individually, above that it deliberately does not (seetype_max_named_membersbelow). - Each member’s
is_aedge getsedge_textin the form{Name} is a {Type}: {facts placing that member against the type summary}.
The same 13 nodes and 23 edges after consolidation. Nothing was added or removed; hover a node to see the rewritten description, and hover person or city to see the type summary built from its members.
person type states that it has five members and names each with a distinguishing fact, and Bob’s is_a edge carries “bob is a person: the lifelong New York resident who has always lived in New York and visited Paris in 2015.”
Step 4: Recall Against the Enriched Graph
recall() shows it being used. Graph retrieval indexes an edge’s edge_text and surfaces it alongside the relationship label, so the is_a lines written in stage 3 — and the member-count and shared-facts claims in the type summary — become part of the retrieved context instead of the bare token is_a.
Example output
Example output
person type summary written in stage 2.Advanced Usage
- Runnable guide script available on our GitHub
- Pipeline implementation: consolidate_entity_descriptions.py
Under the hood
Under the hood
The tasks live in
cognee.tasks.memify.consolidate_entity_descriptions. Four run in sequence:get_entities_with_neighborhood(extraction) — loads allEntitynodes and fetches their incident edges, edge text, and neighbor nodes. An entity’s types are the outgoingis_aedges that land on anEntityTypenode; an entity can have more than one.generate_consolidated_entities— sends each entity plus its neighborhood to the LLM, which returns a refined description.generate_type_descriptions— groups the rewritten entities by type, summarizes each group, then writes theis_aedge text for every member. The summary and theis_alines are separate LLM calls: above the naming threshold the summary must not name members, while everyis_aline must start with one.add_data_points— writes the updatedEntityandEntityTypeobjects, and theis_aedge text, back to the graph and vector DB.
add_data_points runs last and raising would discard the whole run: an entity whose rewrite call fails keeps the description it already had (so its type’s member count stays accurate), and a type whose calls fail is left unsummarized while every other type still lands.A type with more members than fit in one prompt is summarized in batches, and the partial summaries are then merged by a further LLM call into the single final summary. Batching is internal — you always pass the full graph, never the batches.Tuning
Tuning
consolidate_entity_descriptions_pipeline() takes no required arguments. Beyond user, dataset, and run_in_background (all forwarded to memify()), every size and budget cap is overridable per call:These are defensive backstops against pathological inputs — an unusually long description, an over-connected entity, a huge type — not per-model token budgets. Cognee is model-agnostic, so override them at the call site if your data or model needs something different, rather than editing the module constants.The completion-token defaults deliberately carry headroom well above the ~250-token content portion of each call’s budget: reasoning models (including cognee’s default
gpt-5.6-luna) spend hidden reasoning tokens out of the same budget, and a tight budget intermittently returns empty content.Troubleshooting
- No entities found — the graph must already contain
Entitynodes. Runcognee.remember()first. - LLM errors — verify that your LLM provider is configured. See LLM Providers.
- Permission errors — the user must have write access to the target dataset. See Permissions.
Entity Deduplication
Merge near-duplicate entity nodes into one canonical node
Improve
Understand the current improvement workflow
Self-Improving Memory Quickstart
Bridge session memory and enrich a dataset
Search
Query the enriched graph with specialized search types