Wiki memoryBack to the demoFull article on GitHub

This page is the example's README, rendered for reading here. Mermaid diagrams are shown as their source.

Wiki memory for agents: let the model keep the notes

Most agents forget everything between sessions, or remember it in the least useful form: a pile of raw chunks they search again for every question. Wiki memory is a different arrangement. The agent maintains a small wiki of markdown pages. Each time a new source arrives, it updates the pages about the people, systems and policies that source mentions, links them to each other, records what changed, and marks what the source made out of date. Questions are answered from those pages, which already reflect everything read so far.

Andrej Karpathy described this pattern in April 2026 as the “LLM Wiki”. This article explains how it works, compares it with retrieval (RAG) and with other kinds of agent memory, and walks through a complete example: five short sources about a fictional project, ingested one at a time, with the real wiki pages before and after each step.

Try it: this folder contains a small web app that teaches the idea with one question. It shows what plain retrieval returns, explains wiki memory, and then lets you step through five documents. For each one you see what the document says, what the agent did, and the page change that matters most. A check then catches the values that disagree, and the same question is answered again from one page. It runs offline, with no API key. See The demo app.

Key takeaways

  1. Wiki memory moves the work from question time to write time. RAG finds and reconciles fragments of raw documents on every question. A wiki agent does that once, when each source arrives, and keeps the result as pages anyone can read.
  2. There are three layers and three operations. Raw sources are never edited; the wiki belongs to the agent; a schema file tells it how to keep the wiki. The operations are ingest (fold a new source into the pages), query (answer from the pages) and lint (check the whole wiki for contradictions, broken links and stale claims).
  3. Superseding is the part RAG can't do. When a source says “the limit was lowered from 100 to 50”, the agent strikes the old value through on every page that states it. Chunk RAG still holds the March design doc that says 100, and will retrieve it.
  4. Lint is not optional. An ingest only sees the pages it opens. In our example, a draft FAQ introduces two wrong values that no single ingest could catch; a pass over every claim at once finds both.
  5. It is not a replacement for RAG at scale. Karpathy reports that an index file works “at moderate scale (~100 sources, ~hundreds of pages)”. Beyond that you need search over the wiki. And every page is model-written, so errors can persist and spread unless people review the changes.

What wiki memory is, and why it matters

Karpathy's gist starts from how most people use LLMs with documents:

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.

Instead, 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 a new source arrives, the model doesn't just index it: it integrates it, “updating entity pages, revising topic summaries, noting where new data contradicts old claims”. In his words, “the wiki is a persistent, compounding artifact”.

The argument for why this works now is about cost, not intelligence: “Humans abandon wikis because the maintenance burden grows faster than the value.” A model can update fifteen cross-references in one pass without getting bored, so the upkeep that kills human wikis becomes cheap.

How it compares

Agent memory is a crowded space, and the term covers very different things. This table compares wiki memory with the three approaches people usually mean.

Chunk RAG Chat-history memory Extracted-fact (vector or graph) memory Wiki memory
What is stored Raw documents, split into chunks and embedded The conversation, or rolling summaries of it Small facts or memories pulled out of conversations, in a vector store or a knowledge graph Markdown pages about entities and concepts, with links, an index and a log
When the work happens At question time Every turn, by carrying the history At write time (extraction), plus retrieval at question time At write time (ingest) and in periodic lint passes
Handles changed facts No: old and new chunks are both retrieved Only while the change is still in the window or summary Depends on the system; some mark old facts invalid Yes: the agent strikes old claims through and links the source that replaced them
Readable by people The sources are; the index isn't Partly Usually through a tool or API Yes: plain files, diffable in git
Scales to Millions of chunks One context window Large stores, with search Hundreds of pages with an index file; more needs search over the wiki
Main risk Contradictory or outdated chunks with nothing marking which is current Lost details after summarizing Wrong or duplicate extracted facts Model-written errors that persist; drift as pages are rewritten
Examples Most document Q&A tools Conversation buffers and summaries LangMem collections and profiles; Zep, a temporal knowledge graph Karpathy's LLM Wiki; Claude Code's auto memory directory (below)

The ideas overlap. MemGPT (Packer et al., 2023) framed memory as an operating-system problem, with the model moving information between its context window and slower storage. Its successor, Letta, gives agents editable memory blocks and sleep-time agents that reorganize memory between conversations, which is close to a lint pass. LangMem distinguishes semantic memory (“the essential facts and other information that ground an agent's responses”) from episodic and procedural memory, and stores semantic memory either as a collection of separate records or as a profile, a single document that “updates the existing document rather than creating a new one”. A wiki page is a profile per topic, with links between them. A-MEM (Xu et al., NeurIPS 2025) builds linked notes in the style of a Zettelkasten, where a new memory can update the description of older ones.

Coding agents already use a small version of this. Anthropic's memory tool gives Claude a /memories directory it can view, create, edit, rename and delete files in, and the API tells it to check that directory before starting a task. Claude Code's auto memory keeps a MEMORY.md index with “one line per memory” and one topic file per memory. Only the first 200 lines or 25KB of the index load at the start of a session; topic files are read on demand. That is the index-plus-pages structure of a wiki, applied to an agent's own working notes rather than to a body of sources.

How it works

Three layers

Karpathy's gist describes three layers:

Our example's schema is corpus/schema.md. It defines four page types (overview, source, entity, concept), the front matter every page carries, and one rule the gist leaves open: how to record a fact that can change. We call those claims (more on them below).

Two special files

Three operations

Diagram (Mermaid source)
flowchart LR
    RAW["Raw sources<br/>(never edited)"] -->|one at a time| INGEST
    SCHEMA["Schema<br/>(AGENTS.md / CLAUDE.md)"] -.->|rules| INGEST
    SCHEMA -.->|rules| LINT
    subgraph WIKI["Wiki (owned by the agent)"]
      PAGES["Pages<br/>overview · sources · entities · concepts"]
      INDEX[index.md]
      LOG[log.md]
    end
    INGEST["Ingest<br/>summarize the source,<br/>update topic pages and claims,<br/>strike superseded values"] --> PAGES
    INGEST --> INDEX
    INGEST --> LOG
    LINT["Lint<br/>contradictions, missing pages,<br/>orphans, uncited claims"] -->|proposed fixes,<br/>approved by a person| PAGES
    LINT --> LOG
    Q[Question] --> QUERY["Query<br/>read index.md,<br/>open the relevant pages,<br/>answer with citations"]
    INDEX --> QUERY
    PAGES --> QUERY
    QUERY -->|a useful answer can<br/>become a new page| PAGES

Claims: making facts checkable

The gist leaves page formats to you. We added one convention that makes the most important lint check exact. Any fact that can change goes in a ## Claims section, one per line, with a key, a value, the date it applies from and the source:

## Claims
- ~~`billing-api.rate-limit`: 100 requests per second per client (as of 2026-03-16, [[src-design-doc]])~~ superseded by [[src-inc-482]]
- `billing-api.rate-limit`: 50 requests per second per client (as of 2026-04-03, [[src-inc-482]])

The schema has two rules for new values:

Code can then compare every current claim in the wiki: two claims conflict when their keys match, or one is the parent of the other (export.retention and export.retention.standard), and their values differ. Contradictions written only in prose still need a model to find them.

A worked example: Ledger Export

The corpus is five short, original documents about a fictional team building Ledger Export, a feature that lets customers download their invoices as a CSV file. The names, company and numbers are invented. The documents are in corpus/raw/:

Date Source What it adds
2 Mar 2026 Kickoff notes The project, its owner, a nightly job, files kept 30 days
16 Mar 2026 Pipeline design doc Runs at 02:00 UTC; the Billing API allows 100 requests per second, the job will use 80; links expire after 7 days
7 Apr 2026 Incident report INC-482 The Billing API limit was lowered from 100 to 50; the job now uses 40
20 Apr 2026 Support chat thread From 1 May, Enterprise exports are kept 90 days; other plans stay at 30
5 May 2026 Draft help-centre FAQ Says exports run every hour and are kept 7 days. Both are wrong

The pages the agent writes at each step are in corpus/steps/. We wrote them by hand to show what a careful model should produce, following the schema exactly; no model was called (see Reproducibility). Everything else, including the diffs, index, log, graph, lint findings and retrieval results below, is computed from those pages by code in src/. The final wiki, with its index and log, is in results/wiki/.

Ingest 1: the kickoff creates the wiki

The first source creates seven pages: a summary of the source, pages for the project, its two owners and the Billing API, a concept page for the retention policy, and an overview. Here is the project page as created:

---
type: entity
summary: The self-serve invoice CSV export project.
sources: [src-kickoff]
updated: 2026-03-02
---
# Ledger Export

A customer picks a date range and receives one CSV of their invoices. It replaces manual exports by support, about 40 tickets a week ([[src-kickoff]]).

- Owner: [[amara-osei]]. Customer-facing copy: [[rui-costa]].
- Runs as a nightly batch job on the Postgres read replica.
- Reads invoice totals from the [[billing-api]].
- How long files are kept: [[export-retention]].

## Claims
- `export.schedule`: nightly (as of 2026-03-02, [[src-kickoff]])

The Billing API page ends with an open question from the meeting: What request rate may Ledger Export use? The overview lists it too.

Ingest 2: the design doc mostly updates

Two pages are new (the source summary and the Payments team); five are edited. The design doc answers the kickoff's open question, so the agent strikes the question through and says what answered it, rather than deleting it, and adds the claim:

-Owned by the Payments team. [[ledger-export]] reads each invoice's final total from it ([[src-kickoff]]).
+Owned by the [[payments-team]]. [[ledger-export]] reads each invoice's final total from it ([[src-kickoff]]). [[jun-park]] confirmed the limit ([[src-design-doc]]).

 ## Open questions
-- What request rate may Ledger Export use? Raised at the kickoff.
+- ~~What request rate may Ledger Export use? Raised at the kickoff.~~ Answered by [[src-design-doc]].
+
+## Claims
+- `billing-api.rate-limit`: 100 requests per second per client (as of 2026-03-16, [[src-design-doc]])

Note the link to [[jun-park]]: there is no page for Jun yet. Nothing complains now; lint will.

Ingest 3: the incident report supersedes two values

This is the step that RAG has no equivalent for. The incident report says the limit was cut from 100 to 50 and the job now sends 40. The agent rewrites the claims on two pages, keeping the old values as struck-through history. On the project page:

-- Reads invoice totals from the [[billing-api]].
+- Reads invoice totals from the [[billing-api]], backing off on HTTP 429 ([[src-inc-482]]).
-- Risk: a slow Billing API could push the run past 06:00 UTC ([[src-design-doc]]).
+- Alerts if the run hasn't finished by 06:00 UTC ([[src-inc-482]]).
+- Past incidents: [[inc-482]].
 ...
-- `export.billing-api-rate`: 80 requests per second (as of 2026-03-16, [[src-design-doc]])
+- ~~`export.billing-api-rate`: 80 requests per second (as of 2026-03-16, [[src-design-doc]])~~ superseded by [[src-inc-482]]
+- `export.billing-api-rate`: 40 requests per second (as of 2026-04-07, [[src-inc-482]])

It also creates a page for the incident and a concept page, api-rate-limits, for the general lesson (leave headroom, back off on HTTP 429, alert on the outcome). One source touched eight pages, and the graph went from 22 to 38 links.

Ingest 4: a decision made in chat

A four-message thread changes the retention policy. The agent replaces the single 30-day claim with one claim per plan, and says so in prose as well:

-summary: How long finished export files are kept before deletion.
+summary: How long finished export files are kept: 90 days on Enterprise, 30 on other plans.
 ...
+From 1 May 2026 the period depends on the plan: Enterprise files are kept for 90 days and files on all other plans for 30 days. The rule reads a plan tag, so files written before then keep their old date ([[src-support-thread]]).
 ...
-- `export.retention`: 30 days (as of 2026-03-16, [[src-design-doc]])
+- ~~`export.retention`: 30 days (as of 2026-03-16, [[src-design-doc]])~~ superseded by [[src-support-thread]]
+- `export.retention.standard`: 30 days (as of 2026-05-01, [[src-support-thread]])
+- `export.retention.enterprise`: 90 days (as of 2026-05-01, [[src-support-thread]])

Ingest 5: a draft that disagrees

The draft FAQ says exports run every hour and are kept for 7 days. It doesn't claim to change anything, so the schema says: record it, don't choose. The agent adds one line to the retention page and one to the project page:

 - `export.link-expiry`: 7 days (as of 2026-03-16, [[src-design-doc]])
+- `export.retention`: 7 days (as of 2026-05-05, [[src-faq-draft]])

After five ingests the log reads:

## [2026-03-02] ingest | Kickoff notes
- source: raw/2026-03-02-kickoff-notes.md
- created: [[amara-osei]], [[billing-api]], [[export-retention]], [[ledger-export]], [[overview]], [[rui-costa]], [[src-kickoff]]

## [2026-03-16] ingest | Pipeline design doc
- source: raw/2026-03-16-design-doc.md
- created: [[payments-team]], [[src-design-doc]]
- updated: [[amara-osei]], [[billing-api]], [[export-retention]], [[ledger-export]], [[overview]]

## [2026-04-07] ingest | Incident report INC-482
- source: raw/2026-04-07-incident-inc-482.md
- created: [[api-rate-limits]], [[inc-482]], [[src-inc-482]]
- updated: [[amara-osei]], [[billing-api]], [[ledger-export]], [[overview]], [[payments-team]]
...
After ingest Pages Links Current claims Struck through Pages touched Lines added / removed
1 Kickoff 7 12 2 0 7 +95 / −0
2 Design doc 9 22 5 0 7 +53 / −20
3 Incident 12 38 5 2 8 +70 / −17
4 Chat thread 13 44 6 3 5 +35 / −11
5 FAQ draft 14 48 8 3 5 +28 / −10

Lint: what no single ingest could see

src/lint.ts runs four checks over the whole wiki. After the fifth ingest it reports:

Check Found
Contradicting claims 2: export.retention is 30 days (standard), 90 days (Enterprise) and 7 days (FAQ draft); export.schedule is “nightly at 02:00 UTC” (design doc) and “every hour” (FAQ draft)
Links to missing pages 1: [[jun-park]], linked from four pages
Pages nothing links to 0
Claims citing a missing source 0

Note what the lint does not do: pick the newest value. The newest claim here is the FAQ draft's, and it is wrong. Lint proposes fixes and a person approves them. Our scripted fix strikes the draft's two claims through as disputed, notes on the FAQ's source page what needs correcting (“7 days is the download link's expiry”), creates Jun Park's page and updates the overview's open questions. Run again, lint finds nothing.

Query: wiki pages compared with chunk RAG

To compare the two fairly, both sides use the same BM25 ranker (src/retrieve.ts). Chunk RAG ranks the 25 paragraph chunks of the raw sources (each with its document title) and keeps the top 3. The wiki side ranks the 10 topic pages (entities, concepts and the overview) and keeps the top 2, as a stand-in for an agent reading index.md and opening the relevant pages. For each question we listed the facts a correct answer needs and the specific sentences that would mislead, and checked which of them each side retrieved. Struck-through claims are shown but not counted as current.

Question Wiki: needed facts Wiki: misleading statements Chunk RAG: needed facts Chunk RAG: misleading statements
How long are customer exports kept? 2 of 2 0 2 of 2 2: the FAQ draft's “kept for 7 days”, the kickoff's “kept for 30 days, then deleted”
What request rate does the export job use against the Billing API? 2 of 2 0 2 of 2 2: the design doc's “allows 100 requests per second” and “will call it at 80”
Why did the nightly exports fail in April? 2 of 2 0 2 of 2 0

Chunk RAG did find the right answer every time. The problem is what came with it: for the two questions whose answer changed over time, the top chunks also contained the old values, and nothing in the chunks says which one is current. The model answering has to work that out from dates and wording, on every question. The wiki pages had already done it. For the third question, whose whole answer sits in one source that nothing contradicts, chunk RAG did as well as the wiki. That is the honest summary of the trade-off.

This is one small example, not a benchmark. With an embedding retriever, a different chunk size or a larger corpus the rankings would differ.

Trade-offs and failure modes

When to prefer RAG

Wiki memory fits best where knowledge accumulates and changes: a research topic over weeks, an internal project with decisions scattered across meetings and chat, an agent's own notes about a codebase or a user.

Practical advice

  1. Write the schema first. Page types, front matter, how to cite, how to record facts that change, what lint checks. Put it in your agent's instruction file. Expect to revise it after the first ten ingests.
  2. Ingest one source at a time at first, and read the diff. This is when you find out whether the model files things where you would look for them.
  3. Keep raw sources immutable and cite them after every fact. Every claim should lead back to a source that a person can read.
  4. Supersede explicitly; never delete history. Strike old values through with the source that replaced them. Your log and git history then show when and why a fact changed.
  5. Make changeable facts structured. A ## Claims section (or YAML front matter) turns the most important contradiction check into code.
  6. Lint on a schedule, and have a person approve fixes that choose between sources.
  7. File good answers back. If a question took real synthesis, save the answer as a page and link it.
  8. Add search when the index stops fitting in context, and search the wiki, not just the raw sources.

Who does what: the model, code and a person

Wiki memory is often described as "the LLM maintains a wiki", but a working system splits the work three ways. The model does what needs language understanding. Plain code does everything that can be checked exactly, so the model's mistakes are caught rather than compounded. A person decides what neither can.

The model Code A person
Ingest Reads the new document; decides which pages it affects; writes and rewrites page text; crosses out old facts with a reason Stores the files and their Git history; rebuilds the index and the log; enforces that the agent edits only wiki files and that pages stay under a size limit Approves sensitive edits
Checking Spots contradictions written in prose, which need understanding Checks links; compares structured fact values (lint); checks that every quoted sentence exists verbatim in its source; applies the source-ranking rule Decides disputed facts from a review queue
Question time Picks the pages to read and writes the answer, with citations Searches the wiki when the index no longer fits in context Owns the ranking rule and the schema

In this demo, the model's column is written by hand: the page edits and the plain-language notes are scripted. The code's column is real and tested: the tracked changes, index and log, link and fact checks, the ranking rule (src/resolve.ts) and the quote checks.

Taking it to production

Design guidance, not tested here. The demo has five short documents and hand-written edits. This section describes how we would build the same pattern for many large, conflicting documents. Where a claim comes from a source, it is cited; the rest is our own engineering judgement, and the demo does not test it.

The pipeline

Diagram (Mermaid source)
flowchart LR
    NEW["New or changed document"] --> HASH{"Content hash<br/>seen before?"}
    HASH -->|yes| SKIP[Skip]
    HASH -->|no| Q[Ingest queue]
    Q --> ROUTE["Route (cheap model)<br/>index + search over the wiki<br/>→ pages likely affected"]
    ROUTE --> SECT["Per section (strong model)<br/>extract facts: value · scope · source · date"]
    SECT --> MERGE["Merge into pages<br/>(single writer or per-page lock)"]
    MERGE --> CHECK["Code checks<br/>quotes verbatim · links · page size<br/>source-ranking rule"]
    CHECK -->|decided| COMMIT["One Git commit per ingest<br/>index and log rebuilt"]
    CHECK -->|disputed or sensitive| REVIEW[Human review queue]
    REVIEW --> COMMIT
    COMMIT --> LINT["Scheduled lint<br/>+ regression questions"]
Problem What to do
Big documents Don't hand a whole document and the whole wiki to one prompt. Route first: use the index and a search over wiki pages to find the pages a document is likely to affect. Then process it section by section: extract facts from each section, then merge them into pages. Split a page when it grows past a size limit, and leave a short hub page that links to the parts.
A wiki too big for the context window Karpathy reports that an index file is enough "at moderate scale (~100 sources, ~hundreds of pages)" and suggests qmd, a local search engine with "hybrid BM25/vector search and LLM re-ranking", once it isn't. Add hub pages per area, so the index stays short, and search the wiki pages (not the raw chunks) at question time. Claude Code does something similar for its own memory: only the first 200 lines or 25 KB of the MEMORY.md index load at the start of a session, and detail moves into topic files read on demand (docs).
Conflicting facts Store each fact as structured data: value, scope, source, date and status. Many apparent conflicts are scopes: 90 days and 30 days are both right, for Enterprise and for other plans. For real conflicts, use an explicit source-authority ranking, applied by code: approved decision or policy > design doc > incident report or runbook > meeting notes or chat > draft, with the newer document winning within the same rank. Never overwrite silently: cross out the losing value with the reason. When the rule can't decide (same rank, same date, different values), mark the fact disputed, send it to a human review queue, and have answers state the dispute and both sources. The demo implements this rule; see How conflicts are resolved.
Mistakes and drift Treat the raw sources as the truth and the wiki as a cache you can rebuild from them. Require a citation for every fact and check by code that the quoted sentence exists verbatim in its source. Keep a regression set of questions with known answers, and run it with lint on a schedule.
Concurrency Put ingests on a queue. Use a single writer, or per-page locks, so two ingests never rewrite the same page at once. Make one Git commit per ingest, so any ingest can be reviewed or reverted. Skip documents whose content hash has already been ingested, so retries are idempotent.
Cost Ingest cost grows with documents × pages touched per document, not with questions. Use a cheap model for routing and a strong model for the edits. Reprocess only documents that changed (by content hash). Running maintenance in the background, between conversations, is also an option: LangMem calls this "background" memory formation (concepts) and Letta runs "sleep-time" agents that reorganize memory asynchronously (blog).
Deletions, permissions and personal data Keep provenance on every fact, so deleting a source can retract exactly the facts it supported. Let a page inherit the access rules of its most restricted source, or keep separate wikis per audience. Strip personal data before it reaches a page. Anthropic's memory-tool documentation gives similar advice for any file-based memory: validate paths, cap file sizes and periodically delete files that haven't been accessed (docs).
Combining with RAG and knowledge graphs Keep plain retrieval over the raw sources as a fallback, for questions the wiki doesn't cover yet and for exact quotations. Where code needs to traverse typed relationships (who owns what, which service calls which), a knowledge graph complements the pages. Zep, for example, keeps facts in a temporal knowledge graph, records both when an event happened and when it was ingested, and invalidates contradicted edges while keeping their history (paper). Unlike our ranking rule, Zep's paper says it "consistently prioritizes new information" when invalidating, which is a different design choice.

How conflicts are resolved

src/resolve.ts implements the conflict rule above, and the app shows its output. It takes structured facts (value, scope, source, source type and date) and a ranking of source types (corpus/conflicts.json). For each fact and scope, it returns either the current value plus every losing value with its reason, or disputed when the rule can't decide. On the demo's facts:

Fact, scope Result Why
Retention, Enterprise 90 days, from Amara's decision on 20 April The design doc's and kickoff's 30 days and the draft's 7 days all rank below an approved decision
Retention, other plans 30 days, from the same decision The design doc and kickoff agree (kept as support); the draft's 7 days ranks below
Longest date range in one export Disputed: 24 or 12 months Two runbooks, both dated 12 May, disagree. The FAQ draft's 24 months ranks lower and can't settle it, so the question goes to a person

The two runbooks are extra synthetic sources in corpus/review/, added only for this example; they are not part of the walkthrough. Tests check the ranking order, recency within a rank, scope separation, dispute detection, that every quoted sentence exists verbatim in its source, and that the app shows what the resolver returns.

The demo app

The app teaches the idea in eight short sections, read top to bottom. Only the walkthrough plays; everything else is static.

  1. The problem. One question, "How long are customer exports kept?", and the three passages plain retrieval returns from the five raw documents: 7, 30 and 90 days, with nothing to say which is current. Retrieval finds text; it doesn't know which text is still true.
  2. The idea. What wiki memory is, in three sentences. A static diagram compares the two flows: without (question → search five raw documents → conflicting passages) and with (each document read once → the agent updates its pages; question → read one or two up-to-date pages). Then one-line definitions of the five words used later: page, link, index, log and lint.
  3. The walkthrough. It plays by itself once it scrolls into view, at a calm pace, and moves through seven steps: an empty wiki, the five documents, the check (lint) and the approved fix. Each step shows:
    • a one-line caption and the "What the agent did" bullets;
    • the new document, typeset on the left. Each passage that drives an edit is highlighted with a number;
    • the wiki page it changes, on the right, with tracked changes: added text shaded green, and replaced values struck through with the source that replaced them. Each edit carries the same number as its passage. Hovering or tapping either side highlights both. The passage lights up first and the edit follows, one thing at a time, and each pane scrolls to follow the edits. A small map of pages and links, index.md and log.md sit in tabs beside the panes, and the other pages a step changed are one click away. The large Play/Pause button sits next to Previous, Next and the speed control (0.5×, 0.75×, 1×, 1.5×; also ?speed=, remembered in your browser). Any Previous/Next, step-name or tab click pauses autoplay until you press Play again. Scrolling, wheeling or touching a pane stops its auto-scroll for that step. With reduced motion there is no autoplay: every step shows its final state, and the button steps forward.
  4. The payoff. The same question again. The wiki answers from one page, next to the same three retrieval passages, now labelled with which ones are outdated. "Two more questions" shows one case where the wiki helps for the same reason, and one where plain retrieval does just as well.
  5. How conflicts are resolved. The facts the agent extracted (value, scope, source with the quoted sentence, source type, date), the ranking rule in plain words, the resolver's output for each fact and scope (current, with every losing value and its reason, or disputed), and a "Needs a person" review card for the one conflict the rule can't decide.
  6. Who does what. What the model does, what code does and what a person does, with a note on which parts this demo scripts.
  7. Taking it to production. The production pipeline as a static diagram, and a table of the eight problems at scale (big documents, a wiki too big to read, conflicting facts, mistakes and drift, many documents at once, cost, deleted documents and permissions, combining with RAG and knowledge graphs): what goes wrong and how to handle it, with links to the parts the demo shows. Design guidance, shortened from Taking it to production; the demo does not test it.
  8. Recap. Three takeaways, when to use wiki memory, when plain retrieval is enough, how it differs from a knowledge graph, and a reminder that this is a small demo, not a production system.

The plain-language text in each step (lede, key sentences, did bullets) is written by hand in corpus/steps/*/step.json. Tests check that every key sentence appears word for word in its source and that every step shows a page it really changed.

Links for review: ?scene=3 opens a walkthrough step (0 is the empty wiki, 1 to 5 the documents, 6 lint, 7 the fix), &t=2000 freezes it that many milliseconds in, &file=@log opens a file in the panel, ?only=payoff shows a single section (problem, idea, theatre, payoff, conflicts, roles, production, recap), &solo=1 with ?scene= shows only the walkthrough, ?play=1 starts autoplay, and &theme=dark or &theme=light forces a theme.

Run it

Requires Node.js 22.12 or later. No API keys and no network calls apart from Google Fonts. From agents/wiki-memory/:

npm ci
npm start          # builds and serves http://127.0.0.1:4331 (PORT and HOST to change)
npm test           # parsing, diffs, lint, retrieval, layout, and the recorded run
npm run check      # TypeScript type check
npm run data       # rebuilds results/run.json and results/wiki/ from corpus/
npm run export     # static copy of the app in dist/

You should see the opening question and the three passages plain retrieval returns. /article serves this README as a page (built into site/article.html by scripts/article.ts with marked, pinned; Mermaid diagrams appear as source), so the article reads locally and in the static export. npm test should report 22 passing tests; one of them fails if results/run.json is out of date with corpus/ or src/, so run npm run data after editing either.

How it is built

To try your own corpus, replace the files in corpus/raw/ and corpus/steps/, edit src/questions.ts, and run npm run data.

Limitations

Reproducibility

Sources

Related in this repository: Anatomy of a harness (memory and context management as parts of an agent harness) · Chunking strategies · Agents & Workflows community category