quarto/Writing/Obsidian-RAG.qmd
Nicole Dresselhaus ce0c52a66a initial
2025-05-09 21:47:18 +02:00

749 lines
47 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
tags:
- Writing
aliases:
- "RAG für eine Obsidian-Wissensdatenbank: Technische Ansätze"
cssclasses:
- table-wide
- table-wrap
authors:
- name: GPT-4.5
url: https://chatgpt.com
affiliation:
- name: OpenAI
url: https://openai.com
- name: cogito-v1-preview
url: https://www.deepcogito.com/research/cogito-v1-preview
affiliation:
- name: DeepCogito
url: https://www.deepcogito.com
- name: Claude 3.7 Sonnet
url: https://claude.ai
affiliation:
- name: Antrhopic
url: https://www.anthropic.com
- name: Nicole Dresselhaus
affiliation:
- name: Humboldt-Universität zu Berlin
url: https://hu-berlin.de
orcid: 0009-0008-8850-3679
date: 2025-04-24
categories:
- Article
- RAG
- ML
fileClass: authored
lang: de
linter-yaml-title-alias:
"RAG für eine Obsidian-Wissensdatenbank: Technische Ansätze"
title: "RAG für eine Obsidian-Wissensdatenbank: Technische Ansätze"
bibliography:
- obsidian-rag.bib
citation-style: springer-humanities-brackets
image: ../thumbs/writing_obsidian-rag.png
---
## Hintergrund und Zielsetzung
Der Nutzer verfügt über eine Obsidian-Wissensdatenbank, in der Markdown-Dateien
mit **typisierten** Inhalten (FileClasses wie `Person`, `Projekt`, `Deliverable`
etc.) verwaltet werden. Die Notizen enthalten strukturierte **YAML-Metadaten**
(unterstützt durch Plugins wie _Metadata Menu_) und sind durch viele
**Wiki-Links** miteinander vernetzt. Standardisierte Templates (via _Templater_)
sorgen dafür, dass z.B. Personenseiten immer ähnliche Felder (Name, ORCID, etc.)
aufweisen.
**Ziel** ist es, mithilfe eines Language Models (LLM) wiederkehrende Aufgaben zu
erleichtern, zum Beispiel: automatisch YAML-Felder ausfüllen (etwa fehlende
ORCID iDs bei Personen ergänzen), neue Entitätsseiten anhand von Templates
befüllen oder sinnvolle Verlinkungen zwischen Notizen vorschlagen. Dabei reicht
ein tägliches Neu-Einlesen der Obsidian-Daten (via Cronjob o.Ä.) aus eine
Echtzeit-Synchronisation ist optional. Die Obsidian-internen Wikilinks
(`[[...]]`) müssen im LLM-Ausgabeformat nicht unbedingt klickbar sein (es
genügt, wenn sie referenziert werden).
Um diese Funktionen umzusetzen, bieten sich verschiedene **technische Ansätze**
an. Im Folgenden werden fünf Optionen untersucht: (1) Nutzung eines
**Vektorspeichers** für semantische Suche, (2) Aufbau eines **Knowledge Graph**
aus den Notizen, (3) eine **Hybrid-Lösung** aus Graph und Vektor, (4) Extraktion
& Normalisierung der **YAML-Metadaten** und (5) existierende **Tools/Workflows**
zur Automatisierung. Jede Option wird mit Funktionsweise, Vorund Nachteilen,
Aufwand, Integrationsmöglichkeiten (insb. mit lokalen LLMs wie LLaMA, Deepseek,
Cogito etc.) sowie konkreten Tool-Empfehlungen dargestellt.
## 1. Vektorbasierter Ansatz: Semantic Search mit Embeddings
### Prinzip
Alle Markdown-Notizen (bzw. deren Inhalt) werden in kleinere Chunks zerlegt und
durch einen Embedding-Modell in hochdimensionale Vektoren umgewandelt. Diese
Vektoren werden in einem **Vektorstore** (wie ChromaDB oder Weaviate)
gespeichert. Bei Anfragen des LLM (z.B. _"Welche Projekte hat Person X?"_ oder
_"Erstelle eine neue Organisation XYZ basierend auf ähnlichen Einträgen"_),
können mittels **ähnlichkeitssuche** semantisch passende Notiz-Abschnitte
abgerufen und dem LLM als Kontext mitgegeben werden (Retrieval-Augmented
Generation).
### Implementierung
In der Praxis ließe sich z.B. ein Workflow mit **Ollama** + **Nomic
Embeddings** + **Chroma**^[Alle diese Teile laufen bereits individuell in der
Arbeitsgruppe bzw. werden schon genutzt.] aufbauen. Ollama stellt ein lokales
LLM-Serving bereit und bietet auch eine API für Embeddins
[@ollama_chroma_cookbook]. Man könnte ein spezialisiertes Embeddin-Modell wie
`nomic-embed-text` verwenden, welches kompakte 1024-dimensionale Textvektoren
liefert [@ollama_chroma_cookbook]. Die Notizen des Obsidian Vault würden per
Skript täglich eingelesen, in Sinnabschnitte (Chunks) aufgeteilt (z.B. nach
Überschriften oder einer festen Token-Länge) und über Ollamas Embedding-API in
Vektoren umgewandelt [@ollama_chroma_cookbook]. Diese Vektoren speichert man in
einer lokalen DB wie Chroma. Anfragen an das LLM werden dann zunächst an den
Vektorstore gestellt, um die relevantesten Notiz-Abschnitte zu finden, welche
dann zusammen mit der eigentlichen Frage an das LLM gegeben werden (klassischer
RAG-Pipeline). Dieses Verfahren ist vergleichbar mit dem _Smart Connections_
Obsidian-Plugin: Dort wird ebenfalls ein "Text Embedding Model" auf den Vault
angewendet, um zu einer Nutzerfrage automatisch thematisch passende Notizen zu
finden und dem LLM bereitzustellen [@smart_connections_plugin]. So konnte im
Beispiel ein lokales LLaMA-basiertes Modell Fragen zum eigenen Vault korrekt
beantworten, indem es zuvor den passenden Ausschnitt (hier: eine
Styleguide-Notiz) über Embeddings gefunden hatte [@smart_connections_plugin].
### Integration mit lokalen LLMs
Ein Vorteil dieses Ansatzes ist, dass er schon heute mit lokalen
Open-Source-LLMs funktioniert. Beispielsweise ließ sich in _Smart Connections_
ein lokal gehostetes LLaMA-Model (3B Instruct) via text-generation-webui
einbinden [@smart_connections_plugin]. Alternativ kann man auch
_LLM-as-a-service_ Tools wie **Ollama** nutzen, um ein Modell wie Llama 2
bereitzustellen. Die Open-Source-Tools **LangChain** oder **LlamaIndex** bieten
Module, um Vektorstores anzubinden und mit LLM-Abfragen zu kombinieren dies
kann man auch mit lokal eingebundenen Modellen (z.B. über LlamaCpp oder GPT4All)
verwenden. Zahlreiche fertige Projekte demonstrieren dieses Vorgehen: z.B.
_privateGPT_ kombiniert LangChain, GPT4All (lokales LLM) und Chroma, um komplett
offline Fragen über lokale Dateien zu beantworten
[@second_brain_assistant_with_obsidian]. Auch **Khoj** verfolgt einen ähnlichen
Pfad: Es indexiert den Vault und erlaubt semantische **Natürliche Sprache
Suche** über Markdown-Inhalte sowie _"ähnliche Notizen finden"_ [@khoj_plugin].
### Leistung
Dank moderner Embedding-Modelle können semantisch ähnliche Inhalte gefunden
werden, selbst wenn die Schlagwörter nicht exakt übereinstimmen. Das löst das in
Obsidian bekannte Problem, dass die eingebaute Suche nur exakte Worttreffer
findet [@supercharging_obsidian_search]. Der Ansatz skaliert auch auf größere
Wissensbasen; Vektordatenbanken wie Weaviate oder Chroma sind für zehntausende
Einträge ausgelegt. Eine tägliche Aktualisierung ist machbar, da nur
neue/geänderte Notizen re-embedded werden müssen.
### Nachteile und Aufwand
Die Einrichtung erfordert mehrere Komponenten. Man benötigt Pipeline-Schritte
für das Chunking, Embedding und das Handling des Vektorstores dies bedeutet
anfängliche Komplexität und Rechenaufwand [@supercharging_obsidian_search].
Insbesondere das Generieren der Embeddings kann bei großen Vaults zeitund
speicherintensiv sein (je nach Modell und Hardware)
[@supercharging_obsidian_search]. Laufende Kosten sind bei rein lokaler
Verarbeitung allerdings kein Thema außer CPU/GPU-Last. Ein potenzieller Nachteil
ist, dass rein embeddings-basierte Suche keine **strukturierte** Abfrage erlaubt
das Modell findet zwar thematisch passende Textpassagen, aber um z.B. **eine
bestimmte Eigenschaft** (wie eine fehlende ORCID) gezielt abzufragen, müsste man
dennoch im Text suchen oder zusätzliche Logik anwenden. Das LLM kann aus den
gefundenen Texten zwar implizit Fakten entnehmen, hat aber kein explizites
Wissen über die Datenstruktur. Zudem können irrelevante Kontextstücke
eingebunden werden, wenn das semantische Matching fehlerhaft ist (dies erfordert
ggf. Feintuning der Chunk-Größe oder Filtern per Dateityp/-klasse)^[Und diese
Nachteile machen dies zu einem Deal-Breaker. Gerade in Tabellen oder
Auflistungen kann der Attention-Mechanismus der LLM schnell zu einem Mischen
oder Verwechseln von präsentierten Informationen führen. Besonders kleine Netze
(meist bis ~7b) sind hier anfällig.].
### Zusammenfassung Ansatz 1: Vektordatenbank (Embeddings)
| | **Details** |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Vorgehen** | Inhalte aller Markdown-Dateien in semantische Vektoren kodieren (z.B. mit `nomic-embed-text` ([@ollama_chroma_cookbook])) und in einer Vektor-DB speichern. LLM-Anfragen per Similarity Search mit relevantem Kontext anreichern. |
| **Stärken** | _Semantische Suche_ (findet thematisch passende Infos, nicht nur exakte Worttreffer) [@supercharging_obsidian_search]. Skaliert auf große Textmengen. Bereits heute mit lokalen LLMs erprobt (z.B. _Smart Connections_ Plugin) [@smart_connections_plugin]. Gut geeignet für Q&A, Textzusammenfassungen und Link-Vorschläge basierend auf Ähnlichkeit. |
| **Schwächen** | Komplexeres Setup (Embedding-Model + DB + Pipeline) [@supercharging_obsidian_search]. Hoher Rechenaufwand für Embeddings bei großen Vaults. Kein explizites Modell von Beziehungen/Metadaten strukturierte Abfragen (z.B. _"zeige alle Personen ohne ORCID"_) nur mit Zusatzlogik. Kontexttreffer können ungenau sein (erfordert ggf. Feinjustierung). |
| **Integrations-Optionen** | Lokale LLM-Einbindung möglich (z.B. LLaMA 2 über Ollama-API). Tools: **ChromaDB**, **Weaviate** oder **FAISS** als Vektorstore; **LangChain/LlamaIndex** für Pipeline-Management. Obsidian-Plugins: _Smart Connections_ (komplett integriert mit lokalem Embedder+LLM) [@smart_connections_plugin]; _Khoj_ (separater Suchassistent mit Embeddings) [@khoj_plugin]. |
```{mermaid}
%%| column: screen-inset-right
graph LR
A[Obsidian Vault] --> B[Chunking]
B --> C[Embedding Model]
C --> D[(Vector Database)]
E[User Query] --> F[Query Embedding]
F --> G[Similarity Search]
D --> G
G --> H[Relevant Chunks]
H --> I[LLM]
E --> I
I --> J[Response]
```
## 2. Knowledge-Graph-Ansatz: Strukturierte Graphdatenbank
### Prinzip
Statt (oder zusätzlich zu) freiem Text wird der Informationsgehalt des Vaults
als **Graph** modelliert. Jede Notiz entspricht einem **Knoten** im Graphen (mit
Typ-Label gemäß FileClass, z.B. `Person`, `Projekt` etc.). Relationen zwischen
Notizen implizit durch Obsidian-Wikilinks gegeben werden zu expliziten
**Kanten** im Graph (z.B. eine Person "arbeitet in" Organisation, ein Projekt
"liefert" ein Deliverable). Auch Metadaten aus YAML können als Knoten oder
Properties modelliert werden (z.B. ORCID als Attribut eines Person-Knotens, Tags
als Relationen _"hat Schlagwort"_ usw.). Das Ergebnis ist ein **Wissensgraph**,
der ähnlich einem klassischen RDF-Triple-Store oder Neo4j-Property-Graph
komplexe Abfragen und Analysen ermöglicht.
### Erstellung des Graphen
Eine Möglichkeit ist die Obsidian-Daten nach RDF zu exportieren. So beschreibt
Pavlyshyn (2023) ein Verfahren, einen Vault ins RDF-Format zu überführen, um
"komplexe Abfragen mit klassischen Semantic-Tools" zu ermöglichen
[@export_obsidian_to_rdf]. Alternativ kann man direkt in einer Graphdatenbank
wie **Neo4j** modellieren. Ein Community-Plugin (_obsidian-neo4j-stream_) hat
beispielsweise versucht, den Obsidian-Linkgraph in Neo4j importierbar zu machen
[@export_to_common_graph_formats]. Konkret würde man pro Markdown-Datei einen
Node mit dessen YAML-Feldern als Properties anlegen. Bestehende Wiki-Links
zwischen Dateien werden als ungerichtete oder gerichtete Edges abgebildet (hier
kann man, sofern man mehr Semantik will, Link-Typen einführen z.B. im Text
`[[Albert Einstein|Autor]]` könnte der Alias "Autor" als Kanten-Label genutzt
werden). Da Obsidian standardmäßig keine typisierten Kanten unterstützt, bleiben
Relationstypen begrenzt Plugins wie _Juggl_ oder _Graph-Link-Types_ erlauben
allerdings das Hinzufügen von Link-Metadaten, was für eine genauere
Graph-Modellierung hilfreich sein könnte
[@personal_knowledge_graphs_in_obsidian]. YAML-Inhalte, die auf andere Notizen
referenzieren, können ebenfalls als Kanten kodiert werden (Beispiel: In einer
Projekt-Notiz listet das YAML-Feld `team:` mehrere Personen diese Verweise
werden im Graph als Kanten _Projekt —hatTeam→ Person_ umgesetzt). Nicht
referenzielle Metadaten (etwa ein ORCID-Wert) bleiben einfach als Datenfeld am
Knoten.
### Nutzung für LLM-Aufgaben
Ein solcher Graph erlaubt **strukturierte Abfragen** und **Schlussfolgerungen**.
Für wiederkehrende Aufgaben kann man den Graph gezielt auswerten. Beispielsweise
ließen sich _"alle Personen ohne ORCID"_ mittels einer einfachen Graph-Query
ermitteln. Das LLM könnte diese Liste als Input erhalten und dann (ggf. mittels
Tools oder Wissensbasis) die fehlenden IDs ergänzen. Auch _Link-Vorschläge_
können aus dem Graph gezogen werden: Durch Graph-Analysen wie das Finden von
gemeinsamen Nachbarn oder kürzesten Pfaden entdeckt man Verbindungen, die im
Vault noch nicht als direkte Links existieren. So könnte man z.B. feststellen,
dass zwei Personen an vielen gleichen Meetings teilgenommen
haben und dem Nutzer vorschlagen, diese Personen direkt miteinander zu
verknüpfen. Oder man erkennt durch _link prediction_ Algorithmen neue mögliche
Beziehungen. Forschung und Community sehen hier großes Potential: Eine
AI-gestützte Graphanalyse kann helfen, verborgene Zusammenhänge im eigenen
Zettelkasten zu finden [@ai_empowered_zettelkasten_with_ner_and_graph_llm]. Mit
Graph-basiertem Reasoning ließe sich sogar **neues Wissen entdecken** oder
logisch konsistente Antworten generieren
[@ai_empowered_zettelkasten_with_ner_and_graph_llm,
@personal_knowledge_graphs_in_obsidian] etwas, das rein embeddings-basierte
Ansätze so nicht leisten.
### Integration mit LLMs
Die Integration eines Graphen erfordert meist eine **Zwischenschicht**. Ein LLM
kann nicht direkt "in" einer Neo4j-Datenbank suchen, aber man kann ihm eine
Schnittstelle anbieten. Zwei Strategien sind denkbar:
1. **Verbalize & Prompt:** Informationen aus dem Graph gezielt ins Prompt
einbetten. Z.B. könnte man bei einer Frage wie "In welcher Organisation
arbeitet Alice?" erst eine Graphdatenbank-Anfrage (z.B. in Cypher oder
SPARQL) ausführen und das Ergebnis (etwa: "Alice arbeitetBei → AcmeCorp")
in Textform dem Modell vorgeben, bevor es antwortet. Solche Abfragen könnte
ein LLM theoretisch sogar selbst generieren (LangChain bietet z.B. Agents,
die Cypher-Queries formulieren und ausführen können). Für definierte
Use-Cases kann man aber auch feste Query-Vorlagen
verwenden.
1. **LLM-in-the-Loop Graph Reasoning:** Neuere Libraries wie LlamaIndex
ermöglichen es, LLMs als Reasoner über Graphen einzusetzen. Der Graph wird
dabei intern z.B. als Tripel-Liste gehalten, und das LLM kann mittels
promptbasierter Logik Kettenschlüsse durchführen. Allerdings muss der Graph
dafür in das Prompt passen (bei sehr vielen Knoten unrealistisch) es ist
also eher für Teilgraphen oder summarische Beziehungen geeignet^[Via 'Tool
Use' in Modernen LLM könnte das LLM selbst eine Suche auslösen und so den
Teilgraphen wählen. Aber alleine die formulierung der Suche führt dann direkt
zu dem hybriden Ansatz unten.].
Eine andere interessante Möglichkeit ist die Nutzung **graphbasierter
KI-Modelle** (Graph Neural Networks o.ä.), die aber in unserem Kontext
(persönlicher Vault) noch experimentell sind. Erwähnenswert ist z.B. MyKin.ai,
ein Projekt, das einen privaten KI-Assistenten baut, der gemeinsam mit dem
Nutzer einen persönlichen Wissensgraphen aufbaut und nutzt
[@personal_knowledge_graphs_in_obsidian]. Hier übernimmt die KI das "heavy
lifting" der Graph-Pflege, während der Nutzer chattet ein hybrider Ansatz aus
Conversation und Graphaufbau. Für unseren Anwendungsfall wäre jedoch eher ein
statischer Graph sinnvoll, den wir periodisch aktualisieren.
### Zusammenfassung - Ansatz 2: Graphdatenbank
| | **Details** |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Vorgehen** | Konvertiere Vault-Inhalte in einen strukturierten Graphen (Knoten = Notizen/Entitäten; Kanten = Obsidian-Links oder abgeleitete Relationen). Nutzen von Graph-DB (Neo4j, RDF-Store) für Abfragen und Analysen. |
| **Stärken** | Explizite **Struktur**: ermöglicht genaue Abfragen, z.B. Finde fehlende Werte oder alle Verknüpfungen eines Knotens auf einen Blick. **Logische Inferenzen** möglich (Graph Reasoning) unterstützt Link-Empfehlungen und Konsistenzprüfungen [@ai_empowered_zettelkasten_with_ner_and_graph_llm, @personal_knowledge_graphs_in_obsidian]. Gute Ergänzung zu YAML-Typisierung: FileClass-Struktur wird vollständig nutzbar. Persistenz: Graph kann unabhängig von Obsidian analysiert, versioniert, mit anderen Daten gemappt werden (z.B. ORCID-Abgleich via externen Datensatz). |
| **Schwächen** | Erheblicher **Initialaufwand**: Datenmodell entwerfen, Export-Skripte schreiben oder Tools einrichten [@export_to_common_graph_formats]. Keine fertige Out-of-the-box-Lösung für Obsidian↔Graph (bislang nur Ansätze in der Community). Laufende Synchronisation nötig (Vault-Änderungen -> Graph-Update). Die LLM-Integration ist komplexer erfordert Query-Tool oder das Einbetten von Graph-Daten ins Prompt. Für offene Fragen (Freitext) allein nicht ausreichend, da der Graph primär Fakten repräsentiert, nicht Fließtext. |
| **Integrations-Optionen** | **Neo4j** (mit APOC/Neosemantics für RDF-Unterstützung) eignet sich für Property-Graph-Modell; **Apache Jena** oder GraphDB für RDF-Triple-Store. _LangChain_ bietet Memory/Agent, um Wissensgraphen abzufragen (z.B. ConversationKGMemory). _LlamaIndex_ hat einen KnowledgeGraphIndex, der Tripel extrahieren und durchs LLM traversieren kann. Diese Lösungen sind aber noch experimentell. Evtl. Kombination mit Obsidian-Plugin: Ein früher Plugin-Prototyp streamte Obsidian-Daten nach Neo4j [@export_to_common_graph_formats] dieser könnte als Ausgangspunkt dienen. |
```{mermaid}
%%| column: screen-inset-right
graph LR
A[Obsidian Vault] --> B[Entity Extraction]
A --> C[Relationship Extraction]
B --> D[Graph Construction]
C --> D
D --> E[(Graph Database)]
F[User Query] --> G[Query Parser]
G --> H[Graph Traversal]
E --> H
H --> I[Structured Facts]
I --> J[LLM]
F --> J
J --> K[Response]
```
### Fazit Graphdatenbank
Ein Wissensgraph spielt seine Stärken vor allem bei **strukturbezogenen
Aufgaben** aus. Für das automatische Ausfüllen von YAML-Feldern oder das Prüfen
von Verlinkungen ist er ideal, da solche Fragen direkte Graphabfragen
ermöglichen. Auch für neuartige Verknüpfungen (Link-Vorschläge) lässt sich ein
Graph analytisch nutzen (z.B. "Link Prediction" auf Basis von
Graph-Nachbarschaft). Allerdings ist die Umsetzung deutlich komplexer als beim
Vektorstore, und viele RAG-Anwendungsfälle (Zusammenfassungen, inhaltliche Q&A)
erfordern trotzdem den Rückgriff auf die eigentlichen Texte was wiederum den
Vektoransatz benötigt. Daher bietet sich oft eine Kombination beider Methoden
an.
## 3. Hybrid-Ansatz: Kombination aus Graph und Vektor-RAG
Dieser Ansatz versucht, **semantische Textsuche** und **strukturierte
Graph-Abfragen** zu vereinen, um die Vorteile beider Welten auszuschöpfen. In
der Praxis gibt es mehrere Möglichkeiten, wie ein hybrides System ausgestaltet
sein kann:
- **Parallelbetrieb mit separaten Pipelines:** Vektorstore und Knowledge Graph
werden beide gepflegt. Je nach Anfrage oder Teilaufgabe wird das eine oder
andere genutzt. Beispiel: Für eine Q&A-Frage holt das System erst relevante
Text-Passagen via Vektorstore, **und** prüft zusätzlich im Graph, welche
Entitäten darin vorkommen und ruft deren Beziehungen ab. Das LLM bekäme dann
sowohl inhaltliche Ausschnitte als Kontext als auch strukturierte Fakten (z.B.
_"Alice arbeitetBei AcmeCorp"_) als Knowledge-Panel. Für die Aufgabe
_Link-Vorschläge_ könnte das System sowohl einen Embedding-Vergleich zwischen
Notizen nutzen (um thematisch ähnliche Notes zu finden), als auch den Graphen
auswerten (um strukturell nahe, aber unverbundene Knoten zu entdecken). Die
finalen Vorschläge wären die **Schnittmenge** bzw. **Union** beider Methoden
das erhöht Präzision und Reichweite der Empfehlungen.
- **Integration innerhalb einer Datenplattform:** Moderne Vector-Datenbanken wie
_Weaviate_ erlauben es, semantische Vektorsuche mit symbolischen Filtern zu
kombinieren. Man kann Objekte (hier: Notizen) mit ihren strukturierten Feldern
in Weaviate speichern und neben dem Vektorindex auch die Metadaten abfragen.
Z.B. könnte man eine Query formulieren: _"Gib mir die 5 ähnlichsten Notizen zu
`[Text]`, die vom Typ Projekt sind und nach 2020 erstellt wurden."_ Weaviate
würde erst nach Ähnlichkeit filtern, dann die Metadaten-Bedingungen anwenden.
So eine **hybride Suche** könnte man nutzen, um etwa bei Template-Befüllung
**nur vergleichbare Objekte** zum Prompt hinzuzufügen (z.B. nur andere
Organisationen, keine Meeting-Notizen). Auch ChromaDB arbeitet an
Feature-Filterfunktionen, die so etwas erlauben würden. Alternativ kann man
den Graphen selbst mit Vektor-Embeddings anreichern: Man könnte jedem
Knotentyp einen eigenen Vektor zuordnen, der den gesamten Inhalt der
zugehörigen Notiz(en) repräsentiert. Diese Vektoren ließen sich im Graphen als
Attribut halten und für Ähnlichkeitssuchen zwischen Knoten verwenden
(_knowledge graph embeddings_). Allerdings ist das experimentell man müsste
z.B. bei Kanten-Traversierung dynamisch Nachbarschaftsvektoren kombinieren,
was nicht trivial ist.
- **LLM als Orchestrator:** Hier steuert das LLM, wann welcher Ansatz gezogen
wird. Beispielsweise könnte man ein System bauen, in dem das LLM zunächst
entscheidet: _"Brauche ich strukturiertes Wissen?"_ Wenn ja, könnte es per
Tool-Use einen Graph-Query durchführen (z.B. via Cypher) eine Technik, die
mit LangChain Agents umsetzbar wäre. Danach würde es ggf. einen zweiten
Schritt machen: _"Benötige ich noch Detailinformationen oder Zitate?"_ dann
die Vektor-Datenbank abfragen, relevante Textstücke holen, und schließlich
alles in einer konsolidierten Antwort formulieren. Dieser agentenbasierte
Ansatz ist sehr flexibel, aber auch am anspruchsvollsten in der
Implementierung (er erfordert zuverlässig trainierte/verfeinerte LLM-Prompts,
die wissen, wann und wie die jeweiligen Werkzeuge zu benutzen sind).
### Vor-/Nachteile
Die Hybridlösung verspricht **maximale Abdeckung** der Anwendungsfälle.
Strukturierte Fakten und unstrukturierte Inhalte können gemeinsam dem LLM
präsentiert werden, was sowohl präzise Faktenkenntnis als auch reichhaltigen
Kontext ermöglicht. Gerade für komplexe Aufgaben etwa das automatisierte
Erstellen einer neuen Entitätenseite wären wohl beide Aspekte wichtig: das LLM
müsste sich an vorhandenen ähnlichen Seiten **inhaltlich** orientieren
(Vektorsuche nach ähnlichen Organisations-Beschreibungen) und zugleich
**korrekte Verknüpfungen** setzen (Graph checken, ob z.B. die neue Organisation
bereits Personen im Vault hat, die als Mitarbeiter verknüpft werden sollten).
Ein solches System könnte also dem Nutzer sehr viel Arbeit abnehmen und dabei
konsistente, vernetzte Notizen erzeugen.
Dem steht jedoch ein hoher **Architekturund Wartungsaufwand** gegenüber. Man
muss im Grunde zwei Systeme aufbauen und aktuell halten. Zudem ist die Logik,
wie die Ergebnisse zusammenfließen, nicht trivial. Ohne gutes Design kann es
passieren, dass der Graph-Teil und der Vektor-Teil widersprüchliche oder
redundante Informationen liefern. Auch muss man Performance beachten doppelte
Abfragen kosten mehr Zeit. In vielen Fällen mag auch ein einzelner Ansatz
ausreichen, sodass die Zusatzkomplexität nicht immer gerechtfertigt ist.
### Integrationsmöglichkeiten
Auf technischer Seite ist so ein hybrides System durchaus machbar.
Beispielsweise ließe sich **LlamaIndex** verwenden, um unterschiedliche Indexe
(VectorIndex, KnowledgeGraphIndex) zu kombinieren es gibt Konzepte wie
"Composable Indices", mit denen man hierarchische Abfragen bauen kann. So könnte
man erst den Graph nach relevanten Knoten filtern und dann nur die zugehörigen
Dokumente vektor-suchen (oder umgekehrt). Weaviate als All-in-one-Lösung wurde
bereits erwähnt. In kleineren Umgebungen kann man auch pragmatisch vorgehen: Ein
Python-Skript, das bei bestimmten Fragen zuerst einen Neo4j-Query absetzt und
dessen Ergebnis dem LLM als Teil des Prompts voranstellt, während es parallel
eine Chroma-Query macht, wäre eine einfache implementierbare Variante.
### Zusammenfassung Ansatz 3: Hybrid-Lösung
| | **Details** |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Vorgehen** | Kombination beider Ansätze: Pflege einer Graph-Struktur **und** eines Vektorindex. Nutzung je nach Bedarf entweder separat oder durch orchestrierte Abfragen, um sowohl strukturiertes Wissen als auch relevante Texte bereitzustellen. |
| **Stärken** | Sehr **leistungsfähig** deckt sowohl faktische als auch kontextuelle Fragen ab. Kann die **höchste Antwortqualität** liefern (Konsistenz durch Graph-Fakten, Detail durch Textauszüge). Hilft, sowohl "Known-item" Suchen (explizite Werte) als auch "Open-ended" Suchen (Texte) zu bedienen. Für Link-Vorschläge ideal: Kombination aus semantischer Ähnlichkeit und Graph-Nachbarschaft erhöht Trefferquote sinnvoll. |
| **Schwächen** | **Sehr komplex** in Umsetzung und Wartung. Erfordert doppelte Infrastruktur. Koordination zwischen Graph und Vectorstore nötig potenziell fehleranfällig. Höhere Latenz durch Mehrfach-Abfragen. Nur lohnend, wenn wirklich vielfältige Aufgaben automatisiert werden sollen; für rein textliche Q&A overkill. |
| **Integrations-Optionen** | Weaviate (Vectors + strukturierte Class-Properties in einem System), oder Kombination aus Neo4j + Chroma. LangChain Agents könnten Graphund Vektor-Tools parallel nutzen. **LlamaIndex** bietet experimentell kombinierbare Indizes. Workflows müssen sorgfältig entworfen werden (z.B. zuerst Graph-Query, dann Vector-Query auf Untermenge). |
```{mermaid}
%%| column: screen-inset-right
graph LR
A[Obsidian Vault] --> B[Chunking]
A --> C[Entity Extraction]
B --> D[Embedding Model]
C --> E[Graph Construction]
D --> F[(Vector Database)]
E --> G[(Graph Database)]
H[User Query] --> I[Query Embedding]
H --> J[Graph Query]
I --> K[Vector Search]
J --> L[Graph Traversal]
F --> K
G --> L
K --> M[Text Context]
L --> N[Structured Facts]
M --> O[Combined Context]
N --> O
H --> P[LLM]
O --> P
P --> Q[Enriched Response]
```
### Fazit Hybrid-Lösung
Die Hybrid-Lösung ist die **ambitionierteste**, aber auch zukunftsträchtigste
Option. Sie empfiehlt sich, wenn sowohl inhaltliche Assistenz (Texte
zusammenfassen, beantworten) als auch datenbankartige Operationen (Felder
validieren, Beziehungen auswerten) gefragt sind was hier der Fall ist. Oft
kann man auch schrittweise vorgehen: zunächst mit einem Vektor-RAG starten
(geringerer Aufwand) und dann gezielt Graph-Features ergänzen, sobald z.B.
Link-Empfehlungen oder Konsistenzprüfungen wichtiger werden.
## 4. Datenaufbereitung: YAML-Metadaten extrahieren und normalisieren
Unabhängig vom gewählten Retrieval-Ansatz ist es essenziell, die in YAML front
matter steckenden strukturierten Informationen effektiv zu nutzen. Die
Obsidian-Plugins _Metadata Menu_ und _Templater_ stellen sicher, dass viele
wichtige Daten bereits sauber in den Notizen vorliegen (z.B. hat eine
Personenseite Felder wie `fullname`, `birthdate`, `ORCID` usw.). Ein LLM könnte
zwar theoretisch auch direkt im Markdown nach diesen Mustern suchen, aber es ist
deutlich effizienter, die Daten einmalig zu **extrahieren** und in einer
leichter nutzbaren Form vorzuhalten.
### Extraktion
Ein möglicher Schritt im täglichen Refresh ist ein Skript, das alle Dateien
durchläuft und die YAML-Blöcke parst (z.B. mit einem YAML-Parser in Python oder
JavaScript). Die extrahierten Felder können dann in eine **normale Datenbank**
(SQLite/CSV/JSON) oder direkt als Knoten/Properties in den Knowledge Graph
überführt werden. Damit erhält man z.B. eine Tabelle aller Personen mit ihren
ORCID-IDs, eine Liste aller Projekte mit Start-/Enddatum etc.
### Normalisierung
Oft müssen die Rohwerte etwas vereinheitlicht werden. Beispielsweise sollten
Datumsangaben ein konsistentes Format haben, Personennamen evtl. in
Vor-/Nachname zerlegt, und fehlende Felder explizit als `null` markiert werden.
Außerdem kann man hier foreign-key-Bezüge auflösen: Wenn z.B. im YAML einer
Publikation `author: "[[Doe, John]]"` steht, könnte das Skript erkennen, dass
dies die Person mit UID XYZ ist, und entsprechend in der extrahierten Struktur
statt des Link-Codes einen eindeutigen Verweis (auf die Person John Doe)
speichern. Diese Normalisierung erleichtert nachfolgende Analysen enorm
insbesondere kann man einfache Regeln ableiten, die dann vom LLM geprüft oder
genutzt werden. Zum Beispiel: _"Wenn `person.ORCID` leer ist, schlage vor, ihn
zu ergänzen"_ das kann das LLM dann direkt als Aufforderung bekommen. Oder:
_"Beim Erstellen einer neuen Person fülle Felder X,Y nach Vorlage aus"_ hier
weiß man aus der YAML-Definition bereits, welche Felder existieren müssen.
### Nutzung durch LLM
Der aufbereitete YAML-Datensatz kann auf zwei Weisen eingebunden werden:
- **Inline im Prompt:** Für bestimmte Aufgaben kann man dem LLM direkt
Ausschnitte aus dieser strukturierten Sammlung geben. Etwa: _"In unserer
Datenbank fehlt für `Person[42]` der ORCID. Hier ist eine Liste aller
Personennamen mit ORCID, finde anhand des Namens den passenden ORCID und trage
ihn ein."_ Falls die Person woanders erwähnt wurde, könnte das Modell es
herausfinden. (Eher unwahrscheinlich ohne Internetzugriff ORCID erfordert
eher einen API-Call, aber zumindest könnte das LLM erkennen, _dass_ es fehlt
und ggf. den Nutzer nach der ID fragen). Für Link-Empfehlungen könnte man dem
LLM eine Liste aller Titel geben oder besser direkt die Graph-Info wie
_"Person A und Person B haben 3 gemeinsame Projekte"_ siehe Hybrid-Ansatz.
- **Programmatisch außerhalb des LLMs:** Viele Routineaufgaben lassen sich
erkennen, ohne das LLM zu bemühen. Man könnte einen Teil der Automatisierung
rein mit Skripten vorab erledigen. Z.B. neue Links: Ein Skript könnte alle
Personennamen im Fließtext durchsuchen und prüfen, ob sie bereits als
`[[Link]]` markiert sind; wenn nicht, die Stelle hervorheben und dem LLM als
_"Kandidat für Verlinkung"_ präsentieren. Oder bei einer neuen Organisation
könnten automatisch Felder aus externen APIs gezogen und ins Template
eingetragen werden (sofern erlaubt). Das LLM hätte dann eher die Rolle, die
zusammengestellten Infos in schönen Prosa-Text zu gießen, anstatt die Fakten
selbst zu suchen.
### Beispiel-Workflows
- YAML-Exports lassen sich mit vorhandenen Tools unterstützen. Es gibt z.B. das
Obsidian-Plugin _Dataview_, welches Abfragen auf YAML ermöglichen kann
allerdings nur innerhalb Obsidian. Man könnte aber ein Dataview
JS-Skript^[oder Plugins wie _Dataview-Publisher_ benutzen, die die Ergebnisse
als Markdown-Tabell in ein Dokument schreiben] schreiben, das alle Einträge
eines Typs ausgibt, und diese Output-Datei dann weiterverarbeiten. Alternativ
direkt auf Dateisystemebene arbeiten: Python mit `os` und `pyyaml` kann alle
`.md` Files scannen.
- Die extrahierten Daten kann man mit dem Graph-Ansatz koppeln: etwa alle
Personen ohne ORCID als Cypher-Query generieren lassen und automatisch in eine
"ToDo"-Liste (Obsidian Note) schreiben, die vom LLM oder Nutzer geprüft wird.
- Durch Templates sind die Felder pro FileClass ja bekannt. Diese Knowledge kann
ins Prompt fließen: _"Eine Organisation hat die Felder Name, Typ,
Beschreibung, Mitarbeiter, etc. Fülle basierend auf den folgenden Infos…"_ Das
Modell weiß dann genau, welche YAML-Spalten es ausgeben soll.
### Vor- & Nachteile
Die **Vorteile** der strukturierten Extraktion liegen auf der Hand Performance
und Präzision. Man muss nicht jedes Mal den gesamten Markdown-Text durchsuchen,
um z.B. den Wert eines bestimmten Feldes zu finden; man hat ihn direkt. Außerdem
reduziert es die Abhängigkeit vom LLM für einfache Aufgaben (Daten finden,
vergleichen). Für die meisten Menschen ist es auch leichter zu verstehen und zu
prüfen, wenn man z.B. eine CSV mit allen ORCIDs hat, als wenn man dem LLM blind
glauben muss.
Als **Nachteil** kann gesehen werden, dass es zusätzlicher
Implementierungsaufwand ist und eine gewisse Duplizierung der Daten (die
YAML-Inhalte leben dann in zwei Formen: im Markdown und in der extrahierten
Sammlung). Die Synchronisation muss bei Änderungen immer gewährleistet sein
(Cronjob). Allerdings ist das, verglichen mit dem Aufwand der LLM-Integration,
relativ gering und gut automatisierbar.
```{mermaid}
%%| column: screen-inset-right
graph LR
A[Obsidian Vault] --> B[FileClass Detection]
B --> C[Type-Specific Extraction]
C --> D[YAML Parser]
D --> E[Data Validation]
E --> F[Type Normalization]
F --> G[(Typed Collections)]
H[Task Request] --> I[Schema Lookup]
I --> J[Targeted Data Fetch]
G --> J
J --> K[Context Assembly]
H --> K
K --> L[LLM Processing]
L --> M[Schema-Aware Output]
```
### Zusammenfassung Ansatz 4: Extraktion
In jedem Fall sollte man eine Pipeline vorsehen, die die YAML-**Metadaten
extrahiert** und in eine strukturierte Form bringt. Diese bildet das Rückgrat
für den Knowledge-Graph-Ansatz (ohne diese wären die Knoten nackte Titel ohne
Attribute) und ist auch für Vektor-RAG nützlich (z.B. als Filter oder zur
post-processing der LLM-Antworten). Insbesondere dank der FileClass-Typisierung
im Vault kann man hier sehr **zielgerichtet** vorgehen etwa nur definierte
Entitätstypen verarbeiten. In Community-Diskussionen wurde vorgeschlagen,
YAML-Metadaten zu nutzen, um AI-Aufgaben einzuschränken: z.B. NER-Modelle nur
auf bestimmten Notizen laufen zu lassen, die laut YAML einen bestimmten Typ
haben [@ai_empowered_zettelkasten_with_ner_and_graph_llm]. Solche Optimierungen
werden durch saubere strukturelle Aufbereitung erst möglich.
## 5. Automatisierungstools und Workflows
Für die Umsetzung der oben beschriebenen Ansätze gibt es bereits einige Tools,
Projekte und Best Practices, die man nutzen oder von denen man lernen kann. Hier
eine strukturierte Übersicht samt Empfehlungen:
### Obsidian-Plugins (In-App KI-Features)
- _Smart Connections:_ Plugin, das innerhalb Obsidian mit lokalen Embeddings
arbeitet, um **ähnliche Notizen** zu finden, und einen Chatbot bereitstellt.
Es kann ein lokales LLM (oder OpenAI API) einbinden und versorgt es
automatisch mit Kontext aus dem Vault [@smart_connections_plugin]. Vorteil:
einfache Installation, enge Vault-Integration (Antworten können direkt als
Notiz eingefügt werden). Nachteil: begrenzt anpassbar der Workflow ist
vordefiniert (hauptsächlich Q&A Chat). Für den Start aber exzellent, um ein
Gefühl für RAG im eigenen Vault zu bekommen.
- _Khoj:_ Ein Open-Source Projekt, bestehend aus einem lokalen Backend
[@khoj_plugin] und Obsidian-Plugin. Ermöglicht **natürliche Sprachsuche** und
Chat über die eigenen Notizen [@khoj_plugin]. Es kann sowohl online-Modelle
(GPT-4 etc.) als auch lokale Modelle nutzen
[@build_your_second_brain_with_khoj_ai]. Khoj fokussiert auf schnelle
semantische Suche; der Chat-Teil ist vor allem QA-orientiert. Als persönlicher
Suchassistent ist es sehr interessant etwa um via Obsidian Command Palette
Fragen ans Vault zu stellen. Es ist weniger darauf ausgelegt, automatisch
Links zu erzeugen oder YAML zu verändern (dafür wäre wiederum ein LLM mit
Schreibrechten nötig).
- _Obsidian Copilot / GPT-Assistant:_ Es existieren mehrere Plugins, die GPT-3/4
in Obsidian integrieren (teils auch lokal via LLaMA). Diese sind im Prinzip
UI-Verbesserungen, um das LLM "im Editor" zu nutzen. Für RAG kann man sie
einsetzen, indem man manuell Kontext reinkopiert, aber automatisches Retrieval
bieten sie nicht ohne weiteres.
- _Obsidian Neo4j Plugin (Experimentell):_ Das erwähnte _obsidian-neo4j-stream_
von \@HEmile [@export_to_common_graph_formats] könnte als Ausgangspunkt
dienen, falls man die Graph-Route ausprobieren will. Es war dazu gedacht, den
Vault als kontinuierlichen Stream in Neo4j zu spiegeln. Leider wurde es nicht
fertiggestellt/maintained. Dennoch ließe sich der Code evtl. anpassen, um
zumindest einmalig einen Export durchzuführen. Alternativ: Im Obsidian-Forum
gibt es auch Beispiele, wie man mit ein paar Skriptzeilen alle Links
extrahieren kann. Zusammen mit den YAML-Daten könnte man so einen
Basic-Graphen schon bekommen.
### Externe Anwendungen / Skripte
- _LlamaIndex (GPT Index):_ Diese Python-Bibliothek ist eine **Schweizer
Taschenmesser** für RAG. Man kann Dokumente laden (Markdown wird unterstützt),
unterschiedliche Indizes erstellen (Vector, List, KnowledgeGraph etc.) und
Abfragen mit LLM orchestrieren. Sie eignet sich, um schnell Prototypen zu
bauen. Beispielsweise könnte man einen **KnowledgeGraphIndex** erstellen, der
mittels Instruct-LLM Tripel aus den Notizen extrahiert (z.B. "Person X
arbeitet für Organisation Y"). Anschließend kann man Abfragen in natürlicher
Sprache stellen, die vom LLM in Graph-Traversals übersetzt werden. Oder man
nutzt den simpleren VectorIndex auf Markdown-Chunks. LlamaIndex kann auch
**Komposition**: man könnte pro FileClass einen Index bauen (z.B. alle
Personen in einem VectorIndex, alle Projekte in einem anderen) und dann einen
übergeordneten Query laufen lassen. Diese Flexibilität ist mächtig aber es
erfordert eben etwas Programmierung. Für einen produktiven Workflow (täglicher
Cronjob) müsste man ein eigenes Python-Skript schreiben, das die Indizes
aktualisiert.
- _LangChain:_ Ein Framework v.a. für komplexere Chains und Agenten. Es liefert
Bausteine, um z.B. eine Tool-using Agent zu bauen, die mit einer **Vector DB
Suche** und einer **Graph-DB Abfrage** als Tools ausgestattet ist. Damit ließe
sich ein Dialogsystem kreieren, das je nach Frage entscheidet, ob es den
Neo4j-Graph oder den Chroma-Vektorindex konsultiert. Allerdings setzt dies
einiges an Prompt Engineering voraus, damit der Agent zuverlässig
funktioniert. Alternativ kann man LangChain auch einfach nutzen, um entweder
Vector-search oder Graph-DB-Queries einzeln bequemer zu machen (es gibt z.B.
vorgefertigte Neo4j Retriever-Klassen etc.).
- _Haystack:_ Das von deepset (evtl. in der Frage mit "Deepseek" gemeint)
entwickelte Open-Source-Toolkit **Haystack** ist ebenfalls auf Dokumenten-QA
spezialisiert. Es unterstützt das Indexieren von Markdown, verschiedene
Vector-Backends und kann auch Knowledge-Graph-Komponenten integrieren. Zudem
hat es Pipeline-Knoten zum z.B. Fragenklassifizieren, dass bestimmte Fragen an
bestimmte Reader geleitet werden. Für einen produktiven Einsatz mit lokalem UI
ggf. eine Option. Allerdings eher heavy-weight und auf QA fokussiert, weniger
auf Wissensbasis-Pflege.
- _privateGPT / llama.cpp based scripts:_ Für einfache Frage-Antwort-Systeme auf
dem eigenen Vault kann man vorhandene Lösungen wie _privateGPT_ oder _GPT4All_
(mit UI) verwenden [@second_brain_assistant_with_obsidian]. Diese bringen
einen Großteil der Vector+LLM Pipeline schon fertig mit. Sie indexieren Ordner
voller Dokumente (auch Markdown) und erlauben dann Queries an ein lokales
Modell. Der Anpassungsspielraum (z.B. andere Tasks als reines QA) ist aber
gering. Als **Baseline** sind sie nützlich man könnte damit z.B. testen, wie
gut ein LLM mit den eingebetteten Obsidian-Notizen Fragen beantwortet, und
daraus Anforderungen ableiten.
- _Basic Memory (basicmachines):_ Ein innovativer Ansatz ist hier zu erwähnen:
**Basic Memory** speichert AI-Konversationen als Markdown in Obsidian und baut
daraus sukzessive einen semantischen Wissensgraph
[@basic_memory_ai_conversations_that_build_knowledge]. D.h. wenn man mit dem
LLM chatbasiert arbeitet, erstellt das Tool automatisch Notizen und verbindet
sie (z.B. werden erkannte Entitäten verlinkt). Es ist quasi das Gegenstück zu
unserem Problem statt einen bestehenden Vault zu nutzen, erzeugt es einen
Vault. Dennoch kann man sich dort Konzepte abschauen: z.B. wie strukturierte
Notizen aus LLM-Ausgaben generiert werden können, oder wie man
_bi-direktional_ arbeitet (User editiert Notiz, KI liest Änderungen beim
nächsten Mal). Basic Memory setzt auf lokale Dateien und betont Privatsphäre,
was dem hiesigen Anforderungsprofil ähnelt. Für die konkreten Aufgaben
(ORCID-Suche, Link-Vorschlag) liefert es zwar keine fertige Lösung, aber die
**Idee, KI beim Nutzer Notizen anlegen/ändern zu lassen,** ist hier praktisch
umgesetzt.
- **Externe APIs / Datenquellen:**
Für bestimmte Felder wie ORCID wird ein rein lokales LLM kaum die Werte
erraten können, sofern sie nicht schon irgendwo im Vault stehen. Falls
Internetzugriff eine Option ist, könnte man ein Plugin oder einen Workflow
integrieren, der **ORCID API** Abfragen durchführt (z.B. über den Namen der
Person) und die ID zurückliefert. Ein LLM-Agent könnte auch so einen API-Call
ausführen (via Tools in LangChain). Alternativ: Alle bekannten ORCID-IDs der
eigenen Personen könnte man in einer Datei sammeln; wenn das LLM eine Lücke
findet, bittet es den Nutzer um Input. Hier muss man die Limitierungen eines
LLM realistisch sehen und ggf. klassische Automatisierung (API-Skripte)
kombinieren.
```{mermaid}
%%| column: screen-inset-right
graph LR
subgraph Obsidian
A[Vault] --> B[Plugins]
B --> C[Templater]
B --> D[Metadata Menu]
B --> E[AI Assistant]
end
subgraph External Processing
A --> F[Daily Export]
F --> G[Data Processing]
G --> H[LLM Analysis]
H --> I[Automation Scripts]
end
subgraph Integration
I --> J[Change Proposals]
J --> K[User Review]
K --> L[Accepted Changes]
L --> M[Vault Updates]
M --> A
end
```
## Zusammenfassende Empfehlung
Für einen ersten Prototypen empfiehlt es sich, mit dem **Vektorstore-Ansatz
(1)** zu beginnen, da dieser am schnellsten sichtbare Erfolge bringt. Man kann
z.B. mit ChromaDB + einem lokalen LLM experimentieren, oder direkt das
Smart-Connections-Plugin ausprobieren, um ein Gefühl für semantische Suche im
Vault zu bekommen. Die YAML-Daten sollte man von Anfang an **mit-extrahieren
(4)**, da sie die Grundlage für weitere Strukturierungsmaßnahmen bilden.
Anschließend kann man gezielt **Graph-Features (2)** ergänzen: etwa den
exportierten Vault in Neo4j laden und ein paar Abfragen formulieren, um Missing
Links oder fehlende Felder aufzuspüren. Mittelfristig dürfte eine **Kombination
(3)** notwendig sein, um sowohl Inhalt als auch Struktur abzudecken dies kann
man Schritt für Schritt angehen (z.B. zunächst Vector-RAG für inhaltliche
Fragen, und separate Tools/Reports für strukturierte Checks; später dann
Integration zu einem einheitlichen KI-Assistenten). Unterstützend sollte man
vorhandene **Tools (5)** nutzen, wo möglich z.B. Khoj für ad-hoc Fragen, oder
LlamaIndex für schnelle Implementierung von Prototypen. Generell gilt: lokale
LLMs sind inzwischen leistungsfähig genug für solche Aufgaben, wie die genannten
Beispiele zeigen (Chat mit Vault über LLaMA etc.). Wichtig ist es, die
**Vault-Organisation** konsequent weiterzuführen (FileClasses, Templates), da
ein sauber strukturiertes Wissen die Grundlage für jede erfolgreiche RAG-Lösung
ist egal ob Vektor, Graph oder hybrid.
## Quellen
Die Analyse basiert auf aktuellen Erkenntnissen aus der Obsidian-Community und
KI-Fachwelt, u.a. Erfahrungen mit semantischer Suche
[@smart_connections_plugin], Diskussionen zu Knowledge Graphs in PKM
[@ai_empowered_zettelkasten_with_ner_and_graph_llm] und Berichten über lokale
RAG-Implementierungen [@local_free_rag_with_question_generation,
@smart_connections_plugin].
## Methodik / LLMs als 'Autoren' {.appendix}
Erstellt wurde der initial draft mittels Websuche und "Deep-Research" von
`gpt-4.5 (preview)`. Systematische Überarbeitungen (Extraktion Bibliographie,
Überarbeitung Metadaten) mittels `cogito-v0.1` im Editor. Übernahme nach
manueller Prüfung. Erstellung der Mermaid-Diagramme mittels `Claude 3.7 Sonnet`.
Abschließendes Korrekturlesen/inhaltliche Prüfung/Layouting
durch Nicole Dresselhaus.