Building an LLM wiki

~6 min read

Building an LLM wiki

This is the end-to-end pattern: a small, curated vault that an agent keeps growing for you. You drop in raw material, the agent reads it, writes a clean summary page, threads it into the existing pages, and files it so the catalog and the ledger stay current. Do that a few dozen times and you have an interlinked knowledge base instead of a folder of clippings.

The shape comes from Karpathy’s “LLM wiki”: a curated index.md catalog, a raw sources/ layer the agent reads but never edits — the write API enforces this; new sources and appends are allowed, overwriting or deleting an existing one is rejected — and an append-only log.md ledger.

1. Scaffold the wiki

lettuce wiki init research --agents

wiki init writes exactly four files, then --agents adds a fifth tailored brief:

Scaffolded LLM wiki in /…/research:
  CLAUDE.md
  index.md
  log.md
  sources/README.md
  AGENTS.md
Note

wiki init only accepts init. There is no wiki ingest / wiki lint / wiki slidesingest, lint, search, slides, and agents are all top-level lettuce commands.

2. Connect an agent

Point your MCP client at the vault — see Getting started/03 Your first agent connection for the one-minute pairing. In short:

lettuce serve research

The banner prints the API key. The agent’s get_vault_info returns the combined brief (AGENTS.md + CLAUDE.md), so it knows the curation rules before it touches anything — and the active immutable prefixes (sources/ by default), so it knows what it may not overwrite.

Optional: semantic recall

To let the agent find pages by meaning (not just keyword) via semantic_search, build a vector index once: lettuce embed research. It uses any OpenAI-compatible embeddings endpoint — set LETTUCE_EMBED_BASE_URL to a local server like Ollama for a no-key, nothing-leaves-the-machine setup. Re-run lettuce embed after big edits to refresh.

3. Ingest a source

Ways material lands in sources/:

# From the web — pandoc + readability, downloads images, appends a log.md entry:
lettuce ingest https://example.com/some-paper

# From a local file (docx / epub / odt / rtf / html / markdown / …):
lettuce ingest ~/Downloads/whitepaper.docx

# A whole folder at once (batch):
lettuce ingest ~/research-dump/

# …or just drop a note into sources/ by hand:
#   research/sources/interview-notes.md

(PDFs work directly — Lettuce extracts the text layer with PDFKit, so no pandoc needed for them. A scanned/image-only PDF with no text layer errors with a clear “OCR it first”.)

ingest accepts a URL, a local file, or a whole directory and writes sources/<slug>.md for each.

4. The compounding pass

This is the part that makes it a wiki rather than a dumping ground. Ask the agent to digest the new source into the existing pages:

@claude A new source landed at sources/some-paper.md. Digest it:

  1. read_note the source.

  2. Write a tight summary page (claims, evidence, your read).

  3. For each entity or concept it touches, patch_section that page to add what’s new.

  4. file_page the summary so it shows up in the catalog and the log.

A typical sequence of tool calls:

Step Tool What happens
Read the raw input read_note("sources/some-paper.md") Pulls the ingested text.
Find the pages it touches search("retrieval augmentation") — or semantic_search for meaning-based recall Returns {path, title, snippet, score} (lower score = better).
Pull the neighborhood link_graph(path, depth: 2) The bidirectional subgraph to wire links into.
Update 3–5 concept pages patch_section(path, target_type: "heading", target: "Findings", op: "append", content: …) Threads the new claim into each existing page.
File the summary file_page(path, content, summary, title) Writes the page and links it under index.md’s ## Pages and appends a dated log.md entry — in one call.

The key move is file_page: it does the three-way bookkeeping (page + catalog + ledger) so the agent never forgets to update the index. Use patch_section to update an existing page; use file_page only for a brand-new one.

Tip

apply_edits is the surgical alternative to patch_section — give it an array of {find, replace} edits and they apply atomically; if any find doesn’t match exactly once, the whole call rolls back.

So one ingest fans out into: 1 new summary page, 3–5 patched concept pages, 1 catalog link, and 1 log entry. Repeat across sources and the graph densifies on its own.

5. File a question’s answer back as a page

A query worth keeping shouldn’t evaporate in chat. When you ask the agent something that the wiki should know, have it file the answer:

@claude What does the corpus say about eval contamination? Synthesize across the relevant pages, then file_page the answer as Eval contamination.md with a one-line summary.

The agent searches, reads the hits, writes a synthesis, and file_pages it — now the next person (or agent) finds it in the catalog instead of re-asking.

6. A periodic health pass

Run two passes on a schedule (weekly is plenty for a slow-growing wiki):

# Deterministic, offline — broken links, orphans, tag issues:
lettuce lint research

# Add LLM tag suggestions for untagged / missing-required notes:
lettuce lint research --suggest

lint flags unresolved-link, orphan-note, no-inbound (the pattern’s “orphan” — has outbound links but nothing points back), tag-typo, orphan-tag, and untagged-note. The structural files (index.md, CLAUDE.md, AGENTS.md, log.md, sources/**) are exempt from the content rules.

Then have the connected agent run the semantic health-check, which is LLM-backed (it needs a provider configured):

@claude Run lint_semantic over the wiki. Reconcile any contradictions or stale claims you find by patching the relevant pages, and suggest_tags for anything untagged. Record the fixes with a log.md entry.

lint_semantic surfaces contradictions, stale claims, missing-concept pages, and data gaps; suggest_tags proposes tags for untagged or missing-required notes. Both return a clear error if no LLM provider is configured.

Running it hands-off

Want this on autopilot? Put the connected agent behind a propose-only key so its writes land as reviewable proposals instead of committing directly — see Suggestions mode/01 Overview. Since one ingest fans out into several pages, have the agent file them with propose_batch so the whole set queues as a single batch you accept or reject together (Accept all / Reject all in the proposals inspector) rather than page by page. Pair it with a schedule to run the digest + health pass on a cadence, and you have a wiki that maintains itself while you review the diffs.