Before You Start
- Complete Quickstart to understand basic operations
- Ensure you have LLM Providers configured
- Read Global Context Index for the conceptual overview — this guide focuses on the runnable example, not the full parameter surface
- Be familiar with
improve()
Code in Action
What Just Happened
Step 1: Ingest the Initial Facts
Step 2: Build the Index
improve() runs its normal enrichment pass first, then builds the global context index on top: it groups the dataset’s TextSummary nodes into buckets, and buckets into higher buckets, until everything fits under one root summary — see Global Context Index for exactly what a bucket and a root are.
Step 3: Inspect the Initial Structure
print_index_structure() reads the graph directly through get_graph_engine().get_graph_data() — see the “Inspect extracted graph schema” accordion (its “Python SDK” subsection) on the Cognify page for exactly what it returns — a (node_id, properties) pair per node. The loop classifies each node by its type: a TextSummary just increments a counter, while a GlobalContextSummary is split into the single root (is_root=True) or a bucket (everything else), keeping each bucket’s id alongside its text so you can compare it against the next build.
Step 4: Add a Fact and Rebuild
improve(build_global_context_index=True) again does not start over — it only places this one new TextSummary node.
Step 5: Inspect the Updated Structure
Source summaries goes up by one, but the bucket that already covered Alice’s hiking trips keeps the exact same id it had after Step 3 — proof that fact was added to that bucket rather than triggering a full rebuild. The root also keeps the same id (it’s derived only from the dataset, never from its children), though its text is regenerated to reflect the new fact.
Under the Hood
How the Index Is Actually Built and Updated
How the Index Is Actually Built and Updated
- How groupings are actually formed: at level 0,
TextSummarynodes land in the same bucket based on entity overlap — the more entities two summaries share, the more likely they’re grouped together — weighted so entities that show up in almost every summary don’t dominate the grouping. Every level above level 0 (bucket into higher bucket, up to the root) groups by vector distance between embeddings instead. - Bucket capacity:
improve()hardcodesmax_bucket_size=4, not exposed as a configurable option. - Why ids stay stable: a bucket’s id is determined by the dataset, level, and its child ids at the moment the bucket is created. Adding a new child later mutates that bucket’s contents in place — the id is never recomputed. The root’s id depends only on the dataset id, never on its children, so it’s stable for the life of the dataset even though its text gets regenerated whenever something changes underneath it.
- Higher levels: buckets group up to
max_bucket_sizebuckets each. If that still leaves more thanmax_bucket_sizebuckets, another level is built on top, repeating until the topmost level fits under a single root.
Global Context Index
The full concept, configuration options, and when to use it
Improve
Understand improve()‘s other enrichment passes
Reading the Global Context Index
See how include_global_context_index changes retrieval, once the index above exists