A single-file Python command-line tool that finds communities in a graph file, builds a hybrid keyword-plus-embedding search over your markdown notes, flags near-duplicate notes, and writes an HTML memory map.
Open-Source Tools · How-To · Dev & ops tools
How to use memory-map-optimizer: cluster a knowledge graph and search and dedupe notes
Revised
· v1.0.0 · what changed
Code: github.com/herrrickshaw/memory-map-optimizer
Watch the walkthrough
Watch on YouTube: youtu.be/olyhzUrn_0c
Why it is useful
- Who benefits: people who keep a large pile of markdown notes or an AI-assistant memory folder and a graph of how things link, and want structure and duplicates found automatically.
- What it replaces: counting and merging near-identical notes by hand, and a graph tool whose community detection returned zero.
- Evidence from the run: on a synthetic 60-node graph with three planted groups, the cluster command found exactly three communities of 20 nodes each in 0.14 seconds; all 14 bundled checks passed.
- The embedding, search and dedup steps need a downloaded model of about 1.5 GB and were not run here (see limits).
What it is for
The tool has five commands. cluster runs Leiden community detection on a graph JSON with nodes and edges. embed indexes markdown files with a sentence-embedding model. search combines keyword (BM25) and embedding ranks, with an optional reranker. dedup groups near-duplicate files by cosine similarity. report writes an HTML overview.
It was written for one person's Claude Code memory setup, so default paths point at ~/.graphify and ~/.claude. Pass your own paths to use it elsewhere.
Who it is for
- People maintaining a large markdown notes or memory folder
- Developers who want a small, readable example of Leiden clustering and hybrid search
- Non-programmers who want an AI assistant to run it on their notes
- Notes you cannot send to a model download or process locally; check the model licence first.
- Trusting dedup output blindly. The README says to sanity-check search results on a small subset first.
- A drop-in replacement for graphify or qmd. It only reads and writes similar files.
What you need
| Requirement | Why | How to get it |
|---|---|---|
| Python 3 and a virtualenv | macOS Homebrew Python blocks global pip installs | python3 -m venv .venv && source .venv/bin/activate |
| python-igraph, leidenalg | the cluster command | pip install -r requirements.txt |
| rank-bm25 | keyword half of search | in requirements.txt |
| sentence-transformers (and PyTorch) | embed, search, dedup | in requirements.txt; large install plus a model download of about 1.5 GB for the default Qwen3-Embedding-0.6B |
| A graph JSON | input for cluster | your own, with nodes, edges, source, target, id keys (overridable by flags) |
Get the code and an AI assistant
You do not have to be a programmer. Get the repository, give it to an AI assistant, and ask in plain language. Any of these routes works:
| Tool | What you need | Best for |
|---|---|---|
| GitHub | Free account to fork or star; git to clone, or the green Code button, then Download ZIP, or open in Codespaces | Getting the code and keeping up with updates |
| Claude Code | Claude subscription or API key; run claude inside the cloned folder | Letting the AI read and run the whole repo |
| Gemini CLI | Google account; run gemini inside the cloned folder | The same hands-on workflow with Gemini |
| Claude.ai, Gemini or ChatGPT in the browser | A chat account; upload README.md and the files you care about (or paste the output of git ls-files) | Understanding the project and asking questions without installing anything |
| Other tools (Copilot Chat, Cursor, Codex CLI) | Open the cloned folder in the tool and point it at README.md first | Editing and extending the code |
git clone https://github.com/herrrickshaw/memory-map-optimizer.git
cd memory-map-optimizer
claude # or: gemini
Install
- Get the code
git clone https://github.com/herrrickshaw/memory-map-optimizer.git cd memory-map-optimizer - Create an environment and install
python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt
Quick start: commands and what you should see
Run the bundled checks
python test_memory_map_optimizer.py
A line per check ending in ALL TESTS PASSED.
Cluster a graph file
python memory_map_optimizer.py cluster --graph my_graph.json --write-back --out clusters.json
A line such as '60 nodes, 213 edges -> 3 communities (modularity 0.6082)' and a size per cluster.
Index, search and dedupe notes (needs the model download)
python memory_map_optimizer.py embed --memory-dir "./notes/**"
python memory_map_optimizer.py search "token routing" --rerank
python memory_map_optimizer.py dedup --threshold 0.85
An index file, ranked results, and groups of near-duplicate files.
Sample outputs
Real output from a run on the date shown in the sources line; trimmed to fit.
Bundled checks
python test_memory_map_optimizer.py
test_leiden_finds_real_communities OK (4 communities found, planted 4, modularity 0.721)
test_hybrid_search_ranks_relevant_doc_first OK
test_find_duplicate_groups_merges_transitively OK
test_report_runs_without_index_or_clusters OK
ALL TESTS PASSED
Trimmed to four of 14 lines. The search and dedup checks use hand-built vectors, not a real model.
Cluster command on a synthetic memory map
python memory_map_optimizer.py cluster --graph g.json --write-back --out clusters.json
60 nodes, 213 edges -> 3 communities (modularity 0.6082)
cluster 2: 20 nodes
cluster 0: 20 nodes
cluster 1: 20 nodes
wrote clusters.json
wrote community assignments back into g.json
The graph was random: 60 nodes in three groups of 20, dense inside each group (35 percent of node pairs linked) and sparse between them (1 percent). The tool recovered the planted groups exactly.
What the output file looks like
{ "num_nodes": 60, "num_edges": 213, "num_clusters": 3, "modularity": 0.6082,
"cluster_sizes": {...}, "node_to_cluster": {"n0": 2, "n1": 2, ...} }
Each node also receives a 'community' field in the graph JSON when --write-back is set.
embed, search, dedup, report with a real model
Not run. These need sentence-transformers plus a roughly 1.5 GB model download.
The README itself says embed was never confirmed end to end in its build sandbox.
Ways to use it
| Method | How it works |
|---|---|
| Cluster any graph | Any JSON with nodes and edges works; override key names with --nodes-key, --edges-key and the others. |
| Notes search | embed then search for hybrid retrieval over markdown folders. |
| Tidy-up | dedup --sweep START:STOP:STEP to see how many groups appear at different thresholds. |
| Ask an AI assistant | Let the assistant run the commands on a small copy of your notes first. |
Sample prompts for your AI assistant
Copy, paste and edit the parts in [brackets].
- Claude: Read memory_map_optimizer.py and explain how the hybrid BM25 plus embedding ranking is combined.
- Gemini: Build a small graph JSON of 30 nodes in three groups and run the cluster command on it, then explain modularity.
- ChatGPT: Here are my cluster sizes from clusters.json. Which clusters look too big to be useful and why?
- GitHub (Copilot Chat): Add a flag to cluster that prints the three highest-degree nodes in each community, with a test.
- Claude: Run dedup with a sweep on a copy of my notes folder and propose which files to merge, without deleting anything.
Limits and honest caveats
- Only the cluster command and the bundled checks were run live. embed, search, rerank, dedup and the real report need a large model download and were not run.
- The README states the build sandbox could not download the model, so embed has never been confirmed end to end by the author; the logic of search and dedup is tested with hand-built vectors.
- Defaults point at the author's own ~/.graphify and ~/.claude paths; supply your own.
- --write-back edits your graph JSON in place. Work on a copy.
- Leiden results depend on a seed and resolution; different settings give different community counts.
- Notes are processed by a local model; check licences of the Qwen and BGE models you choose.
Sources: Ran test_memory_map_optimizer.py and the cluster command on a synthetic graph from a fresh clone of github.com/herrrickshaw/memory-map-optimizer (commit aff6b31) in a throwaway virtualenv on 19 October 2026, installing python-igraph, leidenalg, rank-bm25 and numpy only. Embedding commands not run.
- v1.0.0 — 23 October 2026 — first published.
About this article: Researched, written and edited by Umashankar Triplicane Dwarakanathan, with AI research assistance; every figure is meant to trace to the primary source cited. See the Editorial Policy for how sourcing, AI use and corrections work.