LLM Wiki nad Obsidianem v QubesOS
Jak jsem rozšířil svůj osobní knowledge management Obsidian vault na perzistentní znalostní bázi pomáhající LLM AI — s qmd, Claude Code a specifiky QubesOS.
> Upozornění: Následující text není všepopisný návod po jednotlivých krocích. Spíš je záznamem na co můžete narazit při implementaci a jak to lze řešit.
💡 Co je LLM Wiki
Andrej Karpathy publikoval v dubnu 2026 jednoduchý nápad: místo toho aby pokaždé znovu vysvětloval AI co ví, nechá ji jednou přeložit zdrojové materiály do strukturované wiki a pak AI z těhle dat odpovídá.
Rozdíl oproti běžnému RAG je zásadní:
| Přístup | Znalost | Stav |
|---|---|---|
| RAG | Odvozuje pokaždé znovu | Bezstavový |
| LLM Wiki | Jednou zkompiluje, tu část, kterou zrovna potřebuje a tu pak čte | Stavový, kumulativní |
RAG je jako vzít knihovnu a pokaždé ji celou přečíst. LLM Wiki je jako mít knihovníka, který si udělal vlastní poznámky a index — a odpovídá z nich.
Základní myšlenka:
zdrojové materiály (raw/) → LLM kompiluje → wiki/ → LLM odpovídá
raw/je source of truth, který píšeš ty.wiki/je synthesis layer, který píše výhradně LLM. Nikdy to nezaměňuješ.
👻 (Víceméně) zbytečné obavy
- “AI mi udělá zmatek v léta opečovávaných poznámkách v mém knowledge management řešení Obsidian.” → Neudělá. Součástí Karpathyho konceptu LLM Wiki je vstupní adredář
raw/jako zdroj, ve kterém nic nemění a výstupní (pro LLM AI pomocný) adresářwiki/. - “Jakmile začnu měnit strukturu dat něco se rozbije”. → Vyloučit to nelze, ale proto si při úpravách počínáme obezřetně a kontrolujeme si zda zamýšlené změny jsou v souladu s tím jak to funguje. Na co je třeba si dát pozor, např. v nastavení Obsidian, je zmíněné dále v textu.
🤔 Výchozí situace: velký existující Obsidian vault
Standardní Karpathy pattern předpokládá, že začínáš od nuly — vytvoříš raw/ a vedle něj wiki/. Pokud ale máš existující Obsidian vault s léty poznámek, narazíš hned na první otázku: kam co patří?
Můj vault (~/Obsidian.SyncThing/) měl přibližně 500 MB obsahu, 1 078 markdown souborů ve 42 složkách a přílohy (obrázky, PDF) přímo v kořeni. Obsah je primárně zaměřen na bezpečnost a IT (Security, IT, pentest, hacking tvoří ~43 % poznámek), dále finance, soukromí, QubesOS, GrapheneOS a různé další poznámky.
Obsidian Vault je synchronizovaný přes Syncthing — stejný obsah je dostupný ve dvou QubesOS VM:
notes(Ubuntu 22.04 LTS, kde běží Obsidian) aai-anthropic(Debian 13 Trixie, kde běží Claude Code).
Syncthing zajišťuje že obě VM vidí vždy stejný stav vaultu, včetně nově přidaných zdrojů a wiki stránek zapsaných agentem. Z toho vyplývá pojmenování složky vaultu: ~/Obsidian.SyncThing/ — název reflektuje způsob synchronizace.
Proč nemít wiki/ přímo v kořeni vaultu
Technicky by šlo mít wiki/ jako podsložku kořene vaultu, kde je i zbytek obsahu. Ale vznikají tím problémy:
- Při promptu “projdi všechny soubory” musíš vždy explicitně vyloučit
wiki/aby se LLM nemátl vlastním výstupem - Totéž platí pro
.obsidian/,.claude/,.stfoldera další skryté složky - Vyjímky je snadné opomenout zmínit → agent čte co sám napsal → chyby se kumulují
Čistší řešení: přesunout veškerý obsah do raw/ a mít jasnou strukturu:
~/Obsidian.SyncThing/
├── raw/ ← tvůj obsah (vstupy jako source of truth)
├── wiki/ ← LLM synthesis výstupy (nikdy needituješ ručně)
├── .obsidian/ ← nastavení Obsidianu
├── .claude/ ← instrukce pro Claude Code
├── .agents/ ← instrukce pro Codex a jiné agenty
├── .stfolder ← Syncthing marker
└── CLAUDE.md ← instrukce pro agenta platné pro celý vault
Přesun obsahu do raw/
Obsidian má ve výchozím nastavení “New link format: Shortest path possible” — wikilinky jako [název souboru](nazev-souboru.html) se resolvují vyhledáním jména po celém vaultu bez ohledu na cestu. Přesun souborů do podsložky tedy wikilinky nerozbije.
Před přesunem si ověř nastavení: Settings → Files & Links → New link format.
Přesun z příkazové řádky:
cd ~/Obsidian.SyncThing
# Vytvoř cílovou složku
mkdir raw
# Přesuň vše kromě skrytých složek a raw samotného
find . -maxdepth 1 \
! -name '.' \
! -name 'raw' \
! -path './.obsidian' \
! -path './.claude' \
! -path './.agents' \
! -path './.stfolder' \
! -path './.trash' \
-exec mv {} raw/ \;
Pozor:
findbez správného vylučování skrytých složek je přesune taky. Vzor výše vylučuje explicitně každou skrytou složku která patří na vault root. Pokud máš jiné skryté složky v kořeni, které nechceš přesouvat, zmiň je ve vyjímkách stejným způsobem. Děláš to jen jednou. Pak už to bude správně.
Po přesunu zkontroluj v Obsidianu: Settings → Files & Links → Default location for new attachments — pokud ukazoval na konkrétní složku, aktualizuj na raw/attachments.
Sjednocení příloh
Přílohy (obrázky, PDF) ze starších importů mohou být roztroušené přímo v raw/ místo v raw/attachments/. Přesun je bezpečný díky Shortest path:
mkdir -p ~/Obsidian.SyncThing/raw/attachments
find ~/Obsidian.SyncThing/raw/ -maxdepth 1 -type f ! -name "*.md" \
-exec mv {} ~/Obsidian.SyncThing/raw/attachments/ \;
Pak nastav výchozí umístění příloh: Settings → Files & Links → Default location for new attachments → “In the folder specified below” → raw/attachments.
Kontrola broken linků
cd ~/Obsidian.SyncThing
# Reference v .md souborech
grep -roh '!\[\[^\](.html)*\]\]' raw/ \
| sed 's/.*!\[\[//;s/\]\].*//' \
| sort -u > /tmp/referenced.txt
# Skutečné soubory příloh
find raw/ -type f ! -name "*.md" \
| xargs -I{} basename {} \
| sort -u > /tmp/existing.txt
# Rozdíl = rozbité linky
comm -23 /tmp/referenced.txt /tmp/existing.txt
Prázdný výstup = vše v pořádku.
💪 Obsidian Skills
Ve vaultu jsou nainstalované obsidian-skills od Steph Anga. Každý skill je markdown soubor v
.claude/skills/<skill-name>/SKILL.md(pro Claude Code) a.agents/skills/<skill-name>/SKILL.md(pro Codex CLI).
Obsah je identický, liší se jen discovery path.
Instalace:
git clone https://github.com/kepano/obsidian-skills.git /tmp/obsidian-skills
mkdir -p ~/Obsidian.SyncThing/.claude/skills
cp -r /tmp/obsidian-skills/skills/* ~/Obsidian.SyncThing/.claude/skills/
mkdir -p ~/Obsidian.SyncThing/.agents/skills
cp -r /tmp/obsidian-skills/skills/* ~/Obsidian.SyncThing/.agents/skills/
rm -rf /tmp/obsidian-skills
Nainstalované skills:
| Skill | Účel |
|---|---|
obsidian-markdown |
Správný Obsidian-flavored markdown: wikilinky, frontmatter, callouts |
obsidian-cli |
Otevírání souborů v Obsidianu z agenta |
obsidian-bases |
Databázové pohledy (Obsidian Bases) |
json-canvas |
Vizuální mapy znalostí v Canvas formátu |
defuddle |
Čištění web obsahu při ingestu (odstraní navigaci, boilerplate) |
Skills cestují s vaultem — při kopírování do jiného VM přes qvm-copy jsou automaticky dostupné bez jakékoliv globální instalace.
CLAUDE.md: instrukce pro agenta
CLAUDE.md v kořeni vaultu čte Claude Code automaticky při každém spuštění session. Definuje strukturu, pravidla a workflow.
Klíčové části:
## Struktura vaultu
~/Obsidian.SyncThing/ ← vault root
├── raw/ ← zdrojový obsah, POUZE čteš
├── wiki/ ← synthesis layer, POUZE ty píšeš
│ ├── synthesis/ ← shrnutí témat
│ ├── query/ ← odpovědi na konkrétní dotazy
│ └── index.md ← přehled co je ve wiki
├── .claude/skills/ ← skills pro Claude Code
└── .obsidian/ ← NIKDY nesahej
## Pravidla
- raw/ nikdy neupravuj, nepřejmenovávej, nesmazávej
- wiki/ píšeš výhradně ty, uživatel ji ručně neupravuje
- Při procházení raw/ vždy vyluč wiki/ aby ses nespletl s vlastním výstupem
Důležitá je sekce kontextu domény, aby agent nepotřeboval vault pokaždé znovu analyzovat:
## Kontext vaultu
Primární témata (pro prioritizaci synthesis):
- Bezpečnost, IT, pentest, hacking (~43 % obsahu)
- Finance, soukromí
- QubesOS, GrapheneOS
- Osobní poznámky, recepty a ostatní
Při technických tématech preferuj přesnost před zjednodušením.
Struktura wiki/
wiki/
├── synthesis/ ← zkompilovaná témata z raw/
├── query/ ← odpovědi na konkrétní dotazy (archiv)
├── index.md ← přehled obsahu wiki
└── log.md ← audit trail co agent dělal a kdy
wiki/synthesis/ obsahuje trvalé stránky kompilované z raw/ obsahu. wiki/query/ je archiv odpovědí na jednorázové dotazy — agent ho přidává ale nemaže.
qmd: lokální search engine
Při 1 078 souborech nestačí procházet soubory jeden po druhém. qmd je lokální search engine pro markdown soubory s hybridním BM25/vektorovým vyhledáváním, které běží plně on-device. Má MCP server, takže ho Claude Code může volat jako nativní nástroj.
Instalace na Fedora / Debian v QubesOS
Ve výchozí instalaci nemusí být dostupný ani bun ani go. qmd je npm balíček, ale jeho wrapper script vyžaduje bun jako runtime:
# 1. Instalace qmd přes npm
npm install -g @tobilu/qmd
# 2. Instalace bun (potřebný runtime)
curl -fsSL https://bun.sh/install | bash
Instalátor bunu automaticky přidá do ~/.bashrc:
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
Pro fish shell je potřeba přidat ručně do ~/.config/fish/config.fish:
fish_add_path "$HOME/.bun/bin"
Ověření:
export PATH="$HOME/.bun/bin:$PATH"
qmd --version
# qmd 0.9.0
Vytvoření kolekcí
Gotcha: Syntaxe
qmd collection addje odlišná od dokumentace. Správně: první argument je cesta, název je--name.
qmd collection add /home/user/Obsidian.SyncThing/raw \
--name my-vault --mask "**/*.md"
qmd collection add /home/user/Obsidian.SyncThing/wiki \
--name wiki --mask "**/*.md"
Gotcha: Nepřidávej kolekce spojené přes
&&pokud první selže — zůstane prázdný záznam v databázi. Přidávej každou zvlášť.
Přidání kontextu (pomáhá při query s re-rankingem):
qmd context add qmd://my-vault/ "Obsidian vault raw obsah - bezpecnost/IT/pentest"
qmd context add qmd://wiki/ "LLM wiki synthesis stranky"
Indexace
# BM25 full-text index (~30 sekund pro 1000 souborů)
qmd update
# Vektorové embeddingy — stáhne ~300 MB modely z HuggingFace
# Spusť na pozadí, zabere 10-20 minut
nohup qmd embed > /tmp/qmd-embed.log 2>&1 &
tail -f /tmp/qmd-embed.log
Po qmd update funguje qmd search (BM25 full-text). Po qmd embed fungují i qmd vsearch (sémantické vyhledávání) a qmd query (BM25 + vektory + LLM re-ranking).
Použití
qmd search "pentest" # BM25 keywords
qmd vsearch "privilege escalation techniky" # sémantické vyhledávání
qmd query "jak detekovat lateral movement" # hybrid + reranking
MCP server pro Claude Code
Gotcha:
mcpServersnepatří do~/.claude/settings.json— validace schématu to odmítne. Správné místo je~/.claude/mcp.json.
{
"mcpServers": {
"qmd": {
"command": "/home/user/.local/bin/qmd",
"args": ["mcp"],
"env": {
"PATH": "/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin"
}
}
}
}
Gotcha: PATH v
envmusí explicitně obsahovat~/.bun/bin— MCP server se spouští s čistým prostředím a bun jinak nenajde.
Ověření bez restartu Claude Code (přímý JSON-RPC):
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"qmd_search","arguments":{"query":"pentest"}}}' \
| PATH="/home/user/.bun/bin:$PATH" /home/user/.local/bin/qmd mcp
Po restartu Claude Code session jsou dostupné nástroje: qmd_search, qmd_vsearch, qmd_query, qmd_get, qmd_multi_get.
🚀 Workflow
💼 Ingest
Přidáš soubor do raw/ (ručně, přes Obsidian Web Clipper nebo jinak) a řekneš agentovi:
Ingestuj raw/[soubor nebo složka]
Agent přečte zdroj, vytvoří nebo aktualizuje wiki/synthesis/[téma].md, aktualizuje wiki/index.md a zapíše do wiki/log.md.
🔍 Query
Odpověz na: [otázka]
Agent prohledá wiki/synthesis/ přes qmd. Pokud téma nenajde, prohledá raw/ a vytvoří wiki/query/[slug].md se syntézou a wikilinky na zdrojové soubory.
🧹 Lint
Lint wiki
Agent zkontroluje synthesis stránky bez zdrojových odkazů, zastaralé stránky a chybějící témata. Výsledek zapíše do wiki/query/lint-[datum].md.
📦 Specifika QubesOS
Aktualizace Obsidian na QubesOS
Systémový .deb balíček se neaktualizuje přes standardní apt, protože na QubesOS je rootfs v AppVM neperzistentní přes restarty (záleží na typu VM).
App verze 1.12.7 se aktualizovala sama, protože:
- Zápis do ~/.config/ v home adresáři je povolen (home je persistentní i na QubesOS AppVM)
- Obsidian auto-updater fungoval v user-space, bez potřeby root
Praktický dopad
- Dokud Electron shell v
/opt/funguje a je kompatibilní, nemusíš .deb aktualizovat - Pokud by Obsidian vyžadoval novější Electron (např. kvůli novým API), pak by
installer versionzaostala a mohly by být problémy — ale to se u 1.7.5 → 1.12.7 zatím nestalo
Dvě verze = dvě různé věci
| Co | Verze | Kde |
|---|---|---|
| Installer version | 1.7.5 | /opt/Obsidian/obsidian — systémový .deb balíček |
| App version | 1.12.7 | ~/.config/obsidian/ — auto-aktualizovaný app bundle |
Jak to funguje
/opt/Obsidian/obsidian
│
│ (Electron shell / launcher)
▼
~/.config/obsidian/obsidian-1.12.7.asar ← skutečná aplikace
.debbalíček nainstaloval Electron runtime (shell) do/opt/Obsidian/- Při prvním spuštění si Obsidian stáhl aktuální verzi aplikace jako
.asarbundle do home adresáře uživatele - Electron launcher vždy načte nejnovější
.asarz~/.config/obsidian/
Lze ověřit:
ls -la ~/.config/obsidian/
# nebo
find ~/.config/obsidian -name "*.asar" 2>/dev/null
Proč to tak dělají
Electron shell se mění zřídka (nová verze Chromia/Node.js), zatímco samotná aplikace se aktualizuje často. Tím pádem nepotřebují root práva pro každou aktualizaci — .asar se aktualizuje pouze v home adresáři.
Vault synchronizace
- Obsidian vault primárně žije v
notes VM(Ubuntu 22.04 LTS) kde běží Obsidian. - Claude Code běží v oddělené
ai-anthropic VM(Debian 13 Trixie).
Synchronizaci mezi VM zajišťuje Syncthing — obě VM sledují stejnou složku vaultu.
Když přidáš zdroj do raw/ v notes VM nebo AI zapíše synthesis stránku do wiki/ v ai-anthropic VM, Syncthing změny automaticky propaguje na opačnou stranu. Není potřeba nic kopírovat ručně.
Syncthing běží v obou VM jako systemd user unit:
systemctl --user status syncthing.service
systemctl --user enable syncthing.service # spuštění při startu VM
Skills v .claude/skills/ a .agents/skills/ jsou součástí vaultu a tedy taky synchronizované — nejsou potřeba žádné globální instalace v agent VM.
qmd a bun jsou nainstalované v ai-anthropic VM. Databáze qmd kolekcí zůstává lokálně v ai-anthropic VM (není součástí vaultu a nesynchronizuje se).
.stfolder je Syncthing marker — musí zůstat na kořeni sledované složky (~/Obsidian.SyncThing/), ne v raw/. Při přesunu obsahu do raw/ ho vynech.
✔️ Výsledný stav
~/Obsidian.SyncThing/
├── raw/ ← 1 078 .md souborů, 42 složek, ~500 MB
│ └── attachments/ ← obrázky a PDF
├── wiki/
│ ├── synthesis/ ← LLM-kompilovaná témata
│ ├── query/ ← archiv dotazů a odpovědí
│ ├── index.md
│ └── log.md
├── .claude/
│ ├── mcp.json ← qmd MCP server config
│ └── skills/ ← obsidian-markdown, obsidian-cli, ...
├── .agents/
│ └── skills/ ← totéž pro Codex
├── .obsidian/
├── .stfolder
└── CLAUDE.md
qmd kolekce: my-vault (1 078 souborů) a wiki. BM25 index aktivní, vektorové embeddingy se doindexovávají (~300 MB modely).
😬 Gotchas shrnutí
findbez vylučování přesune i skryté složky jako.stfolder,.claude— vyluč je explicitněqmd collection add— první argument je cesta, název je--name(ne pozicionální)- Kolekce s
&&— pokud první selže, zanechá prázdný záznam; přidávej každou zvlášť - bun v PATH — qmd wrapper ho vyžaduje; v MCP env ho nastav explicitně
- MCP config patří do
.claude/mcp.json, ne dosettings.json qmd embedje separátní krok odqmd update; bez něj funguje jen BM25 searchwiki/ jako podsložka raw/je funkční alternativa bez přesunu obsahu, ale vyžaduje výjimky v každém promptu —raw/jako explicitní složka je čistší