bradagi/graphmemory/graphmemory
Claude Code and agent skill by bradagi/graphmemory
- community
Checking that the SKILL.md file is still in the repository.
Build and query embedded GraphRAG knowledge graphs with DuckDB-backed vector, full-text, and hybrid search. Use when the user wants to store entities and relations, run RAG over a graph, extract knowledge graphs from text with DSPy, run graph algorithms (PageRank, centrality, components), merge/upsert nodes and edges, fuzzy-dedupe an existing graph, or visualize interactively in a browser. Trigger phrases include "knowledge graph", "GraphRAG", "graph database", "hybrid search", "extract entities and relations", "DuckDB graph", "embedded graph store", "dedupe graph nodes".
Install
npx vskill@latest install bradagi/graphmemory/graphmemorySKILL.md
GraphMemory
Embedded GraphRAG database built on DuckDB. Single Python package — no server, no external services. Ships vector (HNSW), full-text (BM25), hybrid search, fluent query builder, multi-hop traversal, fuzzy dedup, DSPy extraction, NetworkX algorithms, and a zero-dep D3.js visualizer.
When to reach for this
- Knowledge graph with semantic search (not just a vector DB, not just a graph DB).
- RAG where graph traversal is part of retrieval.
- Extract entities/relations from text and store them durably with dedup.
- Prototyping — file-backed or in-memory graph without Neo4j/Postgres/pgvector.
Do not use when: user already has Neo4j/Neptune/ArangoDB, or scale is hundreds of millions of nodes — GraphMemory is DuckDB-embedded, single-writer.
Install
Decision table
| User intent | Method | |
|---|---|---|
| Insert one node | graph.insert_node(node) | |
| Bulk insert | graph.bulk_insert_nodes(nodes) | |
| Insert-or-update by property | graph.merge_node(node, match_keys=["name"]) | |
| Fuzzy insert-or-update | graph.merge_node(node, match_keys=["name"], similarity_threshold=0.9) | |
Dedupe edges on (src, tgt, relation) | graph.merge_edge(edge) | |
| Clean up existing duplicates | graph.resolve_duplicates(match_keys=["name"], similarity_threshold=0.9) | |
| Pure vector kNN | graph.nearest_nodes(vector, limit) | |
| Pure BM25 text | graph.search_nodes(query, limit) | |
| Combined text + vector | graph.hybrid_search(query, query_vector, text_weight, vector_weight) | |
| Lookup by property | graph.nodes_by_attribute("name", "Alice") | |
| Direct neighbors | graph.connected_nodes(node_id) | |
| Multi-hop traversal | graph.query().traverse(source_id=id, depth=2).execute() | |
| Filtered query | graph.query().match(type="Person").where(role="eng").execute() | |
| GraphRAG context assembly | graph.retrieve(query, query_vector, max_hops, max_tokens) | |
| End-to-end Q&A | graph.ask(query, query_vector, llm_callable=fn) | |
| Extract + store from text | extract_and_merge(graph, text, match_keys=["name"]) | |
| Extract in parallel across chunks | extract_and_merge_parallel(graph, chunks, max_workers=8) | |
| PageRank / centrality | pagerank(graph), betweenness_centrality(graph) | |
| Atomic block | with graph.transaction(): ... | |
| Browser visualization | graph.visualize() |
Canonical snippets
Init
Insert + merge
Hybrid search
GraphRAG
Pass llm_callable=None to get retrieval-only output — useful to inspect the context before wiring an LLM.
Query builder
DSPy extraction
Transactions
Advanced patterns
Two-pass dedup (idiomatic)
Extract with a loose threshold, then clean up with a tighter one. This is the pattern in examples/test_ingest.py.
resolve_duplicates picks the first-seen node as survivor, reassigns all incoming/outgoing edges to it, and deletes the rest. Self-loops from the reassignment are dropped.
Custom chunking + sequential linking
Pattern from examples/lexical_graph.py:
Inspect before asking
Gotchas
- `vector_length` and `distance_metric` are locked at init. Swapping embedding models means a new database. Valid metrics:
"l2","cosine","inner_product". - Missing vectors are silently zero-filled in
insert_node—bulk_insert_nodesskips nodes whose vectors don't matchvector_lengthand logs a warning. Validate upstream if correctness matters. - HNSW is auto-built on init (
auto_index=True). Tune viahnsw_ef_construction,hnsw_ef_search,hnsw_m. Callgraph.compact_index()after heavy deletes to reclaim space (also called automatically bydelete_node). - FTS index is lazy — first
search_nodes/hybrid_searchcall after writes rebuilds it. Expect first-search latency. Force a rebuild withgraph.reindex()if you want it warm before traffic. - Edge dedup key is `(source_id, target_id, relation)`. Relations are normalized (lowercased, underscored) before comparison —
"Reports To"and"reports_to"collide. Edge properties are NOT part of the key. - `delete_node` cascades edges in both directions (as source AND as target). No orphan-edge safety net.
- `merge_node` strategies —
UPDATEshallow-merges dicts (incoming wins on collision),REPLACEoverwrites wholesale,KEEPonly inserts if new. Pick intentionally. - `similarity_threshold=1.0` is exact match (the default). Lower it to enable Jaro-Winkler fuzzy matching on string properties. Non-string properties always use JSON equality.
- `match_type=True` (default) requires same `type` for merge. Set
Falseto merge across types — rarely what you want. - `resolve_duplicates` is O(n²)-ish in fuzzy mode. For large graphs, narrow with
match_typeand a tightvector_thresholdfirst. - `extraction` and `algorithms` are optional extras. Wrap imports in try/except or check
pip showbefore recommending code that depends on them. - Single-writer DuckDB. Connection pooling and
@with_retry(exponential backoff on transient IO errors) are built in, but don't open the same file from multiple processes for concurrent writes. - `cursor()` returns independent cursors for concurrent reads; the main connection is RLock-guarded for writes.
- `ask()` with `llm_callable=None` returns retrieval only — no generation. Always use this first to validate context before paying for LLM calls.
Data models
| Model | Key fields | ||
|---|---|---|---|
Node | id: UUID, `type: str \ | None, properties: dict, vector: list[float]` | |
Edge | id, source_id, target_id, relation: str, `weight: float \ | None` | |
SearchResult | node, score (higher = better for both BM25 and hybrid) | ||
NearestNode | node, distance (lower = closer) | ||
TraversalResult | node, depth, path: list[UUID] | ||
RetrievalContext | node, relationships: list[dict], hop_distance: int | ||
RetrievalResult | query, contexts, context_text, token_estimate, seed_node_count, total_node_count | ||
MergeResult | node, created: bool (True = inserted, False = updated) | ||
EdgeMergeResult | edge, created: bool | ||
DuplicateCluster | survivor: Node, merged: list[Node] |
All models are Pydantic. IDs auto-generate as UUIDs.
Examples in the repo
examples/openai_example.py— OpenAI embeddings, similarity search, attribute lookupexamples/lexical_graph.py— chunked Wikipedia text with SentenceTransformer, sequentialfollowed_byedgesexamples/dspy_example_typed_pred.py— DSPy typed-predictor extractionexamples/test_ingest.py— parallel extraction (50 workers, 0.88 threshold) + post-passresolve_duplicatesat 0.90
Read examples/test_ingest.py before building a real ingest pipeline — it's the template.
Testing
296 tests cover the public API. Run them when modifying the library.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingSKILL.md
Popularity
- Repository stars
- 149
- Repository forks
- 15
- 7-day trend score
- 25
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 15 May 2026, 5 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/bradagi/graphmemory/graphmemory)