Layer
neo4j-agent-memoryon top of the production graph you already have — no duplicate nodes, no migration script, idempotent.
This is the headline example for the v0.2 adopt an existing graph workflow. By default the library MERGEs entities on (:Entity {name, type}). If your existing graph has nodes labelled :Person, :Movie, :Client, etc. — none of which carry :Entity — those merges create duplicates. client.schema.adopt_existing_graph(...) attaches the :Entity super-label and the library's required id/type/name properties to your existing nodes so library writes link to them instead.
⚠️ Neo4j Labs ProjectThis example is part of
neo4j-agent-memory, a Neo4j Labs project. It is actively maintained but not officially supported. APIs may change. Community support is available via the Neo4j Community Forum.
Need a different LLM or embedding model? As of
neo4j-agent-memoryv0.3 you can swap providers via a single string —MemorySettings(llm="anthropic/claude-3-5-sonnet-latest", embedding="BAAI/bge-small-en-v1.5"). See Bring Your Own Model.
client.schema.adopt_existing_graph(label_to_type=..., name_property_per_label=...)— one call to attach the library's super-label and properties to nodes from a pre-existing schema. Idempotent; re-runnable safely.SchemaModel.CUSTOM— configureMemorySettingsso library writes target your domain types (MOVIE,GENRE, …) instead of the default POLE+O ontology. This is the first runnable example in the repo using a non-POLE+O domain.- No-LLM, no-API-key path — runs with
llm=Noneand a local sentence-transformers embedder so you can try it offline. - Adoption-aware
name_property_per_label— tells the library that:Movienodes usetitlerather thannamefor their display name.
| File | Purpose |
|---|---|
seed_domain_graph.cypher |
Loads three :Person, three :Movie, two :Genre nodes with relationships. Pre-library style — no :Entity labels, no library properties. Stand-in for "your existing production graph." |
memory_settings.py |
build_settings() — SchemaModel.CUSTOM with the same domain types as the seed graph; no LLM. |
adopt.py |
Calls client.schema.adopt_existing_graph(...) with the per-label name-property mapping. |
memory_io.py |
Writes a couple of messages and verifies that MENTIONS edges link to the existing domain nodes (no duplicates created). |
run.sh |
Loads → adopts → writes → verifies. Run this for the full demo. |
- Neo4j 5.x at
bolt://localhost:7687. Either start the test container withmake neo4j-startfrom the repo root, or pointNEO4J_URI,NEO4J_USERNAME,NEO4J_PASSWORDat your own instance. neo4j-agent-memoryinstalled with thesentence-transformersextra so the local embedder works.
From the repo root:
bash examples/existing-graph/run.shYou should see:
Adopted 8 nodes (0 already adopted, 0 skipped).
Person → PERSON: +3 new, =0 already, ~0 skipped
Movie → MOVIE: +3 new, =0 already, ~0 skipped
Genre → GENRE: +2 new, =0 already, ~0 skipped
…
Per-name node count after writes (1 means adoption worked):
Bob Singh -> 1
Carol Reyes -> 1
Inception -> 1
Arrival -> 1
Re-run bash examples/existing-graph/run.sh to confirm idempotency: the second run reports already adopted for every node and creates no duplicates.
adopt_existing_graph(label_to_type, *, name_property_per_label=None, dry_run=False):
- For each input label, attaches the
:Entitysuper-label. - Sets
typefrom the mapping,namefrom the configured property (defaulting toname), andidfrom any existingidproperty — falling back to a deterministiclabel:namehash so re-runs produce the same id. - Skips nodes that lack the configured name property and reports them in
report.by_label[i].skipped_count. - Returns an
AdoptionReportwith per-label counts.
After adoption, library APIs that MERGE on (:Entity {name, type}) — message-mention extraction, relation writes, preference targeting — link to your existing domain nodes instead of creating duplicates.
- How-to guide:
docs/modules/ROOT/pages/how-to/adopt-existing-graph.adoc— full design, name-property gotchas, how to bring your own ontology. - Reference:
docs/modules/ROOT/pages/reference/schema-objects.adoc— declarative constraints and indexes the library expects.
Verified against neo4j-agent-memory v0.2-dev (branch adopt-existing-graph) on 2026-05-03.