
How can I use Neo4j as long-term memory for AI agents?
Neo4j is a strong choice for long-term memory for AI agents because it does something most memory stores struggle with: it keeps entities, relationships, events, and context connected in a way an agent can query intelligently later. Instead of treating every memory as an isolated chunk of text, Neo4j lets you store a person, preference, project, meeting, or decision as part of a living knowledge graph. That makes it much easier for an agent to recall the right facts, connect them to the current conversation, and reason over time.
If you want an AI agent that remembers users, tracks goals, preserves decisions, and uses past interactions to improve future responses, Neo4j can act as a durable memory layer. The key is to design the memory model carefully: store structured facts in the graph, enrich them with metadata, and retrieve them with both graph queries and semantic search when needed.
Why Neo4j works well for agent memory
Traditional memory approaches usually fall into one of these buckets:
- Conversation buffer: good for short-term context, but it forgets quickly
- Vector database only: useful for similarity search, but weak at explicit relationships
- Relational database: structured, but not ideal for exploring connected context
- Document store: flexible, but less effective for multi-hop reasoning
Neo4j combines the strengths of a knowledge graph and a flexible memory store. That matters because AI agents often need to answer questions like:
- What does this user prefer?
- Which project did we discuss last week?
- What decision was made in the previous meeting?
- Who is connected to this issue?
- What tasks remain open from earlier conversations?
These questions are naturally graph-shaped. Neo4j makes them easy to store and retrieve.
What “long-term memory” should mean for an AI agent
Long-term memory should not just be a dump of chat logs. It should capture information that remains useful across sessions.
A practical memory system usually includes:
1. Factual memory
Stable facts about the user or environment.
Examples:
- User’s name and role
- Preferred writing style
- Company name
- Project names
- Tooling preferences
2. Episodic memory
Important events or interactions.
Examples:
- “We decided to migrate to Kubernetes on March 12”
- “User asked for a follow-up next Friday”
- “The customer complained about onboarding friction”
3. Procedural memory
How the agent should behave.
Examples:
- “Always ask before scheduling meetings”
- “Use concise answers for this user”
- “Prefer JSON output for this workflow”
4. Relational memory
Connections between people, projects, topics, and actions.
Examples:
- User works on Project Alpha
- Project Alpha depends on Service Beta
- Service Beta has a known latency issue
- Latency issue was discussed with Sarah
Neo4j is especially useful because these memory types can coexist in one graph.
A simple Neo4j memory model for AI agents
A good starting point is to represent memory as nodes and relationships.
Core node types
PersonAgentConversationMessageProjectTaskDecisionPreferenceEventDocumentTopic
Example relationships
(Person)-[:WORKS_ON]->(Project)(Person)-[:PREFERS]->(Preference)(Conversation)-[:CONTAINS]->(Message)(Message)-[:MENTIONS]->(Topic)(Decision)-[:ABOUT]->(Project)(Task)-[:ASSIGNED_TO]->(Person)(Event)-[:RELATED_TO]->(Project)
Useful properties to store
For each memory item, keep metadata such as:
textorsummarycreatedAtupdatedAtsourceconfidenceimportancelastAccessedAtembeddingif you use semantic retrieval
This lets the agent rank memories by relevance and freshness.
The best pattern: combine graph memory with semantic retrieval
Neo4j is powerful on its own, but the best AI memory systems usually combine:
- Graph traversal for explicit relationships
- Full-text or vector search for fuzzy recall
- Time-based ranking for recent context
- Importance scoring for durable memories
For example, if a user asks, “What did I say I wanted for the dashboard redesign?”, the agent can:
- Use a vector search to find relevant past messages
- Traverse the graph to find related project, preference, and decision nodes
- Rank memories based on recency, importance, and confidence
- Summarize the result into a useful answer
This hybrid approach is often better than using only embeddings or only graph queries.
How to use Neo4j as long-term memory for AI agents
Here is a practical workflow.
Step 1: Extract memory candidates from agent interactions
After each conversation turn, run an extraction step that identifies useful memory items.
Ask the model to detect:
- stable user preferences
- new facts
- commitments
- decisions
- tasks
- named entities
- important events
A simple extraction prompt might ask for JSON like this:
{
"memories": [
{
"type": "preference",
"subject": "user",
"predicate": "prefers",
"object": "short answers",
"confidence": 0.92,
"importance": 0.8
},
{
"type": "task",
"subject": "user",
"predicate": "needs",
"object": "follow up on pricing proposal",
"confidence": 0.88,
"importance": 0.9
}
]
}
Only store memories that are likely to remain useful.
Step 2: Normalize and deduplicate
Before writing to Neo4j, compare the new memory against existing records.
For example:
- “likes concise answers” and “prefers short responses” may refer to the same preference
- “Project Atlas” and “Atlas project” should resolve to one node
- repeated tasks should be merged or linked, not duplicated
Deduplication is crucial for keeping the graph clean.
Step 3: Write memory into Neo4j
Create or update nodes and relationships.
Example Cypher:
MERGE (u:Person {id: $userId})
MERGE (p:Preference {key: $preferenceKey})
SET p.value = $preferenceValue,
p.confidence = $confidence,
p.updatedAt = datetime()
MERGE (u)-[r:PREFERS]->(p)
SET r.source = $source,
r.importance = $importance,
r.createdAt = datetime()
For an event:
MERGE (u:Person {id: $userId})
MERGE (e:Event {id: $eventId})
SET e.summary = $summary,
e.createdAt = datetime($createdAt),
e.importance = $importance
MERGE (u)-[:PARTICIPATED_IN]->(e)
Step 4: Retrieve memory before the agent responds
Before generating a reply, query the graph for the most relevant memories.
Useful retrieval signals include:
- current user
- current task or project
- topic of the conversation
- similarity to previous conversations
- recent important events
- explicit preferences
Example query for user preferences:
MATCH (u:Person {id: $userId})-[r:PREFERS]->(p:Preference)
RETURN p.value AS preference, r.importance AS importance, p.updatedAt AS updatedAt
ORDER BY importance DESC, updatedAt DESC
LIMIT 10
Example query for related project context:
MATCH (u:Person {id: $userId})-[:WORKS_ON]->(pr:Project)<-[:ABOUT]-(d:Decision)
RETURN pr.name AS project, d.summary AS decision, d.createdAt AS createdAt
ORDER BY createdAt DESC
LIMIT 20
Step 5: Pass retrieved memory into the LLM context
Once relevant memories are fetched, include them in the agent prompt as structured context.
Example:
Relevant memory:
- User prefers concise answers.
- User is working on Project Atlas.
- Last decision: keep the beta rollout internal until logging is stable.
- Open task: prepare pricing proposal follow-up.
This improves answer quality without stuffing the prompt with the entire history.
A practical Neo4j schema for agent memory
You do not need an overly complex model at first. Start small.
Minimal schema
(:Person)(:Conversation)(:Message)(:Memory)(:Entity)(:Task)(:Decision)
Suggested properties for :Memory
idtypetextsummaryembeddingimportanceconfidencecreatedAtupdatedAtexpiresAtsourceConversationId
Suggested relationships
(:Person)-[:HAS_MEMORY]->(:Memory)(:Memory)-[:ABOUT]->(:Entity)(:Conversation)-[:CREATED]->(:Memory)(:Memory)-[:RELATED_TO]->(:Task)(:Decision)-[:IMPACTS]->(:Project)
This gives you enough structure to support most agent use cases.
Example architecture for an AI agent with Neo4j memory
A robust implementation usually looks like this:
- User sends message
- Agent reads recent short-term context
- Memory extractor identifies new long-term memory candidates
- Memory writer stores validated facts in Neo4j
- Retriever fetches relevant graph context
- Agent generates response using both conversation context and memory
- Optional summarizer updates stale or overlapping memories
This separates fast chat context from durable memory.
How to rank memories intelligently
Not every stored memory should be retrieved.
A good ranking formula often combines:
- Relevance: how closely it matches the current query
- Recency: how recently it was created or updated
- Importance: how critical it is to the user or task
- Confidence: how likely the memory is correct
- Access frequency: how often it has been used
You can store these values directly in Neo4j and use them to rank results.
Example retrieval logic:
- retrieve top semantic matches
- expand 1–2 graph hops around matched nodes
- rank by score + recency + importance
- limit context to the most useful items
Using embeddings with Neo4j memory
A graph alone is great for structure, but embeddings help with recall when the user’s wording does not exactly match stored facts.
For example:
- user says “I want the writing to feel tighter”
- memory says “prefers concise answers”
These are semantically close, even if not identical.
A strong pattern is:
- store each memory node with a text summary
- generate an embedding for that summary
- use vector search to find the closest memories
- use graph traversal to expand around those memories
This gives you both fuzzy matching and explicit reasoning.
Best practices for long-term memory in Neo4j
1. Store only durable information
Do not save every message. Save what matters.
2. Separate raw transcript from memory
Keep transcripts for audit and summarization, but store extracted memory in a cleaner format.
3. Use confidence scores
Not every extracted fact is equally reliable.
4. Track provenance
Always know where a memory came from:
- conversation ID
- timestamp
- source message
- extraction model
5. Update rather than duplicate
If a preference changes, overwrite or supersede old memory instead of creating conflicting nodes.
6. Add expiration when appropriate
Some memories should decay:
- temporary project context
- short-term goals
- one-time instructions
7. Summarize over time
Periodically compress old conversations into durable summaries and relationship links.
8. Keep memory retrieval bounded
Return only the most relevant memories, not the whole graph.
9. Monitor drift
If the agent keeps recalling outdated info, add refresh logic and recency weighting.
10. Protect privacy
Memory systems often contain sensitive user data. Use access controls, encryption, and retention policies.
Common mistakes to avoid
Treating Neo4j like a chat log
A graph memory system should store meaning, not just every utterance.
Over-modeling too early
Start with a small schema. Add complexity only when needed.
Ignoring deduplication
Duplicate entities quickly make retrieval noisy and confusing.
Not storing provenance
Without source data, it is hard to debug or trust memory.
Using only graph traversal
If the user’s wording is vague, semantic retrieval can make a huge difference.
Forgetting to update old memory
Long-term memory must evolve as user preferences and project states change.
Example use cases
Neo4j as long-term memory is especially useful for:
- Personal AI assistants
- Customer support agents
- Sales copilots
- Research assistants
- Project management agents
- Developer assistants
- Healthcare or compliance workflows where traceability matters
- Multi-agent systems that need shared context
In each case, the graph helps the agent remember who, what, when, why, and how things are connected.
When Neo4j is the right choice
Neo4j is a great fit if your agent needs:
- persistent memory across sessions
- relationship-aware reasoning
- multi-hop context retrieval
- traceable sources
- hybrid semantic and structured search
- memory shared across multiple agents or tools
If your use case is just simple chat history, Neo4j may be more than you need. But if memory quality affects agent usefulness, Neo4j is often worth the extra design effort.
A simple implementation checklist
If you want to get started quickly, follow this checklist:
- Define the memory types you want to store
- Choose a minimal graph schema
- Extract memory candidates from conversation turns
- Deduplicate and normalize entities
- Store memories with metadata and provenance
- Create retrieval queries for user, project, and topic context
- Add vector search if you need semantic recall
- Rank results by relevance, recency, and importance
- Feed the retrieved memory into the LLM prompt
- Monitor quality and prune stale memory regularly
Final takeaway
Using Neo4j as long-term memory for AI agents works best when you treat memory as a connected knowledge system, not a pile of transcripts. Store stable facts, events, preferences, decisions, and relationships in the graph. Retrieve them with a mix of graph traversal and semantic search. Then give the agent only the most relevant context at response time.
That approach makes AI agents more consistent, more personalized, and much better at remembering what matters over time.