Beispiel für den Vault-Speicherort
# Obsidian als KI-Infrastruktur: Die umfassende technische Referenz
Die wichtigsten Erkenntnisse
Context Engineering, nicht Notizen machen. Der Wert eines Obsidian-Vaults für KI liegt nicht in den Notizen selbst, sondern in der Retrieval-Schicht, die sie abfragbar macht. Ein Vault mit 16.000 Dateien ohne Retrieval ist eine Write-only-Datenbank. Ein Vault mit 200 Dateien, hybrider Suche und MCP-Integration hingegen ist eine KI-Wissensbasis. Die Retrieval-Infrastruktur ist das Produkt. Die Notizen sind das Rohmaterial.
Hybrides Retrieval schlägt reine Stichwort- oder reine semantische Suche. BM25 erfasst exakte Bezeichner und Funktionsnamen. Vektorsuche erfasst Synonyme und konzeptuelle Übereinstimmungen über unterschiedliche Terminologie hinweg. Reciprocal Rank Fusion (RRF) vereint beide Methoden, ohne dass eine Score-Kalibrierung erforderlich ist. Keine der beiden Methoden allein deckt beide Fehlermodi ab. Forschungsergebnisse zum MS MARCO Passage Ranking bestätigen dieses Muster: Hybrides Retrieval übertrifft konsistent jede Einzelmethode.3 Der Deep Dive zum hybriden Retriever behandelt die RRF-Mathematik, durchgerechnete Beispiele mit realen Zahlen, eine Fehlermodus-Analyse und einen interaktiven Fusion-Rechner.
MCP gibt KI-Tools direkten Zugriff auf den Vault. Model Context Protocol (MCP)-Server stellen den Retriever als Tool bereit, das Claude Code, Codex CLI, Cursor und andere KI-Tools direkt aufrufen können. Der Agent fragt den Vault ab, erhält nach Relevanz sortierte Ergebnisse mit Quellenangabe und nutzt den Kontext, ohne ganze Dateien laden zu müssen. Der MCP-Server ist ein dünner Wrapper um die Retrieval-Engine.
Local-first bedeutet null API-Kosten und vollständige Privatsphäre. Der gesamte Stack läuft auf einer einzigen Maschine: SQLite für die Speicherung, Model2Vec für Embeddings, FTS5 für die Stichwortsuche, sqlite-vec für Vektor-KNN. Keine Cloud-Dienste, keine API-Aufrufe, keine Netzwerkabhängigkeit. Persönliche Notizen verlassen niemals den Rechner. Das vollständige Re-Embedding von 49.746 Chunks würde zu OpenAI-API-Preisen etwa 0,30 $ kosten — die eigentlichen Kosten sind jedoch Latenz, Datenschutzrisiko und die Netzwerkabhängigkeit für ein System, das offline funktionieren sollte.4
Inkrementelle Indexierung hält das System in unter 10 Sekunden aktuell. Durch den Vergleich von Dateiänderungszeiten werden Änderungen erkannt. Nur geänderte Dateien werden neu in Chunks aufgeteilt und neu eingebettet. Eine vollständige Neuindexierung dauert auf Apple-M-Series-Hardware etwa vier Minuten. Inkrementelle Aktualisierungen bei einem typischen Tagespensum an Bearbeitungen laufen in unter zehn Sekunden. Das System bleibt ohne manuellen Eingriff aktuell.
Die Architektur skaliert von 200 bis über 20.000 Notizen. Dasselbe dreischichtige Design (Aufnahme, Retrieval, Integration) funktioniert bei jeder Vault-Größe. Beginnen Sie mit einer reinen BM25-Suche über einen kleinen Vault. Fügen Sie Vektorsuche hinzu, wenn Stichwort-Kollisionen zum Problem werden. Ergänzen Sie RRF-Fusion, wenn Sie sowohl exakte als auch semantische Treffer benötigen. Jede Schicht ist unabhängig nützlich und unabhängig entfernbar.
So nutzen Sie diesen Leitfaden
Dieser Leitfaden deckt das vollständige System ab. Ihr Einstiegspunkt hängt davon ab, wo Sie stehen:
| Sie sind… | Starten Sie hier | Dann erkunden Sie |
|---|---|---|
| Neu bei Obsidian + KI | Warum Obsidian als KI-Infrastruktur, Schnellstart | Vault-Architektur, MCP-Server-Architektur |
| Bestehender Vault, KI-Zugriff gewünscht | MCP-Server-Architektur, Claude Code-Integration | Embedding-Modelle, Volltextsuche |
| Aufbau eines Retrieval-Systems | Die vollständige Retrieval-Pipeline, Reciprocal Rank Fusion | Performance-Optimierung, Fehlerbehebung |
| Team- oder Unternehmenskontext | Entscheidungsrahmen, Knowledge-Graph-Muster | Entwickler-Workflow-Rezepte, Migrationsleitfaden |
Abschnitte mit der Markierung Contract enthalten Implementierungsdetails, Konfigurationsblöcke und Fehlermodi. Abschnitte mit der Markierung Narrative behandeln Konzepte, Architekturentscheidungen und die Begründung hinter Designentscheidungen. Abschnitte mit der Markierung Recipe bieten schrittweise Anleitungen.
Warum Obsidian als KI-Infrastruktur
Die These dieses Leitfadens: Obsidian-Vaults sind das beste Substrat für persönliche KI-Wissensbasen, weil sie lokal gespeichert, im Klartextformat, graphbasiert strukturiert sind und Sie jede Schicht des Stacks selbst kontrollieren.
Was Obsidian der KI bietet, was Alternativen nicht bieten
Markdown-Klartextdateien. Jede Notiz ist eine .md-Datei in Ihrem Dateisystem. Kein proprietäres Format, kein Datenbankexport, keine API erforderlich, um den Inhalt zu lesen. Jedes Tool, das Dateien lesen kann, kann Ihren Vault lesen. grep, ripgrep, Pythons pathlib, SQLite FTS5 — sie alle arbeiten direkt mit den Quelldateien. Wenn Sie ein Retrieval-System aufbauen, indexieren Sie Dateien, keine API-Antworten. Der Index ist immer konsistent mit der Quelle, denn die Quelle ist das Dateisystem.
Local-first-Architektur. Der Vault befindet sich auf Ihrem Rechner. Kein Server, keine Abhängigkeit von Cloud-Synchronisation, keine API-Ratenlimits, keine Nutzungsbedingungen, die regeln, wie Sie Ihre eigenen Inhalte verarbeiten. Sie können Ihre Notizen einbetten, indexieren, in Chunks aufteilen und durchsuchen — ohne externen Dienst. Das ist für die KI-Infrastruktur entscheidend, denn die Retrieval-Pipeline läuft so schnell, wie Ihre Festplatte es erlaubt, nicht so schnell, wie ein API-Endpunkt antwortet. Auch für die Privatsphäre ist das relevant: Persönliche Notizen mit Zugangsdaten, Gesundheitsdaten, Finanzinformationen und privaten Reflexionen verlassen niemals Ihren Rechner.
Graphstruktur durch wiki-links. Obsidians [[wiki-link]]-Syntax erzeugt einen gerichteten Graphen über Notizen hinweg. Eine Notiz über die OAuth-Implementierung verlinkt zu Notizen über Token-Rotation, Session-Management und API-Sicherheit. Die Graphstruktur kodiert von Menschen kuratierte Beziehungen zwischen Konzepten. Vektor-Embeddings erfassen semantische Ähnlichkeit, doch wiki-links erfassen intentionale Verbindungen, die der Autor beim Nachdenken über das Thema hergestellt hat. Der Graph ist ein Signal, das Embeddings nicht replizieren können.
Plugin-Ökosystem. Obsidian verfügt über mehr als 2.500 Community-Plugins (Stand März 2026, gegenüber über 1.800 Mitte 2025). Dataview macht Ihren Vault wie eine Datenbank abfragbar. Templater generiert Notizen aus Vorlagen mit JavaScript-Logik. Git-Integration synchronisiert Ihren Vault mit einem Repository. Linter erzwingt Formatierungskonsistenz. Das Bases-Core-Plugin (eingeführt in v1.9.10) ergänzt datenbankähnliche Ansichten — Tabellen, Galerien, Kalender und Kanban-Boards — über Vault-Dateien, wobei frontmatter-Eigenschaften als Felder dienen und als .base-Dateien gespeichert werden.27 Diese Plugins verleihen dem Vault Struktur, ohne das zugrunde liegende Klartextformat zu verändern. Das Retrieval-System indexiert die Ausgabe dieser Plugins, nicht die Plugins selbst.
Über 5 Millionen Benutzer. Obsidian hat eine große, aktive Community, die Vorlagen, Workflows, Plugins und Dokumentation produziert. Wenn Sie auf ein Problem mit der Vault-Organisation oder Plugin-Konfiguration stoßen, hat wahrscheinlich bereits jemand eine Lösung dokumentiert. Die Community erstellt außerdem Obsidian-nahe Tools: MCP-Server, Indexierungsskripte, Publishing-Pipelines und API-Wrapper.
Was ein Dateisystem allein nicht bietet
Ein Verzeichnis mit Markdown-Dateien bietet zwar den Klartextvorteil, es fehlen jedoch drei Dinge, die Obsidian hinzufügt:
-
Bidirektionale Links. Obsidian verfolgt Backlinks automatisch. Wenn Sie von Notiz A auf Notiz B verlinken, zeigt Notiz B an, dass Notiz A darauf verweist. Das Graph-Panel visualisiert Verbindungscluster. Dieses bidirektionale Bewusstsein ist Metadaten, die ein rohes Dateisystem nicht bereitstellt.
-
Live-Vorschau mit Plugin-Rendering. Dataview-Abfragen, Mermaid-Diagramme und Callout-Blöcke werden in Echtzeit gerendert. Das Schreiberlebnis ist reichhaltiger als in einem Texteditor, während das Speicherformat Klartext bleibt. Sie schreiben und organisieren in einer komfortablen Umgebung; das Retrieval-System indexiert das rohe Markdown.
-
Community-Infrastruktur. Plugin-Entdeckung, Theme-Marktplatz, Sync-Service (optional), Publish-Service (optional) und ein Dokumentationsökosystem. Sie können jede einzelne Funktion mit eigenständigen Tools nachbilden, doch Obsidian bündelt sie zu einem kohärenten Workflow.
Was Obsidian NICHT kann (und was Sie selbst bauen)
Obsidian enthält keine Retrieval-Infrastruktur. Es bietet eine einfache Suche (Volltext, Dateiname, Tag), aber keine Embedding-Pipeline, keine Vektorsuche, kein Fusion-Ranking, keinen MCP-Server, keine Credential-Filterung, keine Chunking-Strategie und keine Integrations-Hooks für externe KI-Tools. Dieser Leitfaden behandelt die Infrastruktur, die Sie auf Obsidian aufbauen. Der Vault ist das Substrat. Die Retrieval-Pipeline, der MCP-Server und die Integrations-Hooks sind die Infrastruktur.
Die hier beschriebene Architektur ist Markdown-first, nicht Obsidian-exklusiv. Wenn Sie Logseq, Foam, Dendron oder ein einfaches Verzeichnis mit Markdown-Dateien verwenden, funktioniert die Retrieval-Pipeline identisch. Der Chunker liest .md-Dateien. Der Embedder verarbeitet Textstrings. Der Indexer schreibt in SQLite. Keine dieser Komponenten hängt von Obsidian-spezifischen Funktionen ab. Obsidians Beitrag ist die Schreib- und Organisationsumgebung, die die Markdown-Dateien produziert, welche der Retriever indexiert.
Schnellstart: Erster KI-verbundener Vault
Dieser Abschnitt verbindet einen Vault in fünf Minuten mit einem KI-Tool. Sie installieren Obsidian, erstellen einen Vault, installieren einen MCP-Server und führen Ihre erste Abfrage aus. Der Schnellstart verwendet einen Community-MCP-Server für sofortige Ergebnisse. Spätere Abschnitte behandeln den Aufbau einer maßgeschneiderten Retrieval-Pipeline für den Produktionseinsatz.
Voraussetzungen
- macOS, Linux oder Windows
- Node.js 18+ (für den MCP-Server)
- Obsidian 1.12+ (für CLI-Integration; frühere Versionen funktionieren für reine MCP-Setups)
- Claude Code, Codex CLI oder Cursor installiert
Schritt 1: Vault erstellen
Laden Sie Obsidian von obsidian.md herunter und erstellen Sie einen neuen Vault. Wählen Sie einen Speicherort, den Sie sich merken können — der MCP-Server benötigt den absoluten Pfad.
# Example vault location
~/Documents/knowledge-base/
Fügen Sie einige Notizen hinzu, damit der Retriever etwas zu durchsuchen hat. Bereits 10–20 Notizen reichen aus, um Ergebnisse zu sehen. Jede Notiz sollte eine .md-Datei mit einem aussagekräftigen Titel und mindestens einem Absatz Inhalt sein.
Schritt 2: MCP-Server installieren
Mehrere Community-MCP-Server bieten sofortigen Vault-Zugriff. Das Ökosystem ist im Zeitraum 2025–2026 erheblich gewachsen. Zu den bemerkenswerten jüngsten Updates gehört MCPVault v0.11.0 (März 2026), das list_all_tags zum Scannen von Frontmatter und Hashtags mit Zählwerten hinzufügte, die Handhabung von Ordnern mit Punkten verbesserte und Unterstützung für .base- und .canvas-Dateien einführte.25 Das Paket wurde außerdem auf npm in @bitbonsai/mcpvault umbenannt.
| Server | Autor | Transport | Plugin erforderlich | Hauptfunktion |
|---|---|---|---|---|
| obsidian-mcp-server | StevenStavrakis | STDIO | Nein | Leichtgewichtig, dateibasiert |
| mcp-obsidian | MarkusPfundstein | STDIO | Lokale REST-API | Vollständiges Vault-CRUD über REST |
| obsidian-mcp-tools | jacksteamdev | STDIO | Ja (Plugin) | Semantische Suche + Templater |
| obsidian-claude-code-mcp | iansinnott | WebSocket | Ja (Plugin) | Auto-Discovery für Claude Code |
| obsidian-mcp-server | cyanheads | STDIO | Lokale REST-API | Tags, Frontmatter-Verwaltung |
Für den Schnellstart ist ein dateibasierter Server, der .md-Dateien direkt liest, die einfachste Option:
npm install -g obsidian-mcp-server
Schritt 3: KI-Tool konfigurieren
Claude Code — fügen Sie Folgendes zu ~/.claude/settings.json hinzu:
{
"mcpServers": {
"obsidian": {
"command": "obsidian-mcp-server",
"args": ["--vault", "/absolute/path/to/your/vault"]
}
}
}
Codex CLI — fügen Sie Folgendes zu .codex/config.toml hinzu:
[mcp_servers.obsidian]
command = "obsidian-mcp-server"
args = ["--vault", "/absolute/path/to/your/vault"]
Cursor — fügen Sie Folgendes zu .cursor/mcp.json hinzu:
{
"mcpServers": {
"obsidian": {
"command": "obsidian-mcp-server",
"args": ["--vault", "/absolute/path/to/your/vault"]
}
}
}
Schritt 4: Erste Abfrage ausführen
Öffnen Sie Ihr KI-Tool und stellen Sie eine Frage, die Ihre Vault-Notizen beantworten können:
Search my Obsidian vault for notes about [topic you wrote about]
Das KI-Tool ruft den MCP-Server auf, der Ihren Vault durchsucht und passende Inhalte zurückgibt. Sie sollten Ergebnisse mit Dateipfaden und relevanten Auszügen sehen.
Was Sie gerade aufgebaut haben
Sie haben eine lokale Wissensdatenbank über ein Standardprotokoll mit einem KI-Tool verbunden. Der MCP-Server liest Ihre Vault-Dateien, führt eine einfache Suche durch und gibt Ergebnisse zurück. Dies ist die minimale funktionsfähige Version.
Was dieser Schnellstart NICHT bietet: - Hybrides Retrieval (BM25 + Vektorsuche + RRF-Fusion) - Embedding-basierte semantische Suche - Credential Filtering - Inkrementelle Indizierung - Hook-basierte automatische Kontextinjektion
Der Rest dieses Leitfadens behandelt den Aufbau jeder dieser Fähigkeiten. Der Schnellstart belegt das Konzept. Die vollständige Pipeline liefert produktionsreifes Retrieval.
Obsidian CLI für KI-Workflows
Obsidian 1.12 (Februar 2026) führte eine integrierte Kommandozeilenschnittstelle ein, die eine neue Integrationsebene für KI-Workflows eröffnet.28 Die CLI fungiert als Fernsteuerung für die Obsidian-Benutzeroberfläche — Obsidian muss laufen (oder wird beim ersten Befehl automatisch gestartet). Aktivieren Sie sie unter Einstellungen > Allgemein > Command line interface.
Warum die CLI für KI-Infrastruktur wichtig ist
Die CLI bietet programmatischen Zugriff auf Obsidian-native Operationen, die zuvor die Benutzeroberfläche oder Plugin-APIs erforderten. Für KI-Workflows sind folgende Fähigkeiten entscheidend:
- Suche aus Skripten und Hooks.
obsidian search "query"undobsidian search:context "query"führen Vault-Suchen aus jedem Shell-Skript, Hook oder jeder Automatisierungspipeline aus. Die Variantesearch:contextgibt Trefferzeilen mit umgebendem Kontext zurück — nützlich, um Ergebnisse in KI-Prompts einzuspeisen. - Automatisierung täglicher Notizen.
obsidian dailyöffnet oder erstellt die heutige tägliche Notiz. In Kombination mit Shell-Scripting ermöglicht dies automatisierte tägliche Briefing-Workflows — ein Hook kann KI-generierte Zusammenfassungen an die tägliche Notiz anhängen. - Template-basierte Notizerstellung.
obsidian template listundobsidian template creategenerieren Notizen aus Templater- oder Core-Templates und ermöglichen KI-Agenten, strukturierte Vault-Einträge zu erstellen, ohne direkt Markdown-Dateien zu schreiben. - Property-Verwaltung.
obsidian property setundobsidian property getlesen und schreiben Frontmatter-Properties und ermöglichen Metadaten-Updates aus Skripten, ohne YAML parsen zu müssen. - Plugin-Steuerung.
obsidian plugin enable/disable/listverwaltet Plugins programmatisch — nützlich zum Ein- und Ausschalten von Indizierungs-Plugins während Batch-Operationen. - Aufgabenverwaltung.
obsidian task list/add/completebietet strukturierten Aufgabenzugriff — nützlich für KI-Agenten, die Arbeitspakete im Vault verwalten.
CLI vs. MCP für KI-Zugriff
Die CLI und MCP-Server erfüllen unterschiedliche Rollen und ergänzen sich, statt miteinander zu konkurrieren:
| Aspekt | Obsidian CLI | MCP-Server |
|---|---|---|
| Aufrufer | Shell-Skripte, Hooks, Cron-Jobs | KI-Agenten (Claude Code, Codex, Cursor) |
| Protokoll | POSIX-Prozess (stdin/stdout/stderr) | MCP (JSON-RPC über STDIO oder HTTP) |
| Stärke | Obsidian-native Operationen (Templates, Plugins, Properties) | Benutzerdefiniertes Retrieval (Embeddings, BM25, RRF-Fusion) |
| Einschränkung | Keine Vektorsuche, keine Embedding-Pipeline | Kein Zugriff auf Obsidian-interne Operationen |
| Ideal für | Automatisierungsskripte, Intake-Pipelines, Hook-Aktionen | Echtzeit-KI-Agentenabfragen während Sitzungen |
Empfehlung: Verwenden Sie die CLI für Intake-Automatisierung (Notizen erstellen, Properties verwalten, Obsidian-native Suche ausführen) und MCP für Retrieval (hybride Suche mit Embeddings). Ein PreToolUse-Hook kann obsidian search:context als schnelle Vorabprüfung aufrufen, bevor auf den vollständigen MCP-Retriever für gerankte Ergebnisse zurückgegriffen wird.
Beispiel: CLI-gesteuerter Intake-Hook
#!/bin/bash
# Hook: append today's signals to daily note via CLI
DATE=$(date +%Y-%m-%d)
SUMMARY="$1"
obsidian daily # ensure daily note exists
obsidian file append "Daily Notes/${DATE}.md" "## AI Summary\n${SUMMARY}"
Obsidian Agent-Plugins
Eine wachsende Kategorie von Obsidian-Plugins bettet KI-Coding-Agenten direkt in die Vault-Oberfläche ein und bietet eine Alternative zur externen MCP-Server-Konfiguration. Diese Plugins führen den KI-Agenten in Obsidians Seitenleiste aus, anstatt sich von einem externen Tool zu verbinden.
Claudian
Claudian bettet Claude Code als KI-Kollaborateur in den Vault ein. Das Vault-Verzeichnis wird zum Arbeitsverzeichnis von Claude und gewährt volle agentische Fähigkeiten: Dateien lesen/schreiben, Suche, Bash-Befehle und mehrstufige Workflows.29
Schlüsselfunktionen für KI-Infrastruktur:
- Kontextbewusste Prompts. Hängt automatisch die fokussierte Notiz an, unterstützt @notename-Dateiverweise, Tag-basierte Ausschlüsse und Editor-Auswahl als Kontext.
- Vision-Unterstützung. Analysiert Bilder per Drag-and-Drop, Einfügen oder Dateipfad — nützlich für die Verarbeitung von Screenshots und Diagrammen, die im Vault erfasst wurden.
- Slash-Befehle. Erstellen Sie wiederverwendbare Prompt-Vorlagen, die per /command ausgelöst werden, und ermöglichen Sie standardisierte Vault-Operationen.
- Berechtigungsmodi. YOLO (automatische Genehmigung), Safe (jede Aktion genehmigen) und Plan (nur Planung) mit einer Sicherheits-Blockliste und Vault-Begrenzung.
Agent Client
Agent Client bringt Claude Code, Codex CLI und Gemini CLI über das Agent Client Protocol (ACP) in eine einheitliche Obsidian-Seitenleiste.30
Schlüsselfunktionen:
- Multi-Agent-Wechsel. Chatten Sie mit Claude Code, Codex oder Gemini CLI über dasselbe Panel und wechseln Sie nach Bedarf zwischen Agenten.
- Notiz-Verweise. Verwenden Sie @notename, um Notizinhalte in Prompts einzubinden — ähnlich wie bei Claudian, aber agentenunabhängig.
- Shell-Ausführung. Führen Sie Terminal-Befehle direkt im Chat aus — Build-Skripte, Git-Befehle oder beliebige Terminal-Operationen, ohne die Konversation zu verlassen.
- Aktionsgenehmigung. Feingranulare Kontrolle über Datei-Lese- und Bearbeitungsvorgänge sowie Befehlsausführungen.
Wann Agent-Plugins vs. externe MCP-Server verwenden
| Szenario | Agent-Plugin | Externer MCP-Server |
|---|---|---|
| Vault-Notizen mit KI-Unterstützung schreiben und bearbeiten | Besser — Agent sieht den Editor-Kontext | Funktioniert, aber ohne Editor-Bewusstsein |
| Code-Entwicklung über mehrere Repositories | Eingeschränkt — auf den Vault begrenzt | Besser — projektbezogen mit vollem Dateisystemzugriff |
| Retrieval aus einem großen indizierten Korpus | Nur einfache Suche | Vollständige hybride Retrieval-Pipeline |
| Schnelle Vault-Fragen während Notiz-Sitzungen | Ideal — kein Kontextwechsel | Erfordert Wechsel zum Terminal |
Empfehlung: Verwenden Sie Agent-Plugins für Vault-zentrierte Workflows (Schreiben, Organisieren, Zusammenfassen von Notizen). Verwenden Sie externe MCP-Server für Entwicklungs-Workflows, bei denen der KI-Agent die vollständige Retrieval-Pipeline und Zugriff auf Codebasen außerhalb des Vaults benötigt. Beide Ansätze können koexistieren — nutzen Sie Claudian innerhalb von Obsidian für die Notizarbeit und Claude Code mit MCP extern für die Entwicklung.
Entscheidungsrahmen: Obsidian vs. Alternativen
Nicht jeder Anwendungsfall erfordert Obsidian. Dieser Abschnitt zeigt, wann Obsidian das richtige Fundament ist, wann es überdimensioniert wäre und wann eine andere Lösung besser passt.
Entscheidungsbaum
START: What is your primary content type?
│
├─ Structured data (tables, records, schemas)
│ → Use a database. SQLite, PostgreSQL, or a spreadsheet.
│ → Obsidian is for prose, not tabular data.
│
├─ Ephemeral context (current project, temporary notes)
│ → Use CLAUDE.md / AGENTS.md in the project repo.
│ → These travel with the code and reset per project.
│
├─ Team wiki (shared documentation, onboarding)
│ → Evaluate Notion, Confluence, or a shared git repo.
│ → Obsidian vaults are personal-first. Team sync is possible
│ but not native.
│
└─ Growing personal knowledge corpus
│
├─ < 50 notes
│ → A folder of markdown files + grep is sufficient.
│ → Obsidian adds value mainly through the link graph,
│ which needs density to be useful.
│
├─ 50 - 500 notes
│ → Obsidian adds value. Wiki-links create a navigable graph.
│ → BM25-only search (FTS5) is sufficient at this scale.
│ → Skip vector search and RRF until keyword collisions appear.
│
├─ 500 - 5,000 notes
│ → Full hybrid retrieval becomes valuable. Keyword collisions
│ increase. Semantic search catches queries that BM25 misses.
│ → Add vector search + RRF fusion at this scale.
│
└─ 5,000+ notes
→ Full pipeline is essential. BM25-only returns too much noise.
→ Credential filtering becomes critical (more notes = more
accidentally pasted secrets).
→ Incremental indexing matters (full reindex takes minutes).
→ MCP integration pays dividends on every AI interaction.
Vergleichsmatrix
| Kriterium | Obsidian | Notion | Apple Notes | Einfaches Dateisystem | CLAUDE.md |
|---|---|---|---|---|---|
| Lokal-first | Ja | Nein (Cloud) | Teilweise (iCloud) | Ja | Ja |
| Klartext | Ja (Markdown) | Nein (Blöcke) | Nein (proprietär) | Ja | Ja |
| Graphstruktur | Ja (wiki-links) | Teilweise (Erwähnungen) | Nein | Nein | Nein |
| KI-indexierbar | Direkter Dateizugriff | API erforderlich | Export erforderlich | Direkter Dateizugriff | Bereits im Kontext |
| Plugin-Ökosystem | Über 2.500 Plugins | Integrationen | Keine | N/A | N/A |
| Offlinefähig | Vollständig | Nur zwischengespeichert (Lesezugriff) | Teilweise | Vollständig | Vollständig |
| Skalierbar auf 10.000+ Notizen | Ja | Ja (mit API) | Verschlechtert sich | Ja | Nein (einzelne Datei) |
| Kosten | Kostenlos (Kern) | Ab 10 $/Monat | Kostenlos | Kostenlos | Kostenlos |
Wann Obsidian überdimensioniert ist
- Einzelprojekt-Kontext. Wenn die KI nur Kontext zum aktuellen Codebase benötigt, gehören die Informationen in
CLAUDE.md,AGENTS.mdoder projektspezifische Dokumentation. Diese Dateien gehören zum Repository und werden automatisch geladen. - Strukturierte Daten. Wenn der Inhalt aus Tabellen, Datensätzen oder Schemata besteht, sollten Sie eine Datenbank verwenden. Obsidian-Notizen sind auf Fließtext ausgelegt. Dataview kann zwar frontmatter-Felder abfragen, allerdings bewältigt eine echte Datenbank strukturierte Abfragen deutlich besser.
- Temporäre Recherche. Wenn die Notizen nach Projektende verworfen werden, ist ein einfaches Verzeichnis mit Markdown-Dateien unkomplizierter. Bauen Sie keine Retrieval-Infrastruktur für kurzlebige Inhalte auf.
Wann Obsidian die richtige Wahl ist
- Wissen, das über Monate oder Jahre wächst. Der Wert potenziert sich mit dem Umfang des Korpus. Ein Vault mit 200 Notizen, der sechs Monate lang täglich abgefragt wird, liefert mehr Nutzen als ein Vault mit 5.000 Notizen, der nur einmal abgefragt wird.
- Mehrere Wissensdomänen in einem Korpus. Ein Vault mit Notizen zu Programmierung, Architektur, Sicherheit, Design und persönlichen Projekten profitiert von domänenübergreifendem Retrieval — etwas, das eine projektspezifische
CLAUDE.mdnicht bieten kann. - Datenschutzsensible Inhalte. Durch den Local-first-Ansatz sendet die Retrieval-Pipeline niemals Inhalte an externe Dienste. Der Vault enthält alles, was Sie hineinlegen — auch Inhalte, die Sie niemals in einen Cloud-Dienst hochladen würden.
Mentales Modell: Drei Schichten
Das System besteht aus drei Schichten, die unabhängig voneinander arbeiten, sich aber in Kombination gegenseitig verstärken. Jede Schicht hat einen eigenen Zuständigkeitsbereich und einen eigenen Fehlermodus.
┌─────────────────────────────────────────────────────┐
│ INTEGRATION LAYER │
│ MCP servers, hooks, skills, context injection │
│ Concern: delivering context to AI tools │
│ Failure: wrong context, too much context, stale │
└──────────────────────┬──────────────────────────────┘
│ query + ranked results
┌──────────────────────┴──────────────────────────────┐
│ RETRIEVAL LAYER │
│ BM25, vector KNN, RRF fusion, token budget │
│ Concern: finding the right content for any query │
│ Failure: wrong ranking, missed results, slow queries │
└──────────────────────┬──────────────────────────────┘
│ chunked, embedded, indexed
┌──────────────────────┴──────────────────────────────┐
│ INTAKE LAYER │
│ Note creation, signal triage, vault organization │
│ Concern: what enters the vault and how it's stored │
│ Failure: noise, duplicates, missing structure │
└─────────────────────────────────────────────────────┘
Intake bestimmt, was in den Vault gelangt. Ohne Kuration sammelt sich Rauschen an: Screenshots von Tweets, kopierte Artikel ohne Kommentierung, halbfertige Gedanken ohne Kontext. Die Intake-Schicht ist für die Qualitätskontrolle am Eintrittspunkt verantwortlich. Eine Bewertungspipeline, Tagging-Konvention oder manuelle Prüfung — jeder Mechanismus, der sicherstellt, dass der Vault nur abfragewürdige Inhalte enthält.
Retrieval macht den Vault abfragbar. Dies ist der Motor: Notizen in Sucheinheiten aufteilen (Chunking), Chunks in den Vektorraum einbetten (Embeddings), Indizierung für Keyword- und semantische Suche, Ergebnisfusion mit RRF. Die Retrieval-Schicht verwandelt ein Dateiverzeichnis in eine abfragbare Wissensbasis. Ohne diese Schicht lässt sich der Vault zwar manuell durchsuchen und per einfacher Suche navigieren, ist jedoch nicht programmatisch für KI-Werkzeuge zugänglich.
Integration verbindet die Retrieval-Schicht mit KI-Werkzeugen. Ein MCP-Server stellt das Retrieval als aufrufbares Tool bereit. Hooks injizieren Kontext automatisch. Skills erfassen neues Wissen zurück in den Vault. Die Integrationsschicht bildet die Schnittstelle zwischen der Wissensbasis und den KI-Agenten, die sie nutzen.
Die Schichten sind bewusst entkoppelt. Die Intake-Bewertungspipeline weiß nichts von Embeddings. Der Retriever weiß nichts von Signal-Routing-Regeln. Der MCP-Server weiß nichts darüber, wie Notizen erstellt wurden. Diese Entkopplung ermöglicht es Ihnen, jede Schicht unabhängig zu verbessern. Ersetzen Sie das Embedding-Modell, ohne die Intake-Pipeline zu ändern. Fügen Sie eine neue MCP-Fähigkeit hinzu, ohne den Retriever anzupassen. Ändern Sie die Signal-Scoring-Heuristiken, ohne den Index anzufassen.
Vault-Architektur für KI-gestützte Nutzung
Ein Vault, das für KI-gestütztes Retrieval optimiert ist, folgt anderen Konventionen als eines, das für persönliches Browsen ausgelegt ist. Dieser Abschnitt behandelt Ordnerstruktur, Notiz-Schema, frontmatter-Konventionen und die spezifischen Muster, die die Retrieval-Qualität verbessern.
Ordnerstruktur
Verwenden Sie nummerierte Präfixe für Ordner der obersten Ebene, um eine vorhersagbare organisatorische Hierarchie zu schaffen. Die Nummern implizieren keine Priorität — sie gruppieren verwandte Bereiche und machen die Struktur übersichtlich.
vault/
├── 00-inbox/ # Unsortierte Erfassungen, ausstehende Triage
├── 01-projects/ # Aktive Projektnotizen
├── 02-areas/ # Laufende Verantwortungsbereiche
├── 03-resources/ # Referenzmaterial nach Thema
│ ├── programming/
│ ├── security/
│ ├── ai-engineering/
│ ├── design/
│ └── devops/
├── 04-archive/ # Abgeschlossene Projekte, alte Referenzen
├── 05-signals/ # Bewertete Signal-Eingänge
│ ├── ai-tooling/
│ ├── security/
│ ├── systems/
│ └── ...12 Domain-Ordner
├── 06-daily/ # Tagesnotizen (falls verwendet)
├── 07-templates/ # Notiz-Vorlagen (vom Index ausgeschlossen)
├── 08-attachments/ # Bilder, PDFs (vom Index ausgeschlossen)
├── .obsidian/ # Obsidian-Konfiguration (vom Index ausgeschlossen)
└── .indexignore # Pfade, die vom Retrieval-Index ausgeschlossen werden
Ordner, die indiziert werden sollten: Alles, was Markdown-Prosa enthält — Projekte, Bereiche, Ressourcen, Signale, Tagesnotizen.
Ordner, die von der Indizierung ausgeschlossen werden sollten: Vorlagen (sie enthalten Platzhaltervariablen, keinen Inhalt), Anhänge (Binärdateien), Obsidian-Konfiguration sowie alle Ordner mit sensiblen Inhalten, die nicht im Retrieval-Index erscheinen sollen.
Die .indexignore-Datei
Erstellen Sie eine .indexignore-Datei im Vault-Stammverzeichnis, um Pfade explizit vom Retrieval-Index auszuschließen. Die Syntax entspricht .gitignore:
# Obsidian internal
.obsidian/
# Templates contain placeholders, not content
07-templates/
# Binary attachments
08-attachments/
# Personal health/medical notes
02-areas/health/
# Financial records
02-areas/finance/personal/
# Career documents (resumes, salary data)
02-areas/career/private/
Der Indexer liest diese Datei vor dem Scannen und überspringt übereinstimmende Pfade vollständig. Dateien in ausgeschlossenen Pfaden werden weder in Chunks aufgeteilt, noch eingebettet (Embeddings), noch erscheinen sie in Suchergebnissen.
Notiz-Schema
Jede Notiz sollte YAML frontmatter haben. Der Retriever nutzt frontmatter-Felder zur Filterung und Kontextanreicherung:
---
title: "OAuth Token Rotation Patterns"
type: note # note | signal | project | moc | daily
domain: security # primary domain for routing
tags:
- authentication
- oauth
- token-management
created: 2026-01-15
updated: 2026-02-28
source: "" # URL if captured from external source
status: active # active | archived | draft
---
Erforderliche Felder für das Retrieval:
title— Wird in der Suchergebnisanzeige und als Überschriftenkontext für BM25 verwendettype— Ermöglicht typgefilterte Abfragen („zeige nur MOCs” oder „nur Signale”)tags— Im FTS5-Überschriftenkontext mit Gewichtung 0,3 indiziert, wodurch Keyword-Treffer auch dann möglich sind, wenn der Textkörper andere Terminologie verwendet
Optionale, aber wertvolle Felder:
domain— Ermöglicht domänenbezogene Abfragen („nur in Security-Notizen suchen”)source— Attribution für erfasste Inhalte; der Retriever kann Quell-URLs in Ergebnisse einbindenstatus— Erlaubt das Ausschließen archivierter oder als Entwurf markierter Notizen aus der aktiven Suche
Chunking-Konventionen
Der Retriever teilt Inhalte an H2-Überschriftengrenzen (##) in Chunks auf. Die Struktur Ihrer Notizen beeinflusst daher direkt die Retrieval-Granularität:
Gut für das Retrieval:
## Token Rotation Strategy
The rotation interval depends on the threat model...
## Implementation with refresh_token
The OAuth 2.0 refresh token flow requires...
## Error Handling: Expired Tokens
When a token expires mid-request...
Drei H2-Abschnitte erzeugen drei unabhängig durchsuchbare Chunks. Jeder Chunk enthält genügend Kontext, damit das Embedding seine Bedeutung erfassen kann. Eine Abfrage zu „expired token handling” trifft gezielt den dritten Chunk.
Schlecht für das Retrieval:
# OAuth Notes
Token rotation depends on threat model. The OAuth 2.0 refresh
token flow requires storing the refresh token securely. When a
token expires mid-request, the client should retry after refresh.
The rotation interval is typically 15-30 minutes for access tokens
and 7-30 days for refresh tokens...
Ein langer Abschnitt ohne H2-Überschriften erzeugt einen einzigen großen Chunk. Das Embedding mittelt über alle Themen im Abschnitt hinweg. Eine Abfrage zu einem beliebigen Unterthema trifft die gesamte Notiz gleichermaßen.
Faustregel: Wenn ein Abschnitt mehr als ein Konzept behandelt, teilen Sie ihn in H2-Unterabschnitte auf. Der Chunker erledigt den Rest.
Was nicht in Notizen gehört
Inhalte, die die Retrieval-Qualität verschlechtern:
- Ungekürzte Kopien ganzer Artikel ohne Annotation. Der Retriever indiziert die Keywords des Originalartikels und verwässert damit Ihr Vault mit Inhalten, die Sie nicht selbst verfasst haben. Fügen Sie stattdessen eine Zusammenfassung hinzu, extrahieren Sie die wichtigsten Punkte oder verlinken Sie auf die Quell-URL.
- Screenshots ohne Textbeschreibung. Der Retriever indiziert Markdown-Text. Ein Bild ohne Alt-Text oder umgebende Beschreibung ist sowohl für BM25 als auch für die Vektorsuche unsichtbar.
- Zugangsdaten. API-Schlüssel, Tokens, Passwörter, Verbindungszeichenfolgen. Selbst mit Credential-Filtering ist der sicherste Ansatz, niemals Geheimnisse in Notizen einzufügen. Verweisen Sie stattdessen per Name darauf („der Cloudflare API-Token in
~/.env”). - Automatisch generierte Inhalte ohne Kuratierung. Wenn ein Tool eine Notiz generiert (Meetingtranskript, Readwise-Highlights, RSS-Import), überprüfen und annotieren Sie diese, bevor sie in das permanente Vault aufgenommen wird. Unkuratierte Auto-Importe erhöhen das Volumen, ohne den abrufbaren Wert zu steigern.
Plugin-Ökosystem für KI-Workflows
Obsidian-Plugins, die die Vault-Qualität für KI-gestütztes Retrieval verbessern, lassen sich in drei Kategorien einteilen: strukturelle (erzwingen Konsistenz), abfragebasierte (machen Metadaten zugänglich) und synchronisierende (halten das Vault aktuell).
Essenzielle Plugins
Dataview. Ermöglicht datenbankähnliche Abfragen Ihres Vaults anhand von frontmatter-Feldern. Erstellen Sie dynamische Verzeichnisse: „alle Notizen mit Tag security, die in den letzten 30 Tagen aktualisiert wurden” oder „alle Projektnotizen mit Status active.” Dataview unterstützt das Retrieval nicht direkt, hilft Ihnen jedoch, Lücken in der Abdeckung Ihres Vaults zu identifizieren und aktualisierungsbedürftige Notizen zu finden.
TABLE type, domain, updated
FROM "03-resources"
WHERE status = "active"
SORT updated DESC
LIMIT 20
Templater. Erstellt Notizen aus Vorlagen mit dynamischen Feldern. Stellen Sie sicher, dass jede neue Notiz mit korrektem frontmatter beginnt, indem Sie eine Vorlage verwenden, die created, type und domain automatisch ausfüllt. Konsistentes frontmatter verbessert die Retrieval-Filterung.
<%* /* New Resource Note Template */ %>
---
title: "<% tp.file.cursor() %>"
type: note
domain: <% tp.system.suggester(["programming", "security", "ai-engineering", "design", "devops"], ["programming", "security", "ai-engineering", "design", "devops"]) %>
tags: []
created: <% tp.date.now("YYYY-MM-DD") %>
updated: <% tp.date.now("YYYY-MM-DD") %>
source: ""
status: active
---
## Key Points
## Details
## Referenzen
Linter. Erzwingt Formatierungsregeln im gesamten Vault. Eine konsistente Überschriftenhierarchie (H1 für Titel, H2 für Abschnitte, H3 für Unterabschnitte) stellt sicher, dass der Chunker vorhersagbare Ergebnisse liefert. Linter-Regeln, die für das Retrieval relevant sind:
- Überschriftenabstufung: Sequenzielle Überschriftenebenen erzwingen (kein Sprung von H1 zu H3)
- YAML-Titel: Mit dem Dateinamen abgleichen
- Leerzeichen am Zeilenende: Entfernen (vermeidet FTS5-Tokenisierungsartefakte)
- Aufeinanderfolgende Leerzeilen: Auf 1 begrenzen (sauberere Chunks)
Git-Integration. Versionskontrolle für Ihren Vault. Verfolgen Sie Änderungen über die Zeit, synchronisieren Sie zwischen Geräten und stellen Sie versehentlich gelöschte Dateien wieder her. Git liefert außerdem mtime-Daten, die der Indexer für die inkrementelle Änderungserkennung nutzt.
Plugins, die die Indexierung unterstützen
Smart Connections. Ein Obsidian-Plugin, das KI-gestützte semantische Suche direkt in Obsidian ermöglicht. Smart Connections v4 erstellt standardmäßig lokale Embeddings — sobald Ihr Vault indexiert ist, funktionieren semantische Verknüpfungen und Abfragen vollständig offline ohne API-Aufrufe.23 Das Retrieval-System in diesem Leitfaden ist zwar extern zu Obsidian (läuft als Python-Pipeline), dennoch eignet sich Smart Connections hervorragend zum Erkunden semantischer Zusammenhänge während des Schreibens. Beide Systeme indexieren denselben Inhalt, bedienen jedoch unterschiedliche Anwendungsfälle: Smart Connections für die Entdeckung im Editor, der externe Retriever für die Integration von KI-Tools über MCP.
Metadata Menu. Bietet strukturierte Frontmatter-Bearbeitung mit Autovervollständigung für Feldwerte. Reduziert Tippfehler in type-, domain- und tags-Feldern. Konsistente Metadaten verbessern die Genauigkeit der Retrieval-Filterung.
Plugins, die die Indexierung beeinträchtigen
Excalidraw. Speichert Zeichnungen als in Markdown-Dateien eingebettetes JSON. Das JSON ist syntaktisch gültiges Markdown, erzeugt aber beim Chunking und Embedding unbrauchbare Ergebnisse. Schließen Sie Excalidraw-Dateien über .indexignore oder durch Filtern nach Dateiendung vom Index aus.
Kanban. Speichert den Board-Zustand als speziell formatiertes Markdown. Das Format ist für die Kanban-Darstellung konzipiert, nicht für Prosa-Retrieval. Der Chunker erzeugt Fragmente aus Kartentiteln und Metadaten, die sich schlecht als Embeddings eignen. Schließen Sie Kanban-Boards vom Index aus.
Calendar. Erstellt tägliche Notizen mit minimalem Inhalt (oft nur eine Datumsüberschrift). Leere oder nahezu leere Notizen erzeugen Chunks von geringer Qualität. Wenn Sie tägliche Notizen verwenden, verfassen Sie darin substanzielle Inhalte oder schließen Sie den Ordner für tägliche Notizen vom Index aus.
Plugin-Konfiguration, die relevant ist
Dateiwiederherstellung → Aktiviert. Schützt vor versehentlichem Löschen von Notizen. Steht zwar nicht in direktem Zusammenhang mit dem Retrieval, ist aber unverzichtbar für eine Wissensdatenbank, auf die Sie sich verlassen.
Strikte Zeilenumbrüche → Deaktiviert. Markdown-konforme Zeilenumbrüche (doppelter Zeilenumbruch für Absätze) erzeugen sauberere Chunks als Obsidians strikter Modus (einfacher Zeilenumbruch für <br>).
Standardspeicherort für neue Dateien → Festgelegter Ordner. Leiten Sie neue Dateien nach 00-inbox/ weiter, damit unkategorisierte Notizen die Domänenordner nicht verunreinigen. Die Inbox dient als Zwischenablage; Dateien werden nach der Sichtung in Domänenordner verschoben.
Wiki-Link-Format → Kürzester Pfad wenn möglich. Kürzere Link-Ziele lassen sich vom Retriever bei der Indexierung der Linkstruktur leichter auflösen.
Embedding-Modelle: Auswahl und Konfiguration
Das Embedding-Modell wandelt Textabschnitte in numerische Vektoren für die semantische Suche um. Die Modellwahl bestimmt die Retrievalqualität, Indexgröße, Embedding-Geschwindigkeit und Laufzeitabhängigkeiten. Dieser Abschnitt erläutert, warum Model2Vec’s potion-base-8M die Standardwahl ist und wann Alternativen sinnvoll sind.
Warum Model2Vec potion-base-8M
Modell: minishlab/potion-base-8M
Parameter: 7,6 Millionen
Dimensionen: 256
Größe: ~30 MB
Abhängigkeiten: model2vec (nur numpy, kein PyTorch)
Inferenz: Nur CPU, statische Wort-Embeddings (keine Attention-Layer)
Model2Vec destilliert das Wissen eines Sentence Transformers in statische Token-Embeddings. Anstatt Attention-Layer über die Eingabe laufen zu lassen (wie es BERT, MiniLM und andere Transformer-Modelle tun), erzeugt Model2Vec Vektoren durch gewichtete Mittelung vorberechneter Token-Embeddings.5 Die praktische Konsequenz: Die Embedding-Geschwindigkeit ist 50- bis 500-mal schneller als bei transformerbasierten Modellen, da keine sequentielle Berechnung stattfindet.
Auf der MTEB-Benchmark-Suite erreicht potion-base-8M 89 % der Leistung von all-MiniLM-L6-v2 (50,03 vs. 56,09 im Durchschnitt).6 Die Qualitätslücke von 11 % ist der Kompromiss für die Vorteile bei Geschwindigkeit und Einfachheit. Bei kurzen Markdown-Abschnitten (durchschnittlich 200–400 Wörter in einem typischen Vault) fällt der Qualitätsunterschied weniger ins Gewicht als bei längeren Dokumenten, da beide Modelle bei kurzem, fokussiertem Text zu ähnlichen Repräsentationen konvergieren.
Konfiguration
# embedder.py
DEFAULT_MODEL = "minishlab/potion-base-8M"
EMBEDDING_DIM = 256
class Model2VecEmbedder:
def __init__(self, model_name=DEFAULT_MODEL):
self._model_name = model_name
self._model = None
def _ensure_model(self):
if self._model is not None:
return
_activate_venv() # Add isolated venv to sys.path
from model2vec import StaticModel
self._model = StaticModel.from_pretrained(self._model_name)
def embed_batch(self, texts):
self._ensure_model()
vecs = self._model.encode(texts)
return [v.tolist() for v in vecs]
Lazy Loading. Das Modell wird erst bei der ersten Verwendung geladen, nicht beim Import. Der Import des Embedder-Moduls verursacht keine Kosten, wenn der Retriever im BM25-Only-Fallback-Modus arbeitet (z. B. wenn die Embedding-venv nicht installiert ist).
Isolierte virtuelle Umgebung. Das Modell läuft in einer dedizierten venv (z. B. ~/.claude/venvs/memory/), um Abhängigkeitskonflikte mit der übrigen Toolchain zu vermeiden. Die Funktion _activate_venv() fügt die site-packages der venv zur Laufzeit zu sys.path hinzu.
# Create isolated venv
python3 -m venv ~/.claude/venvs/memory
~/.claude/venvs/memory/bin/pip install model2vec
Stapelverarbeitung. Der Embedder verarbeitet Texte in Stapeln von 64, um den Overhead von Model2Vec zu amortisieren. Der Indexer übergibt Chunks an embed_batch(), anstatt sie einzeln einzubetten.
Wann Alternativen sinnvoll sind
| Modell | Dim | Größe | Geschwindigkeit | Qualität (MTEB) | Geeignet für |
|---|---|---|---|---|---|
| potion-base-8M | 256 | 30 MB | 500x | 50,03 | Standard: lokal, schnell, kein GPU |
| potion-base-32M | 256 | 120 MB | 400x | 52,46 | Höhere Qualität, weiterhin statisch |
| potion-retrieval-32M | 256 | 120 MB | 400x | 36,35 (Retrieval) | Retrieval-optimiert, statisch |
| potion-multilingual-128M | 256 | ~500 MB | 300x | — | Mehrsprachige Vaults (101 Sprachen) |
| all-MiniLM-L6-v2 | 384 | 80 MB | 1x | 56,09 | Höhere Qualität, weiterhin lokal |
| nomic-embed-text-v1.5 | 768 | 270 MB | 0,5x | 62,28 | Beste lokale Qualität |
| text-embedding-3-small | 1536 | API | N/A | 62,30 | API-basiert, höchste Qualität |
Wählen Sie potion-base-32M, wenn Sie eine bessere Qualität als potion-base-8M wünschen, ohne die Familie der statischen Embeddings zu verlassen. Das im Januar 2025 veröffentlichte Modell nutzt ein größeres Vokabular, destilliert aus baai/bge-base-en-v1.5, und erreicht einen MTEB-Durchschnitt von 52,46 (5 % Verbesserung gegenüber potion-base-8M) — bei gleicher 256-dimensionaler Ausgabe und reiner numpy-Abhängigkeit.20 Die vierfach größere Modelldatei erhöht den Speicherverbrauch, allerdings bleibt die Embedding-Geschwindigkeit um Größenordnungen schneller als bei Transformer-Modellen.
Wählen Sie potion-retrieval-32M, wenn Ihr primärer Anwendungsfall Retrieval ist (was bei der Vault-Suche zutrifft). Diese Variante wurde aus potion-base-32M speziell für Retrieval-Aufgaben feinabgestimmt und erzielt 36,35 bei MTEB-Retrieval-Benchmarks gegenüber 33,52 beim Basismodell.20 Der MTEB-Gesamtdurchschnitt sinkt auf 49,73, da das Fine-Tuning allgemeine Leistung zugunsten retrievalspezifischer Verbesserungen eintauscht.
Wählen Sie potion-multilingual-128M, wenn Ihr Vault Notizen in mehreren Sprachen enthält. Dieses im Mai 2025 veröffentlichte 101-Sprachen-Modell ist das leistungsfähigste statische Embedding-Modell für mehrsprachige Aufgaben und erzeugt Embeddings für beliebigen Text in beliebigen Sprachen — bei gleicher reiner numpy-Abhängigkeit wie andere potion-Modelle.24 Die größere Modelldatei (~500 MB) ist der Kompromiss für die sprachübergreifende Fähigkeit. Verwenden Sie dieses Modell, wenn Sie Notizen auf Japanisch, Chinesisch, Deutsch oder in anderen nicht-englischen Sprachen neben englischen Inhalten haben.
Wählen Sie all-MiniLM-L6-v2, wenn die Retrievalqualität wichtiger ist als Geschwindigkeit und Sie PyTorch installiert haben. Die 384-dimensionalen Vektoren vergrößern die SQLite-Datenbank um etwa 50 % im Vergleich zu 256-dimensionalen Vektoren. Die Embedding-Geschwindigkeit sinkt von unter 1 Minute auf etwa 10 Minuten für einen vollständigen Reindex von 15.000 Dateien auf M-Series-Hardware.
Wählen Sie nomic-embed-text-v1.5, wenn Sie die bestmögliche lokale Retrievalqualität benötigen und langsameres Indexieren akzeptieren. Die 768-dimensionalen Vektoren verdreifachen die Datenbankgröße ungefähr. PyTorch sowie eine moderne CPU oder GPU werden vorausgesetzt.
Wählen Sie text-embedding-3-small, wenn Netzwerklatenz und Datenschutzaspekte akzeptable Kompromisse darstellen. Die API liefert die hochwertigsten Embeddings, führt jedoch eine Cloud-Abhängigkeit, Kosten pro Token (0,02 $/Million Tokens) und das Senden Ihrer Inhalte an die Server von OpenAI ein.
Bleiben Sie bei potion-base-8M in allen anderen Fällen. Der Geschwindigkeitsvorteil ist entscheidend für iteratives Indexieren (Reindex während der Entwicklung), die reine numpy-Abhängigkeit vermeidet die Komplexität einer PyTorch-Installation, und die 256-dimensionalen Vektoren halten die Datenbank kompakt.
Quantisierung und Dimensionsreduktion
Model2Vec v0.5.0+ unterstützt das Laden von Modellen mit reduzierter Präzision und Dimensionalität.20 Dies ist nützlich für den Einsatz auf Hardware mit begrenzten Ressourcen oder zur Reduzierung der Datenbankgröße, ohne das Modell wechseln zu müssen:
from model2vec import StaticModel
# Load with int8 quantization (25% of original size)
model = StaticModel.from_pretrained("minishlab/potion-base-8M", quantize=True)
# Load with reduced dimensions (e.g., 128 instead of 256)
model = StaticModel.from_pretrained("minishlab/potion-base-8M", dimensionality=128)
Quantisierte Modelle behalten nahezu identische Retrievalqualität bei einem Bruchteil des Speicherbedarfs. Die Dimensionsreduktion folgt einer Matryoshka-artigen Trunkierung — die ersten N Dimensionen tragen die meiste Information. Eine Reduktion von 256 auf 128 Dimensionen halbiert den Vektorspeicher bei minimalem Qualitätsverlust für das Retrieval kurzer Texte.
Seit Mai 2025 unterstützt Model2Vec außerdem BPE- und Unigram-Tokenizer (zusätzlich zu WordPiece), was die Menge der Sentence Transformers erweitert, die in statische Modelle destilliert werden können.22
Fine-Tuning für Vault-spezifische Embeddings
Model2Vec v0.4.0+ unterstützt das Training benutzerdefinierter Klassifikationsmodelle auf Basis statischer Embeddings, und v0.7.0 ergänzt Vokabular-Quantisierung sowie konfigurierbares Pooling für die Destillation.22 Dies ist relevant für Vaults mit spezialisiertem Vokabular (medizinische Notizen, juristische Referenzen, domänenspezifischer Fachjargon), bei denen die Standard-potion-Modelle semantische Nuancen möglicherweise nicht erfassen:
from model2vec import StaticModel
from model2vec.train import train_model
# Fine-tune on vault-specific data
model = StaticModel.from_pretrained("minishlab/potion-base-8M")
trained_model = train_model(model, train_texts, train_labels)
trained_model.save_pretrained("./vault-embeddings")
Für die meisten Vaults liefert das Standard-potion-base-8M ausreichende Retrievalqualität. Fine-Tuning lohnt sich nur dann, wenn das Retrieval wiederholt domänenspezifische Zusammenhänge verfehlt, die ein Allzweckmodell nicht erfassen kann.
Modell-Hash-Tracking
Der Indexer speichert einen Hash, der aus dem Modellnamen und der Vokabulargröße abgeleitet wird. Wenn Sie das Embedding-Modell wechseln, erkennt der Indexer beim nächsten inkrementellen Durchlauf die Abweichung und löst automatisch einen vollständigen Reindex aus.
def _compute_model_hash(self):
"""Hash model name + vocab size for compatibility tracking."""
key = f"{self._model_name}:{self._model.vocab_size}"
return hashlib.sha256(key.encode()).hexdigest()[:16]
Dies verhindert das Vermischen von Vektoren verschiedener Modelle in derselben Datenbank, was zu unsinnigen cosine similarity-Werten führen würde.
Fehlermodi
Fehlgeschlagener Modell-Download. Beim ersten Durchlauf wird das Modell von Hugging Face heruntergeladen. Schlägt der Download fehl (Netzwerkproblem, Unternehmens-Firewall), wechselt der Retriever in den BM25-Only-Modus. Nach dem ersten erfolgreichen Download wird das Modell lokal zwischengespeichert.
Dimensionskonflikt. Wenn Sie das Modell wechseln, ohne die Datenbank zu leeren, haben die gespeicherten Vektoren eine andere Dimension als neue Embeddings. Der Indexer erkennt dies über den Modell-Hash und löst einen vollständigen Reindex aus. Falls die Hash-Prüfung fehlschlägt (benutzerdefiniertes Modell ohne korrekten Hash), meldet sqlite-vec bei KNN-Abfragen mit nicht übereinstimmenden Dimensionen einen Fehler.
Speicherdruck bei großen Vaults. Das Einbetten von 50.000+ Chunks in einem einzelnen Stapel kann erheblichen Speicher beanspruchen. Der Indexer verarbeitet in Stapeln von 64, um den maximalen Speicherverbrauch zu begrenzen. Falls der Speicher dennoch nicht ausreicht, reduzieren Sie die Stapelgröße.
Volltextsuche mit FTS5
Die FTS5-Erweiterung von SQLite bietet Volltextsuche mit BM25-Ranking. FTS5 ist die Schlüsselwort-Suchkomponente der Hybrid-Retrieval-Pipeline. Dieser Abschnitt behandelt die FTS5-Konfiguration, die Stärken von BM25 sowie dessen spezifische Fehlermodi.
Virtuelle FTS5-Tabelle
CREATE VIRTUAL TABLE chunks_fts USING fts5(
chunk_text,
section,
heading_context,
content=chunks,
content_rowid=id
);
Content-Sync-Modus. Der Parameter content=chunks weist FTS5 an, direkt auf die Tabelle chunks zu verweisen, anstatt eine Kopie des Textes zu speichern. Das halbiert den Speicherbedarf, bedeutet allerdings, dass FTS5 beim Einfügen, Aktualisieren oder Löschen von Chunks manuell synchronisiert werden muss.
Spalten. Drei Spalten werden indexiert:
- chunk_text — Der Hauptinhalt jedes Chunks (BM25-Gewichtung: 1.0)
- section — Der H2-Überschriftentext (BM25-Gewichtung: 0.5)
- heading_context — Notiztitel, Tags und Metadaten (BM25-Gewichtung: 0.3)
BM25-Ranking
BM25 bewertet Dokumente anhand von Termhäufigkeit, inverser Dokumenthäufigkeit und Dokumentlängen-Normalisierung. Die Hilfsfunktion bm25() in FTS5 akzeptiert spaltenspezifische Gewichtungen:
SELECT
c.id, c.file_path, c.section, c.chunk_text,
bm25(chunks_fts, 1.0, 0.5, 0.3) AS score
FROM chunks_fts
JOIN chunks c ON chunks_fts.rowid = c.id
WHERE chunks_fts MATCH ?
ORDER BY score
LIMIT 30;
Die Spaltengewichtungen (1.0, 0.5, 0.3) bedeuten:
- Ein Schlüsselwort-Treffer in chunk_text trägt am stärksten zur Bewertung bei
- Ein Treffer in section (Überschrift) trägt halb so viel bei
- Ein Treffer in heading_context (Titel, Tags) trägt 30 % bei
Diese Gewichtungen sind anpassbar. Wenn Ihr Vault beschreibende Überschriften enthält, die die Inhaltsqualität zuverlässig vorhersagen, erhöhen Sie die Gewichtung von section. Wenn Ihre Tags umfassend und präzise sind, erhöhen Sie die Gewichtung von heading_context.
Wann BM25 überlegen ist
BM25 glänzt bei Abfragen, die exakte Bezeichner enthalten:
- Funktionsnamen:
_rrf_fuse,embed_batch,get_stale_files - CLI-Flags:
--incremental,--vault,--model - Konfigurationsschlüssel:
bm25_weight,max_tokens,batch_size - Fehlermeldungen:
SQLITE_LOCKED,ConnectionRefusedError - Spezifische Fachbegriffe:
PostToolUse,PreToolUse,AGENTS.md
Bei solchen Abfragen findet BM25 den exakten Treffer sofort. Die Vektorsuche würde semantisch verwandte Inhalte liefern, könnte den exakten Treffer jedoch niedriger einordnen als eine konzeptuelle Diskussion.
Wann BM25 versagt
BM25 versagt bei Abfragen, die andere Begriffe verwenden als die gespeicherten Inhalte:
- Abfrage: „how to handle authentication failures” → Der Vault enthält Notizen über „login error recovery” und „session expiration handling”. BM25 findet keine Treffer, weil sich die Schlüsselwörter unterscheiden.
- Abfrage: „what is the best way to manage state” → Der Vault enthält Notizen über „Redux store patterns” und „context providers”. BM25 scheitert, weil „state management” durch spezifische Technologienamen ausgedrückt wird.
BM25 versagt außerdem bei Schlüsselwort-Kollisionen in großen Beständen. In einem Vault mit 15.000 Dateien liefert eine Suche nach „configuration” Hunderte von Treffern, da nahezu jede Projektnotiz das Wort „configuration” erwähnt. Die Ergebnisse sind technisch korrekt, aber praktisch nutzlos — das Ranking kann nicht bestimmen, welche „configuration”-Notiz für die aktuelle Abfrage relevant ist.
FTS5-Tokenizer
FTS5 verwendet standardmäßig den unicode61-Tokenizer, der ASCII- und Unicode-Text verarbeitet. Für Vaults mit umfangreichen CJK-Inhalten (Chinesisch, Japanisch, Koreanisch) empfiehlt sich der trigram-Tokenizer:
-- For CJK-heavy vaults
CREATE VIRTUAL TABLE chunks_fts USING fts5(
chunk_text, section, heading_context,
content=chunks, content_rowid=id,
tokenize='trigram'
);
Der Standard-Tokenizer unicode61 trennt an Wortgrenzen, was bei Sprachen ohne Leerzeichen zwischen Wörtern schlecht funktioniert. Der trigram-Tokenizer teilt jeweils drei Zeichen ab und ermöglicht so Teilzeichenketten-Suche — allerdings auf Kosten der Indexgröße (etwa 3-mal größer).
Wartung
FTS5 erfordert eine explizite Synchronisierung, wenn sich die zugrunde liegende Tabelle chunks ändert:
# After inserting chunks
cursor.execute("""
INSERT INTO chunks_fts(chunks_fts)
VALUES('rebuild')
""")
Der Befehl rebuild rekonstruiert den FTS5-Index aus der Inhaltstabelle. Führen Sie ihn nach Massen-Einfügungen (vollständige Neuindexierung) aus, nicht jedoch nach einzelnen inkrementellen Aktualisierungen — verwenden Sie dafür INSERT INTO chunks_fts(rowid, chunk_text, section, heading_context), um einzelne Zeilen zu synchronisieren.
Vektorsuche mit sqlite-vec
Die sqlite-vec-Erweiterung bringt KNN-Vektorsuche (K-Nearest Neighbors) direkt in SQLite. Dieser Abschnitt behandelt die sqlite-vec-Konfiguration, die Embedding-Pipeline vom Notizdokument zum durchsuchbaren Vektor sowie die spezifischen Abfragemuster.
Virtuelle sqlite-vec-Tabelle
CREATE VIRTUAL TABLE chunk_vecs USING vec0(
id INTEGER PRIMARY KEY,
embedding float[256]
);
Das vec0-Modul speichert 256-dimensionale Float-Vektoren als gepackte Binärdaten. Die id-Spalte bildet eine 1:1-Zuordnung zur chunks-Tabelle und ermöglicht so Joins zwischen Vektorergebnissen und Chunk-Metadaten.
Embedding-Pipeline
Die Pipeline verläuft vom Notizdokument zum durchsuchbaren Vektor:
Note (.md file)
→ Chunker: split at H2 boundaries
→ Chunks (30-2000 chars each)
→ Credential filter: scrub secrets
→ Embedder: Model2Vec encode
→ Vectors (256-dim float arrays)
→ sqlite-vec: store as packed binary
→ Ready for KNN queries
Vektorserialisierung
Das struct-Modul von Python serialisiert Float-Vektoren für die sqlite-vec-Speicherung:
import struct
def _serialize_vector(vec):
"""Pack float list into binary for sqlite-vec."""
return struct.pack(f"{len(vec)}f", *vec)
def _deserialize_vector(blob, dim=256):
"""Unpack binary blob to float list."""
return list(struct.unpack(f"{dim}f", blob))
KNN-Abfrage
Eine Vektorsuchabfrage erzeugt zunächst ein Embedding des Eingabetexts und findet anschließend die K nächsten Chunks anhand der Kosinusdistanz:
def _vector_search(self, query_text, limit=30):
query_vec = self.embedder.embed_batch([query_text])[0]
packed = _serialize_vector(query_vec)
results = self.db.execute("""
SELECT
cv.id,
cv.distance,
c.file_path,
c.section,
c.chunk_text
FROM chunk_vecs cv
JOIN chunks c ON cv.id = c.id
WHERE embedding MATCH ?
AND k = ?
ORDER BY distance
""", [packed, limit]).fetchall()
return results
Der MATCH-Operator in sqlite-vec führt eine approximative Nearest-Neighbor-Suche durch. Der Parameter k steuert die Anzahl der zurückgegebenen Ergebnisse. Die Spalte distance enthält die Kosinusdistanz (0 = identisch, 2 = entgegengesetzt).
KNN-Paginierung mit Distanzbeschränkungen
Seit sqlite-vec v0.1.7 unterstützen KNN-Abfragen WHERE distance < ?-Beschränkungen, wodurch cursorbasierte Paginierung durch große Ergebnismengen möglich wird, ohne frühere Seiten erneut zu durchsuchen.26
def _paginated_vector_search(self, query_vec, page_size=20, max_distance=None):
"""Paginate through KNN results using distance constraints."""
packed = _serialize_vector(query_vec)
constraint = f"AND distance < {max_distance}" if max_distance else ""
results = self.db.execute(f"""
SELECT cv.id, cv.distance, c.file_path, c.chunk_text
FROM chunk_vecs cv
JOIN chunks c ON cv.id = c.id
WHERE embedding MATCH ?
AND k = ?
{constraint}
ORDER BY distance
""", [packed, page_size]).fetchall()
# Use last result's distance as cursor for next page
next_cursor = results[-1][1] if results else None
return results, next_cursor
Dieses Verfahren ersetzt das bisherige Muster, ein großes k abzurufen und in Python zu slicen, und reduziert so den Speicherverbrauch bei explorativen Abfragen über große Vaults.
DELETE-Unterstützung in vec0-Tabellen
Mit sqlite-vec v0.1.7 wurde native DELETE-Unterstützung für virtuelle vec0-Tabellen eingeführt.26 Zuvor erforderte das Entfernen von Vektoren ein Löschen und Neuerstellen der Tabelle. Nun kann der Indexer bei Dateientfernung Vektoren direkt löschen:
# Before v0.1.7: required workaround (drop + recreate, or mark as inactive)
# After v0.1.7: direct DELETE works
db.execute("DELETE FROM chunk_vecs WHERE id = ?", [chunk_id])
Dies vereinfacht die inkrementelle Neuindizierung, wenn Notizen gelöscht oder verschoben werden. Der Indexer benötigt keine zusätzliche „aktive IDs”-Schattentabelle oder Batch-Neuaufbauten mehr.
Wann die Vektorsuche überlegen ist
Die Vektorsuche glänzt bei Abfragen, bei denen das Konzept wichtiger ist als die konkreten Wörter:
- Abfrage: „how to handle authentication failures” → Findet Notizen über „login error recovery” (gleicher semantischer Raum, unterschiedliche Schlüsselwörter)
- Abfrage: „what patterns exist for caching” → Findet Notizen über „memoization”, „Redis TTL strategies” und „HTTP cache headers” (verwandte Konzepte, unterschiedliche Terminologie)
- Abfrage: „approaches to testing asynchronous code” → Findet Notizen über „pytest-asyncio fixtures”, „mock event loops” und „async test patterns” (dasselbe Konzept, ausgedrückt durch Implementierungsdetails)
Wann die Vektorsuche versagt
Bei exakten Bezeichnern stößt die Vektorsuche an ihre Grenzen:
- Abfrage:
_rrf_fuse→ Liefert Notizen über „fusion algorithms” und „rank merging”, stuft die eigentliche Funktionsdefinition jedoch möglicherweise niedriger ein als konzeptuelle Diskussionen - Abfrage:
PostToolUse→ Liefert Notizen über „tool lifecycle hooks” und „post-execution handlers” statt des spezifischen Hook-Namens
Auch bei strukturierten Daten hat die Vektorsuche Schwächen. JSON-Konfigurationsdateien, YAML-Blöcke und Code-Snippets erzeugen Embeddings, die strukturelle Muster statt semantischer Bedeutung erfassen. Eine JSON-Datei mit "review": true wird anders eingebettet als eine Prosadiskussion über Code-Review.
Graceful Degradation
Falls sqlite-vec nicht geladen werden kann (fehlende Erweiterung, inkompatible Plattform, beschädigte Bibliothek), fällt der Retriever auf reine BM25-Suche zurück:
class VectorIndex:
def __init__(self, db_path):
self.db = sqlite3.connect(db_path)
self._vec_available = False
try:
self.db.enable_load_extension(True)
self.db.load_extension("vec0")
self._vec_available = True
except Exception:
pass # BM25-only mode
@property
def vec_available(self):
return self._vec_available
Der Retriever prüft vec_available, bevor er Vektorabfragen ausführt. Im deaktivierten Zustand verwenden alle Suchen ausschließlich BM25, und der RRF-Fusionsschritt entfällt.
Reciprocal Rank Fusion (RRF)
RRF führt zwei Ranglisten zusammen, ohne dass eine Kalibrierung der Bewertungen erforderlich ist. Dieser Abschnitt behandelt den Algorithmus, eine nachvollzogene Beispielabfrage, die Abstimmung des k-Parameters und die Gründe für die Wahl von RRF gegenüber Alternativen. Einen interaktiven Rechner mit bearbeitbaren Rängen, Szenario-Voreinstellungen und einem visuellen Architektur-Explorer finden Sie im Hybrid-Retriever-Deep-Dive.
Der Algorithmus
RRF weist jedem Dokument eine Bewertung zu, die ausschließlich auf seiner Rangposition in jeder Liste basiert:
score(d) = Σ (weight_i / (k + rank_i))
Dabei gilt:
- k ist eine Glättungskonstante (60, nach Cormack et al.3)
- rank_i ist der 1-basierte Rang des Dokuments in Ergebnisliste i
- weight_i ist ein optionaler Multiplikator pro Liste (Standard 1,0)
Dokumente, die in mehreren Listen gut abschneiden, erhalten höhere fusionierte Bewertungen. Dokumente, die nur in einer Liste vorkommen, erhalten eine Bewertung aus dieser einzelnen Quelle.
Warum RRF gegenüber Alternativen
Gewichtete lineare Kombination erfordert die Kalibrierung von BM25-Bewertungen gegen Kosinus-Distanzen. BM25-Bewertungen sind unbegrenzt und skalieren mit der Korpusgröße. Kosinus-Distanzen sind auf [0, 2] begrenzt. Ihre Kombination erfordert eine Normalisierung, deren Parameter datensatzabhängig sind. RRF verwendet ausschließlich Rangpositionen — stets ganzzahlig und bei 1 beginnend, unabhängig von der Bewertungsmethode.
Gelernte Fusionsmodelle benötigen gelabelte Trainingsdaten — Paare aus Abfrage und Dokumentrelevanz. Für eine persönliche Wissensdatenbank existieren solche Trainingsdaten nicht. Sie müssten Hunderte von Abfrage-Dokument-Paaren manuell bewerten, um ein brauchbares Modell zu trainieren. RRF funktioniert ganz ohne Trainingsdaten.
Condorcet-Wahlverfahren (Borda-Zählung, Schulze-Methode) sind theoretisch elegant, aber deutlich komplexer in Implementierung und Abstimmung. Das ursprüngliche RRF-Paper zeigte, dass RRF Condorcet-Methoden auf TREC-Evaluierungsdaten übertrifft.3
Fusion in der Praxis
Abfrage: „how does the review aggregator handle disagreements”
BM25 platziert review-aggregator.py auf Position 3 (exakte Schlüsselwortübereinstimmungen bei „review”, „aggregator”, „disagreements”), setzt jedoch zwei Konfigurationsdateien höher ein (sie matchen „review” prominenter). Die Vektorsuche platziert denselben Chunk auf Position 1 (semantische Übereinstimmung zum Thema Konfliktlösung). Nach der RRF-Fusion:
| Chunk | BM25 | Vec | Fused Score |
|---|---|---|---|
| review-aggregator.py „Disagreement Resolution” | #3 | #1 | 0,0323 |
| code-review-patterns.md „Multi-Reviewer” | #4 | #2 | 0,0317 |
| deliberation-config.json „Review Weights” | #1 | — | 0,0164 |
Chunks, die in beiden Listen gut abschneiden, steigen an die Spitze auf. Chunks, die nur in einer Liste vorkommen, erhalten eine Einzelquellen-Bewertung und fallen hinter doppelt gerankte Ergebnisse zurück. Die eigentliche Logik zur Konfliktlösung gewinnt, weil beide Methoden sie gefunden haben — BM25 über Schlüsselwörter, die Vektorsuche über Semantik.
Die vollständige Schritt-für-Schritt-Nachverfolgung mit RRF-Mathematik pro Rang sowie verschiedene k-Werte zum Ausprobieren finden Sie im interaktiven RRF-Rechner.
Implementierung
RRF_K = 60
def _rrf_fuse(self, bm25_results, vec_results,
bm25_weight=1.0, vec_weight=1.0):
"""Fuse BM25 and vector results using Reciprocal Rank Fusion."""
scores = {}
for rank, r in enumerate(bm25_results, start=1):
cid = r["id"]
if cid not in scores:
scores[cid] = {
"rrf_score": 0.0,
"file_path": r["file_path"],
"section": r["section"],
"chunk_text": r["chunk_text"],
"bm25_rank": None,
"vec_rank": None,
}
scores[cid]["rrf_score"] += bm25_weight / (self._rrf_k + rank)
scores[cid]["bm25_rank"] = rank
for rank, r in enumerate(vec_results, start=1):
cid = r["id"]
if cid not in scores:
scores[cid] = {
"rrf_score": 0.0,
"file_path": r["file_path"],
"section": r["section"],
"chunk_text": r["chunk_text"],
"bm25_rank": None,
"vec_rank": None,
}
scores[cid]["rrf_score"] += vec_weight / (self._rrf_k + rank)
scores[cid]["vec_rank"] = rank
fused = sorted(
scores.values(),
key=lambda x: x["rrf_score"],
reverse=True,
)
return fused
Abstimmung von k
Die Konstante k steuert, wie stark die bestplatzierten Ergebnisse gegenüber niedriger platzierten gewichtet werden:
- Niedriges k (z. B. 10): Bestplatzierte Ergebnisse dominieren. Rang 1 erhält 1/11 = 0,091, Rang 10 erhält 1/20 = 0,050 (1,8-facher Unterschied). Geeignet, wenn Sie darauf vertrauen, dass die einzelnen Ranker das beste Ergebnis korrekt identifizieren.
- Standard-k (60): Ausgewogen. Rang 1 erhält 1/61 = 0,0164, Rang 10 erhält 1/70 = 0,0143 (1,15-facher Unterschied). Rangunterschiede werden komprimiert, sodass das Vorkommen in mehreren Listen stärker ins Gewicht fällt.
- Hohes k (z. B. 200): Das Erscheinen in beiden Listen zählt weit mehr als die Rangposition. Rang 1 erhält 1/201, Rang 10 erhält 1/210 — nahezu identisch. Sinnvoll, wenn die einzelnen Ranker verrauschte Rankings produzieren, die listenübergreifende Übereinstimmung jedoch zuverlässig ist.
Beginnen Sie mit k=60. Das ursprüngliche RRF-Paper erwies diesen Wert als robust über diverse TREC-Datensätze hinweg. Passen Sie ihn erst an, nachdem Sie Fehlerfälle in Ihrer eigenen Abfrageverteilung gemessen haben.
Gleichstandsauflösung
Wenn zwei Chunks identische RRF-Bewertungen aufweisen (selten, aber möglich bei gleichem Rang in einer Liste und fehlendem Eintrag in der anderen), wird der Gleichstand wie folgt aufgelöst:
- Chunks, die in beiden Listen vorkommen, werden gegenüber Chunks bevorzugt, die nur in einer Liste erscheinen
- Unter Chunks in beiden Listen wird derjenige mit dem niedrigeren kombinierten Rang bevorzugt
- Unter Chunks in nur einer Liste wird derjenige mit dem niedrigeren Rang in dieser Liste bevorzugt
Die vollständige Retrieval-Pipeline
Dieser Abschnitt verfolgt eine Abfrage vom Eingang bis zur Ausgabe durch die gesamte Pipeline: BM25-Suche, Vektorsuche, RRF-Fusion, Token-Budget-Kürzung und Kontextaufbereitung.
Ablauf von Ende zu Ende
User query: "PostToolUse hook for context compression"
│
├─ BM25 Search (FTS5)
│ → MATCH "PostToolUse hook context compression"
│ → Top 30 results ranked by BM25 score
│ → 12ms
│
├─ Vector Search (sqlite-vec)
│ → Embed query with Model2Vec
│ → KNN k=30 on chunk_vecs
│ → Top 30 results ranked by cosine distance
│ → 8ms
│
└─ RRF Fusion
→ Merge 60 candidates (may overlap)
→ Score by rank position
→ Top 10 results
→ 3ms
│
└─ Token Budget
→ Truncate to max_tokens (default 4000)
→ Estimate at 4 chars per token
→ Return results with metadata
→ <1ms
Gesamtlatenz: ~23 ms für eine Datenbank mit 49.746 Chunks auf Apple M3 Pro Hardware.
Die Such-API
class HybridRetriever:
def search(self, query, limit=10, max_tokens=4000,
bm25_weight=1.0, vec_weight=1.0):
"""
Search the vault using hybrid BM25 + vector retrieval.
Args:
query: Search query text
limit: Maximum results to return
max_tokens: Token budget for total result text
bm25_weight: Weight for BM25 results in RRF
vec_weight: Weight for vector results in RRF
Returns:
List of SearchResult with file_path, section,
chunk_text, rrf_score, bm25_rank, vec_rank
"""
# BM25 search
bm25_results = self._bm25_search(query, limit=30)
# Vector search (if available)
if self.index.vec_available:
vec_results = self._vector_search(query, limit=30)
fused = self._rrf_fuse(
bm25_results, vec_results,
bm25_weight, vec_weight,
)
else:
fused = bm25_results # BM25-only fallback
# Token budget truncation
results = []
token_count = 0
for r in fused[:limit]:
chunk_tokens = len(r["chunk_text"]) // 4
if token_count + chunk_tokens > max_tokens:
break
results.append(r)
token_count += chunk_tokens
return results
Token-Budget-Kürzung
Der Parameter max_tokens verhindert, dass der Retriever mehr Kontext zurückgibt, als das KI-Tool verarbeiten kann. Die Schätzung verwendet 4 Zeichen pro Token (eine vernünftige Annäherung für englischsprachige Prosa). Ergebnisse werden gierig gekürzt: Sie werden in Rangfolge hinzugefügt, bis das Budget erschöpft ist.
Dies ist eine konservative Strategie. Ein ausgefeilterer Ansatz würde Qualitätsbewertungen pro Ergebnis berücksichtigen und kürzere, qualitativ hochwertigere Ergebnisse gegenüber längeren, qualitativ geringwertigeren bevorzugen. Der gierige Ansatz ist einfacher und funktioniert in der Praxis gut, da die RRF-Rangordnung die Ergebnisse bereits nach Relevanz sortiert.
Datenbankschema (vollständig)
-- Chunk content and metadata
CREATE TABLE chunks (
id INTEGER PRIMARY KEY,
file_path TEXT NOT NULL,
section TEXT NOT NULL,
chunk_text TEXT NOT NULL,
heading_context TEXT DEFAULT '',
mtime_ns INTEGER NOT NULL,
embedded_at REAL NOT NULL
);
CREATE INDEX idx_chunks_file ON chunks(file_path);
CREATE INDEX idx_chunks_mtime ON chunks(mtime_ns);
-- FTS5 for BM25 search (content-synced to chunks table)
CREATE VIRTUAL TABLE chunks_fts USING fts5(
chunk_text, section, heading_context,
content=chunks, content_rowid=id
);
-- sqlite-vec for vector KNN search
CREATE VIRTUAL TABLE chunk_vecs USING vec0(
id INTEGER PRIMARY KEY,
embedding float[256]
);
-- Model metadata for compatibility tracking
CREATE TABLE model_meta (
key TEXT PRIMARY KEY,
value TEXT
);
Schrittweiser Degradationspfad
Full pipeline: BM25 + Vector + RRF → Best results
No sqlite-vec: BM25 only → Good results (no semantic)
No model download: BM25 only → Good results (no semantic)
No FTS5: Vector only → Decent results (no keyword)
No database: Error → Prompt user to run indexer
Der Retriever prüft beim Initialisieren die verfügbaren Fähigkeiten und passt seine Abfragestrategie entsprechend an. Eine fehlende Komponente verschlechtert zwar die Qualität, verursacht jedoch keine Fehler. Der einzige harte Fehlerfall ist eine fehlende Datenbankdatei.
Produktionskennzahlen
Gemessen an einem Vault mit 16.894 Dateien, 49.746 Chunks, 83 MB SQLite-Datenbank, Apple M3 Pro:
| Metrik | Wert |
|---|---|
| Dateien insgesamt | 16.894 |
| Chunks insgesamt | 49.746 |
| Datenbankgröße | 83 MB |
| BM25-Abfragelatenz (p50) | 12 ms |
| Vektor-Abfragelatenz (p50) | 8 ms |
| RRF-Fusionslatenz | 3 ms |
| Suchlatenz Ende-zu-Ende (p50) | 23 ms |
| Vollständige Neuindexierung | ~4 Minuten |
| Inkrementelle Neuindexierung | <10 Sekunden |
| Embedding-Modell | potion-base-8M (256-dim) |
| BM25-Kandidatenpool | 30 |
| Vektor-Kandidatenpool | 30 |
| Standard-Ergebnislimit | 10 |
| Standard-Token-Budget | 4.000 Token |
Content-Hashing und Änderungserkennung
Der Indexer muss wissen, welche Dateien sich seit dem letzten Indexierungslauf geändert haben. Dieser Abschnitt behandelt den Mechanismus zur Änderungserkennung und die Hashing-Strategie.
Vergleich der Dateiänderungszeit
Der Indexer speichert mtime_ns (Dateiänderungszeit in Nanosekunden) für jeden Chunk in der Tabelle chunks. Bei einem inkrementellen Lauf führt der Indexer folgende Schritte aus:
- Durchsucht den Vault nach allen
.md-Dateien in erlaubten Ordnern - Liest die
mtime_nsjeder Datei aus dem Dateisystem - Vergleicht diese mit der gespeicherten
mtime_nsin der Datenbank - Identifiziert drei Kategorien:
- Neue Dateien: Pfad existiert im Dateisystem, aber nicht in der Datenbank
- Geänderte Dateien: Pfad existiert in beiden, aber
mtime_nsunterscheidet sich - Gelöschte Dateien: Pfad existiert in der Datenbank, aber nicht mehr im Dateisystem
def get_stale_files(self, vault_mtimes):
"""Find files whose mtime changed or are new."""
stored = dict(self.db.execute(
"SELECT DISTINCT file_path, mtime_ns FROM chunks"
).fetchall())
stale = []
for path, mtime in vault_mtimes.items():
if path not in stored or stored[path] != mtime:
stale.append(path)
return stale
def get_deleted_files(self, vault_paths):
"""Find files in database that no longer exist in vault."""
stored_paths = set(r[0] for r in self.db.execute(
"SELECT DISTINCT file_path FROM chunks"
).fetchall())
return stored_paths - set(vault_paths)
Warum mtime statt Content-Hash
Content-Hashing (SHA-256 des Dateiinhalts) wäre zuverlässiger als ein mtime-Vergleich — es würde Fälle erkennen, in denen eine Datei berührt wurde, ohne sich zu ändern (z. B. wenn git checkout die ursprüngliche mtime wiederherstellt). Allerdings erfordert Hashing das Lesen jeder Datei bei jedem inkrementellen Lauf. Bei 16.894 Dateien dauert das Lesen der Dateiinhalte 2–3 Sekunden. Das Lesen der mtimes aus dem Dateisystem dauert hingegen unter 100 ms.
Der Kompromiss: Ein mtime-Vergleich löst gelegentlich eine unnötige Neuindexierung unveränderter Dateien aus (falsch-positive Treffer), übersieht aber niemals tatsächliche Änderungen. Falsch-positive Treffer kosten lediglich einige zusätzliche Embedding-Aufrufe pro Lauf. Der Geschwindigkeitsunterschied (100 ms gegenüber 3 Sekunden) macht mtime zur pragmatischen Wahl für ein System, das bei jeder KI-Interaktion ausgeführt wird.
Umgang mit Löschungen
Wird eine Datei aus dem Vault gelöscht, entfernt der Indexer alle zugehörigen Chunks aus der Datenbank:
def remove_file(self, file_path):
"""Remove all chunks and vectors for a file."""
chunk_ids = [r[0] for r in self.db.execute(
"SELECT id FROM chunks WHERE file_path = ?",
[file_path],
).fetchall()]
for cid in chunk_ids:
self.db.execute(
"DELETE FROM chunk_vecs WHERE id = ?", [cid]
)
self.db.execute(
"DELETE FROM chunks WHERE file_path = ?",
[file_path],
)
Die Anweisung DELETE FROM chunk_vecs funktioniert nativ ab sqlite-vec v0.1.7.26 Frühere Versionen erforderten Workarounds (Löschen und Neuerstellen der virtuellen Tabelle oder Pflege einer externen Menge „aktiver IDs”). Falls Sie eine Version vor 0.1.7 verwenden, führen Sie vor der Nutzung direkter Löschungen ein Upgrade durch.
FTS5-Content-Sync-Tabellen erfordern eine explizite Löschung über INSERT INTO chunks_fts(chunks_fts, rowid, ...) VALUES('delete', ?, ...) für jede entfernte Zeile. Der Indexer übernimmt dies im Rahmen des Dateientfernungsprozesses.
Inkrementelle vs. vollständige Neuindizierung
Der Indexer unterstützt zwei Modi: inkrementell (schnell, für den täglichen Gebrauch) und vollständig (langsam, gelegentlich). Dieser Abschnitt behandelt, wann welcher Modus zum Einsatz kommt, welche Idempotenz-Garantien bestehen und wie eine Wiederherstellung nach Beschädigung funktioniert.
Inkrementelle Neuindizierung
Wann verwenden: Tägliche Indizierung nach dem Bearbeiten von Notizen. Der Standardmodus.
Ablauf: 1. Vault nach Dateiänderungen durchsuchen (mtime-Vergleich) 2. Chunks gelöschter Dateien entfernen 3. Geänderte Dateien neu aufteilen und neu einbetten 4. Neue Chunks für neue Dateien einfügen 5. FTS5-Index synchronisieren
Typische Dauer: <10 Sekunden für die Bearbeitungen eines Tages bei einem Vault mit 16.000 Dateien.
python index_vault.py --incremental
Vollständige Neuindizierung
Wann verwenden: - Nach einem Wechsel des Embedding-Modells (Abweichung beim Model-Hash erkannt) - Nach einer Schema-Migration (neue Spalten, geänderte Indizes) - Nach einer Datenbankbeschädigung (Integritätsprüfung schlägt fehl) - Wenn die inkrementelle Indizierung unerwartete Ergebnisse liefert
Ablauf: 1. Alle vorhandenen Daten löschen (Chunks, Vektoren, FTS5-Einträge) 2. Gesamten Vault durchsuchen 3. Alle Dateien in Chunks aufteilen 4. Alle Chunks einbetten 5. FTS5-Index von Grund auf neu erstellen
Typische Dauer: ~4 Minuten für 16.894 Dateien auf einem Apple M3 Pro.
python index_vault.py --full
Idempotenz
Beide Modi sind idempotent: Wird derselbe Befehl zweimal ausgeführt, ergibt sich dasselbe Ergebnis. Der Indexer löscht bestehende Chunks einer Datei, bevor neue eingefügt werden – ein erneuter inkrementeller Durchlauf auf einer bereits aktuellen Datenbank erzeugt daher null Änderungen. Ein erneuter vollständiger Durchlauf erzeugt eine identische Datenbank.
Wiederherstellung nach Beschädigung
Falls die SQLite-Datenbank beschädigt wird (Stromausfall während eines Schreibvorgangs, Festplattenfehler, abgebrochener Prozess mitten in einer Transaktion):
# Check integrity
sqlite3 vectors.db "PRAGMA integrity_check;"
# If corruption detected, full reindex rebuilds from source files
python index_vault.py --full
Die Quelle der Wahrheit sind stets die Vault-Dateien, nicht die Datenbank. Die Datenbank ist ein abgeleitetes Artefakt, das jederzeit neu erstellt werden kann. Diese Designeigenschaft ist entscheidend: Sie müssen die Datenbank niemals sichern.
Das --incremental-Flag
Wenn der Indexer mit --incremental ausgeführt wird:
- Model-Hash-Prüfung. Gespeicherter Model-Hash wird mit dem aktuellen Modell verglichen. Bei Abweichung wechselt der Indexer automatisch in den vollständigen Neuindizierungsmodus und gibt eine Warnung aus.
- Datei-Scan. Erlaubte Ordner werden durchlaufen, Dateipfade und mtimes erfasst.
- Änderungserkennung. Abgleich mit den gespeicherten Daten.
- Stapelverarbeitung. Geänderte Dateien werden in Stapeln von 64 neu aufgeteilt und eingebettet.
- Fortschrittsanzeige. Anzahl der verarbeiteten Dateien und verstrichene Zeit werden ausgegeben.
- Kontrolliertes Herunterfahren. Bei SIGINT wird die aktuelle Datei noch fertig verarbeitet, bevor der Prozess stoppt.
Credential Filtering und Datengrenzen
Persönliche Notizen enthalten Geheimnisse: API-Schlüssel, Bearer-Token, Datenbank-Verbindungszeichenfolgen, Private Keys, die während Debugging-Sitzungen eingefügt wurden. Der Credential-Filter verhindert, dass diese in den Abrufindex gelangen.
Das Problem
Eine Notiz über das Debugging einer OAuth-Integration könnte Folgendes enthalten:
The token was: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
I used this curl command:
curl -H "Authorization: Bearer sk-ant-api03-abc123..."
Ohne Filterung würden sowohl das JWT als auch der API-Schlüssel in Chunks aufgeteilt, eingebettet und in der Datenbank gespeichert. Eine Suche nach „authentication” würde den Chunk mit echten Geheimnissen zurückliefern. Schlimmer noch: Wenn der Retriever Ergebnisse über MCP an ein KI-Tool weiterleitet, erscheinen die Geheimnisse im Kontextfenster der KI und möglicherweise in den Logs des Tools.
Musterbasierte Filterung
Der Credential-Filter wird auf jeden Chunk vor der Speicherung angewendet und erkennt 25 herstellerspezifische Muster sowie generische Muster:
Herstellerspezifische Muster:
| Muster | Beispiel | Regex |
|---|---|---|
| OpenAI API-Schlüssel | sk-... |
sk-[a-zA-Z0-9_-]{20,} |
| Anthropic API-Schlüssel | sk-ant-api03-... |
sk-ant-api\d{2}-[a-zA-Z0-9_-]{20,} |
| GitHub PAT | ghp_... |
gh[ps]_[a-zA-Z0-9]{36,} |
| AWS Access Key | AKIA... |
AKIA[0-9A-Z]{16} |
| Stripe-Schlüssel | sk_live_... |
[sr]k_(live\|test)_[a-zA-Z0-9]{24,} |
| Cloudflare-Token | ... |
Verschiedene Muster |
Generische Muster:
| Muster | Erkennung |
|---|---|
| JWT-Token | eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+ |
| Bearer-Token | Bearer\s+[a-zA-Z0-9_\-\.]+ |
| Private Keys | -----BEGIN (RSA\|EC\|OPENSSH) PRIVATE KEY----- |
| Base64 mit hoher Entropie | Zeichenfolgen mit >4,5 Bit/Zeichen Entropie, 40+ Zeichen |
| Passwortzuweisungen | password\s*[:=]\s*["'][^"']+["'] |
Filter-Implementierung
def clean_content(text):
"""Scrub credentials from text before indexing."""
result = ScanResult(is_clean=True, match_count=0, patterns=[])
for pattern in CREDENTIAL_PATTERNS:
matches = pattern.regex.findall(text)
if matches:
text = pattern.regex.sub(
f"[REDACTED:{pattern.name}]", text
)
result.is_clean = False
result.match_count += len(matches)
result.patterns.append(pattern.name)
return text, result
Zentrale Designentscheidungen:
-
Filterung vor dem Embedding. Der bereinigte Text wird eingebettet. Die Vektordarstellung kodiert niemals Credential-Muster. Eine Abfrage nach „API-Schlüssel” liefert Notizen zurück, die das Management von API-Schlüsseln behandeln – nicht Notizen, die tatsächliche Schlüssel enthalten.
-
Ersetzen statt Entfernen. Der
[REDACTED:pattern-name]-Token bewahrt den semantischen Kontext des umgebenden Textes. Das Embedding erfasst, dass „hier etwas Credential-artiges stand”, ohne das Credential selbst zu kodieren. -
Muster protokollieren, nicht Werte. Der Filter protokolliert, welche Muster erkannt wurden (z. B. „Scrubbed 2 credential(s) from oauth-debug.md [jwt, bearer-token]”), aber niemals den Credential-Wert selbst.
Pfadbasierter Ausschluss
Die .indexignore-Datei ermöglicht grobgranularen Ausschluss nach Pfad. Der Credential-Filter bietet feingranulare Bereinigung innerhalb indizierter Dateien. Beide Mechanismen sind notwendig:
.indexignorefür ganze Ordner, die bekanntermaßen sensible Inhalte enthalten (Gesundheitsnotizen, Finanzdaten, Karrieredokumente)- Credential-Filter für Geheimnisse, die versehentlich in ansonsten indizierbaren Inhalten eingebettet sind
Datenklassifizierung
Für Vaults mit vielfältigen Inhalten empfiehlt sich eine Klassifizierung der Notizen nach Sensitivität:
| Stufe | Beispiele | Indizieren? | Filtern? |
|---|---|---|---|
| Öffentlich | Blog-Entwürfe, technische Notizen | Ja | Ja |
| Intern | Projektpläne, Architekturentscheidungen | Ja | Ja |
| Sensibel | Gehaltsdaten, Gesundheitsdaten | Nein (.indexignore) | N/A |
| Eingeschränkt | Credentials, Private Keys | Nein (.indexignore) | N/A |
MCP-Server-Architektur
Model Context Protocol (MCP)-Server stellen den Retriever als Werkzeug bereit, das KI-Agenten aufrufen können. Dieser Abschnitt behandelt das Server-Design, den Funktionsumfang und die Berechtigungsgrenzen.
Protokollwahl: STDIO vs. HTTP
MCP unterstützt zwei Transportmodi:
STDIO — Das KI-Tool startet den MCP-Server als Kindprozess und kommuniziert über stdin/stdout. Dies ist der Standardmodus für lokale Tools. Claude Code, Codex CLI und Cursor unterstützen alle STDIO-MCP-Server.
{
"mcpServers": {
"obsidian": {
"command": "python",
"args": ["/path/to/obsidian_mcp.py"],
"env": {
"VAULT_PATH": "/path/to/vault",
"DB_PATH": "/path/to/vectors.db"
}
}
}
}
HTTP — Der MCP-Server läuft als eigenständiger HTTP-Dienst. Nützlich für Fernzugriff, Multi-Client-Setups oder Team-Konfigurationen, bei denen der Vault auf einem gemeinsamen Server liegt.
{
"mcpServers": {
"obsidian": {
"url": "http://localhost:3333/mcp"
}
}
}
Empfehlung: Verwenden Sie STDIO für persönliche Vaults. Es ist einfacher, sicherer (keine Netzwerkexposition) und der Server-Lebenszyklus wird vom KI-Tool verwaltet. Nutzen Sie HTTP nur, wenn mehrere Tools oder mehrere Rechner gleichzeitigen Zugriff auf denselben Vault benötigen.
Entwicklung der MCP-Spezifikation. Die MCP-Spezifikation vom Juni 2025 führte OAuth 2.1-Autorisierung, strukturierte Tool-Ausgaben (typisierte Rückgabeschemata) und Elicitation (serverinitiierte Benutzerabfragen) ein. Das Release vom November 2025 brachte Streamable HTTP als vollwertigen Transportmodus,
.well-known-URL-Discovery für automatisches Durchsuchen von Server-Fähigkeiten, strukturierte Tool-Annotationen zur Deklaration, ob ein Tool nur lesend oder verändernd arbeitet, sowie ein SDK-Tier-Standardisierungssystem.1821 Das nächste Spezifikationsrelease (voraussichtlich Mitte 2026) schlägt asynchrone Operationen für langlaufende Aufgaben, domänenspezifische Protokollerweiterungen für Branchen wie Gesundheitswesen und Finanzen sowie Agent-zu-Agent-Kommunikationsstandards für Multi-Agenten-Workflows vor.21 Für persönliche Vault-Server bleibt STDIO der einfachste Weg. Streamable HTTP und.well-known-Discovery kommen vor allem Enterprise-HTTP-Deployments mit Multi-Tenant-Routing und Load Balancing zugute. Verfolgen Sie die MCP-Roadmap, um Änderungen im Blick zu behalten, die Ihre Transportwahl beeinflussen.
Fähigkeitsdesign
Der MCP-Server sollte einen minimalen Satz an Tools bereitstellen:
search — Das primäre Tool. Führt Hybrid-Retrieval durch und liefert gerankte Ergebnisse.
{
"name": "obsidian_search",
"description": "Search the Obsidian vault using hybrid BM25 + vector retrieval",
"parameters": {
"query": { "type": "string", "description": "Search query" },
"limit": { "type": "integer", "default": 5 },
"max_tokens": { "type": "integer", "default": 2000 }
}
}
read_note — Liest den vollständigen Inhalt einer bestimmten Notiz anhand des Dateipfads. Nützlich, wenn der Agent den kompletten Kontext eines Suchergebnisses einsehen möchte.
{
"name": "obsidian_read_note",
"description": "Read the full content of a note by file path",
"parameters": {
"file_path": { "type": "string", "description": "Relative path within vault" }
}
}
list_notes — Listet Notizen auf, die einem Filter entsprechen (nach Ordner, Tag, Typ oder Datumsbereich). Nützlich für explorative Suchen, wenn der Agent keine spezifische Anfrage hat.
{
"name": "obsidian_list_notes",
"description": "List notes matching filters",
"parameters": {
"folder": { "type": "string", "description": "Folder path within vault" },
"tag": { "type": "string", "description": "Tag to filter by" },
"limit": { "type": "integer", "default": 20 }
}
}
get_context — Ein Komfort-Tool, das eine Suche durchführt und die Ergebnisse als Kontextblock formatiert, der sich zur Einspeisung in eine Konversation eignet.
{
"name": "obsidian_get_context",
"description": "Get formatted context from vault for a topic",
"parameters": {
"topic": { "type": "string", "description": "Topic to get context for" },
"max_tokens": { "type": "integer", "default": 2000 }
}
}
Berechtigungsgrenzen
Der MCP-Server sollte strikte Grenzen durchsetzen:
-
Nur Lesezugriff. Der Server liest den Vault und die Indexdatenbank. Er erstellt, ändert oder löscht keine Notizen. Schreiboperationen (Erfassen neuer Notizen) werden von separaten Hooks oder Skills übernommen, nicht vom MCP-Server.
-
Vault-begrenzt. Der Server liest ausschließlich Dateien innerhalb des konfigurierten Vault-Pfads. Path-Traversal-Versuche (
../../etc/passwd) müssen abgewiesen werden. -
Anmeldeinformationen-gefilterte Ausgabe. Auch wenn die Datenbank bereits vorgefilterte Inhalte enthält, sollte als Defense-in-Depth-Maßnahme eine Credential-Filterung auf die Ausgabe angewendet werden.
-
Token-begrenzte Antworten. Erzwingen Sie
max_tokensbei allen Tool-Antworten, um zu verhindern, dass das KI-Tool übermäßig große Kontextblöcke erhält.
Fehlerbehandlung
MCP-Tools sollten strukturierte Fehlermeldungen zurückgeben, die dem KI-Tool bei der Wiederherstellung helfen:
def search(self, query, limit=5, max_tokens=2000):
if not self.db_path.exists():
return {
"error": "Index database not found. Run the indexer first.",
"suggestion": "python index_vault.py --full"
}
results = self.retriever.search(query, limit, max_tokens)
if not results:
return {
"results": [],
"message": f"No results found for '{query}'. Try broader terms."
}
return {
"results": [
{
"file_path": r["file_path"],
"section": r["section"],
"text": r["chunk_text"],
"score": round(r["rrf_score"], 4),
}
for r in results
],
"count": len(results),
"query": query,
}
Claude Code-Integration
Claude Code ist der primäre Nutzer des Obsidian-Retrievalsystems. Dieser Abschnitt behandelt die MCP-Konfiguration, die Hook-Integration und das obsidian_bridge.py-Muster.
MCP-Konfiguration
Fügen Sie den Obsidian-MCP-Server zu ~/.claude/settings.json hinzu:
{
"mcpServers": {
"obsidian": {
"command": "python",
"args": ["/path/to/obsidian_mcp.py"],
"env": {
"VAULT_PATH": "/absolute/path/to/vault",
"DB_PATH": "/absolute/path/to/vectors.db"
}
}
}
}
Starten Sie Claude Code nach dem Hinzufügen der Konfiguration neu. Der MCP-Server wird als Kindprozess gestartet. Überprüfen Sie, ob er läuft:
> What tools do you have from the obsidian MCP server?
Claude Code sollte die verfügbaren Tools auflisten (obsidian_search, obsidian_read_note usw.).
Hook-Integration
Hooks erweitern das Verhalten von Claude Code an definierten Lebenszykluspunkten. Zwei Hooks sind für die Obsidian-Integration relevant:
PreToolUse-Hook — Fragt den Vault ab, bevor der Agent einen Tool-Aufruf verarbeitet. Relevanter Kontext wird automatisch injiziert.
#!/bin/bash
# ~/.claude/hooks/pre-tool-use/obsidian-context.sh
# Automatically inject vault context before tool execution
TOOL_NAME="$1"
PROMPT="$2"
# Only inject context for code-related tools
case "$TOOL_NAME" in
Edit|Write|Bash)
# Query the vault
CONTEXT=$(python /path/to/retriever.py search "$PROMPT" --limit 3 --max-tokens 1500)
if [ -n "$CONTEXT" ]; then
echo "---"
echo "Relevant vault context:"
echo "$CONTEXT"
echo "---"
fi
;;
esac
PostToolUse-Hook — Erfasst bedeutende Tool-Ausgaben und schreibt sie zur späteren Abfrage zurück in den Vault.
#!/bin/bash
# ~/.claude/hooks/post-tool-use/capture-insight.sh
# Capture significant outputs to vault (selective)
TOOL_NAME="$1"
OUTPUT="$2"
# Only capture substantial outputs
if [ ${#OUTPUT} -gt 500 ]; then
python /path/to/capture.py --text "$OUTPUT" --source "claude-code-$TOOL_NAME"
fi
Das obsidian_bridge.py-Muster
Ein Bridge-Modul stellt eine Python-API bereit, die Hooks und Skills aufrufen können:
# obsidian_bridge.py
from retriever import HybridRetriever
_retriever = None
def get_retriever():
global _retriever
if _retriever is None:
_retriever = HybridRetriever(
db_path="/path/to/vectors.db",
vault_path="/path/to/vault",
)
return _retriever
def search_vault(query, limit=5, max_tokens=2000):
"""Search vault and return formatted context."""
retriever = get_retriever()
results = retriever.search(query, limit, max_tokens)
if not results:
return ""
lines = ["## Vault Context\n"]
for r in results:
lines.append(f"**{r['file_path']}** — {r['section']}")
lines.append(f"> {r['chunk_text'][:500]}")
lines.append("")
return "\n".join(lines)
Der /capture-Skill
Ein Claude Code-Skill zum Erfassen von Erkenntnissen zurück in den Vault:
/capture "OAuth token rotation requires both access and refresh token invalidation"
--domain security
--tags oauth,tokens
Der Skill erstellt eine neue Notiz in 00-inbox/ mit korrektem Frontmatter und löst eine inkrementelle Neuindizierung aus, sodass die neue Notiz sofort durchsuchbar ist.
Benutzerdefinierte Befehlsmuster
Claude Code-Skills können Vault-Operationen in benannte Befehle kapseln. Anwender haben Bibliotheken Obsidian-spezifischer Befehle aufgebaut, die den Vault sowohl als Lesequelle als auch als Schreibziel nutzen.
Signalüberwachung. Ein /scan-intel-Befehl fragt externe Quellen ab, bewertet Ergebnisse anhand persönlicher Forschungsinteressen und schreibt qualifizierende Signale als Vault-Notizen mit Frontmatter:
/scan-intel --topics "agent infrastructure, security" --lookback 7d
Der Befehl ruft Daten von konfigurierten Quellen ab (arXiv, HN, RSS), wendet ein Bewertungsmodell an (Relevanz, Umsetzbarkeit, Tiefe, Autorität) und schreibt passende Signale in themenspezifische Vault-Ordner. Der Vault wird zum nachgelagerten Konsumenten einer automatisierten Informationspipeline.
Captain’s Log. Ein /captains-log-Befehl aggregiert die tägliche Git-Aktivität über alle Repositories, schreibt einen strukturierten Journaleintrag in den Vault und enthält getroffene Entscheidungen, Erkenntnisse und offene Themen:
/captains-log
Der Befehl zieht die Commit-Historie von GitHub, gruppiert nach Repository und formatiert als narrativer Journaleintrag. Im Laufe der Zeit entsteht durch die täglichen Einträge ein durchsuchbares Protokoll dessen, was ausgeliefert wurde und warum.
Obsidian-Erfassung. Ein /obsidian-capture-Befehl nimmt eine Erkenntnis aus der aktuellen Claude Code-Sitzung und schreibt sie mit korrekten Metadaten direkt in den Vault:
/obsidian-capture "SAST gates in agent loops increase security degradation"
--folder AI-Tools --tags security,agents
Dieses Muster lässt sich auf jede Vault-Operation übertragen: Erstellen von MOCs, Aktualisieren von Projektstatusnotizen, Verknüpfen verwandter Signale oder Generieren wöchentlicher Zusammenfassungen aus gesammelten Tageseinträgen.
Community-Beispiele. Anwender veröffentlichen ihre Befehlsbibliotheken. Ein Entwickler teilte 22 benutzerdefinierte Obsidian- und Claude Code-Befehle für tägliche Reviews, Projektplanung, Recherche-Erfassung und Content-Workflows.1 Ein anderer baute einen „Visual Explainer”-Skill, der aus Codeanalysen Diagrammnotizen im Vault erzeugt.2 Die Befehle variieren, doch die Architektur bleibt konsistent: Claude Code-Skills als Schnittstelle, Vault-Notizen als Speicherschicht und die Retrieval-Infrastruktur als Abfrage-Engine.
Kontextfenster-Verwaltung
Die Integration sollte das Kontextfenster von Claude Code berücksichtigen:
- Beschränken Sie injizierten Kontext auf 1.500–2.000 Token pro Abfrage. Mehr konkurriert mit dem Arbeitsgedächtnis des Agenten.
- Quellenangaben einschließen. Geben Sie stets den Dateipfad und die Abschnittsüberschrift an, damit der Agent die Quelle referenzieren kann.
- Chunk-Text kürzen. Lange Chunks sollten mit
...abgeschnitten statt vollständig weggelassen werden. Die ersten 300–500 Zeichen enthalten in der Regel die wesentlichen Informationen. - Nicht bei jedem Tool-Aufruf injizieren. Der PreToolUse-Hook sollte Kontext selektiv basierend auf dem aufgerufenen Tool injizieren. Leseoperationen benötigen keinen Vault-Kontext. Schreib- und Edit-Operationen profitieren davon.
Codex-CLI-Integration
Codex CLI verbindet sich über config.toml mit MCP-Servern. Das Integrationsmuster unterscheidet sich von Claude Code in der Konfigurationssyntax und der Art der Instruktionsübermittlung.
MCP-Konfiguration
Fügen Sie Folgendes zu .codex/config.toml oder ~/.codex/config.toml hinzu:
[mcp_servers.obsidian]
command = "python"
args = ["/path/to/obsidian_mcp.py"]
[mcp_servers.obsidian.env]
VAULT_PATH = "/absolute/path/to/vault"
DB_PATH = "/absolute/path/to/vectors.db"
AGENTS.md-Muster
Codex CLI liest AGENTS.md für projektbezogene Anweisungen. Fügen Sie Hinweise zur Vault-Suche ein:
## Available Tools
### Obsidian Vault (MCP: obsidian)
Use the `obsidian_search` tool to find relevant context from the knowledge base.
Search the vault when you need:
- Background on a concept or pattern
- Prior decisions or rationale
- Reference material for implementation
Example queries:
- "authentication patterns in FastAPI"
- "how does the review aggregator work"
- "sqlite-vec configuration"
Unterschiede zu Claude Code
| Funktion | Claude Code | Codex CLI |
|---|---|---|
| MCP-Konfiguration | settings.json |
config.toml |
| Hooks | ~/.claude/hooks/ |
Nicht unterstützt |
| Skills | ~/.claude/skills/ |
Nicht unterstützt |
| Instruktionsdatei | CLAUDE.md |
AGENTS.md |
| Genehmigungsmodi | --dangerously-skip-permissions |
suggest / auto-edit / full-auto |
Wesentlicher Unterschied: Codex CLI unterstützt keine Hooks. Das automatische Kontextinjektionsmuster (PreToolUse-Hook) steht nicht zur Verfügung. Stattdessen sollten Sie in AGENTS.md explizite Anweisungen aufnehmen, die den Agenten anweisen, vor Arbeitsbeginn den Vault zu durchsuchen.
Cursor und andere Tools
Cursor und andere KI-Tools, die MCP unterstützen, können sich mit demselben Obsidian-MCP-Server verbinden. Dieser Abschnitt behandelt die Konfiguration für gängige Tools.
Cursor
Fügen Sie Folgendes zur .cursor/mcp.json im Stammverzeichnis Ihres Projekts hinzu:
{
"mcpServers": {
"obsidian": {
"command": "python",
"args": ["/path/to/obsidian_mcp.py"],
"env": {
"VAULT_PATH": "/absolute/path/to/vault",
"DB_PATH": "/absolute/path/to/vectors.db"
}
}
}
}
Cursors .cursorrules-Datei kann Anweisungen zur Nutzung des Vaults enthalten:
When working on implementation tasks, search the Obsidian vault
for relevant context before writing code. Use the obsidian_search
tool with descriptive queries about the concept you're implementing.
Kompatibilitätsmatrix
| Tool | MCP-Unterstützung | Transport | Konfigurationsort |
|---|---|---|---|
| Claude Code | Vollständig | STDIO | ~/.claude/settings.json |
| Codex CLI | Vollständig | STDIO | .codex/config.toml |
| Cursor | Vollständig | STDIO | .cursor/mcp.json |
| Windsurf | Vollständig | STDIO | .windsurf/mcp.json |
| Continue.dev | Teilweise | HTTP | ~/.continue/config.json |
| Zed | In Entwicklung | STDIO | Einstellungen-UI |
| Claudian (Obsidian-Plugin) | N/A (eingebettet) | Claude Code CLI | Obsidian-Plugin-Einstellungen |
| Agent Client (Obsidian-Plugin) | N/A (eingebettet) | ACP | Obsidian-Plugin-Einstellungen |
Fallback für Tools ohne MCP
Für Tools ohne MCP-Unterstützung lässt sich der Retriever als CLI einbinden:
# Search from command line
python retriever_cli.py search "query text" --limit 5
# Output formatted for copy-paste into any tool
python retriever_cli.py context "query text" --format markdown
Die CLI gibt strukturierten Text aus, der manuell in die Eingabe eines beliebigen KI-Tools eingefügt werden kann. Das ist weniger elegant als eine MCP-Integration, funktioniert aber universell.
Prompt-Caching aus strukturierten Notizen
Strukturierte Notizen im Vault können als wiederverwendbare Kontextblöcke dienen, die den Token-Verbrauch über KI-Interaktionen hinweg reduzieren. Dieser Abschnitt behandelt das Cache-Key-Design und die Verwaltung des Token-Budgets.
Das Muster
Anstatt bei jeder Interaktion nach Kontext zu suchen, lassen sich Kontextblöcke aus gut strukturierten Vault-Notizen vorab erstellen und cachen:
# cache_keys.py
CONTEXT_BLOCKS = {
"auth-patterns": {
"vault_query": "authentication patterns implementation",
"max_tokens": 1500,
"ttl_hours": 24, # Rebuild daily
},
"api-conventions": {
"vault_query": "API design conventions REST patterns",
"max_tokens": 1000,
"ttl_hours": 168, # Rebuild weekly
},
"project-architecture": {
"vault_query": "current project architecture decisions",
"max_tokens": 2000,
"ttl_hours": 12, # Rebuild twice daily
},
}
Cache-Invalidierung
Die Cache-Invalidierung basiert auf zwei Signalen:
- TTL-Ablauf. Jeder Kontextblock hat eine Time-to-Live. Nach Ablauf der TTL wird der Block durch erneute Vault-Abfrage neu aufgebaut.
- Vault-Änderungserkennung. Erkennt der Indexer Änderungen an Dateien, die zu einem gecachten Kontextblock beigetragen haben, wird dieser sofort invalidiert.
Token-Budget-Verwaltung
Eine Sitzung beginnt mit einem Gesamtkontextbudget. Gecachte Blöcke verbrauchen einen Teil dieses Budgets:
Total context budget: 8,000 tokens
├─ System prompt: 1,500 tokens
├─ Cached blocks: 3,000 tokens (pre-loaded)
├─ Dynamic search: 2,000 tokens (on-demand)
└─ Conversation: 1,500 tokens (remaining)
Die gecachten Blöcke werden zu Sitzungsbeginn geladen. Dynamische Suchergebnisse füllen das verbleibende Budget pro Abfrage auf. Dieser hybride Ansatz gibt dem Agenten eine Grundlage häufig benötigten Kontexts und bewahrt gleichzeitig Budget für spezifische Abfragen.
Token-Verbrauch im Vorher/Nachher-Vergleich
Ohne Caching: Jede relevante Abfrage löst eine Vault-Suche aus, die 1.500–2.000 Token Kontext zurückgibt. Über 10 Abfragen in einer Sitzung verbraucht der Agent 15.000–20.000 Token an Vault-Kontext.
Mit Caching: Drei vorab erstellte Kontextblöcke verbrauchen insgesamt 4.500 Token. Zusätzliche Suchen ergeben 1.500–2.000 Token pro einzigartiger Abfrage. Bei 10 Abfragen, von denen 6 durch gecachte Blöcke abgedeckt werden, verbraucht der Agent 4.500 + (4 × 1.500) = 10.500 Token — etwa die Hälfte des ungecachten Verbrauchs.
PostToolUse-Hooks zur Kontextkomprimierung
Tool-Ausgaben können umfangreich sein: Stack-Traces, Dateilisten, Testergebnisse. Ein PostToolUse-Hook kann diese Ausgaben komprimieren, bevor sie Platz im Kontextfenster beanspruchen.
Das Problem
Ein Bash-Tool-Aufruf, der Tests ausführt, könnte Folgendes zurückgeben:
PASSED tests/test_auth.py::test_login_success
PASSED tests/test_auth.py::test_login_failure
PASSED tests/test_auth.py::test_token_refresh
PASSED tests/test_auth.py::test_session_expiry
... (200 more lines)
FAILED tests/test_api.py::test_rate_limit_exceeded
Die vollständige Ausgabe umfasst 5.000 Token, doch das Signal steckt in 2 Zeilen: 200 bestanden, 1 fehlgeschlagen.
Hook-Implementierung
#!/bin/bash
# ~/.claude/hooks/post-tool-use/compress-output.sh
# Compress verbose tool outputs to preserve context window
TOOL_NAME="$1"
OUTPUT="$2"
OUTPUT_LEN=${#OUTPUT}
# Only compress large outputs
if [ "$OUTPUT_LEN" -lt 2000 ]; then
exit 0 # Pass through unchanged
fi
case "$TOOL_NAME" in
Bash)
# Compress test output
if echo "$OUTPUT" | grep -q "PASSED\|FAILED"; then
PASSED=$(echo "$OUTPUT" | grep -c "PASSED")
FAILED=$(echo "$OUTPUT" | grep -c "FAILED")
FAILURES=$(echo "$OUTPUT" | grep "FAILED")
echo "Tests: $PASSED passed, $FAILED failed"
if [ "$FAILED" -gt 0 ]; then
echo "Failures:"
echo "$FAILURES"
fi
fi
;;
esac
Schutz vor rekursiver Auslösung
Ein Komprimierungs-Hook, der Ausgaben erzeugt, könnte sich selbst auslösen, wenn kein Schutz vorhanden ist:
# Guard against recursive invocation
if [ -n "$COMPRESS_HOOK_ACTIVE" ]; then
exit 0
fi
export COMPRESS_HOOK_ACTIVE=1
Komprimierungsheuristiken
| Ausgabetyp | Erkennung | Komprimierungsstrategie |
|---|---|---|
| Testergebnisse | Schlüsselwörter PASSED / FAILED |
Bestanden/Fehlgeschlagen zählen, nur Fehler anzeigen |
| Dateilisten | ls oder find im Befehl |
Auf die ersten 20 Einträge kürzen + Gesamtanzahl |
| Stack-Traces | Schlüsselwort Traceback |
Ersten und letzten Frame + Fehlermeldung beibehalten |
| Git-Status | modified: / new file: |
Anzahl nach Status zusammenfassen |
| Build-Ausgabe | warning: / error: |
Info-Zeilen entfernen, Warnungen/Fehler beibehalten |
Signal-Aufnahme und Triage-Pipeline
Die Aufnahmeschicht bestimmt, was in den Vault gelangt. Ohne Kuratierung sammelt der Vault Rauschen an. Dieser Abschnitt behandelt die Scoring-Pipeline, die Signale in Domänenordner weiterleitet.
Quellen
Signale stammen aus mehreren Kanälen:
- RSS-Feeds: Technische Blogs, Sicherheitshinweise, Release Notes
- Lesezeichen: Browser-Lesezeichen, gespeichert über Obsidian Web Clipper oder Bookmarklet
- Newsletter: Zentrale Auszüge aus E-Mail-Newslettern
- Manuelle Erfassung: Notizen aus Lektüre, Gesprächen oder Recherche
- Tool-Ausgaben: Bedeutsame KI-Tool-Ausgaben, erfasst über Hooks
- iOS-Share-Extension: Die iOS-App von Obsidian (Anfang 2026 aktualisiert) enthält eine Share Extension, die Inhalte aus Safari, sozialen Netzwerken und anderen Apps direkt im Vault speichert, ohne Obsidian öffnen zu müssen.31 Das schafft einen reibungsarmen mobilen Aufnahmepfad — einen Artikel aus Safari teilen, und er landet als Vault-Notiz, bereit zur Bewertung.
- Obsidian CLI: Shell-Skripte und Hooks können Notizen über
obsidian file createerstellen oder überobsidian file appendan bestehende Notizen anhängen, was automatisierte Aufnahme-Pipelines auf dem Desktop ermöglicht.
Bewertungsdimensionen
Jedes Signal wird in vier Dimensionen bewertet (jeweils 0,0 bis 1,0):
| Dimension | Frage | Niedriger Wert (0,0–0,3) | Hoher Wert (0,7–1,0) |
|---|---|---|---|
| Relevanz | Bezieht sich das auf meine aktiven Domänen? | Tangential, außerhalb des Rahmens | Direkt relevant für aktuelle Arbeit |
| Umsetzbarkeit | Kann ich diese Information nutzen? | Reine Theorie, keine Anwendung | Spezifische Technik oder Muster, das ich anwenden kann |
| Tiefe | Wie substanziell ist der Inhalt? | Schlagzeilen, oberflächliche Zusammenfassung | Detaillierte Analyse mit Beispielen |
| Autorität | Wie glaubwürdig ist die Quelle? | Anonymer Blog, nicht verifiziert | Primärquelle, peer-reviewed, anerkannter Experte |
Gesamtbewertung und Weiterleitung
composite = (relevance * 0.35) + (actionability * 0.25) +
(depth * 0.25) + (authority * 0.15)
| Wertbereich | Aktion |
|---|---|
| 0,55+ | Automatische Weiterleitung in Domänenordner |
| 0,40–0,55 | In Warteschlange zur manuellen Prüfung |
| < 0,40 | Verwerfen (nicht speichern) |
Domänen-Weiterleitung
Signale mit einem Wert über 0,55 werden anhand von Keyword-Matching und Themenklassifikation in einen von 12 Domänenordnern weitergeleitet:
05-signals/
├── ai-tooling/ # Claude, LLMs, AI development tools
├── security/ # Vulnerabilities, auth, cryptography
├── systems/ # Architecture, distributed systems
├── programming/ # Languages, patterns, algorithms
├── web/ # Frontend, backends, APIs
├── data/ # Databases, data engineering
├── devops/ # CI/CD, containers, infrastructure
├── design/ # UI/UX, product design
├── mobile/ # iOS, Android, cross-platform
├── career/ # Industry trends, hiring, growth
├── research/ # Academic papers, whitepapers
└── other/ # Signals that don't fit a domain
Produktionsstatistiken
Über 14 Monate Betrieb:
| Metrik | Wert |
|---|---|
| Verarbeitete Signale insgesamt | 7.771 |
| Automatisch weitergeleitet (>0,55) | 4.832 (62 %) |
| Zur Prüfung eingereiht (0,40–0,55) | 1.543 (20 %) |
| Verworfen (<0,40) | 1.396 (18 %) |
| Aktive Domänenordner | 12 |
| Durchschnittliche Signale pro Tag | ~18 |
Knowledge-Graph-Muster
Obsidians Wiki-Link-Graph kodiert Beziehungen zwischen Notizen. Dieser Abschnitt behandelt Link-Semantik, Graph-Traversierung zur Kontexterweiterung und Anti-Patterns, die die Graph-Qualität beeinträchtigen.
Backlink-Semantik
Jeder Wiki-Link erzeugt eine gerichtete Kante im Graphen. Obsidian verfolgt sowohl Forward-Links als auch Backlinks:
- Forward-Link: Notiz A enthält
[[Note B]]→ A verlinkt auf B - Backlink: Notiz B zeigt an, dass Notiz A sie referenziert
Der Graph kodiert je nach Kontext verschiedene Arten von Beziehungen:
| Link-Muster | Semantik | Beispiel |
|---|---|---|
| Inline-Link | „Steht in Bezug zu” | “See [[OAuth Token Rotation]] for details” |
| Header-Link | „Hat Unterthema” | ”## Related\n- [[Token Rotation]]\n- [[Session Management]]” |
| Tag-artiger Link | „Ist kategorisiert als” | ”[[type/reference]]” |
| MOC-Link | „Ist Teil von” | Eine Maps of Content-Notiz, die verwandte Notizen auflistet |
Maps of Content (MOCs)
MOCs sind Index-Notizen, die verwandte Notizen in einer navigierbaren Struktur organisieren:
---
title: "Authentication & Security MOC"
type: moc
domain: security
---
## Core Concepts
- [[OAuth 2.0 Overview]]
- [[JWT Token Anatomy]]
- [[Session Management Patterns]]
## Implementation Patterns
- [[OAuth Token Rotation]]
- [[Refresh Token Security]]
- [[PKCE Flow Implementation]]
## Failure Modes
- [[Token Expiry Handling]]
- [[Session Fixation Prevention]]
- [[CSRF Defense Strategies]]
MOCs verbessern das Retrieval auf zwei Arten:
- Direkter Treffer. Eine Suche nach „authentication overview” trifft den MOC selbst und liefert dem Agenten eine kuratierte Liste verwandter Notizen.
- Kontexterweiterung. Nach dem Auffinden einer bestimmten Notiz kann der Retriever prüfen, ob die Notiz in MOCs vorkommt, und die MOC-Struktur in die Ergebnisse einbeziehen — so erhält der Agent eine Übersichtskarte des breiteren Themas.
Graph-Traversierung zur Kontexterweiterung
Eine zukünftige Erweiterung des Retrievers: Nach dem Auffinden der besten Ergebnisse wird der Kontext durch Verfolgen von Links erweitert:
def expand_context(results, depth=1):
"""Follow wiki-links from top results to find related context."""
expanded = set()
for result in results:
# Parse wiki-links from chunk text
links = extract_wiki_links(result["chunk_text"])
for link_target in links:
# Resolve link to file path
target_path = resolve_wiki_link(link_target)
if target_path and target_path not in expanded:
expanded.add(target_path)
# Include target's most relevant chunk
target_chunks = get_chunks_for_file(target_path)
# ... rank and include best chunk
return results + list(expanded_results)
Dies ist im aktuellen Retriever nicht implementiert, stellt jedoch eine natürliche Erweiterung der Graph-Struktur dar.
Anti-Patterns
Verwaiste Cluster. Gruppen von Notizen, die untereinander verlinkt sind, aber keine Verbindungen zum Rest des Vaults haben. Das Graph-Panel in Obsidian macht diese als isolierte Inseln sichtbar. Verwaiste Cluster deuten auf fehlende MOCs oder fehlende domänenübergreifende Links hin.
Tag-Wildwuchs. Inkonsistente Verwendung von Tags oder das Erstellen zu vieler feingranularer Tags. Ein Vault mit 500 einzigartigen Tags bei 5.000 Notizen hat durchschnittlich 1 Notiz pro 10 Tags — die Tags sind zum Filtern nicht nützlich. Konsolidieren Sie auf 20–50 übergeordnete Tags, die Ihren Domänen-Ordnern entsprechen.
Link-lastige, inhaltsarme Notizen. Notizen, die ausschließlich aus Wiki-Links ohne Fließtext bestehen. Diese Notizen werden schlecht indexiert, da der Chunker keinen Text zum Einbetten (Embedding) hat. Fügen Sie mindestens einen Absatz Kontext hinzu, der erklärt, warum die verlinkten Notizen zusammenhängen.
Bidirektionale Links für alles. Nicht jede Erwähnung erfordert einen Wiki-Link. Wenn „OAuth” nur beiläufig genannt wird, braucht es kein [[OAuth 2.0 Overview]]. Reservieren Sie Wiki-Links für intentionale, navigierbare Beziehungen, bei denen ein Klick auf den Link nützlichen Kontext liefern würde.
Entwickler-Workflow-Rezepte
Praxisnahe Workflows, die Vault-Retrieval mit alltäglichen Entwicklungsaufgaben kombinieren.
Morgendlicher Kontextaufbau
Starten Sie den Tag, indem Sie relevanten Kontext laden:
Search my vault for notes about [current project] updated in the last week
Der Retriever gibt aktuelle Notizen zu Ihrem aktiven Projekt zurück und verschafft Ihnen einen schnellen Überblick darüber, wo Sie aufgehört haben. Deutlich effektiver als das erneute Lesen der gestrigen Commit-Nachrichten.
Wissenserfassung während des Programmierens
Halten Sie beim Implementieren einer Funktion Erkenntnisse fest, ohne den Editor verlassen zu müssen:
/capture "FastAPI dependency injection with async generators requires yield,
not return. The generator is the dependency lifecycle."
--domain programming
--tags fastapi,dependency-injection
Die erfasste Erkenntnis wird sofort indexiert und steht für zukünftiges Retrieval zur Verfügung. Über Monate hinweg bauen diese Mikro-Erfassungen einen Korpus implementierungsspezifischen Wissens auf.
Projekt-Kickoff
Beim Start eines neuen Projekts oder Features:
- Vault durchsuchen: „Was weiß ich über [Technologie/Muster]?”
- Die Top-5-Ergebnisse auf frühere Entscheidungen und Stolperfallen prüfen
- Prüfen, ob ein MOC für die Domäne existiert; falls nicht, einen erstellen
- Nach Fehlermodi suchen: „Probleme mit [Technologie]”
Debugging mit Vault-Suche
Bei einem Fehler oder unerwartetem Verhalten:
Search my vault for [error message or symptom]
Frühere Debugging-Notizen enthalten oft die Ursache und die Lösung. Besonders wertvoll ist dies bei wiederkehrenden Problemen über Projekte hinweg — der Vault erinnert sich an das, was Sie vergessen.
Vorbereitung auf Code Reviews
Vor dem Review eines PRs:
Search my vault for patterns and conventions about [module being changed]
Der Vault liefert frühere Entscheidungen, architektonische Einschränkungen und Coding-Standards, die für den zu überprüfenden Code relevant sind. Das Review basiert so auf institutionellem Wissen, nicht nur auf dem Diff.
Performance-Optimierung
Dieser Abschnitt behandelt Optimierungsstrategien für verschiedene Vault-Größen und Nutzungsmuster.
Verwaltung der Indexgröße
| Vault-Größe | Chunks | DB-Größe | Vollständige Neuindexierung | Inkrementell |
|---|---|---|---|---|
| 500 Notizen | ~1.500 | 3 MB | 15 Sekunden | <1 Sekunde |
| 2.000 Notizen | ~6.000 | 12 MB | 45 Sekunden | 2 Sekunden |
| 5.000 Notizen | ~15.000 | 30 MB | 2 Minuten | 4 Sekunden |
| 15.000 Notizen | ~50.000 | 83 MB | 4 Minuten | <10 Sekunden |
| 50.000 Notizen | ~150.000 | 250 MB | 15 Minuten | 30 Sekunden |
Ab 50.000+ Notizen sollten Sie folgende Maßnahmen in Betracht ziehen: - Erhöhung der batch_size von 64 auf 128 für schnelleres Embedding - Verwendung des WAL-Modus (Standard) für gleichzeitigen Zugriff - Ausführung der vollständigen Neuindexierung außerhalb der Hauptnutzungszeiten
Abfrageoptimierung
WAL-Modus. Der Write-Ahead-Logging-Modus von SQLite ermöglicht gleichzeitiges Lesen, während der Indexer schreibt:
db.execute("PRAGMA journal_mode=WAL")
Dies ist entscheidend, wenn der MCP-Server Abfragen verarbeitet, während der Indexer ein inkrementelles Update durchführt.
Connection Pooling. Der MCP-Server sollte Datenbankverbindungen wiederverwenden, anstatt pro Abfrage eine neue Verbindung zu öffnen. Eine einzelne langlebige Verbindung mit WAL-Modus unterstützt gleichzeitige Lesezugriffe.
# MCP server initialization
db = sqlite3.connect(DB_PATH, check_same_thread=False)
db.execute("PRAGMA journal_mode=WAL")
db.execute("PRAGMA mmap_size=268435456") # 256 MB mmap
Memory-Mapped I/O. Das mmap_size-Pragma weist SQLite an, Memory-Mapped I/O für die Datenbankdatei zu verwenden. Bei einer 83 MB großen Datenbank eliminiert das Mapping der gesamten Datei in den Speicher die meisten Lesezugriffe auf die Festplatte.
FTS5-Optimierung. Führen Sie nach einer vollständigen Neuindexierung folgenden Befehl aus:
INSERT INTO chunks_fts(chunks_fts) VALUES('optimize');
Dies führt die internen B-Tree-Segmente von FTS5 zusammen und reduziert die Abfragelatenz für nachfolgende Suchen.
Skalierungs-Benchmarks
Gemessen auf einem Apple M3 Pro, 36 GB RAM, NVMe SSD:
| Operation | 500 Notizen | 5.000 Notizen | 15.000 Notizen | 50.000 Notizen |
|---|---|---|---|---|
| BM25-Abfrage | 2 ms | 5 ms | 12 ms | 25 ms |
| Vektor-Abfrage | 1 ms | 3 ms | 8 ms | 20 ms |
| RRF-Fusion | <1 ms | <1 ms | 3 ms | 5 ms |
| Vollständige Suche | 3 ms | 8 ms | 23 ms | 50 ms |
Alle Benchmarks beinhalten Datenbankzugriff, Abfrageausführung und Ergebnisformatierung. Die Netzwerklatenz für die MCP-STDIO-Kommunikation addiert 1–2 ms.
Fehlerbehebung
Index-Drift
Symptom: Die Suche liefert veraltete Ergebnisse oder übersieht kürzlich hinzugefügte Notizen.
Ursache: Der inkrementelle Indexer wurde nach dem Hinzufügen von Notizen nicht ausgeführt, oder die mtime einer Datei wurde nicht aktualisiert (z. B. bei Synchronisierung von einem anderen Gerät mit beibehaltenen Zeitstempeln).
Lösung: Führen Sie eine vollständige Neuindexierung durch: python index_vault.py --full
Wechsel des Embedding-Modells
Symptom: Nach dem Wechsel des Embedding-Modells liefert die Vektorsuche unsinnige Ergebnisse.
Ursache: Alte Vektoren (vom vorherigen Modell) werden mit neuen Abfragevektoren verglichen. Die Dimensionen oder die Semantik des Vektorraums sind inkompatibel.
Lösung: Der Indexer sollte die Abweichung des Modell-Hashs erkennen und automatisch eine vollständige Neuindexierung auslösen. Falls dies nicht geschieht, löschen Sie die Datenbank manuell und indexieren Sie neu:
rm vectors.db
python index_vault.py --full
FTS5-Wartung
Symptom: FTS5-Abfragen liefern nach vielen inkrementellen Aktualisierungen fehlerhafte oder unvollständige Ergebnisse.
Ursache: Interne FTS5-Segmente können nach vielen kleinen Aktualisierungen fragmentiert werden.
Lösung: Neuaufbau und Optimierung durchführen:
INSERT INTO chunks_fts(chunks_fts) VALUES('rebuild');
INSERT INTO chunks_fts(chunks_fts) VALUES('optimize');
MCP-Timeout
Symptom: Das KI-Tool meldet, dass der MCP-Server eine Zeitüberschreitung hatte.
Ursache: Die erste Abfrage löst das Laden des Modells aus (Lazy Initialization), was 2–5 Sekunden dauert. Das Standard-MCP-Timeout des KI-Tools ist möglicherweise kürzer eingestellt.
Lösung: Wärmen Sie das Modell beim Serverstart vor:
# In MCP server initialization
retriever = HybridRetriever(db_path, vault_path)
retriever.search("warmup", limit=1) # Trigger model load
SQLite-Dateisperren
Symptom: SQLITE_BUSY- oder SQLITE_LOCKED-Fehler.
Ursache: Mehrere Prozesse schreiben gleichzeitig in die Datenbank. Der WAL-Modus erlaubt zwar parallele Lesezugriffe, jedoch nur einen einzelnen Schreibprozess.
Lösung: Stellen Sie sicher, dass nur ein Prozess (der Indexer) in die Datenbank schreibt. Der MCP-Server und Hooks sollten ausschließlich lesen. Falls Sie parallele Schreibzugriffe benötigen, verwenden Sie den WAL-Modus und setzen Sie ein Busy-Timeout:
db.execute("PRAGMA busy_timeout=5000") # Wait up to 5 seconds
sqlite-vec lässt sich nicht laden
Symptom: Die Vektorsuche ist deaktiviert; der Retriever läuft im reinen BM25-Modus.
Ursache: Die sqlite-vec-Erweiterung ist nicht installiert, wird im Bibliothekspfad nicht gefunden oder ist mit der SQLite-Version inkompatibel.
Lösung:
# Install via pip
pip install sqlite-vec
# Or compile from source
git clone https://github.com/asg017/sqlite-vec
cd sqlite-vec && make
Überprüfen Sie, ob die Erweiterung geladen wird:
import sqlite3
db = sqlite3.connect(":memory:")
db.enable_load_extension(True)
db.load_extension("vec0")
print("sqlite-vec loaded successfully")
Speicherprobleme bei großen Vaults
Symptom: Out-of-Memory-Fehler während der vollständigen Neuindexierung eines großen Vaults (50.000+ Notizen).
Ursache: Die Embedding-Batchgröße ist zu groß, oder alle Dateiinhalte werden gleichzeitig in den Arbeitsspeicher geladen.
Lösung: Reduzieren Sie die Batchgröße und verarbeiten Sie Dateien inkrementell:
BATCH_SIZE = 32 # Reduce from 64
Stellen Sie außerdem sicher, dass der Indexer Dateien einzeln verarbeitet (Lesen, Chunking und Embedding jeder Datei vor dem Übergang zur nächsten), anstatt alle Dateien gleichzeitig in den Arbeitsspeicher zu laden.
Migrationsleitfaden
Von Apple Notes
- Exportieren Sie Apple Notes über die Option „Alle exportieren” (macOS) oder verwenden Sie ein Migrationstool wie
apple-notes-liberator - Konvertieren Sie HTML-Exporte mit
markdownifyoderpandocin Markdown - Verschieben Sie die konvertierten Dateien in den
00-inbox/-Ordner Ihres Vaults - Überprüfen Sie jede Notiz und fügen Sie frontmatter hinzu
- Verschieben Sie die Notizen in die entsprechenden Domänenordner
Von Notion
- Exportieren Sie aus Notion: Einstellungen → Exportieren → Markdown & CSV
- Entpacken Sie den Export in den
00-inbox/-Ordner Ihres Vaults - Beheben Sie Notion-spezifische Markdown-Artefakte:
- Notion verwendet
- [ ]für Checklisten — dies ist Standard-Markdown - Notion fügt Eigenschaftstabellen als HTML ein — konvertieren Sie diese in YAML-frontmatter
- Notion bettet Bilder als relative Pfade ein — kopieren Sie die Bilder in Ihren Anhänge-Ordner
- Fügen Sie Standard-frontmatter hinzu (
type,domain,tags) - Ersetzen Sie Notion-Seitenlinks durch Obsidian-wiki-links
Von Google Docs
- Verwenden Sie Google Takeout, um alle Dokumente zu exportieren
- Konvertieren Sie
.docx-Dateien in Markdown:pandoc -f docx -t markdown input.docx -o output.md - Stapelkonvertierung:
for f in *.docx; do pandoc -f docx -t markdown "$f" -o "${f%.docx}.md"; done - Verschieben Sie die Dateien in den Vault, fügen Sie frontmatter hinzu und organisieren Sie sie in Ordnern
Von reinem Markdown (ohne Obsidian)
Falls Sie bereits ein Verzeichnis mit Markdown-Dateien haben:
- Öffnen Sie das Verzeichnis als Obsidian-Vault (Obsidian → Vault öffnen → Ordner öffnen)
- Fügen Sie
.obsidian/zur.gitignorehinzu, falls das Verzeichnis versionskontrolliert ist - Erstellen Sie frontmatter-Vorlagen und wenden Sie diese auf bestehende Dateien an
- Beginnen Sie, Notizen beim Lesen und Organisieren mit
[[wiki-links]]zu verknüpfen - Führen Sie den Indexer sofort aus — das Retrieval-System funktioniert ab dem ersten Tag
Von einem anderen Retrieval-System
Falls Sie von einem anderen Embedding-/Suchsystem migrieren:
- Versuchen Sie nicht, Vektoren zu migrieren. Unterschiedliche Modelle erzeugen inkompatible Vektorräume. Führen Sie eine vollständige Neuindexierung mit dem neuen Modell durch.
- Migrieren Sie den Inhalt, nicht den Index. Die Vault-Dateien sind die Quelle der Wahrheit. Der Index ist ein abgeleitetes Artefakt.
- Überprüfen Sie nach der Migration. Führen Sie 10–20 Abfragen durch, deren Antworten Sie kennen, und verifizieren Sie, dass die Ergebnisse Ihren Erwartungen entsprechen.
Änderungsprotokoll
| Datum | Änderung |
|---|---|
| 01.04.2026 | Obsidian-CLI-Abschnitt hinzugefügt (v1.12-Befehle für KI-Workflows). Agent-Plugin-Abschnitt ergänzt (Claudian, Agent Client). Bases-Core-Plugin für Vault-Organisation dokumentiert. Plugin-Anzahl auf 2.500+ aktualisiert. iOS Share Extension als Eingangsquelle hinzugefügt. Kompatibilitätsmatrix mit eingebetteten Agent-Plugins aktualisiert. |
| 30.03.2026 | MCPVault v0.11.0: list_all_tags-Tool, .base/.canvas-Unterstützung, umbenannt in @bitbonsai/mcpvault. Obsidian Desktop v1.12.7 bündelt CLI-Binary für schnellere Terminal-Interaktionen. |
| 23.03.2026 | sqlite-vec v0.1.7 stable dokumentiert: DELETE-Unterstützung für vec0-Tabellen, KNN-Distanzbeschränkungen für Paginierung. DiskANN Approximate-Nearest-Neighbor-Index für kommende Version angekündigt. |
| 07.03.2026 | potion-multilingual-128M (101 Sprachen, Mai 2025) zum Embedding-Modellvergleich hinzugefügt. sqlite-vec bei v0.1.7-alpha.10 (CI/CD-Fixes, keine Funktionsänderungen). MCP-Spezifikation und Retrieval-Techniken als aktuell bestätigt. |
| 03.03.2026 | MCP-Spezifikationsentwicklung aktualisiert (Nov 2025 ausgeliefert: Streamable HTTP, .well-known, Tool-Annotationen). Model2Vec-Fine-Tuning und BPE/Unigram-Tokenizer-Unterstützung hinzugefügt. Community-MCP-Serververgleichstabelle ergänzt. Smart Connections auf v4 aktualisiert. |
| 02.03.2026 | potion-base-32M und potion-retrieval-32M zum Modellvergleich hinzugefügt. Abschnitt zu Quantisierung/Dimensionalitätsreduktion ergänzt. Hinweis zur MCP-Spezifikationsentwicklung hinzugefügt. |
| 01.03.2026 | Erstveröffentlichung |
Referenzen
-
Internet Vin, „22 commands I use with Obsidian and Claude Code,” März 2026, x.com/internetvin/status/2026461256677245131. ↩
-
Nicopreme, „Visual Explainer” Agent-Skill mit Slash-Befehlen, x.com/nicopreme/status/2023495040258261460. ↩
-
Cormack, G.V., Clarke, C.L.A., and Buettcher, S. Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods. SIGIR, 2009. Stellt RRF mit k=60 als parameterfreie Methode zur Kombination von Ranglisten vor. ↩↩↩
-
OpenAI Embeddings Pricing. text-embedding-3-small: 0,02 $ pro Million Tokens. Geschätzte Vault-Kosten pro vollständiger Neuindizierung: ca. 0,30 $. ↩
-
van Dongen, T. et al. Model2Vec: Turn any Sentence Transformer into a Small Fast Model. arXiv, 2025. Beschreibt den Destillationsansatz zur Erzeugung statischer Embeddings aus Sentence Transformers. ↩
-
MTEB: Massive Text Embedding Benchmark. potion-base-8M erreicht einen Durchschnitt von 50,03 gegenüber 56,09 für all-MiniLM-L6-v2 (89 % Retention). ↩
-
SQLite FTS5 Extension. FTS5 bietet Volltextsuche mit BM25-Ranking und konfigurierbaren Spaltengewichtungen. ↩
-
sqlite-vec: A vector search SQLite extension. Stellt
vec0-virtuelle Tabellen für KNN-Vektorsuche innerhalb von SQLite bereit. ↩ -
Robertson, S. and Zaragoza, H. The Probabilistic Relevance Framework: BM25 and Beyond. Foundations and Trends in Information Retrieval, 2009. ↩
-
Karpukhin, V. et al. Dense Passage Retrieval for Open-Domain Question Answering. EMNLP, 2020. Dichte Repräsentationen übertreffen BM25 um 9–19 % bei Open-Domain-QA. ↩
-
Reimers, N. and Gurevych, I. Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks. EMNLP, 2019. Grundlegende Arbeit zu dichter semantischer Ähnlichkeit. ↩
-
Luan, Y. et al. Sparse, Dense, and Attentional Representations for Text Retrieval. TACL, 2021. Hybrid Retrieval übertrifft konsistent Einzelmodalitäts-Ansätze auf MS MARCO. ↩
-
SQLite Write-Ahead Logging. WAL-Modus für gleichzeitige Lesezugriffe bei einem einzelnen Schreiber. ↩
-
Gao, Y. et al. Retrieval-Augmented Generation for Large Language Models: A Survey. arXiv, 2024. Überblick über RAG-Architekturen und Chunking-Strategien. ↩
-
Thakur, N. et al. BEIR: A Heterogeneous Benchmark for Zero-shot Evaluation of Information Retrieval Models. NeurIPS, 2021. ↩
-
Model2Vec: Distill a Small Fast Model from any Sentence Transformer. Minish Lab, 2024. ↩
-
Obsidian Documentation. Offizielle Dokumentation für Obsidian. ↩
-
Model Context Protocol Specification. Der MCP-Standard zur Verbindung von KI-Tools mit Datenquellen. ↩
-
Produktionsdaten des Autors. 16.894 Dateien, 49.746 Chunks, 83,56 MB SQLite-Datenbank, 7.771 verarbeitete Signale über 14 Monate. Abfragelatenz gemessen mittels
time.perf_counter(). ↩ -
Model2Vec Potion Models. Minish Lab, 2025. Potion-base-32M (MTEB 52,46), potion-retrieval-32M (MTEB Retrieval 36,35) sowie Quantisierungs- und Dimensionsreduktionsfunktionen ab v0.5.0. ↩↩↩
-
Update on the Next MCP Protocol Release. Das November-2025-Release lieferte Streamable-HTTP-Transport, .well-known-URL-Erkennung, strukturierte Tool-Annotationen und SDK-Tier-Standardisierung. Das nächste Release ist vorläufig für Mitte 2026 geplant – mit asynchronen Operationen, domänenspezifischen Erweiterungen und Agent-zu-Agent-Kommunikation. ↩↩
-
Model2Vec Releases. v0.4.0 (Feb. 2025): Trainings- und Feinabstimmungs-Unterstützung. v0.5.0 (Apr. 2025): Backend-Rewrite, Quantisierung, Dimensionsreduktion. v0.7.0 (Okt. 2025): Vokabular-Quantisierung, BPE/Unigram-Tokenizer-Unterstützung. ↩↩
-
Smart Connections for Obsidian. Smart Connections v4: Local-first-KI-Embeddings, semantische Suche funktioniert nach der ersten Indizierung offline. ↩
-
potion-multilingual-128M. Minish Lab, Mai 2025. Statisches Embedding-Modell für 101 Sprachen, leistungsstärkstes mehrsprachiges statisches Embedding-Modell. Gleiche reine numpy-Abhängigkeit wie andere Potion-Modelle. ↩
-
MCPVault v0.11.0. März 2026. Neues
list_all_tags-Tool zum Scannen von Frontmatter und Hashtags mit Zählwerten. Verbesserte Handhabung von Ordnern mit Punkt-Präfix, Unterstützung für.base- und.canvas-Dateien. Paket auf npm in@bitbonsai/mcpvaultumbenannt. ↩ -
sqlite-vec v0.1.7 Release. 17. März 2026. Stabiles Release: DELETE-Unterstützung für vec0-virtuelle Tabellen, KNN-Distanzbeschränkungen für Paginierung, Verbesserungen beim Fuzz-Testing. DiskANN-Approximate-Nearest-Neighbor-Indizierung für ein zukünftiges Release angekündigt. ↩↩↩
-
Introduction to Bases. In Obsidian v1.9.10 eingeführtes Core-Plugin. Datenbankähnliche Ansichten (Tabellen, Galerien, Kalender, Kanban-Boards) über Vault-Dateien unter Nutzung von Frontmatter-Properties als Felder. Dateien werden im
.base-Format gespeichert. ↩ -
Obsidian 1.12 Desktop Changelog. 27. Februar 2026. Einführung der Obsidian CLI für terminalbasierte Vault-Automatisierung. Befehle umfassen Suche, tägliche Notizen, Vorlagen, Properties, Plugins, Aufgaben und Entwicklerwerkzeuge. CLI-Dokumentation. ↩
-
Claudian. Obsidian-Plugin, das Claude Code als KI-Mitarbeiter in den Vault einbettet. Bietet Seitenleisten-Chat, kontextbezogene Prompts, Bildunterstützung, Slash-Befehle und Berechtigungsmodi. ↩
-
Agent Client. Obsidian-Plugin mit einer einheitlichen Oberfläche für Claude Code, Codex CLI und Gemini CLI über das Agent Client Protocol (ACP). Unterstützt Notiz-Erwähnungen, Shell-Ausführung und Aktionsbestätigung. ↩
-
Obsidian iOS Changelog. Updates Anfang 2026 umfassen die Share Extension zum Speichern von Inhalten aus anderen Apps direkt in den Vault, Korrekturen für das Tägliche-Notiz- und Lesezeichen-Widget sowie Verbesserungen bei der Aktualisierung des Notiz-Ansicht-Widgets. ↩