Notizie IA Logo

AITalk

Nachrichten und Analysen zur Künstlichen Intelligenz

Ich habe Karpathys LLM Wiki für meine Artikel von Grund auf neu gebaut

Generative AIApplicationsE-learning

llm-wiki-autocostruita.jpg

Ein Jahr lang habe ich auf AiTalk geschrieben und Artikel für Artikel eine Art persönliches Tagebuch über künstliche Intelligenz angesammelt. Irgendwann hatte ich 164 Dateien in einem Ordner, jede voller Konzepte, Namen, Unternehmen und Modelle, die alle zwar erwähnt, aber nie wirklich miteinander verknüpft waren. Ich wusste, dass ich über ein bestimmtes Thema geschrieben hatte, konnte mich aber nicht erinnern, wo. Es wiederzufinden bedeutete, die Dateien nacheinander zu öffnen und auf mein Gedächtnis oder eine glückliche "Suche im Text" zu hoffen. Kurz gesagt: ein Archiv, kein Wissen.

Das Problem erinnerte mich an Szenen aus Memento, dem Film von Christopher Nolan, in dem sich der Protagonist Fakten auf die Haut tätowierte, die er nicht mehr behalten konnte: Jeder Beweis existierte isoliert, ohne einen Faden, der ihn mit dem Rest verband. Ich hatte das gleiche Problem in bescheidenerem Maße – ein Textarchiv statt Tätowierungen –, aber mit einem ähnlichen Gefühl: Informationen vorhanden, Verbindung nicht vorhanden.

Die Lösung, der ich mich näherte, entsprang nicht meiner eigenen Intuition, sondern einem sehr bekannten Pattern, das in der Entwickler-Community unter dem Namen seines Schöpfers Andrej Karpathy kursiert: dem LLM Wiki. Die Idee ist kurz gesagt, dass man ein Modell nicht jedes Mal, wenn man eine Frage stellt, die Dokumente durchsuchen lässt. Stattdessen lässt man es die Dokumente einmal lesen, strukturierte und miteinander verknüpfte Seiten erstellen und lässt es dann dieses bereits kompilierte Wissen konsultieren, wenn man Fragen stellt. Ich hatte bereits in einem vorherigen Artikel darüber gesprochen; hier wollte ich erzählen, was passiert, wenn man aufhört, darüber zu sprechen, und versucht, es tatsächlich zu bauen – mit seinen 164 Dateien, seinen Fehlern und seinen Zweifeln.

Ich bin nicht als Experte für diese Art von Systemen gestartet, sondern als Neugieriger mit einem konkreten Problem, das es zu lösen galt. Was folgt, ist ein ehrlicher Bericht über den Weg, einschließlich der Entscheidungen, die ich verworfen habe, und derer, bei denen ich mir auch heute noch nicht ganz sicher bin.

Die Methode, die ich nicht suchte

Die erste Versuchung bei einem solchen Problem besteht darin, sich auf ein Script zu verlassen. Ich dachte an eine Konzept-Extraktion mit Bibliotheken wie spaCy oder NLTK, eine schnelle Textanalyse. Ich habe das fast sofort verworfen, weil diese Art von Werkzeugen Entitäten und Schlüsselwörter erkennt, nicht aber die Bedeutung einer Argumentation, die sich über einen ganzen Artikel erstreckt. Genau das aber brauchte ich.

Ich dachte auch an Obsidian, vielleicht mit Community-Plugins, die dafür gedacht sind, Wissensgraphen aufzubauen. Ich hatte das in der Vergangenheit bereits für andere Projekte ausprobiert, und das Gefühl war immer dasselbe: Eine Konfigurationsebene zwischen mir und dem Ergebnis entzog mir mehr Kontrolle, als sie einbrachte.

Es blieb der am häufigsten eingeschlagene Weg, ein klassisches RAG-System mit einer Vektordatenbank wie Chroma oder Weaviate. Es funktioniert und ist erprobt, löst aber ein anderes Problem als meines: Es ruft für jede Frage relevante Textfragmente ab, ohne jemals ein Verständnis aufzubauen, das im Laufe der Zeit wächst. Jede Anfrage startet bei Null, ähnlich wie der kleine Fisch Dory aus Findet Nemo, der die Entdeckung der Welt alle paar Sekunden von vorne beginnt. Als Charakter sympathisch, als Wissensarchitektur weniger praktisch.

Ich habe mir auch komplexere Lösungen angesehen. Graphify, worüber ich in der Vergangenheit geschrieben hatte, baut Wissensgraphen auf der Grundlage des syntaktischen Parsings von Code auf, konzipiert für Agenten wie Claude Code oder Cursor auf echten Codebases: ein mächtiges Werkzeug, das jedoch auf einen anderen Anwendungsfall ausgerichtet ist als mein reiner Markdown-Workflow. Microsoft GraphRAG schien mir für ein persönliches Projekt übertrieben, mit einer Infrastruktur, die ich jahrelang hätte pflegen müssen, nur um meine eigenen Artikel abzufragen. MeMex-Zero-RAG ist bereit für die Produktion, wurde jedoch für über MCP verbundene Agenten konzipiert, nicht für eine autonome Nutzung wie meine. Das Community-Projekt obsidian-llm-wiki kam dem, was ich suchte, am nächsten, blieb jedoch an Obsidian gebunden, und ich wollte etwas noch Minimalistischeres.

Schließlich verwarf ich alle fertigen Lösungen, auch diejenigen, die meinem Anwendungsfall am nächsten kamen, und beschloss, das Pattern von Grund auf selbst zu bauen. Nicht aus Snobismus gegenüber bestehenden Werkzeugen, sondern einfach, weil mir die Idee, es mit meinen eigenen Händen zu versuchen – eher spielerisch als aus Notwendigkeit –, als der beste Weg erschien, um wirklich zu verstehen, wie der Mechanismus unter der Oberfläche funktioniert. So hatte ich die Möglichkeit, auf dem Weg etwas zu lernen, selbst wenn das Endergebnis unvollkommen sein sollte.

Als Agenten wählte ich OpenCode, Open Source und modellagnostisch, in der Lage, sowohl mit Cloud-Providern als auch mit lokalen Modellen zu arbeiten: keine fertige Lösung zum Erstellen von Wikis, sondern nur ein guter Ausführer, dem man die Regeln anvertraut. Ich übergab ihm das Karpathy-Pattern in seiner einfachsten Form: einen raw/-Ordner mit den unveränderlichen Quellen, einen wiki/-Ordner mit dem kompilierten Wissen. Von dort aus begann ich, alles andere aufzubauen, eine Regeldatei nach der anderen, ohne Datenbanken, ohne zu verwaltende Embedding-Systeme, ohne Infrastruktur außerhalb des Dateisystems (filesystem).

Wie es in der Praxis funktioniert

Das Projekt lebt in einer einfachen Struktur: In raw/articoli/ befinden sich die 164 originalen Markdown-Dateien; in wiki/ haben sich im Laufe der Zeit drei Unterordner gebildet: concepts/ für Ideen und wiederkehrende Themen, entities/ für Personen, Unternehmen und Werkzeuge sowie synthesis/ für Vergleichs- und übergreifende Analyseseiten, dazu eine index.md als allgemeine Übersichtskarte und ein log.md, das jeden Vorgang protokolliert.

Das Herzstück des Systems ist eine Datei, die ich AGENTS.md genannt habe – der Kompass, den OpenCode vor jedem Eingriff konsultiert. Dort habe ich die Grundregeln festgehalten: Die Dateien in raw/ bleiben unveränderlich; jede Wiki-Seite muss eine zitierte Quelle im Format [Quelle: raw/dateiname.md] enthalten; Verknüpfungen zwischen Seiten folgen der Wikilink-Syntax [[Seitenname]]; und jede Seite trägt ein YAML-Frontmatter mit Titel, Erstellungs- und Aktualisierungsdatum, Kategorie, Tags und Quellen. Ich habe auch einen Mindestqualitätsstandard hinzugefügt: Jede Seite muss mit mindestens zwei anderen existierenden Seiten verknüpft sein, andernfalls bleibt sie verwaist (orphan), isoliert vom Rest des Netzwerks.

Das Schreiben dieser Datei erinnerte mich an das World-Building in manchen Pen-and-Paper-Rollenspielen, bei denen man vor dem Spielen die Regeln der Welt festlegen muss, damit alles, was danach geschieht, eine innere Konsistenz besitzt. AGENTS.md ist genau das: kein Inhalt, sondern Regeln, um Inhalte konsistent zu generieren. immagine1 .jpg Schema der Struktur des AiTalk.it-Wikis

Zehn Batches, viele Überraschungen

Für den Ingest-Prozess habe ich DeepSeek V4 Flash gewählt, das über OpenCode Zen kostenlos verfügbar ist – eine pragmatische statt einer ideologischen Entscheidung: Die Inhalte waren bereits öffentlich, sodass es keine Datenschutzprobleme beim Durchlauf über einen Cloud-Dienst gab, und die Geschwindigkeit des Modells passte gut zu einem Projekt dieser Größenordnung.

Ich ging in Batches vor, nummerierte die Dateien fortlaufend und startete jedes Mal denselben Befehl: "Verarbeite den nächsten Batch noch nicht verarbeiteter Dateien gemäß AGENTS.md", gefolgt von einer Linter-Prüfung (lint), um fehlerhafte Links, fehlende Zitate oder verwaiste Seiten aufzuspüren. Insgesamt zehn Batches, von den ersten fünfzehn Dateien bis zu den letzten vierundzwanzig, mit einer von Batch zu Batch abnehmenden Ausbeute an neu erstellten Seiten: Viele neue Seiten am Anfang, als die grundlegenden Konzepte erst Gestalt annehmen mussten, immer weniger im Laufe der Zeit, weil ein Großteil der neuen Informationen bestehende Seiten anreicherte, anstatt neue zu generieren. Für mich ein Zeichen dafür, dass das Wissensnetzwerk tatsächlich zu einer stabilen Struktur konvergierte.

Das Endergebnis nach den zehn Batches und einer gezielten Nachbearbeitung verbliebener Dateien belief sich auf 154 Inhaltsseiten aus 164 Quellartikeln: 68 Konzeptseiten, 80 Entitätenseiten, 5 Syntheseseiten, null fehlerhafte Links, null verwaiste Seiten, gültiges Frontmatter auf allen 156 Seiten insgesamt (inklusive Index und Log) und ein Schnitt von fast acht Links pro Seite. Die Hauptknotenpunkte (hubs) des Netzwerks mit den meisten eingehenden Links waren sicherheit-ai, large-language-models, KI-Regulierung und KI-Ethik. Keine Überraschung, wenn man bedenkt, wie sehr diese Themen in einem Großteil meiner Texte wiederkehren, aber es durch die Struktur des Wikis selbst bestätigt zu sehen, war erfreulich – quasi ein Gegenbeweis für die Konsistenz meiner eigenen Arbeit.

Die größte Überraschung war jedoch der Blick auf den belegten Speicherplatz auf der Festplatte: Das gesamte Projekt, alle 154 Seiten inklusive Index und Log, wiegt 4,4 Megabyte. Ein RAG-System mit Vektorembeddings für dasselbe Artikelvolumen hätte wahrscheinlich zwischen 50 und 200 Megabyte belegt, wenn man die für die semantische Suche erforderlichen Indizes und Vektoren berücksichtigt. Hier gibt es stattdessen nur strukturierten Text, keine Chunks, keine zu speichernden Embeddings: Das kompilierte Wissen wiegt sogar weniger als die Quellartikel, aus denen es generiert wurde. Ein Wiki, das bequem auf einen USB-Stick passt, sich in wenigen Sekunden über Git synchronisiert und mit einfachem Kopieren und Einfügen auf einen anderen Computer übertragen lässt. Es ist schwer, nicht darüber nachzudenken, wie sehr die Infrastruktur rund um die künstliche Intelligenz normalerweise die entgegengesetzte Tendenz hat – ständig an Größe und Komplexität zuzunehmen. immagine2.jpg Screenshot einer Abfrage des AiTalk.it LLM-Wikis über OpenCode und ein Cloud-Modell (DeepSeek V4 Flash)

Wo der Mensch notwendig bleibt

Es wäre bequem, das Projekt als automatischen Prozess darzustellen, der gestartet und bis zum Endergebnis sich selbst überlassen wurde. Dem war nicht so, und genau dieser Punkt erscheint mir am interessantesten.

Während der zehn Batches musste ich mehrmals eingreifen. Drei Dateien waren zurückgeblieben, nur im Index vorhanden und noch nicht verarbeitet, sodass ich einen gezielten Ingest starten musste, um sie nachzuholen. Einige wichtige Entitäten wie Dario Amodei, Elon Musk, Sam Altman, Jensen Huang, Hugging Face, Tesla und Waymo hatten keine eigene Seite, obwohl sie in mehreren Artikeln zitiert wurden – fünfzehn Seiten, die ich nachträglich hinzugefügt habe, nachdem mir die Lücke erst bei der Abfrage des Wikis auffiel. Ich korrigierte einen Kodierungsfehler (encoding) im Namen einer Datei, korrigierte neunzehn Seiten mit falschem Aktualisierungsdatum, fügte einunddreißig Konzepten, die nur eine hatten, eine zweite Quelle hinzu und integrierte einen Fazit-Abschnitt in vier Syntheseseiten, denen dieser fehlte.

Keiner dieser Eingriffe war dramatisch, aber alle haben mir etwas über die realen Grenzen des Systems gelehrt: Wenn die Batches groß sind und viele Dateien in einer einzigen Session verarbeitet werden, neigt das Modell dazu, kleinere Details aus den Augen zu verlieren. Das ist ähnlich wie beim Lesen zu vieler Kapitel eines Gesellschaftsromans in einer einzigen Sitzung, bei dem man am Ende einige Nebenfiguren verwechselt. Es erinnerte mich an bestimmte Mangas mit Dutzenden von Charakteren, die im selben Handlungsbogen eingeführt werden, bei denen selbst der aufmerksamste Leser einige Nebenstränge aus den Augen verliert, um sie erst einige Bände später wiederzufinden.

Nun, da ich das Archiv im Wiki angeglichen habe, werde ich jedoch künftig mit dem Ingest von jeweils einem Artikel statt mit großen Batches fortfahren. Diese Hypothese muss ich in der Praxis erst noch verifizieren. Meine Intuition sagt mir, dass sich die Präzision verbessert, wenn pro Ingest weniger Informationen verarbeitet werden, aber ich habe noch nicht genügend Daten, um das mit Sicherheit sagen zu können. Es bleibt die wichtigste Lehre des gesamten Weges: Das Pattern von Karpathy ist keine vollständige Automatisierung, sondern eine Zusammenarbeit zwischen Mensch und Modell, bei der Ersterer überwacht, korrigiert und bereichert, was Letzteres generiert.

Dasselbe Wiki, ohne Cloud

Nachdem das Wiki mit dem Cloud-Modell fertiggestellt war, fragte ich mich, ob das gesamte System auch offline mit einem privaten Modell auf meinem Computer funktionieren könnte. Die Gründe dafür waren vielfältig: Datenschutz, da die Daten in diesem Fall den Rechner nie verlassen würden; Kontrolle, da ich jedes Modell ohne Abhängigkeit von einem externen Anbieter wählen könnte; und die Kosten, die nach dem Laden des Modells entfallen würden.

Ich nutzte LM Studio als lokale Engine mit dem auf Port 8001 aktiven Server. Als Modell wählte ich Ornith 1.0 mit 35 Milliarden Parametern, über das ich in einem eigenen Artikel geschrieben hatte: In meinen Versuchen hat es sich sowohl in Tests als auch im täglichen Gebrauch als das präziseste der getesteten Modelle erwiesen. Dennoch ist es möglich, jedes andere in LM Studio geladene Modell auszuwählen.

Um OpenCode mit dem lokalen Server zu verbinden, wählte ich den manuellen Weg und änderte die Konfigurationsdatei direkt mit einem neuen Provider, der auf den lokalen Endpoint verweist. Ich verzichtete auf das Plugin opencode-lmstudio, das zwar konkrete Vorteile wie die automatische Erkennung geladener Modelle und die dynamische Verwaltung von Ports und Endpoints geboten hätte. Ich entschied mich aus einem praktischen Grund für die manuelle Konfiguration: Mein Anwendungsfall sieht gelegentliche Abfragen auf einem bereits vollständigen Wiki vor, keinen häufigen Modellwechsel. Zudem gab es einen persönlicheren Grund: Ich wollte genau verstehen, was in dieser Konfigurationsdatei steht, ohne Zwischenhändler. Ich räume ein, dass das Plugin für eine dynamischere Nutzung mit häufigen Architekturwechseln die bequemere Wahl bliebe.

Die Tests haben mich positiv überrascht. Eine einfache Frage zu einem bereits behandelten Konzept wie MTV fand korrekt Verweis auf der Seite, die Musik und künstlicher Intelligenz gewidmet ist. Eine komplexere Frage, die darum bat, die wichtigsten Unternehmen der Branche und ihre jeweiligen CEOs unter Angabe von Quellen aufzulisten, lieferte eine präzise Antwort zu acht Unternehmen. Die Zitate verwiesen korrekt auf die kompilierten Wiki-Seiten und nicht auf die ursprünglichen Rohdateien – ein Zeichen dafür, dass das Modell tatsächlich die von mir aufgebaute Struktur nutzte. Es hat sogar selbstständig zwei Lücken identifiziert: Mark Zuckerberg, der nur am Rande erwähnt wurde, und Sundar Pichai, der völlig fehlte. Das ist ein wichtiges Detail, denn das Modell hat bei einer Suche Lücken aufgespürt und mir ermöglicht, diese mit einer einfachen Anfrage zu schließen.

Die erste Antwort traf langsam ein – die Zeit, die benötigt wird, um den gesamten Wiki-Kontext zu laden –, die folgenden dank Caching deutlich schneller. Ich musste das Kontextlimit von 25.000 auf 160.000 Token anheben, damit das Modell die gesamte Struktur ohne Kürzungen lesen konnte. Dabei stellte ich fest, dass das lokale Modell im Gegensatz zum für den Ingest verwendeten Cloud-Modell dem Pattern nicht automatisch folgt, wenn man es nicht explizit anweist, die AGENTS.md zu lesen und nur aus dem Ordner wiki/ zu schöpfen. Ein Detail, das klein erscheint, aber den Unterschied zwischen einer relevanten und einer generischen Antwort ausmacht. immagine3.jpg Screenshot einer Abfrage des AiTalk.it LLM-Wikis über OpenCode und ein lokales Modell (LM Studio + Ornith 1.0 35B)

Was noch fehlt

Am Ende des Weges nehme ich mehr offene Fragen als endgültige Gewissheiten mit nach Hause, und ich glaube, das ist auch gut so. Ich habe gelernt, dass Karpathys Pattern in der Praxis mit reinen Open-Source-Werkzeugen und ohne komplexe Infrastrukturen funktioniert. Ich habe gelernt, dass die menschliche Aufsicht unverzichtbar bleibt und keine vorübergehende Notlösung ist, bis bessere Modelle kommen. Und ich habe gelernt, dass die Kompaktheit dieses Ansatzes – diese 4,4 Megabyte insgesamt – kein marginales technisches Detail ist, sondern eine Eigenschaft, die das Projekt tragbar und teilbar macht.

Es bleiben Fragen offen, auf die ich noch keine Antwort habe. Wird der Ingest Datei für Datei, den ich gerade anstelle großer Batches eingeführt habe, die Präzision wirklich so verbessern, wie ich glaube, oder führt er nur zu mehr Langsamkeit ohne proportionalen Nutzen? Ich würde das Hinzufügen zum Wiki gerne automatisieren, sobald ich einen neuen Artikel veröffentliche, statt mich erst Wochen später daran zu erinnern. Ich würde auch gerne einen eigenen Abschnitt für Sprachmodelle als eigenständige Entitäten hinzufügen, allen voran ChatGPT und Claude, die heute nur am Rande auf anderen Seiten erwähnt werden.

Schließlich bleibt eine grundlegendere Frage, die mich während des gesamten Weges begleitet hat: Wie viel von diesem kompilierten Wissen spiegelt wirklich das wider, was ich denke, und wie viel ist bereits eine Synthese des Modells, die sich zwischen mich und meine eigenen Artikel geschlichen hat? Eine endgültige Antwort habe ich nicht. Vorerst beschränke ich mich darauf zu kontrollieren, zu korrigieren und zu bereichern, wohlwissend, dass das Projekt darauf ausgelegt ist, sich durch das Lernen neuer Dinge auf dem Weg zu verbessern – genau wie ich es versuche.