← Back to homepage

ML Wiki

A personal research wiki that ingests papers, Zotero libraries, PDFs, and experiment logs into a structured directory of interlinked markdown pages, with semantic fragment search, contradiction detection, and staleness tracking, all orchestrated through Claude Code.

Overview

ML Wiki turns a reading list into a maintained body of knowledge. It ingests papers, Zotero libraries, PDFs, markdown notes, and ML experiment logs, then produces a directory of interlinked markdown pages: paper summaries, topic Maps of Content, syntheses, and idea pages. The current wiki holds ~1,070 paper pages, ~121 topic pages, and ~4,570 searchable knowledge fragments drawn from four Zotero libraries.

Why a wiki, not RAG

Most LLM-and-document workflows are retrieval-based: upload files, retrieve relevant chunks at query time, generate an answer from scratch. Nothing accumulates. A subtle question that spans five papers re-derives the same fragments every time.

ML Wiki takes the opposite approach. When a new paper is added, the LLM reads it, extracts the key knowledge, and integrates it into the existing wiki. Cross-references are already in place. Contradictions have already been flagged. The synthesis already reflects everything read so far.

The maintenance problem

Personal knowledge bases die from bookkeeping, not from a lack of reading: updating cross-references, keeping summaries current, noting when new evidence contradicts old claims. The maintenance burden grows faster than the value. LLMs flip that: they don’t get bored, don’t forget a cross-reference, and can touch every file in one pass. Maintenance cost drops to near zero, so the wiki stays alive.

Architecture

Three layers, each with a single responsibility:

  • CLI layer. A Python Click CLI that orchestrates everything: resolves config, calls scripts, dispatches LLM calls, validates output.
  • LLM layer. OpenRouter calls with JSON output, validated against JSON schemas and domain-specific post-validators.
  • Script layer. Python scripts for all file I/O, index CRUD, source extraction, and page assembly. No script calls another; they communicate via stdin/stdout/files/exit codes.

A JSONL index is the single source of truth. Fragments (self-contained one- or two-sentence claims, methods, and findings) are the atomic units: they power meaning-based search and let the linter detect contradictions across papers that share a tag.

Staleness tracking runs at build time. A check flags synthesis and idea pages whose last-improved timestamp predates newer entries sharing two or more tags (along with idea pages never improved at all), and a batch pass then inserts or clears a staleness banner at the top of each affected page.

Design notes

The system enforces a strict separation of concerns: Zotero is the library, ml-journal is the experiment log, the wiki is the synthesis layer, Obsidian is the viewer. Data flows one direction (sources to index to wiki to viewer), and nothing writes back upstream.

It also separates by cost. Index operations (ingest, sync, diff) are fast and free; LLM operations (render, query, synthesis) cost time and tokens. The two are always decoupled, so ingesting an entire Zotero library takes seconds and rendering happens on demand.