Skip to content

Instantly share code, notes, and snippets.

@karpathy
Created April 4, 2026 16:25
Show Gist options
  • Select an option

  • Save karpathy/442a6bf555914893e9891c11519de94f to your computer and use it in GitHub Desktop.

Select an option

Save karpathy/442a6bf555914893e9891c11519de94f to your computer and use it in GitHub Desktop.
llm-wiki

LLM Wiki

A pattern for building personal knowledge bases using LLMs.

This is an idea file, it is designed to be copy pasted to your own LLM Agent (e.g. OpenAI Codex, Claude Code, OpenCode / Pi, or etc.). Its goal is to communicate the high level idea, but your agent will build out the specifics in collaboration with you.

The core idea

Most people's experience with LLMs and documents looks like RAG: you upload a collection of files, the LLM retrieves relevant chunks at query time, and generates an answer. This works, but the LLM is rediscovering knowledge from scratch on every question. There's no accumulation. Ask a subtle question that requires synthesizing five documents, and the LLM has to find and piece together the relevant fragments every time. Nothing is built up. NotebookLM, ChatGPT file uploads, and most RAG systems work this way.

The idea here is different. Instead of just retrieving from raw documents at query time, the LLM incrementally builds and maintains a persistent wiki — a structured, interlinked collection of markdown files that sits between you and the raw sources. When you add a new source, the LLM doesn't just index it for later retrieval. It reads it, extracts the key information, and integrates it into the existing wiki — updating entity pages, revising topic summaries, noting where new data contradicts old claims, strengthening or challenging the evolving synthesis. The knowledge is compiled once and then kept current, not re-derived on every query.

This is the key difference: the wiki is a persistent, compounding artifact. The cross-references are already there. The contradictions have already been flagged. The synthesis already reflects everything you've read. The wiki keeps getting richer with every source you add and every question you ask.

You never (or rarely) write the wiki yourself — the LLM writes and maintains all of it. You're in charge of sourcing, exploration, and asking the right questions. The LLM does all the grunt work — the summarizing, cross-referencing, filing, and bookkeeping that makes a knowledge base actually useful over time. In practice, I have the LLM agent open on one side and Obsidian open on the other. The LLM makes edits based on our conversation, and I browse the results in real time — following links, checking the graph view, reading the updated pages. Obsidian is the IDE; the LLM is the programmer; the wiki is the codebase.

This can apply to a lot of different contexts. A few examples:

  • Personal: tracking your own goals, health, psychology, self-improvement — filing journal entries, articles, podcast notes, and building up a structured picture of yourself over time.
  • Research: going deep on a topic over weeks or months — reading papers, articles, reports, and incrementally building a comprehensive wiki with an evolving thesis.
  • Reading a book: filing each chapter as you go, building out pages for characters, themes, plot threads, and how they connect. By the end you have a rich companion wiki. Think of fan wikis like Tolkien Gateway — thousands of interlinked pages covering characters, places, events, languages, built by a community of volunteers over years. You could build something like that personally as you read, with the LLM doing all the cross-referencing and maintenance.
  • Business/team: an internal wiki maintained by LLMs, fed by Slack threads, meeting transcripts, project documents, customer calls. Possibly with humans in the loop reviewing updates. The wiki stays current because the LLM does the maintenance that no one on the team wants to do.
  • Competitive analysis, due diligence, trip planning, course notes, hobby deep-dives — anything where you're accumulating knowledge over time and want it organized rather than scattered.

Architecture

There are three layers:

Raw sources — your curated collection of source documents. Articles, papers, images, data files. These are immutable — the LLM reads from them but never modifies them. This is your source of truth.

The wiki — a directory of LLM-generated markdown files. Summaries, entity pages, concept pages, comparisons, an overview, a synthesis. The LLM owns this layer entirely. It creates pages, updates them when new sources arrive, maintains cross-references, and keeps everything consistent. You read it; the LLM writes it.

The schema — a document (e.g. CLAUDE.md for Claude Code or AGENTS.md for Codex) that tells the LLM how the wiki is structured, what the conventions are, and what workflows to follow when ingesting sources, answering questions, or maintaining the wiki. This is the key configuration file — it's what makes the LLM a disciplined wiki maintainer rather than a generic chatbot. You and the LLM co-evolve this over time as you figure out what works for your domain.

Operations

Ingest. You drop a new source into the raw collection and tell the LLM to process it. An example flow: the LLM reads the source, discusses key takeaways with you, writes a summary page in the wiki, updates the index, updates relevant entity and concept pages across the wiki, and appends an entry to the log. A single source might touch 10-15 wiki pages. Personally I prefer to ingest sources one at a time and stay involved — I read the summaries, check the updates, and guide the LLM on what to emphasize. But you could also batch-ingest many sources at once with less supervision. It's up to you to develop the workflow that fits your style and document it in the schema for future sessions.

Query. You ask questions against the wiki. The LLM searches for relevant pages, reads them, and synthesizes an answer with citations. Answers can take different forms depending on the question — a markdown page, a comparison table, a slide deck (Marp), a chart (matplotlib), a canvas. The important insight: good answers can be filed back into the wiki as new pages. A comparison you asked for, an analysis, a connection you discovered — these are valuable and shouldn't disappear into chat history. This way your explorations compound in the knowledge base just like ingested sources do.

Lint. Periodically, ask the LLM to health-check the wiki. Look for: contradictions between pages, stale claims that newer sources have superseded, orphan pages with no inbound links, important concepts mentioned but lacking their own page, missing cross-references, data gaps that could be filled with a web search. The LLM is good at suggesting new questions to investigate and new sources to look for. This keeps the wiki healthy as it grows.

Indexing and logging

Two special files help the LLM (and you) navigate the wiki as it grows. They serve different purposes:

index.md is content-oriented. It's a catalog of everything in the wiki — each page listed with a link, a one-line summary, and optionally metadata like date or source count. Organized by category (entities, concepts, sources, etc.). The LLM updates it on every ingest. When answering a query, the LLM reads the index first to find relevant pages, then drills into them. This works surprisingly well at moderate scale (~100 sources, ~hundreds of pages) and avoids the need for embedding-based RAG infrastructure.

log.md is chronological. It's an append-only record of what happened and when — ingests, queries, lint passes. A useful tip: if each entry starts with a consistent prefix (e.g. ## [2026-04-02] ingest | Article Title), the log becomes parseable with simple unix tools — grep "^## \[" log.md | tail -5 gives you the last 5 entries. The log gives you a timeline of the wiki's evolution and helps the LLM understand what's been done recently.

Optional: CLI tools

At some point you may want to build small tools that help the LLM operate on the wiki more efficiently. A search engine over the wiki pages is the most obvious one — at small scale the index file is enough, but as the wiki grows you want proper search. qmd is a good option: it's a local search engine for markdown files with hybrid BM25/vector search and LLM re-ranking, all on-device. It has both a CLI (so the LLM can shell out to it) and an MCP server (so the LLM can use it as a native tool). You could also build something simpler yourself — the LLM can help you vibe-code a naive search script as the need arises.

Tips and tricks

  • Obsidian Web Clipper is a browser extension that converts web articles to markdown. Very useful for quickly getting sources into your raw collection.
  • Download images locally. In Obsidian Settings → Files and links, set "Attachment folder path" to a fixed directory (e.g. raw/assets/). Then in Settings → Hotkeys, search for "Download" to find "Download attachments for current file" and bind it to a hotkey (e.g. Ctrl+Shift+D). After clipping an article, hit the hotkey and all images get downloaded to local disk. This is optional but useful — it lets the LLM view and reference images directly instead of relying on URLs that may break. Note that LLMs can't natively read markdown with inline images in one pass — the workaround is to have the LLM read the text first, then view some or all of the referenced images separately to gain additional context. It's a bit clunky but works well enough.
  • Obsidian's graph view is the best way to see the shape of your wiki — what's connected to what, which pages are hubs, which are orphans.
  • Marp is a markdown-based slide deck format. Obsidian has a plugin for it. Useful for generating presentations directly from wiki content.
  • Dataview is an Obsidian plugin that runs queries over page frontmatter. If your LLM adds YAML frontmatter to wiki pages (tags, dates, source counts), Dataview can generate dynamic tables and lists.
  • The wiki is just a git repo of markdown files. You get version history, branching, and collaboration for free.

Why this works

The tedious part of maintaining a knowledge base is not the reading or the thinking — it's the bookkeeping. Updating cross-references, keeping summaries current, noting when new data contradicts old claims, maintaining consistency across dozens of pages. Humans abandon wikis because the maintenance burden grows faster than the value. LLMs don't get bored, don't forget to update a cross-reference, and can touch 15 files in one pass. The wiki stays maintained because the cost of maintenance is near zero.

The human's job is to curate sources, direct the analysis, ask good questions, and think about what it all means. The LLM's job is everything else.

The idea is related in spirit to Vannevar Bush's Memex (1945) — a personal, curated knowledge store with associative trails between documents. Bush's vision was closer to this than to what the web became: private, actively curated, with the connections between documents as valuable as the documents themselves. The part he couldn't solve was who does the maintenance. The LLM handles that.

Note

This document is intentionally abstract. It describes the idea, not a specific implementation. The exact directory structure, the schema conventions, the page formats, the tooling — all of that will depend on your domain, your preferences, and your LLM of choice. Everything mentioned above is optional and modular — pick what's useful, ignore what isn't. For example: your sources might be text-only, so you don't need image handling at all. Your wiki might be small enough that the index file is all you need, no search engine required. You might not care about slide decks and just want markdown pages. You might want a completely different set of output formats. The right way to use this is to share it with your LLM agent and work together to instantiate a version that fits your needs. The document's only job is to communicate the pattern. Your LLM can figure out the rest.

@A13x3i

A13x3i commented Jun 29, 2026

Copy link
Copy Markdown

Gezz the AI Slop is storing in this one's comment section... I just wanted to point out that NotebookLM is kinda intended to be this way as well, you get sources extract whatever you need make it a source, disable sources you don't need anymore

@kibotu

kibotu commented Jun 29, 2026

Copy link
Copy Markdown

it's also important to reduce the pages to the absolute min. simplification is important in any larger code/knowledge base otherwise you end up with way too much overhead.

@theluk

theluk commented Jun 29, 2026

Copy link
Copy Markdown

@A13x3i yeah crazy isnt it? That's AEO

antways, regarding NotebookLM, I mean sure, but there is more to it. Especially the Linter is I think one real addition. I am btw using this Linter Concept almost everywhere now. So Thanks @karpathy for that concept idea.

LLMs do make mistakes no matter what you do, that's why you need an agent that iterates over the stuff and verifies that things are working. Here is an example agent I have running on one wiki

# Wiki Linter — System Prompt

You are a wiki health checker. When invoked, you run a structured lint pass
over a markdown wiki stored in a knowledge base and produce a report.

You have access to two tools primarily:
- `queryFrontmatter` — filter/sort pages by YAML frontmatter fields
- `readFile` — read individual page content

---

## Lint Checks (run in order)

### 1. Schema Integrity
Use `queryFrontmatter` to find pages missing any of the required fields:
`type`, `title`, `description`, `tags`, `timestamp`, `sources`

For any page missing a field:
- Flag it by name and note which field(s) are absent
- Repair metadata with `setFrontmatter` where the correct value is unambiguous
- Flag for user review where the value is uncertain

### 2. Staleness
Sort all pages by `timestamp` ascending. Surface the 5–10 oldest.
For each, check whether newer pages contradict or supersede their content.
Flag any that do. Propose specific updates but do not apply them unilaterally.

### 3. Coverage Gaps
Scan all `summary`, `entity`, and `concept` pages for mentions of things
(tools, people, projects, concepts) that lack their own dedicated page.
List each gap. Do not create pages — flag them for the ingestor or user.

### 4. Overview Drift
Compare the `timestamp` on `overview.md` against the newest
`summary`, `entity`, and `concept` pages.
If `overview.md` lags by more than one ingest cycle, flag it as drifted.

### 5. Orphan Check
For each page, check whether any other page links to it.
Flag any page with zero inbound links as an orphan.
Suggest which existing pages should link to it.

### 6. Duplicate Detection
Look for multiple files with the same or near-identical names or titles.
List all suspected duplicates with their file IDs.
Do NOT delete anything. Flag for user approval.

---

## Output Format

Produce a markdown report with this structure:

# Lint Report — {DATE}

## Summary
One-line overall health status: 🟢 Green / 🟡 Yellow / 🔴 Red

## 1. Schema Integrity
## 2. Staleness
## 3. Coverage Gaps
## 4. Overview Drift
## 5. Orphan Check
## 6. Duplicate Detection

## Overall Health
Table or bullet list of all checks with pass/fail/warn status.

## Next Steps
Numbered list of actions — note which require user approval before execution.

---

## Hard Rules

- **Never delete files unilaterally.** Flag duplicates and orphans; act only on explicit approval.
- **Never create or edit wiki content pages.** That is the ingestor's job.
- **Do** repair frontmatter metadata (`setFrontmatter`) when the correct value is certain.
- Log the lint pass to `log.md` when done.

And I dont do it just for the Knowledge Wiki, I do it for SEO (interlinking checks, quality checks) and more. It's really one helpful agent that can be used in general on data structures that are somehow related.

@william-Johnason

Copy link
Copy Markdown

it's also important to reduce the pages to the absolute min. simplification is important in any larger code/knowledge base otherwise you end up with way too much overhead.

@kibotu agreed, simplification is the harder problem. One thing that helps is building compression into the ingestion step itself. In Synthadoc, raw sources get compiled into concept pages, so 100 ingested documents might synthesize down to a dozen wiki pages, topics that appear across multiple sources merge rather than accumulate. The active knowledge surface stays small by design, not by discipline.

@william-Johnason

Copy link
Copy Markdown

Really interesting approach. I think one challenge that will show up as these systems grow is keeping synthesized knowledge reliable over time. Retrieval is only part of the problem—making sure older summaries stay accurate without constantly rebuilding everything seems much harder.

Keeping the raw sources immutable feels like the right foundation. I also wonder if adding a simple confidence or verification status to wiki pages could help highlight which pages are well-supported and which ones may need another review after new sources are added.

@devmubs the confidence/verification state idea is exactly what we should land on too - each page carries a lifecycle status, so when new sources arrive, the system knows which pages to re-examine rather than rebuilding everything.

@dumanyu666-byte

Copy link
Copy Markdown

good thanks

@Onevirtual

Copy link
Copy Markdown

Thanks for the pattern Mr. Karpathy: I've noted added few things that were worth my time.

For the metadata, I am using breadcrumds which enables me to replicate somehow standard .owl relationships from inference engines. It's useful when you are trying to associate pages, oppose pages, label pages or whatever relationships you want to bring in the classification.

For the document structure:
I use a notepad blended source for the LLM to write in, those are where the main questions from the dialogical interaction takes places.

Then I have a personal notes which I use in order to put my thoughts into, it enables me to enhance my critical thinking and derives from what the llm is generating from my own curated sources. Whenever I use a webfetch tool I also make clear from which source the generation took from.

The skill for this has this purpose : - One is a prompt crawler in which I ask questions within the personal note component in the page area.Using ^[put prompt here], when I am populating the wiki with my thoughts, then I add a footnote next to it ^[put prompt here][^1], that way, I can reread my own thoughts and contrast it with the LLM Response, which is interesting for me because I am always able to tell what was generated versus what I was writing.

And Last I have a go further section which is another prompt then analyses the "idées-forces" between my notes and the llm-generated ones, it gives me direction. It was especially insightful during my readings and commenting of Mumford's Art and Techniques conferences and a Quine's Article.

What I found the most interesting in the pattern is two things :

  • Focusing on the graph and the correct linking of the ideas, I don't trust the LLMs enough to build alone a categorization that is worth and I like to reason on the semantics of clusterization with it.
  • Secondly, it gives me a very good feeling of abstraction ascending. When I am creating an instance, I generally tweak the concept a few times before it becomes a category. The moment where a mono page concept becomes a category of its own is very satisfying and aligning with how inference for human works; derivating rules and organisation through repeated exposures to observations.

Thank you for that, I have rediscovered a lot of books I had on my bookshelves, blending from Homere Odysseus to Philosophy of mind through agentic patterns.

@alfadur7

alfadur7 commented Jun 30, 2026

Copy link
Copy Markdown

@Motya-cobol your split — deterministic scripts for intake/validation, model only for judgment — is exactly the right instinct; it's the same division I landed on.

The piece that helped most on top of it: never let the agent read page bodies just to find what's relevant.
Give it a small CLI to check the "map" first:

  • shortest path between two pages
  • a page's neighbors and cluster
  • a local BM25 / vector search

Let it pick ~10 pages from that, and only then read those in full. The index stays a one-line-per-entry directory (a link + a one-line summary per page), with sources split into per-cluster sub-catalogs — so it's a routing file, not something to scan.

On @Mirorrn's subagent point: +1 to keeping the narrowing off the orchestrator's context. I do it with a deterministic CLI call rather than a separate agent, but same goal — and since it's just Python, it drives fine from Codex too.

Search/traversal CLI if useful → https://github.com/alfadur7/llm-wiki-newsroom/blob/main/tools/query.py

@distorx

distorx commented Jun 30, 2026

Copy link
Copy Markdown

This maps almost 1:1 to a system we have been running in production for ~6 months to manage infrastructure/ops knowledge. A few notes from actually living with the pattern at ~4000+ interlinked concepts:

  • The schema file is everything. Our CLAUDE.md is exactly the "disciplined maintainer vs. generic chatbot" config you describe — it encodes the ingest/query/lint workflows + naming conventions, and it co-evolved into the single most important file in the repo.
  • index.md at scale: the flat index works great to a few hundred pages. Past that we added hybrid search (SQLite FTS5 + on-device embeddings, reciprocal-rank-fused) rather than standing up embedding-RAG infra — same spirit as qmd. We expose it as both a CLI (agent shells out) and an MCP server (native tool). ~1ms keyword, ~350ms hybrid.
  • New page vs. edit (@alinawab): heuristic that works for us — new page when it is a distinct entity/concept you would link to from elsewhere; edit in place when it is an attribute/update of an existing one. The agent gets this right ~90% of the time once the schema enumerates the page types.
  • Team sharing (@geetansharora): the wiki is just a private git repo, auto-synced. Teammates browse in Obsidian or hit the same MCP server. Git history doubles as the log.md audit trail for free.
  • Biggest failure mode (@alinawab): drift — the agent under-updating cross-references on ingest, so pages silently go stale. The lint pass is not optional; we run it on a timer (orphan detection + contradiction flagging + stale-claim checks) and that is what keeps the graph healthy.

The "compounding artifact" framing is exactly right — after a few thousand concepts the wiki answers questions the raw sources never could, because the synthesis already happened. Thanks for writing it up so cleanly.

@despindola

Copy link
Copy Markdown

This pattern is the most important thing I have adopted this year, and thank you for sharing it as an idea rather than a repo.

One observation from outside the dev world: almost everyone I know who would benefit most from this stops at the terminal. Writers, advisors, researchers, founders. The bookkeeping that LLMs handle so well is exactly the part they want, but the setup asks for skills or interests they do not have.

I have been building a hosted version of this same idea, with no terminal or config, aimed squarely at that group. Happy to compare notes with anyone else thinking about the non-technical on-ramp. It feels like it is where most of the latent demand actually is.

@maurizio-persi

Copy link
Copy Markdown

First of all, thanks to @karpathy for introducing and describing the LLM-Wiki paradigm: a simple yet brilliant idea that, in my opinion, will revolutionize corporate document management (replacing heavy, complex knowledge bases), help students avoid superficial LLM usage, and serve as a great ally for methodical learning.

I have built a Personal LLM-Wiki prioritizing two fundamental aspects:

  1. Privacy: All components run completely offline.
  2. Efficiency: I focused on creating an executable suitable for modest hardware (with or without a GPU), making it accessible despite current market prices for graphics cards.

The core concept is straightforward: perform non-LLM-specific operations deterministically using standard Python libraries, which consume significantly fewer resources than a giant language model. It feels inefficient to waste LLM tokens on repetitive tasks that only require classic computational power.

While my initial prototype worked, the model's responses were often too generic or limited to brief definitions. To achieve the exhaustive, structured lessons I envisioned, I integrated a few key components to enrich the context:

Key Components

  • Graphify: Maps relationships between Markdown files, SQL schemas, scripts, and PDFs. It improves navigation based on structural relationships rather than just keywords, creating a navigable "map" directly accessible to the AI or via Obsidian. This drastically reduced dependency on compute while improving coherence.
  • ChromaDB: A lightweight vector database used as the pillar for semantic search and document retrieval, executing operations efficiently on the CPU.
  • NetworkX: Manages a dual data structure in memory with a lazy cache: an Undirected Graph ($G$) for generic relationships and a Directed Graph ($DiG$) focused exclusively on formative dependencies. This helps identify correlations and cite diverse sources covering the requested topic.
  • SQLite: An embedded, serverless relational database dedicated to managing the system's transactional state and audit logs.

Operational Flow

[Phase 1 (Optional): Pre-processing (Whisper)] ──> 
──> [Phase 2: Synthesis (Qwen3VL)]
──> [Phase 3: Graph Building (Graphify)]
──> [Phase 4: Indexing (ChromaDB)]
──> [Phase 5: Context Assembly]
──> [Phase 6: Inference (Qwen3.5 9B)]

Advanced features included: Semantic Query Cache, Cross-Encoder Re-Ranker, and Reciprocal Rank Fusion (RRF) for HyDE.

Additional Features

  • Localization & UI: Built a lightweight Flask web page with "on-the-fly" language switching managed via simple .lng files.
  • Secure Telegram Bot: Accessible without exposing ports or reverse proxies (restricted to authorized Telegram IDs). It includes an interactive poll after each response, allowing the user to save the text, export it as a Marp Markdown presentation, or generate an audio podcast.
  • Quiz Mode: Generates multiple-choice questions based on the wiki content with customizable difficulty, evaluating errors and explaining why a specific answer was wrong.

A Critique of the Paradigm: No New Wiki Pages Without Raw Sources

The only critique I have regarding the baseline LLM-Wiki paradigm concerns creating new wiki pages derived from LLM responses.

I don't find it useful to generate additional pages beyond those processed during the Ingest phase. Reprocessing existing concepts in different forms consumes resources and slows down the system (more pages to scan per query) without introducing genuinely new information. Since the LLM should not invent anything (avoiding hallucinations), it doesn't enrich the source base.

In my implementation, the only generated pages allowed are the Markdown files exported for Presentations (Marp syntax)-treated strictly as "output documents" for the user, rather than being re-fed into the pipeline as wiki sources.


I haven't published the repository on GitHub yet, as I am still refining the integration to make it as user-friendly as possible. I hope this architecture can serve as inspiration for anyone looking to customize or optimize their local LLM-Wiki setup!


Below is an example of an answer to the question “Explain me what Kubernetes is.”

Personal LLM-WIKI

@RightL

RightL commented Jul 1, 2026

Copy link
Copy Markdown

Love this. I think the key idea is not “chatbot over files,” but “LLM-maintained structure that compounds.” We’re building RightMemory from a very similar motivation, but focused on memory for teams of coding agents.

The core of RightMemory is ordinary Git-backed Markdown, with a small tree + graph schema. The tree gives agents readable local context through headings. The graph gives durable relationships through ids and typed edges, so facts, decisions, preferences, TODOs, and related project knowledge can point across sections and files. The memory stays inspectable as Markdown, but it is structured enough for agents to navigate precisely.

A major design point is that this is not RAG. RightMemory is not primarily a vector database or a chunk retrieval layer. The durable artifact is the maintained Markdown memory itself. Retrieval reads the current structured memory; updates change the memory; consolidation improves it over time. The system is closer to an agent-maintained knowledge graph/wiki than to “embed documents and search at query time.”

Another important part is teams of agents. RightMemory is designed so memory can survive across sessions, devices, agent clients, and collaborating agent teams. Different memory roots can share selected context through controlled shared views, so one project/person/team can expose only the relevant memory to another without dumping the whole private memory store.

We also lean heavily into the CLI direction you mention. The rightmemory CLI is the main command surface, so any command-capable coding agent can use the same memory substrate. Codex, Claude Code, and other CLI-style agents can call the same retrieve/update/status/shared-view commands instead of memory being locked into one vendor UI.

One more design choice I care a lot about: the roles are all pure agents with explicit authority boundaries. There is a retriever role for read-oriented memory lookup, an updater role for durable memory edits, a dreamer role for consolidation/restructuring, and a reviewer role for extracting useful memory from prior sessions. The main coding agent does not casually mutate memory while doing unrelated work; memory operations are delegated to the right role.

So the overlap with your LLM Wiki pattern is strong: persistent Markdown, LLM-maintained structure, compounding context, and tooling around the artifact. RightMemory’s specific bet is that coding-agent memory should be tree + graph Markdown, operated through CLI-accessible agent roles, built for teams of agents, and not reduced to a RAG pipeline.

Project: https://github.com/RightL/RightMemory
Example memory file: https://github.com/RightL/RightMemory/blob/main/MEMORY.example.md
Schema: https://github.com/RightL/RightMemory/blob/main/skills/rightmemory-schema.md

@ojuschugh1

Copy link
Copy Markdown

  ███████╗ ██████╗ ███████╗
  ██╔════╝██╔═══██╗╚══███╔╝
  ███████╗██║   ██║  ███╔╝
  ╚════██║██║▄▄ ██║ ███╔╝
  ███████║╚██████╔╝███████╗
  ╚══════╝ ╚══▀▀═╝ ╚══════╝
  

Compress LLM context to save tokens and reduce costs

Real session stats: 3,003 compressions · 178,442 tokens saved · 24.7% avg reduction · up to 92% with dedup

Featured

Crates.io npm PyPI VS Code Firefox JetBrains Discord Homebrew

Install · How It Works · Supported Tools · Changelog · Discord


sqz compresses command output before it reaches your LLM. Single Rust binary, zero config.

The real win is dedup: when the same file gets read 5 times in a session, sqz sends it once and returns a 13-token reference for every repeat.

Without sqz:                    With sqz:

File read #1:  2,000 tokens     File read #1:  ~800 tokens (compressed)
File read #2:  2,000 tokens     File read #2:  ~13 tokens  (dedup ref)
File read #3:  2,000 tokens     File read #3:  ~13 tokens  (dedup ref)
───────────────────────         ───────────────────────
Total:         6,000 tokens     Total:         ~826 tokens (86% saved)

Token Savings

24.7% average reduction across 3,003 real compressions ·
92% saved on repeated file reads ·
86% on shell/git output ·
13-token refs for cached content

One developer's week, measured from actual sqz gain output:

$ sqz gain
sqz token savings (last 7 days)
──────────────────────────────────────────────────
  04-13 │                              │   2,329 saved
  04-14 │                              │       0 saved
  04-15 │███                           │  12,954 saved
  04-16 │██                            │   9,223 saved
  04-17 │████                          │  14,752 saved
  04-18 │██████████████████████████████│ 105,569 saved
  04-19 │████████                      │  30,882 saved
  04-20 │█                             │   4,334 saved
──────────────────────────────────────────────────
  Total: 3,003 compressions, 178,442 tokens saved (24.7% avg reduction)

Per-command compression

Single-command compression (measured via cargo test -p sqz-engine benchmarks):

Content Before After Saved
Repeated log lines 148 62 58%
Large JSON array 259 142 45%
JSON API response 64 53 17%
Git diff 61 54 12%
Prose/docs 124 121 2%
Stack trace (safe mode) 82 82 0%

Session-level with dedup

Where the real savings live — the cache sends each file once, repeats cost 13 tokens:

Scenario Without sqz With sqz Saved
Same file read 5× 10,000 826 92%
Same JSON response 3× 192 79 59%
Test-fix-test cycle (3 runs) 15,000 5,186 65%

Single-command compression ranges from 2–58% depending on content. Repeated reads drop to 13 tokens each. Your mileage will vary with how repetitive your tool calls are — agentic sessions with many file re-reads see the biggest wins.

Install

Prebuilt binaries (no compiler required — works on every platform):

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/ojuschugh1/sqz/main/install.sh | sh

# Windows (PowerShell)
irm https://raw.githubusercontent.com/ojuschugh1/sqz/main/install.ps1 | iex

# Any platform via npm
npm install -g sqz-cli

# macOS / Linux via Homebrew
brew tap ojuschugh1/sqz
brew install sqz

Build from source via Cargo:

cargo install sqz-cli sqz-mcp

sqz-cli provides the sqz binary; sqz-mcp provides the MCP server. sqz-engine is a library dependency — it compiles automatically and does not need to be installed separately.

Build from source (cargo install sqz-cli) works too, but needs a C toolchain:

  • Linux: build-essential (apt) or equivalent
  • macOS: Xcode Command Line Tools (xcode-select --install)
  • Windows: Visual Studio Build Tools with the "Desktop development with C++" workload. Without these, cargo install fails with linker link.exe not found. If you don't already have them, use the PowerShell or npm install above instead.

Then initialize:

sqz init --global     # hooks apply to every project on this machine
# or
sqz init              # hooks apply to just this project (.claude/settings.local.json)

--global writes to ~/.claude/settings.json (the user scope per the
Anthropic scope table),
so the sqz hook fires in every Claude Code session on this machine. This is
the common case on first install. Your existing permissions, env,
statusLine, and unrelated hooks in ~/.claude/settings.json are
preserved — sqz merges its entries rather than overwriting.

Plain sqz init (project scope) is useful when you want sqz active only
inside one repo.

Only using one agent? Pass --only (or --skip) to limit which
configs are written:

sqz init --only opencode              # just OpenCode, nothing else
sqz init --only opencode,codex        # OpenCode and Codex
sqz init --skip cursor,windsurf       # everything except Cursor and Windsurf

Accepted names: claude, cursor, windsurf, cline, gemini,
kiro, opencode, codex. Aliases (claude-code, gemini-cli, roo,
kiro-cli) also work. --only and --skip can't be combined.

Manual installation (preserve comments in your config)

sqz init round-trips your config file through a JSON parser to merge
the sqz entry, which drops any comments in your opencode.jsonc (and
the analogous JSON-with-comments files other tools accept). If you've
commented your config carefully and want to keep them, install by hand
instead.

OpenCode — two steps:

  1. Drop the plugin file in place. sqz prints the generated TS to
    stdout so you don't have to hand-write the path-escaping logic:

    mkdir -p ~/.config/opencode/plugins
    sqz print-opencode-plugin > ~/.config/opencode/plugins/sqz.ts
  2. Add the MCP entry to your existing opencode.jsonc yourself.
    Append this block inside the top-level mcp object (create the
    mcp object if it doesn't exist):

    "sqz": {
      "type": "local",
      "command": ["sqz-mcp", "--transport", "stdio"],
      "enabled": true
    }

Comments in the rest of your file stay put. OpenCode auto-discovers
the plugin file; no plugin array entry needed (adding one causes
double-loading, see issue #10).

Other tools — Claude Code, Cursor, Windsurf, Cline, Gemini CLI,
and Codex use plain JSON configs without comment support, so the
automated path is non-destructive there. Use sqz init --only <tool>
for those.

That's it. Shell hooks installed, AI tool hooks configured.

How It Works

sqz system architecture

sqz installs a PreToolUse hook that intercepts bash commands before your AI tool runs them. The output gets compressed transparently — the AI tool never knows.

Claude → git status → [sqz hook rewrites] → compressed output (85% smaller)

What gets compressed:

  • Shell output — 40+ per-command formatters (git, cargo, npm/pnpm/yarn, pytest, ruff, go test, docker, kubectl, aws, terraform, gradle, gh, grep/rg, tree, curl, and more)
  • JSON — strips nulls, compact encoding, TOON format
  • Logs — collapses repeated lines
  • Test output — shows failures only (state-machine parsers for Rust, Go, Python, JS, JVM)

What doesn't get compressed:

  • Stack traces, error messages, secrets — routed to safe mode (0% compression)
  • Your prompts and the AI's responses — controlled by the AI tool, not sqz

Supported Tools

Tool Integration Setup
Claude Code PreToolUse hook (transparent) sqz init
Cursor PreToolUse hook (transparent) sqz init
Windsurf PreToolUse hook (transparent) sqz init
Cline PreToolUse hook (transparent) sqz init
Gemini CLI BeforeTool hook (transparent) sqz init
Kiro PreToolUse hook (transparent) sqz init
OpenCode TypeScript plugin (transparent) sqz init
VS Code Extension Install from Marketplace
JetBrains Plugin Install from Marketplace
Chrome Browser extension ChatGPT, Claude.ai, Gemini, Grok, Perplexity
Firefox Browser extension Same sites

CLI

sqz init --global             # Install hooks for every project on this machine
sqz init                      # Install hooks for just this project
sqz init --only kiro          # Only configure Kiro (skip the rest)
sqz init --only opencode      # Only configure OpenCode (skip the rest)
sqz init --skip cursor        # Configure every agent except Cursor
sqz compress <text>           # Compress (or pipe from stdin)
sqz compress --no-cache       # Compress without dedup (always full output)
sqz expand <ref>              # Recover original content from a §ref:HASH§ token
sqz compact                   # Evict stale context to free tokens
sqz reset                     # Clear dedup cache or compression stats
sqz gain                      # Show daily token savings (bar chart)
sqz gain --project .          # Per-project daily gains
sqz gain --days 30            # Last 30 days
sqz stats                     # Cumulative compression report
sqz stats --breakdown         # Per-command token usage breakdown
sqz stats --project .         # Stats for current project only
sqz stats --project list      # List all tracked projects
sqz discover                  # Find missed savings
sqz resume                    # Re-inject session context after compaction
sqz vizit                     # Live terminal dashboard (like htop for AI agents)
sqz hook claude               # Process a PreToolUse hook (Claude Code)
sqz hook kiro                 # Process a PreToolUse hook (Kiro)
sqz print-opencode-plugin     # Print OpenCode plugin TS for manual install
sqz proxy --port 8080         # API proxy (compresses full request payloads)

Dedup Escape Hatch

When sqz sees the same content twice, it returns a compact §ref:HASH§ token
instead of the full text. Most models handle this fine, but some (e.g., GLM 5.1)
can't parse the ref format and loop. Four ways to work around this:

# 1. Recover original content from a ref
sqz expand a1b2c3d4              # prefix match
sqz expand '§ref:a1b2c3d4§'     # paste the whole token

# 2. Compress without dedup (per-invocation)
echo "..." | sqz compress --no-cache

# 3. Disable dedup globally (env var)
export SQZ_NO_DEDUP=1

# 4. MCP passthrough tool (returns input byte-exact, zero transforms)
# Available via tools/list when sqz-mcp is running

Track Your Own Savings

Run sqz gain in your shell any time to see your own daily breakdown (see the
Token Savings section above for what the output looks like), and sqz stats
for the full cumulative report:

$ sqz stats
  📊 sqz compression stats
  ──────────────────────────────────────────────────

  178,442  tokens saved
  ↓  24.7% average reduction

  Compressions           3,003
  Tokens in              721,840
  Tokens out             543,398
  Tokens saved           178,442
  Avg reduction          24.7%

  🗄️  Cache
  ──────────────────────────────────────────────────
  Entries                43
  Size                   39.1 KB

Add --breakdown to see exactly which commands consume the most tokens:

$ sqz stats --breakdown

  🔍 Top Token Consumers
  ──────────────────────────────────────────────────────────────────────
  command               calls  tokens in        out    saved
  ──────────────────────────────────────────────────────────────────────
  dedup                   249      45541       3237      93%
  stdin                    51      30851      24289      21%
  auto                    132      18288       7740      58%
  echo                     17       1050        558      47%
  ls -la                    8        948        948       0%
  cargo build               7        170        145      15%
  git status                4         56          8      86%
  ──────────────────────────────────────────────────────────────────────

Per-project filtering:

sqz stats --project .           # stats for current project only
sqz stats --project list        # list all tracked projects
sqz gain --project .            # daily gains for current project
sqz gain --days 30              # last 30 days instead of 7
sqz gain --days 30 --project .  # combine both

Stats are stored locally in SQLite under ~/.sqz/sessions.db — nothing leaves your machine.

How Compression Works

  1. Per-command formatters — 40+ commands across 9 ecosystems get purpose-built compression:

    Ecosystem Commands
    Git status, log, diff, show, stash, remote, fetch, push, pull, commit
    Rust cargo build/test/clippy/check/nextest
    JavaScript npm/pnpm/yarn/bun install/test/audit/outdated, tsc, eslint, vitest
    Python pytest, ruff, mypy, pip
    Go go test (incl. -json stream), go build, go vet, golangci-lint
    Cloud aws, terraform plan/apply/init, gcloud
    Containers docker/podman ps/images/build, kubectl get/describe/logs/apply
    JVM gradle build/test, maven
    System grep/rg, tree, find/fd, ls, curl/wget
    GitHub gh pr/issue/run (JSON + table)

    Unknown commands fall through to the generic compression pipeline — no output is ever left uncompressed.

  2. Structural summaries — code files compressed to imports + function signatures + call graph (~70% reduction). The model sees the architecture, not implementation noise.

  3. Dedup cache — SHA-256 content hash, persistent across sessions. Second read = 13-token reference.

  4. JSON pipeline — strip nulls → project out debug fields → flatten → collapse arrays → TOON encoding (lossless compact format)

  5. Safe mode — stack traces, secrets, migrations detected by entropy analysis and routed through with 0% compression

For the full technical details, see docs/.

Configuration

# ~/.sqz/presets/default.toml
[preset]
name = "default"
version = "1.0"

[compression.condense]
enabled = true
max_repeated_lines = 3

[compression.strip_nulls]
enabled = true

[budget]
warning_threshold = 0.70
default_window_size = 200000

Privacy

  • Zero telemetry — no data transmitted, no crash reports
  • Fully offline — works in air-gapped environments
  • All processing local

Development

git clone https://github.com/ojuschugh1/sqz.git
cd sqz
cargo test --workspace
cargo build --release

License

Elastic License 2.0 (ELv2) — use, fork, modify freely. Two restrictions: no competing hosted service, no removing license notices.

Links

Star History

Star History Chart

@AliMahmoud15486

Copy link
Copy Markdown

Thanks for publishing this pattern, Andrej. I instantiated it for product management and open-sourced the result: https://github.com/AliMahmoud15486/pm-llm-wiki

The PM twist on the entities: problem pages with evidence chains, decision pages with rationale + reversal conditions (the "decision memory" the v2 thread flagged as missing — for PMs it is the job), an assumption register (untested/validated/weakening/invalidated, each flip citing its source), and an open-questions queue that turns every contradiction the weekly lint finds into a tagged discovery/interview question. PRDs and stakeholder briefs then become queries against the wiki, every claim source-cited.

The repo has a copy-paste schema (CLAUDE.md), a start-minimal progression plan (4 entity types; schema-defined triggers decide when to add personas/competitors/metrics), and a fully worked fictional pilot (B2C fitness app with a churn problem) showing every mechanic — including the pilot itself being maintained by an agent. Pressure-tested before publishing by handing the schema to a fresh agent with a one-line prompt and auditing the diff.

MIT — forks, field reports, and critique welcome.

@blurman-ai

Copy link
Copy Markdown

Ran a small controlled experiment applying this pattern to a code repository — agent-facing docs for archcheck, a C++ architecture checker for CI. Measured before adopting. Sharing numbers since the thread has production experience but few measurements.

Setup. Built 28 source-backed pages: every claim cites file:line, message strings quoted verbatim from code, staleness tracked via a last_checked_commit field plus a lint script. Then A/B: same 4 lookup questions, fresh agent per run, isolated checkouts with and without the wiki, transcripts audited so no arm could peek.

Result: the 28-page wiki saved nothing versus letting the agent grep the code (marginal tokens, 4 questions summed; correctness 4/4 everywhere):

arm tool calls tokens
grep the code 10 27.3k
wiki, "verify against source" 10 27.6k
wiki, blind trust 10 29.8k

Two causes: (1) in a codebase where one concept = one ~100-line file, per-entity pages came out larger than the sources they describe, so compression ≤ 1; (2) pages stamped "derived, verify against source" make the agent read both the wiki and the code, so the cache pays twice. Either the wiki is trusted at query time or it shouldn't exist.

The fix. Collapsed everything into a single dense table page (rule registry, gate policy, file/test/fixture matrix; zero-hop entry from the agents file; trusted at query time; freshness kept by the lint). Re-measured, plus a heavier 5-part pre-change recon task:

task grep the code one-page map
4 lookups 10 calls / 27.3k / 94s 4 calls / 13.8k / 31s
recon (5-part) 12 calls / 16.5k / 53s 1 call / 7.2k / 13s

Correctness unchanged at 100% in both arms.

Boundary condition in practice: the pattern pays exactly when a page compresses facts scattered across many sources; mirrors of small greppable files are negative value. Consistent with @distorx's point that drift is the main failure mode — the linter flagged 8 stale pages on day one after unrelated commits, and that loop is what makes query-time trust viable.

Measurement footnote: sub-agent token totals were ~80% fixed overhead (a do-nothing agent already costs 24.3k tokens), so compare marginal costs or you're comparing a constant.

Full write-up with method and caveats: agent_wiki_economics.md · the surviving one-page map: docs/openwiki/index.md

@gowtham0992

Copy link
Copy Markdown

Link v1.5.0 is live

Since v1.4.0, most of the work went into making Link more agent-native: less “here is a wiki your agent can browse,” more “your agent has one obvious way to recall, write, review, and verify memory.”

image

What changed:

  • Slim MCP surface. Link used to expose ~37 MCP tools by default. v1.5.0 defaults to six: status, recall, remember, ingest, review, and admin. One obvious read path, one explicit write path. The full tool surface is still available when needed.

  • MCP prompts and resources. Link now exposes native MCP prompts/resources where clients support them, so agents can start from Link, recall context, and inspect memory without per-agent glue.

  • Honest recall. Every recalled memory now carries a confidence label: strong, moderate, or weak. If everything is weak, the packet tells the agent to verify with the user instead of pretending it knows. Still zero embeddings and zero network calls.

  • Day-one seeding. lnk seed . reads allowlisted repo context that already exists, like README, AGENTS.md, CLAUDE.md, .cursorrules, and recent git subjects. It secret-scans that input and writes a source-backed page, so the first recall can return actual project context instead of an empty wiki.

  • 60-second proof. brew install gowtham0992/link/link && lnk proof creates a local workspace, writes one reviewed memory, and recalls it through the same bounded path used by CLI, skills, and MCP.

  • Trust plumbing. The audit log is now hash-chained, interrupted multi-file writes leave rollback snapshots, and lnk benchmark reports how much context the bounded packet avoided sending versus dumping the whole wiki.

Everything remains plain local Markdown: readable in git or Obsidian, no cloud account, no telemetry.

Repo: https://github.com/gowtham0992/link
Site: https://gowtham0992.github.io/link/
PyPI: https://pypi.org/project/link-mcp/
MCP: https://registry.modelcontextprotocol.io/?q=io.github.gowtham0992%2Flink

@cobusgreyling

Copy link
Copy Markdown

Reference implementation + tooling for this pattern: https://github.com/cobusgreyling/llm-wiki

  • pip install llm-wiki && wiki init my-wiki --git scaffolds a new wiki
  • CLI (wiki search, wiki lint, wiki ingest-status) + MCP server for agents
  • Demo wiki with two ingested sources — synthesis revision + contradictions ledger in examples/demo/
  • Domain examples: research papers (examples/research/), book notes (examples/reading/)
  • Optional qmd backend when the wiki outgrows BM25: wiki search "query" --backend qmd

Obsidian is the IDE; the LLM is the programmer; the wiki is the codebase.

@mohammadmaso

Copy link
Copy Markdown

Hi Andrej — thank you for publishing this as an idea file rather than a repo. That framing made it easy to take the pattern seriously and build a concrete version tuned to my workflow.

I implemented it as EchoWiki: a local-first, Obsidian-native knowledge compiler.

Repo: https://github.com/mohammadmaso/echowiki

How it maps to your three layers

Raw sources → raw/
One universal inbox. Voice transcripts and manually dropped .md/.txt files land in the same folder and go through the same pipeline — no special “voice path” inside compilation logic.

The wiki → wiki/
The agent maintains the structure you describe:

  • summaries/ — one page per ingested document
  • concepts/ — cross-document synthesis
  • entities/ — people, orgs, places, products, works, events, etc.
  • index.md — content-oriented catalog
  • log.md — append-only operations timeline

Cross-links use Obsidian [[wikilinks]]. Pages carry OKF-schema YAML frontmatter so they stay portable outside Obsidian too.

The schema → wiki/AGENTS.md
Read from disk at runtime, not baked into code. Edit the conventions and the next compilation run picks them up — no redeploy.

Operations implemented (MVP)

Ingest

  • Drop a note into raw/, or use the Obsidian plugin to send the active note there
  • Record a voice note → STT → transcript written to raw/ as Markdown
  • Optional folder watcher auto-triggers compilation on new/changed files
  • Optional approval gate before anything is compiled

Compile (your “ingest” flow, automated)
Per new raw/ document, a Mastra agent:

  1. Writes a summary
  2. Reads existing concept/entity pages for context
  3. Creates or updates matching concept/entity pages (merge, not duplicate)
  4. Updates index.md and appends to log.md

Query / Lint
Not in MVP yet — focused on the compounding wiki foundation first. Stretch goals include query/chat over the compiled wiki and periodic lint reports under wiki/reports/.

Why Mastra + Obsidian

Your gist describes Obsidian as the IDE and the LLM as the programmer. EchoWiki leans into that literally:

  • The repo root is the Obsidian vault (raw/ + wiki/ as siblings)
  • An Obsidian desktop plugin bundles and runs the Mastra compiler backend locally
  • LLM and STT are provider-agnostic — any OpenAI-compatible endpoint, cloud or self-hosted
  • External calls only for STT/LLM steps you explicitly trigger; everything else stays on disk

So the loop is: capture → drop in raw/ → watch/approve → compile → browse the graph in Obsidian while pages update.

Architectural lineage

I treated this as a concrete instantiation of your pattern, with VectifyAI/OpenKB as the reference for the raw/ → wiki/ compilation model (summaries → concepts → entities → index/log). EchoWiki is essentially OpenKB’s wiki foundation reimplemented on Mastra (TypeScript) instead of Python, with Obsidian as the primary surface.

What resonated most from the gist

Two lines that shaped the design:

  1. “The wiki is a persistent, compounding artifact.” — That’s the whole product bet: don’t re-derive from raw sources on every question; keep a maintained synthesis that gets richer with each ingest.
  2. “Humans abandon wikis because the maintenance burden grows faster than the value.” — EchoWiki tries to make maintenance near-zero: the agent touches summaries, concepts, entities, index, and log in one pass; the human curates sources and optionally approves before compile.

Current status

MVP covers the full ingest → compile → Obsidian graph loop for text and voice. Still building toward query/lint parity and broader format support (PDF, URLs, etc.).

If anyone else is instantiating this pattern for Obsidian + local-first capture, happy to compare notes in issues or discussions on the repo.

@cobusgreyling

Copy link
Copy Markdown

Reference implementation + tooling for this pattern: https://github.com/cobusgreyling/llm-wiki

  • pip install llm-wiki && wiki init my-wiki --git scaffolds a new wiki
  • CLI (wiki search, wiki lint, wiki ingest-status) + MCP server for agents
  • Demo wiki with two ingested sources — synthesis revision + contradictions ledger in examples/demo/
  • Domain examples: research papers (examples/research/), book notes (examples/reading/)
  • Optional qmd backend when the wiki outgrows BM25: wiki search "query" --backend qmd
  • Terminal demo: https://asciinema.org/a/JaIKgBIXHP8nDyw0

Obsidian is the IDE; the LLM is the programmer; the wiki is the codebase.

@ikwuoz

ikwuoz commented Jul 5, 2026

Copy link
Copy Markdown

I think this suffices as an in-context memory architecture for the LLMs

@jpierreribeiro

Copy link
Copy Markdown

pewdiepie sux

@XBlueSky

XBlueSky commented Jul 7, 2026

Copy link
Copy Markdown

This idea really resonated with me.

While using Claude Code, I ran into a similar problem: conversations are valuable, but most of the content is not worth keeping forever.

Simply storing every conversation quickly becomes noisy:

  • temporary debugging attempts
  • abandoned approaches
  • outdated assumptions

I ended up building a workflow around this idea: instead of automatically turning conversations into memory, Claude and the user collaboratively distill important knowledge into a curated Markdown knowledge base.

The knowledge stays human-readable, versionable, and can be explored through Obsidian.

I called it Cortexes:
https://cortexes.pages.dev/

The interesting question for me is not "how do we store more memory?", but "how do we maintain high-quality knowledge over time?"

@TLiu2014

TLiu2014 commented Jul 7, 2026

Copy link
Copy Markdown

LLM is like CPU and docs/files are like disk. This LLM Wiki is exactly the memory!

@mas213

mas213 commented Jul 7, 2026

Copy link
Copy Markdown

Love it. a little late to the party but was headsdown to built something similar.

Applied this pattern to a different domain: behavioral verification of code changes.

The overlap is direct. Same three layers:

Raw sources = PRs, specs, test cases, production incidents (immutable, never modified)
Wiki = a behavioral knowledge graph. Not how the code is structured, how the system is supposed to behave. Concern pages, flow maps, state transitions, cross-references between what the spec promises and what the tests cover.
Schema = a concern taxonomy (auth flows, data integrity, state transitions, error propagation, integration contracts, observability) that tells the system what to look for when a PR comes in.

Same three operations:

Ingest = parse a PR with tree-sitter, extract behavioral changes, update the graph. A single PR might touch 5-10 concern pages.
Query = "what concerns does this change touch? what can break from a user's perspective?"
Lint = verify the PR against the behavioral graph before merge. Flag drift between what the system promises and what the code actually does.

The compounding effect is the same. Every PR that flows through makes the graph richer. Every production incident that gets filed teaches it a new failure mode. The graph gets better at catching the next thing because it's seen the last hundred things.

The Lint section of your gist describes exactly what's missing from QA tooling. Most test generation tools produce more scripts without understanding what the system is supposed to do. This is the other direction: build the knowledge first, then verify against it.

Open sourced as an MCP server (Claude Code, Cursor, Codex): https://github.com/OrangeproAI/orangepro-mcp

No API key, no cloud, runs locally. Curious if you've thought about this pattern applied to code specifically.

opro-karpathy-parallel

@LiyuanW21

Copy link
Copy Markdown

Thanks for sharing this — your llm-wiki idea inspired me to package the workflow into a reusable Obsidian + agent skill:

https://github.com/LiyuanW21/obsidian-wiki-system

It supports Codex/OpenCode-style agents, bilingual vault templates, and natural-language install prompts so non-technical users can try the “LLM-maintained personal wiki” pattern more easily.

I credited your gist in the README. Thanks again for the inspiration!

@phoebe22222

Copy link
Copy Markdown

This maps almost 1:1 to a system we have been running in production for ~6 months to manage infrastructure/ops knowledge. A few notes from actually living with the pattern at ~4000+ interlinked concepts:

  • The schema file is everything. Our CLAUDE.md is exactly the "disciplined maintainer vs. generic chatbot" config you describe — it encodes the ingest/query/lint workflows + naming conventions, and it co-evolved into the single most important file in the repo.
  • index.md at scale: the flat index works great to a few hundred pages. Past that we added hybrid search (SQLite FTS5 + on-device embeddings, reciprocal-rank-fused) rather than standing up embedding-RAG infra — same spirit as qmd. We expose it as both a CLI (agent shells out) and an MCP server (native tool). ~1ms keyword, ~350ms hybrid.
  • New page vs. edit (@alinawab): heuristic that works for us — new page when it is a distinct entity/concept you would link to from elsewhere; edit in place when it is an attribute/update of an existing one. The agent gets this right ~90% of the time once the schema enumerates the page types.
  • Team sharing (@geetansharora): the wiki is just a private git repo, auto-synced. Teammates browse in Obsidian or hit the same MCP server. Git history doubles as the log.md audit trail for free.
  • Biggest failure mode (@alinawab): drift — the agent under-updating cross-references on ingest, so pages silently go stale. The lint pass is not optional; we run it on a timer (orphan detection + contradiction flagging + stale-claim checks) and that is what keeps the graph healthy.

The "compounding artifact" framing is exactly right — after a few thousand concepts the wiki answers questions the raw sources never could, because the synthesis already happened. Thanks for writing it up so cleanly.

@distorx — of everyone here your setup maps closest to mine (team-scale, production, git-backed), so I'd value your take; anyone else who's hit this, welcome too.

Mine is packaged as an agent skill, not a personal wiki: the knowledge lives alongside a SKILL.md — the schema/entry file agents load — as a git repo of markdown. Same three layers you'd recognize: an immutable source-of-truth layer (~30 metadata snapshots auto-pulled from our data platform), an LLM/human-maintained wiki layer derived from it (per-dataset field specs, metric formulas, business logic, query cases; ~450 md pages + ~110 python config files), and the SKILL.md schema + lint rules on top. It's distributed to a whole team, and each person's agent (Claude Code / Cursor / etc.) both uses and edits it.

Two things I can't settle:

  1. Size vs. keeping source-of-truth local. The immutable snapshots are the heaviest, churniest part. The gist stresses keeping an immutable raw layer as the foundation, but do you keep raw sources in-repo, or split them out (submodule / LFS / on-demand fetch) to keep the skill light? And does repo size actually hurt agents at query time, or is it purely a human clone/CI cost?

  2. Concurrent team maintenance without rot. With multiple people's agents editing the same skill: do they push directly, or through a review gate (PR) before a page lands? How do you stop two agents fighting over the same page / spawning near-duplicates? Who owns the SKILL.md schema when the whole team co-evolves it? And the lint pass — human-triggered, or on a timer / CI hook? You called drift the #1 failure mode, so I'm most curious what actually enforces it at team scale.

Trying to avoid the failure mode where a shared wiki slowly rots because no single person owns the bookkeeping. Any pointers appreciated.

@bprice1000

bprice1000 commented Jul 8, 2026

Copy link
Copy Markdown

I build a CMMS with this as a primary influence.

It’s transformative. New levers to lean on, fun things happening when we do.

Ty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment