GraphMemory: Building Deep Knowledge Graphs with DuckDB
Learn how to build and query embedded GraphRAG knowledge graphs with GraphMemory and DuckDB. Hybrid search, fuzzy deduping, and easy extraction.
Why GraphMemory is the Missing Piece for RAG
Standard Retrieval-Augmented Generation (RAG) often suffers from a lack of context. If you only use vector search, you are retrieving isolated snippets of text that happen to share semantic similarity. But real-world data is connected. If you want your AI to understand that 'Alice' works for 'Company B' which is a subsidiary of 'Enterprise C,' simple flat vector search isn't enough. You need a graph.
Enter graphmemory. Built by bradAGI, this skill provides an embedded GraphRAG database powered by DuckDB. It allows you to store entities and relations, run multi-hop traversals, and perform hybrid searches—all without the overhead of maintaining a standalone Neo4j or Neptune instance.
What It Does
GraphMemory is a single Python package that turns DuckDB into a high-performance graph store. It ships with built-in HNSW vector search, BM25 full-text search, and a fluent query builder. Key features include:
- Hybrid Search: Combine vector similarity with keyword relevance to find exactly what you need.
- DSPy Extraction: Automatically extract entities and relations from raw text and merge them into the graph.
- Fuzzy Deduplication: Resolve duplicate nodes based on property similarity, ensuring your graph stays clean.
- Graph Algorithms: Run PageRank, centrality, and community detection using NetworkX integrations.
- Interactive Visualization: Use the zero-dependency D3.js visualizer to inspect your graph directly in the browser.
When to Use GraphMemory
You should reach for graphmemory when your RAG application requires more than just similarity scores. It is ideal for:
- Semantic Knowledge Bases: Storing complex relationships where traversal is part of the retrieval process.
- Prototyping: You need a file-backed or in-memory graph database without setting up external services.
- Knowledge Extraction: Using LLMs to build structured graphs from unstructured documents using the
extractionmodule.
Do not use it if you are operating at the scale of hundreds of millions of nodes or if your infrastructure already relies on a managed graph service like Neo4j or ArangoDB.
How to Install
Installation is modular. You can install the base package or include extras for extraction and specialized algorithms.
lovable add graphmemory
# Or via pip for specific features
pip install graphmemory[extraction] # For DSPy extraction
pip install graphmemory[algorithms] # For NetworkX support
Getting Started with GraphMemory
Initializing a persistent graph database is straightforward. You define your vector length and distance metric at the start.
from graphmemory import GraphMemory, Node, Edge
# Initialize a file-backed graph
graph = GraphMemory(
database="knowledge_base.db",
vector_length=1536,
distance_metric="cosine",
auto_index=True
)
# Adding entities
alice = Node(type="Person", properties={"name": "Alice"}, vector=[...])
bob = Node(type="Person", properties={"name": "Bob"}, vector=[...])
graph.insert_node(alice)
graph.insert_node(bob)
# Defining relationships
graph.insert_edge(Edge(source_id=alice.id, target_id=bob.id, relation="colleague"))
Hybrid Search and GraphRAG
The real power comes from combining graph traversal with search. Instead of just asking for 'nodes similar to this vector,' you can assemble a full context window based on graph hops.
# Perform a hybrid search for relevant entities
results = graph.hybrid_search(
query="Who does Alice work with?",
query_vector=[...],
text_weight=0.5,
vector_weight=0.5
)
# Retrieve multi-hop context for a RAG prompt
context = graph.retrieve(
query="Alice's network",
query_vector=[...],
max_hops=2,
max_tokens=2000
)
Decision Table for Common Operations
| If you want to... | Use this method... |
|---|---|
| Prevent duplicate nodes | graph.merge_node(node, match_keys=["name"]) |
| Deep cleaning of data | graph.resolve_duplicates(similarity_threshold=0.9) |
| Multi-hop traversal | graph.query().traverse(source_id=id, depth=2).execute() |
| End-to-end Q&A | graph.ask(query, query_vector, llm_callable=my_llm) |
| Visualise in Browser | graph.visualize() |
Expert Developer Tips
- Use Transactions: Wrap bulk updates in
with graph.transaction():to ensure atomicity and significant performance gains during ingestion. - Fuzzy Merging: When extracting entities from clinical or technical text, set a
similarity_thresholdinmerge_nodeto handle minor spelling variations automatically. - HNSW Tuning: If search speed is a bottleneck, adjust
hnsw_ef_searchduring initialization. Higher values increase accuracy; lower values increase speed.
GraphMemory provides the structure that pure vector databases lack, giving your AI agents a logical map of the world to navigate.
Learn more and see the full source at /skill/graphmemory.
Related posts
- May 20, 2026Best Claude Skills 2026: 15 Skills Worth Installing Today
A curated list of the 15 best Claude Skills in 2026, grouped by use case: foundational UI, backend, AI agents, devops, and content. Battle-tested and well-described.
- May 20, 2026How to Create a Claude Skill: A Step-by-Step Tutorial (2026)
Build your first Claude Skill in 10 minutes. Step-by-step tutorial covering SKILL.md, templates, scripts, and installing in Claude Desktop or Lovable.
- May 20, 2026Claude Skills vs MCP: Which One Should You Use in 2026?
Claude Skills bundle knowledge and procedures, MCP connects Claude to live systems. A clear, plain-English guide to picking the right one — with side-by-side comparison and real examples.