Getting Started
This guide walks you through installing neo4j-agent-memory, connecting to Neo4j, and performing your first memory operations.
Prerequisites
Before you begin, ensure you have:
-
Python 3.10+ installed
-
Neo4j 5.20+ running (local or cloud)
-
OpenAI API key (optional, for embeddings and LLM extraction)
Installation
Installation with Extras
Choose the extras that match your needs:
| Extra | Description | Command |
|---|---|---|
|
OpenAI embeddings and LLM extraction |
|
|
spaCy NER extraction (local) |
|
|
GLiNER zero-shot NER (local) |
|
|
Full extraction pipeline (spaCy + GLiNER) |
|
|
Local embeddings with Sentence Transformers |
|
|
Command-line interface for extraction and schemas |
|
|
OpenTelemetry tracing for observability |
|
|
Opik LLM-focused observability |
|
|
Google Vertex AI embeddings |
|
|
Amazon Bedrock embeddings (Titan, Cohere) |
|
|
AWS cloud provider bundle (Bedrock) |
|
|
AWS Strands Agents SDK integration |
|
|
All features including local models |
|
Setting Up Neo4j
Option 1: Docker (Recommended for Development)
docker run -d \
--name neo4j \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/password \
-e NEO4J_PLUGINS='["apoc"]' \
neo4j:5.26-community
Option 2: Neo4j Desktop
Download Neo4j Desktop and create a new database.
Option 3: Neo4j AuraDB (Cloud)
Create a free instance at Neo4j AuraDB.
Basic Usage
Connecting to Neo4j
import asyncio
from neo4j_agent_memory import MemoryClient, MemorySettings
from pydantic import SecretStr
async def main():
# Configure connection
settings = MemorySettings(
neo4j={
"uri": "bolt://localhost:7687",
"username": "neo4j",
"password": SecretStr("password"),
}
)
# Connect using async context manager
async with MemoryClient(settings) as memory:
print(f"Connected: {memory.is_connected}")
# Your memory operations here
stats = await memory.get_stats()
print(f"Memory stats: {stats}")
asyncio.run(main())
Storing Conversation Messages
async with MemoryClient(settings) as memory:
# Add a user message
message = await memory.short_term.add_message(
session_id="session-123",
role="user",
content="What's the best pizza place in New York?"
)
print(f"Stored message: {message.id}")
# Add an assistant response
await memory.short_term.add_message(
session_id="session-123",
role="assistant",
content="I recommend Joe's Pizza in Greenwich Village!"
)
# Retrieve conversation history
messages = await memory.short_term.get_messages(
session_id="session-123",
limit=10
)
for msg in messages:
print(f"{msg.role}: {msg.content}")
Working with Entities
Entities are automatically extracted from messages when extract_entities=True (default):
async with MemoryClient(settings) as memory:
# This message will have entities extracted automatically
await memory.short_term.add_message(
session_id="session-123",
role="user",
content="I work at Acme Corp in San Francisco with John Smith",
extract_entities=True # Default is True
)
# Search for entities
entities = await memory.long_term.search_entities(
query="companies in San Francisco",
limit=5
)
for entity in entities:
print(f"{entity.name} ({entity.type}): {entity.confidence}")
Storing Preferences
async with MemoryClient(settings) as memory:
# Add a user preference
pref = await memory.long_term.add_preference(
category="food",
preference="Prefers vegetarian options",
importance=0.8,
metadata={"source": "user_profile"}
)
# Search preferences
prefs = await memory.long_term.search_preferences(
query="dietary restrictions",
limit=5
)
Getting Context for LLM Prompts
async with MemoryClient(settings) as memory:
# Get combined context from all memory types
context = await memory.get_context(
query="restaurant recommendation",
session_id="session-123",
include_short_term=True, # Recent conversation
include_long_term=True, # Facts and preferences
include_reasoning=True, # Past reasoning patterns
max_items=10
)
# Use context in your LLM prompt
prompt = f"""
Based on the following context:
{context}
Please recommend a restaurant.
"""
Geocoding Locations (Optional)
Enable geocoding to automatically add coordinates to LOCATION entities, enabling geospatial queries:
from neo4j_agent_memory import (
MemoryClient,
MemorySettings,
GeocodingConfig,
GeocodingProvider,
)
settings = MemorySettings(
geocoding=GeocodingConfig(
enabled=True,
provider=GeocodingProvider.NOMINATIM, # Free, or GOOGLE for higher accuracy
)
)
async with MemoryClient(settings) as memory:
# LOCATION entities are automatically geocoded
await memory.short_term.add_message(
session_id="session-123",
role="user",
content="I'm visiting the Eiffel Tower in Paris",
)
# Find locations near a point
nearby = await memory.long_term.search_locations_near(
latitude=48.8584,
longitude=2.2945,
radius_km=5.0,
)
See Geocoding Configuration for more details.
Configuration with Environment Variables
You can configure neo4j-agent-memory using environment variables with the NAM_ prefix:
# Neo4j connection
export NAM_NEO4J__URI=bolt://localhost:7687
export NAM_NEO4J__USERNAME=neo4j
export NAM_NEO4J__PASSWORD=your-password
# OpenAI configuration
export NAM_EMBEDDING__PROVIDER=openai
export NAM_EMBEDDING__MODEL=text-embedding-3-small
export OPENAI_API_KEY=sk-...
# Extraction configuration
export NAM_EXTRACTION__EXTRACTOR_TYPE=pipeline
export NAM_EXTRACTION__ENABLE_SPACY=true
export NAM_EXTRACTION__ENABLE_GLINER=true
export NAM_EXTRACTION__ENABLE_LLM_FALLBACK=true
Then create the client without explicit configuration:
from neo4j_agent_memory import MemoryClient, MemorySettings
# Settings loaded from environment variables
settings = MemorySettings()
async with MemoryClient(settings) as memory:
# Your memory operations here
pass
Error Handling
from neo4j_agent_memory import (
MemoryClient,
MemorySettings,
ConnectionError,
NotConnectedError,
ExtractionError,
)
try:
async with MemoryClient(settings) as memory:
await memory.short_term.add_message(...)
except ConnectionError as e:
print(f"Failed to connect to Neo4j: {e}")
except ExtractionError as e:
print(f"Entity extraction failed: {e}")
except NotConnectedError as e:
print(f"Client not connected: {e}")