obsidian:~/vault$ search --hybrid obsidian

Obsidian MCP + wyszukiwanie hybrydowe: przewodnik na 2026 rok

# Połącz Obsidian z Claude i innymi agentami przez MCP: konfiguracja serwera, hybrydowe wyszukiwanie BM25 + wektorowe oraz indeksowanie sejfu zawierającego 16 894 plików — z działającymi konfiguracjami.

author: words: 16592 read_time: 63m updated: 2026-08-16 11:28
$ retriever search --hybrid obsidian

Obsidian nie jest aplikacją do notatek. To lokalny w pierwszej kolejności, tekstowy korpus markdown o strukturze grafu, który po dodaniu infrastruktury wyszukiwania staje się rezerwuarem kontekstu dla AI. 16 894 pliki. 49 746 fragmentów. Zapytania w 23 ms. Zero wywołań API. Jeden plik SQLite o rozmiarze 83 MB. Ten przewodnik omawia cały system: od architektury skarbca, przez hybrid retrieval, po integrację z MCP i workflow operacyjne.


Najważniejsze wnioski

Inżynieria kontekstu, a nie sporządzanie notatek. Wartość sejfu Obsidian dla AI nie polega na samych notatkach, lecz na warstwie wyszukiwania, która umożliwia ich przeszukiwanie za pomocą zapytań. Sejf z 16 000 plików bez mechanizmu wyszukiwania jest bazą danych tylko do zapisu. Sejf z 200 plikami, wyszukiwaniem hybrid i integracją MCP jest bazą wiedzy AI. Infrastruktura wyszukiwania jest produktem. Notatki są surowym materiałem.

Wyszukiwanie hybrid przewyższa czyste wyszukiwanie po słowach kluczowych lub semantyczne. BM25 wychwytuje dokładne identyfikatory i nazwy funkcji. Wyszukiwanie wektorowe wychwytuje synonimy i dopasowania koncepcyjne przy użyciu różnej terminologii. Reciprocal Rank Fusion (RRF) łączy oba podejścia bez potrzeby kalibracji wyników. Żadna z tych metod samodzielnie nie pokrywa obu trybów awarii. Badania nad rankingiem fragmentów MS MARCO potwierdzają ten wzorzec: hybrid retrieval konsekwentnie przewyższa każdą z metod stosowaną osobno.3 Szczegółowe omówienie hybrid retriever obejmuje matematykę RRF, przykłady z rzeczywistymi liczbami, analizę trybów awarii oraz interaktywny kalkulator fuzji.

MCP zapewnia narzędziom AI bezpośredni dostęp do sejfu. Serwery Model Context Protocol (MCP) udostępniają retriever jako narzędzie, które mogą bezpośrednio wywoływać Claude Code, Codex CLI, Cursor i inne narzędzia AI. Agent wysyła zapytanie do sejfu, otrzymuje uszeregowane wyniki z atrybucją źródła i wykorzystuje kontekst bez wczytywania całych plików. Serwer MCP jest cienką warstwą otaczającą silnik wyszukiwania.

Podejście local-first oznacza zerowe koszty API i pełną prywatność. Cały stos działa na jednej maszynie: SQLite do przechowywania danych, Model2Vec do embeddings, FTS5 do wyszukiwania po słowach kluczowych, sqlite-vec do wektorowego KNN. Bez usług chmurowych, wywołań API i zależności od sieci. Osobiste notatki nigdy nie opuszczają maszyny. Pełne ponowne utworzenie embeddings dla 49 746 chunków kosztowałoby około 0,30 USD według cen API OpenAI, lecz rzeczywistymi kosztami są opóźnienia, ekspozycja prywatnych danych i zależność od sieci w systemie, który powinien działać offline.4

Indeksowanie przyrostowe utrzymuje aktualność systemu w mniej niż 10 sekund. Porównanie czasu modyfikacji plików wykrywa zmiany. Ponownie dzielone na chunki i przetwarzane na embeddings są tylko zmodyfikowane pliki. Pełne ponowne indeksowanie trwa około czterech minut na sprzęcie Apple z serii M. Przyrostowe aktualizacje dla typowych zmian z jednego dnia zajmują mniej niż dziesięć sekund. System pozostaje aktualny bez ręcznej interwencji.

Architektura skaluje się od 200 do ponad 20 000 notatek. Ten sam trójwarstwowy projekt (przyjmowanie danych, wyszukiwanie, integracja) działa przy każdym rozmiarze sejfu. W małym sejfie należy zacząć od wyszukiwania wyłącznie z użyciem BM25. Wyszukiwanie wektorowe warto dodać, gdy problemem stają się kolizje słów kluczowych. Fuzję RRF należy dodać, gdy potrzebne są zarówno dokładne, jak i semantyczne dopasowania. Każda warstwa jest niezależnie użyteczna i może być niezależnie usunięta.


Jak korzystać z tego przewodnika

Ten przewodnik obejmuje kompletny system. Punkt wyjścia zależy od obecnej sytuacji:

Pan/Pani jest… Zacznij tutaj Następnie poznaj
Nowy użytkownik Obsidian + AI Dlaczego Obsidian dla infrastruktury AI, Konfiguracja Obsidian MCP Architektura sejfu, Architektura serwera MCP
Istniejący sejf, potrzebny dostęp AI Architektura serwera MCP, Integracja z Claude Code Modele embeddingów, Wyszukiwanie pełnotekstowe
Tworzenie systemu wyszukiwania Kompletny potok wyszukiwania, Reciprocal Rank Fusion Dostrajanie wydajności, Rozwiązywanie problemów
Kontekst zespołowy lub korporacyjny Ramy decyzyjne, Wzorce grafu wiedzy Przepisy na workflow deweloperski, Przewodnik migracji

Sekcje oznaczone jako Contract zawierają szczegóły implementacyjne, bloki konfiguracji i tryby awarii. Sekcje oznaczone jako Narrative skupiają się na koncepcjach, decyzjach architektonicznych i uzasadnieniu wyborów projektowych. Sekcje oznaczone jako Recipe zawierają workflow krok po kroku.


Dlaczego Obsidian dla infrastruktury AI

Teza tego przewodnika: sejfy Obsidian są najlepszym podłożem dla osobistych baz wiedzy AI, ponieważ działają local-first, wykorzystują zwykły tekst, mają strukturę grafu, a użytkownik kontroluje każdą warstwę stosu.

Co Obsidian zapewnia AI, czego nie oferują alternatywy

Pliki Markdown w zwykłym tekście. Każda notatka jest plikiem .md w systemie plików. Bez zastrzeżonego formatu, eksportu bazy danych ani potrzeby używania API do odczytu treści. Każde narzędzie, które odczytuje pliki, może odczytać sejf. grep, ripgrep, pathlib Python, SQLite FTS5 — wszystkie działają bezpośrednio na plikach źródłowych. Podczas tworzenia systemu wyszukiwania indeksowane są pliki, a nie odpowiedzi API. Indeks zawsze jest zgodny ze źródłem, ponieważ źródłem jest system plików.

Architektura local-first. Sejf znajduje się na Państwa maszynie. Bez serwera, zależności od synchronizacji chmurowej, limitów szybkości API ani warunków świadczenia usług regulujących sposób przetwarzania własnych treści. Można tworzyć embeddings, indeksować, dzielić na chunki i przeszukiwać notatki bez żadnej usługi zewnętrznej. Jest to istotne dla infrastruktury AI, ponieważ potok wyszukiwania działa tak szybko, jak pozwala dysk, a nie jak szybko odpowiada punkt końcowy API. Ma to również znaczenie dla prywatności: osobiste notatki zawierające dane uwierzytelniające, dane zdrowotne, informacje finansowe i prywatne przemyślenia nigdy nie opuszczają maszyny.

Struktura grafu dzięki wiki-links. Składnia [[wiki-link]] Obsidian tworzy graf skierowany między notatkami. Notatka o implementacji OAuth zawiera linki do notatek o rotacji tokenów, zarządzaniu sesjami i bezpieczeństwie API. Struktura grafu koduje relacje między pojęciami, które zostały starannie ustalone przez człowieka. Wektorowe embeddings wychwytują podobieństwo semantyczne, lecz wiki-links odzwierciedlają zamierzone połączenia utworzone przez autora podczas pracy nad tematem. Graf jest sygnałem, którego embeddings nie potrafią odtworzyć.

Ekosystem wtyczek. Obsidian ma ponad 2 500 wtyczek społecznościowych (liczba przekroczyła 2 500 w marcu 2026 r., wzrastając z ponad 1 800 w połowie 2025 r.). Dataview umożliwia wykonywanie zapytań do sejfu jak do bazy danych. Templater generuje notatki z szablonów przy użyciu logiki JavaScript. Integracja z Git synchronizuje sejf z repozytorium. Linter wymusza spójność formatowania. Główna wtyczka Bases (wprowadzona w wersji 1.9.10) dodaje widoki podobne do baz danych — tabele, galerie, kalendarze i tablice kanban — dla plików sejfu, wykorzystując właściwości frontmatter jako pola i zapisując je jako pliki .base.15 Wtyczki te dodają strukturę do sejfu bez zmiany podstawowego formatu zwykłego tekstu. System wyszukiwania indeksuje wynik działania tych wtyczek, a nie same wtyczki.

Ponad 5 milionów użytkowników. Obsidian ma dużą aktywną społeczność tworzącą szablony, workflow, wtyczki i dokumentację. Gdy pojawi się problem z organizacją sejfu lub konfiguracją wtyczki, ktoś najprawdopodobniej udokumentował już rozwiązanie. Społeczność tworzy także narzędzia powiązane z Obsidian: serwery MCP, skrypty indeksujące, potoki publikowania i wrappery API.

Czego sam system plików nie zapewnia

Katalog plików Markdown ma zaletę zwykłego tekstu, lecz brakuje mu trzech rzeczy, które dodaje Obsidian:

  1. Dwukierunkowe linki. Obsidian automatycznie śledzi backlinki. Gdy zostanie utworzony link z notatki A do notatki B, notatka B pokazuje, że odwołuje się do niej notatka A. Panel grafu wizualizuje klastry połączeń. Ta dwukierunkowa świadomość jest metadanymi, których nie zapewnia surowy system plików.

  2. Podgląd na żywo z renderowaniem przez wtyczki. Zapytania Dataview, diagramy Mermaid i bloki callout są renderowane w czasie rzeczywistym. Pisanie jest wygodniejsze niż w edytorze tekstu, podczas gdy format przechowywania pozostaje zwykłym tekstem. Pisanie i organizacja odbywają się w bogatym środowisku; system wyszukiwania indeksuje surowy Markdown.

  3. Infrastruktura społeczności. Odkrywanie wtyczek, marketplace motywów, usługa synchronizacji (opcjonalna), usługa publikowania (opcjonalna) oraz ekosystem dokumentacji. Każdą pojedynczą funkcję można odtworzyć za pomocą samodzielnych narzędzi, ale Obsidian łączy je w spójny workflow.

Czego Obsidian NIE robi (i co należy zbudować)

Obsidian nie zawiera infrastruktury wyszukiwania. Ma podstawowe wyszukiwanie (pełnotekstowe, według nazwy pliku i tagu), lecz nie ma potoku embeddings, wyszukiwania wektorowego, rankingu fuzji, serwera MCP, filtrowania danych uwierzytelniających, strategii chunking ani hooków integracyjnych dla zewnętrznych narzędzi AI. Ten przewodnik obejmuje infrastrukturę budowaną na bazie Obsidian. Sejf jest podłożem. Potok wyszukiwania, serwer MCP i hooki integracyjne są infrastrukturą.

Opisana tutaj architektura jest markdown-first, a nie przeznaczona wyłącznie dla Obsidian. W przypadku korzystania z Logseq, Foam, Dendron lub zwykłego katalogu plików Markdown potok wyszukiwania działa identycznie. Chunker odczytuje pliki .md. Embedder przetwarza ciągi tekstowe. Indexer zapisuje dane w SQLite. Żaden z tych komponentów nie zależy od funkcji specyficznych dla Obsidian. Wkładem Obsidian jest środowisko do pisania i organizacji, które tworzy pliki Markdown indeksowane przez retriever.

Konfiguracja Obsidian MCP

Model Context Protocol (MCP) to standardowy interfejs, który daje Claude Code, Codex CLI, Cursor i innym narzędziom AI bezpośredni dostęp do sejfu Obsidian. Ta sekcja pozwala połączyć sejf z narzędziem AI w pięć minut. Zainstalujesz Obsidian, utworzysz sejf, zainstalujesz serwer MCP i wykonasz pierwsze zapytanie. Szybki start korzysta ze społecznościowego serwera MCP, aby zapewnić natychmiastowe rezultaty. Kolejne sekcje opisują budowę własnego potoku pobierania danych do zastosowań produkcyjnych.

Wymagania wstępne

  • macOS, Linux lub Windows
  • Node.js 18+ (dla serwera MCP)
  • Obsidian 1.12+ (dla integracji z CLI; 1.13.7 to aktualna publiczna wersja desktopowa – kanały stable i beta zostały połączone, linia 1.13 opuściła Catalyst 30 lipca 2026 r.; wcześniejsze wersje działają w konfiguracjach wyłącznie z MCP)
  • zainstalowane Claude Code, Codex CLI lub Cursor

Krok 1: Utwórz sejf

Pobierz Obsidian z obsidian.md i utwórz nowy sejf. Wybierz lokalizację, którą łatwo zapamiętać — serwer MCP potrzebuje ścieżki bezwzględnej.

# Example vault location
~/Documents/knowledge-base/

Dodaj kilka notatek, aby moduł pobierania miał na czym pracować. Nawet 10-20 notatek wystarczy, aby zobaczyć rezultaty. Każda notatka powinna być plikiem .md z sensownym tytułem i co najmniej jednym akapitem treści.

Krok 2: Zainstaluj serwer MCP

Kilka społecznościowych serwerów MCP zapewnia natychmiastowy dostęp do sejfu. Ekosystem znacznie rozrósł się w latach 2025-2026. Na uwagę zasługuje MCPVault (npm @bitbonsai/mcpvault, repozytorium bitbonsai/mcpvault), obecnie w wersji v0.15.0 (zweryfikowane w npm 14 sierpnia 2026 r.) — to osobny projekt względem MarkusPfundstein/mcp-obsidian opisanego niżej, a nie jego nowa nazwa. Wersja v0.11.0 (marzec 2026 r.) dodała list_all_tags do skanowania frontmatter i hashtagów wraz z licznikami, usprawniła obsługę folderów z kropkami oraz dodała obsługę .base/.canvas. Warto zastosować trzy poprawki wydane tego samego dnia, 23 lipca 2026 r.: v0.12.3 dodaje narzędzie wiki_link, które rozwiązuje formy [[Document Name]], [[Name|Display]], z escapowaniem w tabelach [[Name\|Display]] oraz #fragment, zwracając treść notatki wraz z rozwiązaną ścieżką i ewentualnymi niejednoznacznymi alternatywami — prymityw pobierania danych, który pozwala agentowi podążać za własnym grafem linków sejfu zamiast wyszukiwać je ponownie — oraz wyklucza .trash/ z każdego narzędzia przez domyślny filtr ścieżek; v0.12.4 rozszerza wiki_link o linki kwalifikowane ścieżką, takie jak [[folder/Note]]; v0.12.2 zapobiega uszkadzaniu przez patch_note wstawek zawierających wzorce zastępowania $ i normalizuje ścieżki, które przypadkowo zawierają prefiks sejfu. Dwa ostrzeżenia o średnim poziomie ważności (GHSA-9c83-rr99-vfwj i GHSA-j99q-93c9-h869) zostały ujawnione dla listy blokowanych katalogów opartej na filtrze ścieżek; oba naprawiono na długo przed linią 0.12, w wersjach 0.11.4 i 0.11.5, więc każda wersja 0.12.x jest od nich wolna.13

Zmiana z kwietnia 2026 r. — Obsidian CLI jako preferowany most: Obsidian 1.12.0 wprowadził natywne CLI, a publiczny instalator 1.12.7 (23 marca 2026 r.) zawierał samodzielny binarny plik wykonywalny, TUI oraz usprawnienia pliku socket, które ułatwiły instalację i uruchamianie przepływów pracy w terminalu.16 Linia 1.13 dotarła do publicznego kanału jako 1.13.4 30 lipca 2026 r. — była to wersja dotycząca ustawień/obrazów/bezpieczeństwa URI, bez nowych możliwości AI ani automatyzacji poza powierzchnią CLI z wersji 1.12.x (wiersz changelogu wyjaśnia, co się zmieniło).2526 Narzędzia społecznościowe aktywnie migrują z wtyczki Local REST API (na której oparto mcp-obsidian) do integracji opartej na CLI, ponieważ jest szybsza i stabilniejsza. Repozytorium MarkusPfundstein/mcp-obsidian jest nadal utrzymywane — commity do maja 2026 r. dodały narzędzia, w tym search_by_tag i get_frontmatter — choć nie publikuje oznaczonych wersji (instalacja z przypiętego commita). Nadal opiera się na Local REST-API; w nowych konfiguracjach most CLI jest zwykle szybszy i stabilniejszy, dlatego warto wybrać go lub nowsze alternatywy społecznościowe wymienione niżej.20 Zalecaną konfigurację opisuje dalsza sekcja tego przewodnika „Obsidian CLI dla przepływów pracy AI”.

Serwer Autor Transport Wymaga wtyczki Kluczowa funkcja
obsidian-mcp (npm obsidian-mcp) StevenStavrakis STDIO Nie Lekki, oparty na plikach
mcp-obsidian MarkusPfundstein STDIO Local REST API Pełne CRUD sejfu przez REST oraz search_by_tag/get_frontmatteraktywnie utrzymywany (commity do maja 2026 r.); brak oznaczonych wersji, należy przypiąć commit20
obsidian-mcp-tools jacksteamdev STDIO Tak (wtyczka) Wyszukiwanie semantyczne + Templater
obsidian-claude-code-mcp iansinnott WebSocket Tak (wtyczka) Automatyczne wykrywanie dla Claude Code
obsidian-mcp-server (npm obsidian-mcp-server) cyanheads STDIO Local REST API Tagi, zarządzanie frontmatter — konfiguracja przez OBSIDIAN_API_KEY/OBSIDIAN_BASE_URL, a nie flagi CLI
Hybrid Search MCP społeczność STDIO Nie Serwer MCP do wyszukiwania BM25 + semantycznego + CLI. Utrzymywany przez społeczność; przed wdrożeniem należy zweryfikować najnowsze commity.

W przypadku szybkiego startu najprostszą opcją jest serwer oparty na plikach, który bezpośrednio odczytuje pliki .md. Należy uważać na kolizję nazw w npm: serwer oparty na plikach to npm obsidian-mcp (StevenStavrakis); npm obsidian-mcp-server to serwer cyanheads oparty na REST-API, który wymaga wtyczki Local REST API oraz klucza API — częsta pomyłka, przez którą użytkownicy otrzymują serwer, którego nie da się uruchomić:

npm install -g obsidian-mcp

Krok 3: Skonfiguruj narzędzie AI

Claude Code — zarejestruj serwer za pomocą claude mcp add (Claude Code przechowuje serwery MCP w ~/.claude.json dla zakresu użytkownika lub w .mcp.json projektu — nie w ~/.claude/settings.json, który po cichu ignoruje blok mcpServers):

# User scope (all your projects)
claude mcp add obsidian -s user -- npx -y obsidian-mcp@2 serve --vault notes=/absolute/path/to/your/vault

# Or project scope, shared with the repo (writes .mcp.json)
claude mcp add obsidian -s project -- npx -y obsidian-mcp@2 serve --vault notes=/absolute/path/to/your/vault

Codex CLI — dodaj do ~/.codex/config.toml:

[mcp_servers.obsidian]
command = "npx"
args = ["-y", "obsidian-mcp@2", "serve", "--vault", "notes=/absolute/path/to/your/vault"]

Cursor — dodaj do .cursor/mcp.json:

{
  "mcpServers": {
    "obsidian": {
      "command": "npx",
      "args": ["-y", "obsidian-mcp@2", "serve", "--vault", "notes=/absolute/path/to/your/vault"]
    }
  }
}

Krok 4: Uruchom pierwsze zapytanie

Otwórz narzędzie AI i zadaj pytanie, na które mogą odpowiedzieć notatki w sejfie:

Search my Obsidian vault for notes about [topic you wrote about]

Narzędzie AI wywołuje serwer MCP, który przeszukuje sejf i zwraca pasującą treść. Powinny pojawić się wyniki ze ścieżkami plików i trafnymi fragmentami.

Co Claude potrafi po połączeniu

Dokładne nazwy narzędzi różnią się zależnie od serwera, lecz podstawowy zakres możliwości jest spójny między implementacjami:

Możliwość Typowe narzędzie Co agent z nim robi
Przeszukiwanie sejfu obsidian_search / search Znajduje notatki pasujące do zapytania i zwraca uszeregowane fragmenty ze ścieżkami plików oraz wskazaniem źródła
Odczyt pełnej notatki obsidian_read_note / read_note Pobiera pełną treść notatki, gdy fragment z wyszukiwania nie wystarcza
Wyświetlanie i przeglądanie listy obsidian_list_notes / list_notes Przegląda notatki według folderu, tagu lub zakresu dat, gdy brak konkretnego zapytania
Pobieranie sformatowanego kontekstu obsidian_get_context Zwraca blok kontekstu dopasowany do tematu i ograniczony budżetem tokenów, gotowy do wstrzyknięcia do rozmowy

W praktyce Claude odpowiada na pytania na podstawie notatek ze wskazaniem źródeł, pobiera wcześniejsze decyzje i materiały referencyjne do sesji programowania oraz bada strukturę sejfu bez ładowania całych plików do kontekstu. Niektóre serwery społecznościowe udostępniają również operacje zapisu (tworzenie, dopisywanie, zarządzanie tagami i frontmatter); własny serwer zbudowany później w tym przewodniku jest celowo tylko do odczytu, a tworzenie notatek obsługują zamiast niego hooki.

Szczegółowe omówienia: Architektura serwera MCP dotycząca projektu narzędzi i uprawnień, Integracja z Claude Code dotycząca hooków i wzorca mostu, Integracja z Codex CLI oraz Cursor i inne narzędzia dla innych agentów.

Co właśnie zbudowano

Lokalna baza wiedzy została połączona z narzędziem AI za pomocą standardowego protokołu. Serwer MCP odczytuje pliki sejfu, wykonuje podstawowe wyszukiwanie i zwraca wyniki. To minimalna działająca wersja.

Czego ten szybki start NIE zapewnia: - Hybrid retrieval (wyszukiwanie BM25 + wektorowe + fuzja RRF) - Wyszukiwanie semantyczne oparte na embeddings - Filtrowanie poświadczeń - Indeksowanie przyrostowe - Automatyczne wstrzykiwanie kontekstu oparte na hookach

Pozostała część przewodnika opisuje budowę każdej z tych możliwości. Szybki start dowodzi słuszności koncepcji. Pełny potok zapewnia pobieranie danych o jakości produkcyjnej.


Obsidian CLI dla przepływów pracy AI

Obsidian 1.12 (luty 2026) wprowadził wbudowany interfejs wiersza poleceń, który otwiera nową płaszczyznę integracji dla przepływów pracy AI; pozostaje on aktualny w wersji 1.13.7 (linia 1.13 trafiła do kanału publicznego 30 lipca 2026; od tego czasu nie dodano nowych możliwości CLI).162526 CLI działa jak zdalne sterowanie interfejsem GUI Obsidian — Obsidian musi być uruchomiony (lub uruchomi się automatycznie przy pierwszym poleceniu). Należy go włączyć w Settings > General > Command line interface.

Dlaczego CLI ma znaczenie dla infrastruktury AI

CLI zapewnia programowy dostęp do natywnych operacji Obsidian, które wcześniej wymagały GUI lub APIs wtyczek. W przypadku przepływów pracy AI kluczowe możliwości obejmują:

  • Wyszukiwanie ze skryptów i hooków. obsidian search "query" oraz obsidian search:context "query" wykonują wyszukiwanie w vault z dowolnego skryptu powłoki, hooka lub potoku automatyzacji. Wariant search:context zwraca pasujące wiersze z otaczającym kontekstem, co przydaje się do przekazywania wyników do promptów AI.
  • Automatyzacja codziennych notatek. obsidian daily otwiera lub tworzy dzisiejszą codzienną notatkę. W połączeniu ze skryptami powłoki umożliwia to zautomatyzowane przepływy codziennych podsumowań — hook może dopisywać do codziennej notatki podsumowania wygenerowane przez AI.
  • Tworzenie notatek na podstawie szablonów. obsidian template list i obsidian template create generują notatki na podstawie szablonów Templater lub szablonów podstawowych, umożliwiając agentom AI tworzenie uporządkowanych wpisów w vault bez bezpośredniego zapisywania plików markdown.
  • Zarządzanie właściwościami. obsidian property set i obsidian property get odczytują i zapisują właściwości frontmatter, umożliwiając aktualizowanie metadanych ze skryptów bez analizowania YAML.
  • Sterowanie wtyczkami. obsidian plugin enable/disable/list umożliwia programowe zarządzanie wtyczkami, co przydaje się do przełączania wtyczek indeksujących podczas operacji wsadowych.
  • Zarządzanie zadaniami. obsidian task list/add/complete zapewnia uporządkowany dostęp do zadań, przydatny dla agentów AI zarządzających elementami pracy w vault.

CLI a MCP w dostępie AI

Serwery CLI i MCP pełnią różne role oraz wzajemnie się uzupełniają, a nie konkurują ze sobą:

Aspekt Obsidian CLI Serwer MCP
Wywołujący Skrypty powłoki, hooki, zadania cron Agenci AI (Claude Code, Codex, Cursor)
Protokół Proces POSIX (stdin/stdout/stderr) MCP (JSON-RPC przez STDIO lub HTTP)
Mocna strona Operacje natywne dla Obsidian (szablony, wtyczki, właściwości) Niestandardowe wyszukiwanie (embeddings, BM25, łączenie RRF)
Ograniczenie Brak wyszukiwania wektorowego i potoku embeddings Brak dostępu do wewnętrznych operacji Obsidian
Najlepsze zastosowanie Skrypty automatyzacji, potoki przyjmowania danych, akcje hooków Zapytania agentów AI w czasie rzeczywistym podczas sesji

Rekomendacja: Warto używać CLI do automatyzacji przyjmowania danych (tworzenie notatek, zarządzanie właściwościami, uruchamianie natywnego wyszukiwania Obsidian), a MCP do wyszukiwania (hybrid search z embeddings). Hook UserPromptSubmit może wywołać obsidian search:context jako szybkie sprawdzenie przed uruchomieniem bardziej obciążającego wyszukiwania hybrydowego (zdarzenia hooków o zakresie narzędzi nie mogą wstrzykiwać danych — ich stdout nigdy nie dociera do modelu).

Przykład: hook przyjmowania danych oparty na CLI

#!/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}"

Wtyczki agentów Obsidian

Rosnąca kategoria wtyczek Obsidian osadza agentów kodujących AI bezpośrednio w interfejsie vault, oferując alternatywę dla konfiguracji zewnętrznego serwera MCP. Wtyczki te uruchamiają agenta AI na pasku bocznym Obsidian, zamiast łączyć się z zewnętrznego narzędzia.

Claudian

Claudian osadza Claude Code jako współpracownika AI w vault. Katalog vault staje się katalogiem roboczym Claude, zapewniając mu pełne możliwości agentowe: odczyt i zapis plików, wyszukiwanie, polecenia Bash oraz wieloetapowe przepływy pracy.17

Kluczowe funkcje dla infrastruktury AI: - Prompty uwzględniające kontekst. Automatycznie dołącza aktywną notatkę, obsługuje wzmianki o plikach @notename, wykluczanie oparte na tagach oraz zaznaczenie w edytorze jako kontekst. - Obsługa Vision. Analizowanie obrazów przez przeciąganie i upuszczanie, wklejanie lub ścieżkę pliku — przydatne do przetwarzania zrzutów ekranu i diagramów zapisanych w vault. - Polecenia slash. Tworzenie wielokrotnego użytku szablonów promptów wywoływanych przez /command, umożliwiające standaryzowane operacje w vault. - Tryby uprawnień. Tryby YOLO (automatyczne zatwierdzanie), Safe (zatwierdzanie każdej akcji) i Plan (tylko planowanie), z bloklistą bezpieczeństwa oraz ograniczeniem do vault.

Agent Client

Agent Client łączy Claude Code, Codex CLI i Gemini CLI w jednolitym pasku bocznym Obsidian za pomocą Agent Client Protocol (ACP).18

Kluczowe funkcje: - Przełączanie między agentami. Możliwość rozmowy z Claude Code, Codex lub Gemini CLI z tego samego panelu oraz przełączania między agentami w razie potrzeby. - Wzmianki o notatkach. Użycie @notename w celu dołączenia zawartości notatek do promptów, podobnie jak w Claudian, ale niezależnie od agenta. - Wykonywanie poleceń powłoki. Wykonywanie poleceń terminala bezpośrednio na czacie — tworzenie skryptów, polecenia git lub dowolne operacje terminalowe bez opuszczania rozmowy. - Zatwierdzanie działań. Szczegółowa kontrola nad odczytem plików, edycjami i wykonywaniem poleceń.

Kiedy używać wtyczek agentów, a kiedy zewnętrznego MCP

Scenariusz Wtyczka agenta Zewnętrzny MCP
Pisanie i edytowanie notatek vault z pomocą AI Lepsza — agent widzi kontekst edytora Działa, ale bez świadomości edytora
Tworzenie oprogramowania w wielu repozytoriach Ograniczone — zakres vault Lepsze — zakres projektu z pełnym systemem plików
Wyszukiwanie w dużym zaindeksowanym korpusie Tylko podstawowe wyszukiwanie Pełny potok wyszukiwania hybrydowego
Szybkie pytania i odpowiedzi dotyczące vault podczas tworzenia notatek Idealne — bez przełączania kontekstu Wymaga przełączenia do terminala

Rekomendacja: Wtyczki agentów warto stosować do przepływów pracy skoncentrowanych na vault (pisanie, organizowanie i podsumowywanie notatek). Zewnętrzne serwery MCP sprawdzają się w przepływach pracy programistycznej, w których agent AI potrzebuje pełnego potoku wyszukiwania oraz dostępu do baz kodu poza vault. Oba podejścia mogą współistnieć — należy uruchomić Claudian wewnątrz Obsidian do pracy z notatkami oraz Claude Code z zewnętrznym MCP do programowania.


Schemat decyzyjny: Obsidian a alternatywy

Nie każdy przypadek użycia wymaga Obsidian. Ta sekcja pokazuje, kiedy Obsidian jest właściwą podstawą, kiedy jest rozwiązaniem nadmiarowym, a kiedy lepiej sprawdzi się coś innego.

Drzewo decyzyjne

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.

Macierz porównawcza

Kryterium Obsidian Notion Apple Notes Zwykły system plików CLAUDE.md
Local-first Tak Nie (chmura) Częściowo (iCloud) Tak Tak
Plaintext Tak (markdown) Nie (bloki) Nie (format własnościowy) Tak Tak
Struktura grafu Tak (wiki-linki) Częściowo (wzmianki) Nie Nie Nie
Indeksowalne przez AI Bezpośredni dostęp do plików Wymagane API Wymagany eksport Bezpośredni dostęp do plików Już w kontekście
Ekosystem wtyczek Ponad 2 500 wtyczek Integracje Brak Nie dotyczy Nie dotyczy
Praca offline Pełna Buforowane tylko do odczytu Częściowa Pełna Pełna
Skalowanie do ponad 10 tys. notatek Tak Tak (z API) Ulega pogorszeniu Tak Nie (pojedynczy plik)
Koszt Bezpłatnie (rdzeń) Od 10 USD/mies. Bezpłatnie Bezpłatnie Bezpłatnie

Kiedy Obsidian jest rozwiązaniem nadmiarowym

  • Kontekst pojedynczego projektu. Jeśli AI potrzebuje wyłącznie kontekstu dotyczącego bieżącej bazy kodu, należy umieścić go w CLAUDE.md, AGENTS.md albo dokumentacji na poziomie projektu. Te pliki podróżują razem z repozytorium i są ładowane automatycznie.
  • Dane strukturalne. Jeśli treścią są tabele, rekordy albo schematy, należy użyć bazy danych. Notatki Obsidian są przede wszystkim prozą. Dataview potrafi odpytywać pola frontmatter, ale prawdziwa baza danych lepiej obsługuje zapytania strukturalne.
  • Tymczasowe badania. Jeśli notatki zostaną wyrzucone po zakończeniu projektu, prostszy będzie katalog roboczy z plikami markdown. Nie należy budować infrastruktury retrieval dla treści efemerycznych.

Kiedy Obsidian jest właściwym wyborem

  • Gromadzenie wiedzy przez miesiące lub lata. Wartość narasta wraz ze wzrostem korpusu. Vault z 200 notatkami odpytywany codziennie przez sześć miesięcy daje więcej wartości niż vault z 5 000 notatek odpytany raz.
  • Wiele dziedzin w jednym korpusie. Vault zawierający notatki o programowaniu, architekturze, bezpieczeństwie, projektowaniu i projektach osobistych korzysta z retrieval międzydziedzinowego, którego projektowy CLAUDE.md nie jest w stanie zapewnić.
  • Treści wrażliwe pod względem prywatności. Local-first oznacza, że pipeline retrieval nigdy nie wysyła treści do usług zewnętrznych. Vault zawiera wszystko, co zostanie w nim umieszczone, w tym treści, których nie przesłano by do usługi chmurowej.

Model mentalny: trzy warstwy

System ma trzy warstwy, które działają niezależnie, ale po połączeniu wzmacniają swoje działanie. Każda warstwa odpowiada za inny obszar i ma inny tryb awarii.

┌─────────────────────────────────────────────────────┐
                 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 określa, co trafia do vault. Bez selekcji vault gromadzi szum: zrzuty ekranu tweetów, skopiowane artykuły bez adnotacji, niedokończone myśli bez kontekstu. Warstwa intake odpowiada za kontrolę jakości w punkcie wejścia. Pipeline scoringowy, konwencja tagowania albo proces ręcznego przeglądu — dowolny mechanizm, który zapewnia, że vault zawiera treści warte odzyskiwania.

Retrieval sprawia, że vault staje się odpytywalny. To silnik: dzielenie notatek na jednostki wyszukiwania, osadzanie fragmentów w przestrzeni wektorowej, indeksowanie pod kątem wyszukiwania słów kluczowych i wyszukiwania semantycznego, łączenie wyników za pomocą RRF. Warstwa retrieval przekształca katalog plików w odpytywalną bazę wiedzy. Bez tej warstwy vault można przeglądać ręcznie i przeszukiwać podstawowo, ale nie jest programowo dostępny dla narzędzi AI.

Integration łączy warstwę retrieval z narzędziami AI. Serwer MCP udostępnia retrieval jako narzędzie możliwe do wywołania. Hooki automatycznie wstrzykują kontekst. Skills zapisują nową wiedzę z powrotem do vault. Warstwa integration jest interfejsem między bazą wiedzy a agentami AI, którzy z niej korzystają.

Warstwy są celowo rozłączone. Pipeline scoringowy intake nie wie nic o embeddings. Retriever nie wie nic o regułach routingu sygnałów. Serwer MCP nie wie nic o tym, jak powstały notatki. To rozłączenie oznacza, że każdą warstwę można ulepszać niezależnie. Można wymienić model embedding bez zmieniania pipeline’u intake. Można dodać nową funkcję MCP bez modyfikowania retrievera. Można zmienić heurystyki oceny sygnałów bez dotykania indeksu.


Architektura skarbca pod kątem wykorzystania przez AI

Skarbiec zoptymalizowany pod pobieranie informacji przez AI kieruje się innymi konwencjami niż skarbiec zoptymalizowany pod osobiste przeglądanie. Ta sekcja omawia strukturę folderów, schemat notatek, konwencje frontmatter oraz konkretne wzorce poprawiające jakość pobierania.

Struktura folderów

W przypadku folderów najwyższego poziomu warto używać numerowanych prefiksów, aby utworzyć przewidywalną hierarchię organizacyjną. Numery nie oznaczają priorytetu — grupują powiązane domeny i ułatwiają szybkie odczytanie struktury.

vault/
├── 00-inbox/              # Unsorted captures, pending triage
├── 01-projects/           # Active project notes
├── 02-areas/              # Ongoing areas of responsibility
├── 03-resources/          # Reference material by topic
   ├── programming/
   ├── security/
   ├── ai-engineering/
   ├── design/
   └── devops/
├── 04-archive/            # Completed projects, old references
├── 05-signals/            # Scored signal intake
   ├── ai-tooling/
   ├── security/
   ├── systems/
   └── ...12 domain folders
├── 06-daily/              # Daily notes (if used)
├── 07-templates/          # Note templates (excluded from index)
├── 08-attachments/        # Images, PDFs (excluded from index)
├── .obsidian/             # Obsidian config (excluded from index)
└── .indexignore            # Paths to exclude from retrieval index

Foldery, które powinny być indeksowane: Wszystko, co zawiera prozę w markdown — projekty, obszary, zasoby, sygnały, notatki dzienne.

Foldery, które powinny być wyłączone z indeksowania: Templates (zawierają zmienne zastępcze, nie treść), attachments (pliki binarne), konfiguracja Obsidian oraz każdy folder zawierający wrażliwe treści, których nie należy umieszczać w indeksie pobierania.

Plik .indexignore

W katalogu głównym skarbca należy utworzyć plik .indexignore, aby jawnie wykluczyć ścieżki z indeksu pobierania. Składnia odpowiada .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/

Indexer odczytuje ten plik przed skanowaniem i całkowicie pomija pasujące ścieżki. Pliki w wykluczonych ścieżkach nigdy nie są dzielone na chunki, nigdy nie otrzymują embeddings i nigdy nie pojawiają się w wynikach wyszukiwania.

Schemat notatek

Każda notatka powinna mieć frontmatter YAML. Retriever używa pól frontmatter do filtrowania i wzbogacania kontekstu:

---
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
---

Pola wymagane do pobierania:

  • title — używane w wyświetlaniu wyników wyszukiwania oraz w kontekście nagłówków dla BM25
  • type — umożliwia zapytania filtrowane według typu („pokaż tylko MOC” albo „tylko sygnały”)
  • tags — indeksowane w kontekście nagłówków FTS5 z wagą 0,3, zapewniając dopasowania słów kluczowych nawet wtedy, gdy treść używa innej terminologii

Pola opcjonalne, ale wartościowe:

  • domain — umożliwia zapytania ograniczone do domeny („przeszukaj tylko notatki o bezpieczeństwie”)
  • source — atrybucja przechwyconych treści; retriever może uwzględniać źródłowe URL-e w wynikach
  • status — pozwala wykluczyć z aktywnego wyszukiwania notatki zarchiwizowane lub robocze

Konwencje chunking

Retriever dzieli treść na chunki na granicach nagłówków H2 (##). Oznacza to, że struktura notatki bezpośrednio wpływa na granularność pobierania:

Dobre pod kątem pobierania:

## 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...

Trzy sekcje H2 tworzą trzy niezależnie przeszukiwalne chunki. Każdy chunk ma wystarczająco dużo kontekstu, aby embedding uchwycił jego znaczenie. Zapytanie o „obsługę wygasłego tokenu” dopasowuje konkretnie trzeci chunk.

Słabe pod kątem pobierania:

# 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...

Jedna długa sekcja bez nagłówków H2 tworzy jeden duży chunk. Embedding uśrednia wszystkie tematy w sekcji. Zapytanie o dowolny podtemat dopasowuje całą notatkę w takim samym stopniu.

Praktyczna zasada: Jeśli sekcja obejmuje więcej niż jedno pojęcie, należy podzielić ją na podsekcje H2. Chunker zajmie się resztą.

Czego nie umieszczać w notatkach

Treści, które obniżają jakość pobierania:

  • Surowe wklejki całych artykułów bez adnotacji. Retriever indeksuje słowa kluczowe oryginalnego artykułu, rozcieńczając skarbiec treściami, których Pan/Pani nie napisał(a). Zamiast tego warto dodać podsumowanie, wyodrębnić kluczowe punkty albo podać link do źródłowego URL-a.
  • Zrzuty ekranu bez opisu tekstowego. Retriever indeksuje tekst markdown. Obraz bez tekstu alternatywnego albo otaczającego opisu jest niewidoczny zarówno dla BM25, jak i vector search.
  • Ciągi danych uwierzytelniających. Klucze API, tokeny, hasła, connection strings. Nawet przy filtrowaniu danych uwierzytelniających najbezpieczniej nigdy nie wklejać sekretów do notatek. Zamiast tego należy odwoływać się do nich nazwą („token Cloudflare API w ~/.env”).
  • Treści wygenerowane automatycznie bez kuracji. Jeśli narzędzie generuje notatkę (transkrypcję spotkania, wyróżnienia z Readwise, import RSS), przed włączeniem jej do stałego skarbca należy ją przejrzeć i opatrzyć adnotacjami. Niekuratowane automatyczne importy zwiększają objętość bez dodawania wartości możliwej do pobrania.

Ekosystem pluginów dla przepływów pracy AI

Pluginy Obsidian, które poprawiają jakość vaultu pod kątem wyszukiwania AI, dzielą się na trzy kategorie: strukturalne (wymuszają spójność), zapytań (udostępniają metadane) i synchronizacji (utrzymują aktualność vaultu).

Niezbędne pluginy

Dataview. Odpytuje vault jak bazę danych, korzystając z pól frontmatter. Pozwala tworzyć dynamiczne indeksy: „wszystkie notatki z tagiem security zaktualizowane w ostatnich 30 dniach” albo „wszystkie notatki projektowe ze statusem active”. Dataview nie pomaga bezpośrednio w wyszukiwaniu, ale ułatwia wykrywanie luk w pokryciu vaultu i znajdowanie notatek wymagających aktualizacji.

TABLE type, domain, updated
FROM "03-resources"
WHERE status = "active"
SORT updated DESC
LIMIT 20

Templater. Tworzy notatki z szablonów z polami dynamicznymi. Warto dopilnować, aby każda nowa notatka zaczynała się od poprawnego frontmatter, używając szablonu, który wstępnie wypełnia pola created, type i domain. Spójny frontmatter poprawia filtrowanie wyników wyszukiwania.

<%* /* 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

## References

Linter. Wymusza reguły formatowania w całym vaulcie. Spójna hierarchia nagłówków (H1 dla tytułu, H2 dla sekcji, H3 dla podsekcji) sprawia, że chunker daje przewidywalne wyniki. Reguły Linter istotne dla wyszukiwania:

  • Przyrost nagłówków: wymuszenie kolejnych poziomów nagłówków (bez przeskakiwania z H1 do H3)
  • Tytuł YAML: zgodny z nazwą pliku
  • Spacje końcowe: usuwanie (zapobiega artefaktom tokenizacji FTS5)
  • Kolejne puste wiersze: ograniczenie do 1 (czystsze fragmenty)

Integracja z Git. Kontrola wersji dla vaultu. Pozwala śledzić zmiany w czasie, synchronizować pracę między maszynami i odzyskiwać przypadkowo usunięte treści. Git dostarcza też dane mtime, których indexer używa do przyrostowego wykrywania zmian.

Pluginy wspierające indeksowanie

Smart Connections. Plugin Obsidian zapewniający semantyczne wyszukiwanie wspierane przez AI w samym Obsidian. Smart Connections v4 domyślnie tworzy lokalne embeddings — po zindeksowaniu vaultu połączenia semantyczne i wyszukiwanie działają całkowicie offline, bez wywołań API.11 v4.5.0 (5 maja 2026) przenosi połączenia w stopce do Smart Connections Core, więc każda instalacja może pokazywać połączenia z powiązanymi notatkami w stopce bez otwierania panelu bocznego. Ostatnie wydania v4 dodały też widoki grafowe dla list połączeń, konfigurowalne lokalizacje dokowania, lepsze odzyskiwanie block-embedding po przerwanych przebiegach indeksowania oraz „Substrate”, środowisko międzypluginowe pozwalające Smart Connections, Smart Chat i Smart Composer współdzielić stan.21 Chociaż system wyszukiwania w tym przewodniku jest zewnętrzny wobec Obsidian (działa jako pipeline Python), Smart Connections przydaje się do eksplorowania relacji semantycznych podczas pisania. Oba systemy indeksują tę samą treść, ale obsługują różne przypadki użycia: Smart Connections służy do odkrywania treści w edytorze, a zewnętrzny retriever do integracji narzędzi AI przez MCP.

Pluginy AI-native wydane w kwietniu 2026. Fala nowych pluginów społecznościowych celuje bezpośrednio w przepływ pracy Claude Code / Codex / Gemini-CLI:

Plugin Wydany Co robi
Cortex 4 kwietnia Agent vaultu zasilany przez Claude Code — traktuje vault jako przestrzeń roboczą agenta, a nie tylko magazyn notatek
VaultSearch 7 kwietnia Lokal-first hybrid search: BM25 + semantyczne + fuzzy (bezpośrednie pokrycie ze stosem wyszukiwania z tego przewodnika)
LLM Wiki 9 kwietnia Przekształca vault w prywatnie odpytywaną bazę wiedzy
Drift 11 kwietnia Przeglądarka różnic w stylu VS Code dla edycji Obsidian wspieranej przez AI; pozycjonowana pod przepływy pracy Claude Code
EngramQuest 11 kwietnia Generuje wyzwania pamięciowe z notatek; dostarcza „AI Skills” dla Claude Code / Gemini CLI / Cursor
Hybrid Search MCP marzec (nadal nowy) Serwer MCP + CLI z BM25 + wyszukiwaniem semantycznym — zbudowany specjalnie dla asystentów AI

Warto traktować to jako wyłaniający się obszar — kilka z tych rozwiązań prawdopodobnie skonsoliduje się albo zostanie wchłoniętych przez Smart Connections / rdzeń Obsidian w ciągu najbliższych kwartałów. Jeśli dziś trzeba wybrać jedno, VaultSearch i Hybrid Search MCP są filozoficznie najbliższe zewnętrznemu retrieverowi z tego przewodnika.

Uwaga o Dataview: Dataview (długo istniejący plugin zapytań dla Obsidian) ostatnio wydał wersję 0.5.70 w kwietniu 2025 roku i od tego czasu jest w praktyce uśpiony. Przy nowych pracach wbudowana funkcja Bases w Obsidian (1.9+) jest domyślnym następcą i zalecaną ścieżką.

Metadata Menu. Zapewnia strukturalną edycję frontmatter z autouzupełnianiem wartości pól. Zmniejsza liczbę literówek w polach type, domain i tags. Spójne metadane poprawiają dokładność filtrowania wyników wyszukiwania.

Pluginy szkodzące indeksowaniu

Excalidraw. Przechowuje rysunki jako JSON osadzone w plikach markdown. JSON jest składniowo poprawnym markdown, ale po podziale na fragmenty i utworzeniu embedding daje bezużyteczne wyniki. Należy wykluczyć pliki Excalidraw z indeksu przez .indexignore albo filtrować je po rozszerzeniu pliku.

Kanban. Przechowuje stan tablicy jako specjalnie sformatowany markdown. Format jest zaprojektowany do renderowania Kanban, a nie do wyszukiwania prozy. Chunker tworzy fragmenty tytułów kart i metadanych, które źle nadają się do embedding. Należy wykluczyć tablice Kanban z indeksu.

Calendar. Tworzy notatki dzienne z minimalną treścią (często tylko nagłówkiem z datą). Puste lub prawie puste notatki generują fragmenty niskiej jakości. Jeśli używa się notatek dziennych, należy wpisywać w nich treści merytoryczne albo wykluczyć folder notatek dziennych z indeksu.

Konfiguracja pluginów, która ma znaczenie

File recovery → Enabled. Chroni przed przypadkowym usunięciem notatki. Nie wiąże się bezpośrednio z wyszukiwaniem, ale jest krytyczne dla bazy wiedzy, na której można polegać.

Strict line breaks → Disabled. Standardowe dla markdown łamanie wierszy (podwójny znak nowego wiersza dla akapitu) tworzy czystsze fragmenty niż tryb strict w Obsidian (pojedynczy znak nowego wiersza dla <br>).

Default new file location → Designated folder. Kieruje nowe pliki do 00-inbox/, aby nieskategoryzowane notatki nie zanieczyszczały folderów domenowych. Inbox jest obszarem przejściowym; po selekcji pliki trafiają do folderów domenowych.

Wiki-link format → Shortest path when possible. Krótsze cele linków są łatwiejsze do rozwiązania przez retriever podczas indeksowania struktury linków.


Modele embeddingów: wybór i konfiguracja

Model embeddingów przekształca fragmenty tekstu w wektory liczbowe na potrzeby wyszukiwania semantycznego. Wybór modelu decyduje o jakości wyszukiwania, rozmiarze indeksu, szybkości tworzenia embeddingów i zależnościach uruchomieniowych. Ta sekcja wyjaśnia, dlaczego domyślnym wyborem jest Model2Vec potion-base-8M i kiedy warto wybrać alternatywy.

Dlaczego Model2Vec potion-base-8M

Model: minishlab/potion-base-8M Parametry: 7,6 miliona Wymiary: 256 Rozmiar: ~30 MB Zależności: model2vec (tylko numpy, bez PyTorch) Inferencja: tylko CPU, statyczne embeddingi słów (bez warstw attention)

Model2Vec destyluje wiedzę sentence transformera do statycznych embeddingów tokenów. Zamiast uruchamiać warstwy attention na danych wejściowych (jak robią to BERT, MiniLM i inne modele transformerowe), Model2Vec tworzy wektory przez ważone uśrednianie wstępnie obliczonych embeddingów tokenów.5 Praktyczna konsekwencja: tworzenie embeddingów jest 50-500 razy szybsze niż w modelach opartych na transformerach, ponieważ nie ma obliczeń sekwencyjnych.

Na aktualnej stronie wyników Model2Vec potion-base-8M osiąga około 92% łącznego wyniku all-MiniLM-L6-v2 dla wszystkich zadań (51,32 wobec 55,80), pozostając jednocześnie o rzędy wielkości szybszy.6 Pozostała różnica jakości to kompromis w zamian za szybkość i prostotę. W przypadku krótkich fragmentów markdown (średnio 200-400 słów w typowym vault) różnica jakości jest mniej widoczna niż w dłuższych dokumentach, ponieważ oba modele zbiegają się ku podobnym reprezentacjom krótkiego, skoncentrowanego tekstu.

Konfiguracja

# 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]

Leniwe ładowanie. Model ładuje się przy pierwszym użyciu, a nie w czasie importu. Import modułu embeddera nic nie kosztuje, gdy retriever działa w trybie awaryjnym tylko BM25 (np. gdy venv dla embeddingów nie jest zainstalowany).

Izolowane środowisko wirtualne. Model działa w dedykowanym venv (np. ~/.claude/venvs/memory/), aby uniknąć konfliktów zależności z resztą toolchainu. Funkcja _activate_venv() dodaje site-packages danego venv do sys.path w czasie działania.

# Create isolated venv
python3 -m venv ~/.claude/venvs/memory
~/.claude/venvs/memory/bin/pip install model2vec

Przetwarzanie wsadowe. Embedder przetwarza teksty w partiach po 64, aby zamortyzować narzut Model2Vec. Indexer przekazuje fragmenty do embed_batch(), zamiast tworzyć embedding dla każdego fragmentu osobno.

Kiedy wybrać alternatywy

Model Wym. Rozmiar Szybkość Jakość (MTEB) Najlepsze zastosowanie
potion-base-8M 256 30 MB 500x 51,32 Domyślnie: lokalnie, szybko, bez GPU
potion-base-32M 256 120 MB 400x 52,83 Wyższa jakość, nadal statyczny
potion-retrieval-32M 256 120 MB 400x 35,06 (retrieval) Statyczny model zoptymalizowany pod retrieval
potion-multilingual-128M 256 ~500 MB 300x Wielojęzyczne vaults (101 języków)
all-MiniLM-L6-v2 384 80 MB 1x 55,80 Wyższa jakość, nadal lokalnie
nomic-embed-text-v1.5 768 270 MB 0,5x 62,28 Najlepsza lokalna jakość
text-embedding-3-small 1536 API N/A 62,30 Oparte na API, najwyższa jakość

Proszę wybrać potion-base-32M, gdy potrzebna jest lepsza jakość niż w potion-base-8M bez opuszczania rodziny statycznych embeddingów. Model używa większego słownika destylowanego z baai/bge-base-en-v1.5, osiągając łączny wynik dla wszystkich zadań 52,83 (około 3% wyżej niż potion-base-8M), przy zachowaniu tego samego 256-wymiarowego wyjścia i zależności wyłącznie od numpy.8 Plik modelu większy 4 razy zwiększa zużycie pamięci, ale szybkość tworzenia embeddingów nadal pozostaje o rzędy wielkości wyższa niż w modelach transformerowych.

Proszę wybrać potion-retrieval-32M, gdy głównym przypadkiem użycia jest retrieval (czyli dokładnie wyszukiwanie w vault). Ten wariant jest dostrajany z potion-base-32M specjalnie pod zadania retrieval i uzyskuje 35,06 w tabeli benchmarków retrieval Model2Vec wobec 32,67 dla potion-base-32M.8 Kompromis polega na tym, że model jest zoptymalizowany pod retrieval, a nie pod ogólną jakość embeddingów.

Proszę wybrać potion-multilingual-128M, gdy vault zawiera notatki w wielu językach. Wydany w maju 2025 roku model obsługujący 101 języków jest najlepiej działającym statycznym modelem embeddingów do zadań wielojęzycznych: generuje embeddingi dla dowolnego tekstu w dowolnym języku, zachowując tę samą zależność wyłącznie od numpy co inne modele potion.12 Większy plik modelu (~500 MB) jest kompromisem za możliwości międzyjęzykowe. Warto go użyć, gdy obok treści po angielsku występują notatki po japońsku, chińsku, niemiecku lub w innych językach.

Proszę wybrać all-MiniLM-L6-v2, gdy jakość wyszukiwania jest ważniejsza niż szybkość i PyTorch jest zainstalowany. Wektory 384-wymiarowe zwiększają rozmiar bazy SQLite o ~50% w porównaniu z wektorami 256-wymiarowymi. Szybkość tworzenia embeddingów spada z <1 minuty do ~10 minut przy pełnym reindeksowaniu 15 000 plików na sprzęcie z serii M.

Proszę wybrać nomic-embed-text-v1.5, gdy potrzebna jest najlepsza możliwa lokalna jakość retrieval i akceptowalne jest wolniejsze indeksowanie. Wektory 768-wymiarowe mniej więcej potrajają rozmiar bazy danych. Wymaga PyTorch oraz nowoczesnego CPU lub GPU.

Proszę wybrać text-embedding-3-small, gdy opóźnienia sieciowe i prywatność są akceptowalnymi kompromisami. API tworzy embeddingi najwyższej jakości, ale wprowadza zależność od chmury, koszt za token (0,02 USD za milion tokenów) i wysyła treść na serwery OpenAI.

W pozostałych przypadkach warto pozostać przy potion-base-8M. Przewaga szybkości jest krytyczna przy iteracyjnym indeksowaniu (reindeksowanie podczas developmentu), zależność wyłącznie od numpy pozwala uniknąć złożoności instalacji PyTorch, a wektory 256-wymiarowe utrzymują bazę danych w kompaktowym rozmiarze.

Kwantyzacja i redukcja wymiarowości

Model2Vec v0.5.0+ obsługuje ładowanie modeli ze zmniejszoną precyzją i liczbą wymiarów.8 Jest to przydatne przy wdrożeniach na ograniczonym sprzęcie albo zmniejszaniu rozmiaru bazy danych bez zmiany modelu:

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)

Modele kwantyzowane zachowują niemal identyczną jakość retrieval przy ułamku zajętości pamięci. Redukcja wymiarowości działa zgodnie ze stylem Matryoshka — pierwsze N wymiarów przenosi najwięcej informacji. Zmniejszenie z 256 do 128 wymiarów zmniejsza o połowę miejsce potrzebne na wektory, przy minimalnej utracie jakości w retrieval krótkich tekstów.

Model2Vec v0.8.x aktualizuje wewnętrzne mechanizmy tokenizera i trwałego zapisu, wycofuje wsparcie dla Python 3.9 oraz odświeża opublikowane wyniki do nowszych tabel MTEB. Przed aktualizacją produkcyjnego indexera należy przypiąć albo przetestować model2vec, ponieważ aktualizacje biblioteki mogą zmienić ścieżki ładowania modeli, nawet jeśli nazwa modelu embeddingów pozostaje taka sama.10

Fine-tuning embeddingów pod konkretny vault

Model2Vec v0.4.0+ obsługuje trenowanie niestandardowych modeli klasyfikacyjnych na statycznych embeddingach, v0.7.0 dodaje kwantyzację słownika i konfigurowalne pooling do destylacji, a v0.8.x refaktoryzuje zachowanie tokenizera i trwałego zapisu.10 Ma to znaczenie dla vaults ze specjalistycznym słownictwem (notatki medyczne, odniesienia prawne, żargon domenowy), gdzie domyślne modele potion mogą nie uchwycić niuansów semantycznych:

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")

W większości vaults domyślny potion-base-8M zapewnia wystarczającą jakość retrieval. Fine-tuning ma sens tylko wtedy, gdy retrieval konsekwentnie pomija połączenia specyficzne dla danej domeny, których model ogólnego przeznaczenia nie potrafi uchwycić.

Śledzenie hasha modelu

Indexer przechowuje hash wyprowadzony z nazwy modelu i rozmiaru słownika. Po zmianie modelu embeddingów indexer wykrywa niezgodność przy następnym przebiegu przyrostowym i automatycznie uruchamia pełne reindeksowanie.

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]

Zapobiega to mieszaniu wektorów z różnych modeli w tej samej bazie danych, co dawałoby nonsensowne wyniki cosine similarity.

Tryby awarii

Błąd pobierania modelu. Pierwsze uruchomienie pobiera model z Hugging Face. Jeśli pobieranie się nie powiedzie (problem z siecią, firmowy firewall), retriever przechodzi w tryb tylko BM25. Po pierwszym pobraniu model jest cache’owany lokalnie.

Niezgodność wymiarów. Jeśli model zostanie zmieniony bez wyczyszczenia bazy danych, zapisane wektory będą miały inną liczbę wymiarów niż nowe embeddingi. Indexer wykrywa to przez hash modelu i uruchamia pełne reindeksowanie. Jeśli sprawdzenie hasha się nie powiedzie (niestandardowy model bez poprawnego hasha), sqlite-vec zgłosi błąd przy zapytaniach KNN z niedopasowanymi wymiarami.

Presja pamięci przy dużych vaults. Tworzenie embeddingów dla ponad 50 000 fragmentów w jednej partii może zużywać dużo pamięci. Indexer przetwarza dane w partiach po 64, aby ograniczyć szczytowe zużycie pamięci. Jeśli pamięć nadal stanowi problem, należy zmniejszyć rozmiar partii.


Wyszukiwanie pełnotekstowe z FTS5

Rozszerzenie FTS5 w SQLite zapewnia wyszukiwanie pełnotekstowe z rankingiem BM25. FTS5 jest komponentem wyszukiwania słów kluczowych w pipeline wyszukiwania hybrydowego. Ta sekcja omawia konfigurację FTS5, sytuacje, w których BM25 sprawdza się najlepiej, oraz jego konkretne tryby awarii.

Tabela wirtualna FTS5

CREATE VIRTUAL TABLE chunks_fts USING fts5(
    chunk_text,
    section,
    heading_context,
    content=chunks,
    content_rowid=id
);

Tryb synchronizacji treści. Parametr content=chunks informuje FTS5, aby odwoływał się bezpośrednio do tabeli chunks, zamiast przechowywać zduplikowaną kopię tekstu. Zmniejsza to wymagania dotyczące pamięci masowej o połowę, ale oznacza, że FTS5 musi być synchronizowany ręcznie po wstawieniu, zaktualizowaniu lub usunięciu chunków.

Kolumny. Indeksowane są 3 kolumny: - chunk_text — Główna treść każdego chunka (waga BM25: 1,0) - section — Tekst nagłówka H2 (waga BM25: 0,5) - heading_context — Tytuł notatki, tagi i metadata (waga BM25: 0,3)

Ranking BM25

BM25 szereguje dokumenty według częstotliwości termów, odwrotnej częstotliwości dokumentów oraz normalizacji długości dokumentu. Funkcja pomocnicza bm25() w FTS5 przyjmuje wagi dla poszczególnych kolumn:

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;

Wagi kolumn (1,0, 0,5, 0,3) oznaczają: - Dopasowanie słowa kluczowego w chunk_text wnosi największy wkład do wyniku - Dopasowanie w section (nagłówku) wnosi o połowę mniejszy wkład - Dopasowanie w heading_context (tytule, tagach) wnosi 30% tego wkładu

Te wagi można dostrajać. Jeśli vault zawiera opisowe nagłówki, które silnie przewidują jakość treści, należy zwiększyć wagę section. Jeśli tagi są kompletne i dokładne, należy zwiększyć wagę heading_context.

Kiedy BM25 wygrywa

BM25 świetnie sprawdza się w zapytaniach zawierających dokładne identyfikatory:

  • Nazwy funkcji: _rrf_fuse, embed_batch, get_stale_files
  • Flagi CLI: --incremental, --vault, --model
  • Klucze konfiguracji: bm25_weight, max_tokens, batch_size
  • Komunikaty błędów: SQLITE_LOCKED, ConnectionRefusedError
  • Konkretne terminy specjalistyczne: PostToolUse, PreToolUse, AGENTS.md

W przypadku takich zapytań BM25 natychmiast znajduje dokładne dopasowanie. Wyszukiwanie wektorowe zwróciłoby semantycznie powiązaną treść, ale mogłoby umieścić dokładne dopasowanie niżej niż omówienie koncepcyjne.

Kiedy BM25 zawodzi

BM25 zawodzi przy zapytaniach, które używają innej terminologii niż przechowywana treść:

  • Zapytanie: „how to handle authentication failures” → Vault zawiera notatki o „login error recovery” i „session expiration handling”. BM25 nie znajduje dopasowania, ponieważ słowa kluczowe się różnią.
  • Zapytanie: „what is the best way to manage state” → Vault zawiera notatki o „Redux store patterns” i „context providers”. BM25 pomija je, ponieważ „state management” jest wyrażone przez nazwy konkretnych technologii.

BM25 zawodzi również przy kolizji słów kluczowych w dużej skali. W vaulcie obejmującym 15 000 plików wyszukiwanie słowa „configuration” dopasowuje setki notatek, ponieważ prawie każda notatka projektowa wspomina o konfiguracji. Wyniki są technicznie poprawne, ale praktycznie bezużyteczne — ranking nie jest w stanie określić, która notatka o „configuration” jest istotna dla bieżącego zapytania.

Tokenizer FTS5

FTS5 domyślnie używa tokenizera unicode61, który obsługuje tekst ASCII i Unicode. W przypadku vaultów ze znaczną ilością treści CJK (chińskich, japońskich, koreańskich) warto rozważyć tokenizer trigram:

-- For CJK-heavy vaults
CREATE VIRTUAL TABLE chunks_fts USING fts5(
    chunk_text, section, heading_context,
    content=chunks, content_rowid=id,
    tokenize='trigram'
);

Domyślny tokenizer unicode61 dzieli tekst na granicach słów, co działa słabo w językach, w których między wyrazami nie ma spacji. Tokenizer trigram dzieli tekst co 3 znaki, umożliwiając dopasowywanie podciągów kosztem rozmiaru indeksu (około 3 razy większego).

Utrzymanie

FTS5 wymaga jawnej synchronizacji, gdy zmienia się bazowa tabela chunks:

# After inserting chunks
cursor.execute("""
    INSERT INTO chunks_fts(chunks_fts)
    VALUES('rebuild')
""")

Polecenie rebuild rekonstruuje indeks FTS5 na podstawie tabeli treści. Należy uruchamiać je po operacjach masowego wstawiania (pełne ponowne indeksowanie), ale nie po pojedynczych aktualizacjach przyrostowych — w ich przypadku należy użyć INSERT INTO chunks_fts(rowid, chunk_text, section, heading_context), aby zsynchronizować pojedyncze wiersze.

Wyszukiwanie wektorowe z sqlite-vec

Rozszerzenie sqlite-vec wprowadza wyszukiwanie wektorowe KNN (K-Nearest Neighbors) do SQLite. Ta sekcja omawia konfigurację sqlite-vec, pipeline embedding od notatki do przeszukiwalnego wektora oraz konkretne wzorce zapytań.

Tabela wirtualna sqlite-vec

CREATE VIRTUAL TABLE chunk_vecs USING vec0(
    id INTEGER PRIMARY KEY,
    embedding float[256]
);

Moduł vec0 przechowuje 256-wymiarowe wektory float jako spakowane dane binarne. Kolumna id mapuje się 1:1 na tabelę chunks, umożliwiając złączenia między wynikami wektorowymi a metadanymi fragmentów.

Pipeline embedding

Pipeline przepływa od notatki do przeszukiwalnego wektora:

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

Serializacja wektorów

Moduł struct w Python serializuje wektory float do przechowywania w sqlite-vec:

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))

Zapytanie KNN

Zapytanie wyszukiwania wektorowego tworzy embedding zapytania wejściowego, a następnie znajduje K najbliższych fragmentów według odległości cosinusowej:

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

Operator MATCH w sqlite-vec wykonuje wyszukiwanie przybliżonych najbliższych sąsiadów. Parametr k kontroluje liczbę zwracanych wyników. Kolumna distance zawiera odległość cosinusową (0 = identyczne, 2 = przeciwne).

Paginacja KNN z ograniczeniami odległości

Od sqlite-vec v0.1.7 zapytania KNN obsługują ograniczenia WHERE distance < ?, co umożliwia paginację opartą na kursorze przez duże zbiory wyników bez ponownego skanowania wcześniejszych stron.14 Późniejsze stabilne wydania v0.1.8 i v0.1.9 dotyczą pakietowania oraz poprawek błędów DELETE, a nie nowego modelu zapytań, dlatego v0.1.7 pozostaje granicą funkcji dla tego wzorca paginacji.23

Na horyzoncie linia v0.1.10-alpha (31 marca – 18 maja 2026) jako pierwsza wyprowadza sqlite-vec poza brute-force KNN: wprowadza typy indeksów approximate-nearest-neighbor — rescore, eksperymentalny indeks ivf (inverted-file), który nie jest domyślnie włączony, oraz dyskowy indeks DiskANN dla skarbców zbyt dużych, aby utrzymywać wektory w pamięci.23 Zmieniłoby to historię skalowania dla bardzo dużych skarbców, ale linia 0.1.10 nadal jest pre-release (alpha) — indeksowanie ANN należy traktować jako eksperymentalne i dla skarbców produkcyjnych nadal budować na stabilnej ścieżce brute-force KNN z v0.1.9, dopóki nie ukaże się stabilne 0.1.10.

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

Zastępuje to wcześniejszy wzorzec pobierania dużego k i wycinania wyników w Python, zmniejszając użycie pamięci przy eksploracyjnych zapytaniach w dużych skarbcach.

Obsługa DELETE w tabelach vec0

sqlite-vec v0.1.7 dodał natywną obsługę DELETE dla tabel wirtualnych vec0, a v0.1.9 naprawił ścieżkę błędu DELETE związaną z tekstowymi kolumnami metadanych dłuższymi niż 12 znaków.1423 Wcześniej usuwanie wektorów wymagało usunięcia i ponownego utworzenia tabeli. Teraz ścieżka usuwania plików w indekserze może usuwać wektory bezpośrednio:

# 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])

Upraszcza to przyrostową ponowną indeksację po usunięciu lub przeniesieniu notatek. Indekser nie musi już utrzymywać pomocniczej tabeli „aktywnych ID” ani wykonywać przebudów wsadowych.

Kiedy wyszukiwanie wektorowe wygrywa

Wyszukiwanie wektorowe sprawdza się przy zapytaniach, w których ważniejsze jest pojęcie niż konkretne słowa:

  • Zapytanie: „how to handle authentication failures” → znajduje notatki o „login error recovery” (ta sama przestrzeń semantyczna, inne słowa kluczowe)
  • Zapytanie: „what patterns exist for caching” → znajduje notatki o „memoization”, „Redis TTL strategies” i „HTTP cache headers” (powiązane pojęcia, zróżnicowana terminologia)
  • Zapytanie: „approaches to testing asynchronous code” → znajduje notatki o „pytest-asyncio fixtures”, „mock event loops” i „async test patterns” (to samo pojęcie wyrażone przez szczegóły implementacyjne)

Kiedy wyszukiwanie wektorowe zawodzi

Wyszukiwanie wektorowe ma trudności z dokładnymi identyfikatorami:

  • Zapytanie: _rrf_fuse → zwraca notatki o „fusion algorithms” i „rank merging”, ale może umieścić właściwą definicję funkcji niżej niż dyskusje koncepcyjne
  • Zapytanie: PostToolUse → zwraca notatki o „tool lifecycle hooks” i „post-execution handlers”, zamiast konkretnej nazwy hooka

Wyszukiwanie wektorowe ma też trudności ze structured data. Pliki konfiguracyjne JSON, bloki YAML i fragmenty kodu tworzą embeddings, które wychwytują wzorce strukturalne, a nie znaczenie semantyczne. Plik JSON z "review": true osadza się inaczej niż prozatorska dyskusja o code review.

Łagodna degradacja

Jeśli sqlite-vec nie uda się załadować (brakujące rozszerzenie, niezgodna platforma, uszkodzona biblioteka), retriever przechodzi awaryjnie na wyszukiwanie wyłącznie BM25:

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

Retriever sprawdza vec_available przed próbą wykonania zapytań wektorowych. Gdy funkcja jest wyłączona, wszystkie wyszukiwania używają wyłącznie BM25, a krok RRF fusion jest pomijany.


Reciprocal Rank Fusion (RRF)

RRF scala dwie listy rankingowe bez konieczności kalibracji wyników. Ta sekcja omawia algorytm, prześledzony przykład zapytania, dostrajanie parametru k oraz powody wyboru RRF zamiast alternatyw. Interaktywny kalkulator z edytowalnymi pozycjami rankingowymi, presetami scenariuszy i wizualnym eksploratorem architektury znajduje się w sekcji szczegółowe omówienie hybrid retriever.

Algorytm

RRF przypisuje każdemu dokumentowi wynik wyłącznie na podstawie jego pozycji rankingowej na każdej liście:

score(d) = Σ (weight_i / (k + rank_i))

Gdzie: - k to stała wygładzania (60, zgodnie z Cormack et al.3) - rank_i to 1-indeksowana pozycja dokumentu na liście wyników i - weight_i to opcjonalny mnożnik dla danej listy (domyślnie 1.0)

Dokumenty, które zajmują wysokie miejsca na wielu listach, otrzymują wyższe wyniki po scaleniu. Dokumenty występujące tylko na jednej liście otrzymują wynik z tego jednego źródła.

Dlaczego RRF zamiast alternatyw

Ważona kombinacja liniowa wymaga kalibracji wyników BM25 względem odległości cosine. Wyniki BM25 są nieograniczone i skalują się wraz z rozmiarem korpusu. Odległości cosine są ograniczone do zakresu [0, 2]. Ich łączenie wymaga normalizacji, a parametry normalizacji zależą od zbioru danych. RRF korzysta wyłącznie z pozycji rankingowych, które zawsze są liczbami całkowitymi zaczynającymi się od 1, niezależnie od metody punktacji.

Wyuczone modele fuzji wymagają oznaczonych danych treningowych — par zapytanie-dokument określających trafność. W osobistej bazie wiedzy takie dane treningowe nie istnieją. Aby wytrenować użyteczny model, należałoby ręcznie ocenić setki par zapytanie-dokument. RRF działa bez jakichkolwiek danych treningowych.

Metody głosowania Condorceta (Borda count, Schulze method) są teoretycznie eleganckie, ale trudniejsze do wdrożenia i dostrojenia. Oryginalna praca o RRF pokazała, że RRF przewyższa metody Condorceta na danych ewaluacyjnych TREC.3

Fuzja w praktyce

Zapytanie: „how does the review aggregator handle disagreements”

BM25 umieszcza review-aggregator.py na pozycji 3 (dokładne dopasowania słów kluczowych „review”, „aggregator”, „disagreements”), ale wyżej umieszcza dwa pliki konfiguracyjne (mocniej dopasowują „review”). Wyszukiwanie wektorowe umieszcza ten sam chunk na pozycji 1 (dopasowanie semantyczne do rozwiązywania konfliktów). Po fuzji RRF:

Chunk BM25 Vec Wynik po scaleniu
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

Chunki zajmujące wysokie miejsca na obu listach wypływają na górę. Chunki występujące tylko na jednej liście otrzymują wynik z jednego źródła i spadają poniżej wyników sklasyfikowanych w obu rankingach. Rzeczywista logika rozwiązywania niezgodności wygrywa, ponieważ odnalazły ją obie metody — BM25 przez słowa kluczowe, a wyszukiwanie wektorowe przez semantykę.

Pełny ślad krok po kroku z obliczeniami RRF dla każdej pozycji można przeanalizować, testując różne wartości k w interaktywnym kalkulatorze RRF.

Implementacja

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

Dostrajanie k

Stała k kontroluje, ile wagi otrzymują najwyżej sklasyfikowane wyniki względem wyników z niższych pozycji:

  • Niższe k (np. 10): Wyniki z najwyższych pozycji dominują. Pozycja 1 daje wynik 1/11 = 0,091, pozycja 10 daje 1/20 = 0,050 (różnica 1,8x). Dobre rozwiązanie, gdy można ufać pojedynczym rankerom, że poprawnie wybiorą najlepszy wynik.
  • Domyślne k (60): Zrównoważone. Pozycja 1 daje wynik 1/61 = 0,0164, pozycja 10 daje 1/70 = 0,0143 (różnica 1,15x). Różnice między pozycjami są skompresowane, dzięki czemu większe znaczenie ma występowanie na wielu listach.
  • Wyższe k (np. 200): Występowanie na obu listach ma znacznie większe znaczenie niż sama pozycja rankingowa. Pozycja 1 daje 1/201, pozycja 10 daje 1/210 — niemal identycznie. Warto użyć, gdy pojedyncze rankery tworzą zaszumione rankingi, ale zgodność między listami jest wiarygodna.

Proszę zacząć od k=60. Oryginalna praca o RRF wykazała, że ta wartość jest odporna na zróżnicowanych zbiorach danych TREC. Dostrajanie warto przeprowadzać dopiero po zmierzeniu przypadków niepowodzeń na własnym rozkładzie zapytań.

Rozstrzyganie remisów

Gdy dwa chunki mają identyczne wyniki RRF (rzadkie, ale możliwe przy tej samej pozycji na jednej liście i braku wystąpienia na drugiej), remisy należy rozstrzygać tak:

  1. Preferować chunki występujące na obu listach względem chunków występujących tylko na jednej
  2. Wśród chunków z obu list preferować ten z niższą łączną pozycją rankingową
  3. Wśród chunków tylko z jednej listy preferować ten z niższą pozycją na tej liście

Pełny pipeline retrieval

Ta sekcja śledzi zapytanie od wejścia do wyjścia przez cały pipeline: wyszukiwanie BM25, wyszukiwanie wektorowe, fuzję RRF, przycinanie budżetu tokenów i składanie kontekstu.

Przepływ end-to-end

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

Całkowite opóźnienie: ~23ms dla bazy danych obejmującej 49 746 chunków na sprzęcie Apple M3 Pro.

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

Przycinanie budżetu tokenów

Parametr max_tokens zapobiega zwracaniu przez retriever większej ilości kontekstu, niż narzędzie AI może wykorzystać. Szacunek przyjmuje 4 znaki na token (rozsądne przybliżenie dla prozy angielskiej). Wyniki są przycinane zachłannie: dodaje się je w kolejności rankingu, aż budżet zostanie wyczerpany.

To strategia konserwatywna. Bardziej zaawansowane podejście uwzględniałoby oceny jakości poszczególnych wyników i preferowało krótsze wyniki wyższej jakości zamiast dłuższych wyników niższej jakości. Podejście zachłanne jest prostsze i w praktyce działa dobrze, ponieważ ranking RRF już porządkuje wyniki według trafności.

Schemat bazy danych (pełny)

-- 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
);

Ścieżka łagodnej degradacji

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

Retriever sprawdza możliwości podczas inicjalizacji i dostosowuje strategię zapytań. Brakujący komponent obniża jakość, ale nie powoduje błędów. Jedyną awarią krytyczną jest brak pliku bazy danych.

Statystyki produkcyjne

Pomiar wykonano na skarbcu zawierającym 16 894 pliki, 49 746 chunków, bazę SQLite o rozmiarze 83 MB, Apple M3 Pro:

Metryka Wartość
Łączna liczba plików 16 894
Łączna liczba chunków 49 746
Rozmiar bazy danych 83 MB
Opóźnienie zapytania BM25 (p50) 12ms
Opóźnienie zapytania wektorowego (p50) 8ms
Opóźnienie fuzji RRF 3ms
Opóźnienie wyszukiwania end-to-end (p50) 23ms
Czas pełnego ponownego indeksowania ~4 minuty
Czas przyrostowego ponownego indeksowania <10 sekund
Model embeddings potion-base-8M (256-dim)
Pula kandydatów BM25 30
Pula kandydatów wektorowych 30
Domyślny limit wyników 10
Domyślny budżet tokenów 4 000 tokenów

Hashowanie treści i wykrywanie zmian

Indexer musi wiedzieć, które pliki zmieniły się od ostatniego uruchomienia indeksowania. Ta sekcja omawia mechanizm wykrywania zmian oraz strategię hashowania.

Porównanie czasu modyfikacji pliku

Indexer przechowuje mtime_ns (czas modyfikacji pliku w nanosekundach) dla każdego chunka w tabeli chunks. Podczas uruchomienia przyrostowego indexer:

  1. Skanuje skarbiec w poszukiwaniu wszystkich plików .md w dozwolonych folderach
  2. Odczytuje mtime_ns każdego pliku z systemu plików
  3. Porównuje tę wartość z mtime_ns zapisanym w bazie danych
  4. Identyfikuje 3 kategorie:
  5. Nowe pliki: ścieżka istnieje w systemie plików, ale nie w bazie danych
  6. Zmienione pliki: ścieżka istnieje w obu miejscach, ale mtime_ns jest inny
  7. Usunięte pliki: ścieżka istnieje w bazie danych, ale nie w systemie plików
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)

Dlaczego mtime, a nie hash treści

Hashowanie treści (SHA-256 zawartości pliku) byłoby bardziej niezawodne niż porównywanie mtime — wykrywałoby przypadki, w których plik został dotknięty bez zmiany treści (np. git checkout przywracający oryginalny mtime). Hashowanie wymaga jednak odczytania każdego pliku przy każdym uruchomieniu przyrostowym. Dla 16 894 plików odczyt zawartości zajmuje 2-3 sekundy. Odczyt mtimes z systemu plików zajmuje <100ms.

Kompromis: porównanie mtime czasami uruchamia niepotrzebne ponowne indeksowanie niezmienionych plików (wyniki fałszywie dodatnie), ale nigdy nie pomija rzeczywistych zmian. Wyniki fałszywie dodatnie kosztują kilka dodatkowych wywołań embeddings na uruchomienie. Różnica szybkości (100ms vs 3 sekundy) sprawia, że mtime jest pragmatycznym wyborem dla systemu uruchamianego przy każdej interakcji z AI.

Obsługa usunięć

Gdy plik zostanie usunięty ze skarbca, indexer usuwa wszystkie jego chunki z bazy danych:

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],
    )

Instrukcja DELETE FROM chunk_vecs działa natywnie od sqlite-vec v0.1.7, z poprawką błędu w v0.1.9 dotyczącą operacji DELETE na tabelach vec0 z dłuższymi kolumnami tekstowymi metadanych.1423 Wcześniejsze wersje wymagały obejść (usunięcia i ponownego utworzenia tabeli wirtualnej albo utrzymywania zewnętrznego zestawu „aktywnych ID”). Jeśli używana jest wersja starsza niż 0.1.9, należy przeprowadzić aktualizację przed poleganiem na bezpośrednim usuwaniu w schematach intensywnie wykorzystujących metadane.

Tabele synchronizacji treści FTS5 wymagają jawnego usunięcia przez INSERT INTO chunks_fts(chunks_fts, rowid, ...) VALUES('delete', ?, ...) dla każdego usuwanego wiersza. Indexer obsługuje to jako część procesu usuwania pliku.


Reindeksowanie incremental vs full

Indekser obsługuje 2 tryby: incremental (szybki, do codziennego użycia) oraz full (wolny, okazjonalny). Ta sekcja wyjaśnia, kiedy używać każdego z nich, jakie są gwarancje idempotencji oraz jak odzyskać stan po uszkodzeniu danych.

Reindeksowanie incremental

Kiedy używać: Codzienne indeksowanie po edycji notatek. Jest to tryb domyślny.

Co robi: 1. Skanuje vault pod kątem zmian w plikach (porównanie mtime) 2. Usuwa fragmenty dla skasowanych plików 3. Ponownie dzieli na fragmenty i ponownie tworzy embeddings dla zmienionych plików 4. Wstawia nowe fragmenty dla nowych plików 5. Synchronizuje indeks FTS5

Typowy czas trwania: <10 sekund dla dziennych edycji w vault zawierającym 16 000 plików.

python index_vault.py --incremental

Reindeksowanie full

Kiedy używać: - Po zmianie modelu embeddings (wykryto niezgodność hash modelu) - Po migracji schematu (nowe kolumny, zmienione indeksy) - Po uszkodzeniu bazy danych (kontrola integralności kończy się niepowodzeniem) - Gdy indeksowanie incremental daje nieoczekiwane wyniki

Co robi: 1. Usuwa wszystkie istniejące dane (fragmenty, wektory, wpisy FTS5) 2. Skanuje cały vault 3. Dzieli wszystkie pliki na fragmenty 4. Tworzy embeddings dla wszystkich fragmentów 5. Buduje indeks FTS5 od zera

Typowy czas trwania: ~4 minuty dla 16 894 plików na Apple M3 Pro.

python index_vault.py --full

Idempotencja

Oba tryby są idempotentne: dwukrotne uruchomienie tego samego polecenia daje ten sam wynik. Przed wstawieniem nowych fragmentów indekser usuwa istniejące fragmenty danego pliku, więc ponowne uruchomienie indeksowania incremental na już aktualnej bazie danych nie wprowadza żadnych zmian. Ponowne uruchomienie indeksowania full tworzy identyczną bazę danych.

Odzyskiwanie po uszkodzeniu danych

Jeśli baza danych SQLite zostanie uszkodzona (utrata zasilania podczas zapisu, błąd dysku, zakończenie procesu w trakcie transakcji):

# Check integrity
sqlite3 vectors.db "PRAGMA integrity_check;"

# If corruption detected, full reindex rebuilds from source files
python index_vault.py --full

Źródłem prawdy zawsze są pliki w vault, nie baza danych. Baza danych jest artefaktem pochodnym, który można w każdej chwili odbudować. To kluczowa właściwość projektu: nigdy nie trzeba wykonywać kopii zapasowej bazy danych.

Flaga --incremental

Gdy indekser działa z --incremental:

  1. Kontrola hash modelu. Porównuje zapisany hash modelu z bieżącym modelem. Jeśli są różne, automatycznie przełącza się w tryb reindeksowania full i ostrzega użytkownika.
  2. Skanowanie plików. Przechodzi przez dozwolone foldery, zbiera ścieżki plików i mtimes.
  3. Wykrywanie zmian. Porównuje je z zapisanymi danymi.
  4. Przetwarzanie wsadowe. Ponownie dzieli na fragmenty i ponownie tworzy embeddings dla zmienionych plików w partiach po 64.
  5. Raportowanie postępu. Wypisuje liczbę przetworzonych plików i czas, który upłynął.
  6. Łagodne zamykanie. Obsługuje SIGINT, kończąc bieżący plik przed zatrzymaniem.

Filtrowanie poświadczeń i granice danych

Notatki osobiste zawierają sekrety: klucze API, bearer tokens, connection strings do baz danych, klucze prywatne wklejone podczas sesji debugowania. Filtr poświadczeń zapobiega trafianiu ich do indeksu wyszukiwania.

Problem

Notatka o debugowaniu integracji OAuth może zawierać:

The token was: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
I used this curl command:
  curl -H "Authorization: Bearer sk-ant-api03-abc123..."

Bez filtrowania zarówno JWT, jak i klucz API zostałyby podzielone na fragmenty, osadzone jako embeddings i zapisane w bazie danych. Wyszukiwanie „authentication” zwróciłoby fragment zawierający prawdziwe sekrety. Co gorsza, jeśli retriever przekaże wyniki do narzędzia AI przez MCP, sekrety pojawią się w oknie kontekstu AI i potencjalnie w logach narzędzia.

Filtrowanie oparte na wzorcach

Filtr poświadczeń działa na każdym fragmencie przed zapisem, dopasowując 25 wzorców specyficznych dla dostawców oraz wzorce ogólne:

Wzorce specyficzne dla dostawców:

Wzorzec Przykład Regex
Klucz API OpenAI sk-... sk-[a-zA-Z0-9_-]{20,}
Klucz API Anthropic sk-ant-api03-... sk-ant-api\d{2}-[a-zA-Z0-9_-]{20,}
PAT GitHub ghp_... gh[ps]_[a-zA-Z0-9]{36,}
AWS Access Key AKIA... AKIA[0-9A-Z]{16}
Klucz Stripe sk_live_... [sr]k_(live\|test)_[a-zA-Z0-9]{24,}
Token Cloudflare ... Różne wzorce

Wzorce ogólne:

Wzorzec Wykrywanie
Tokeny JWT eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+
Bearer tokens Bearer\s+[a-zA-Z0-9_\-\.]+
Klucze prywatne -----BEGIN (RSA\|EC\|OPENSSH) PRIVATE KEY-----
base64 o wysokiej entropii Ciągi z entropią >4,5 bitu/znak, 40+ znaków
Przypisania haseł password\s*[:=]\s*["'][^"']+["']

Implementacja filtra

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

Kluczowe decyzje projektowe:

  1. Filtrowanie przed embeddings. Oczyszczony tekst jest tym, dla czego tworzone są embeddings. Reprezentacja wektorowa nigdy nie koduje wzorców poświadczeń. Zapytanie o „klucz API” zwraca notatki omawiające zarządzanie kluczami API, a nie notatki zawierające rzeczywiste klucze.

  2. Zastępowanie zamiast usuwania. Token [REDACTED:pattern-name] zachowuje semantyczny kontekst otaczającego tekstu. Embedding wychwytuje, że „w tym miejscu znajdowało się coś podobnego do poświadczenia”, bez kodowania samego poświadczenia.

  3. Logowanie wzorców, nie wartości. Filtr loguje, które wzorce zostały dopasowane (np. „Scrubbed 2 credential(s) from oauth-debug.md [jwt, bearer-token]”), ale nigdy nie loguje wartości poświadczenia.

Wykluczanie oparte na ścieżkach

Plik .indexignore zapewnia ogólne wykluczanie według ścieżki. Filtr poświadczeń zapewnia precyzyjne oczyszczanie wewnątrz indeksowanych plików. Oba mechanizmy są potrzebne:

  • .indexignore dla całych folderów, o których wiadomo, że zawierają wrażliwe treści (notatki zdrowotne, dokumenty finansowe, dokumenty zawodowe)
  • Filtr poświadczeń dla sekretów przypadkowo umieszczonych w treści, która poza tym nadaje się do indeksowania

Klasyfikacja danych

W przypadku vault zawierających zróżnicowane treści warto rozważyć klasyfikację notatek według wrażliwości:

Poziom Przykłady Indeksować? Filtrować?
Publiczne Szkice blogowe, notatki techniczne Tak Tak
Wewnętrzne Plany projektów, decyzje architektoniczne Tak Tak
Wrażliwe Dane o wynagrodzeniu, dokumentacja zdrowotna Nie (.indexignore) Nie dotyczy
Zastrzeżone Poświadczenia, klucze prywatne Nie (.indexignore) Nie dotyczy

Architektura serwera MCP

Serwery Model Context Protocol (MCP) udostępniają retriever jako narzędzie, które mogą wywoływać agenci AI. Ta sekcja omawia projekt serwera, zakres funkcji i granice uprawnień.

Wybór protokołu: STDIO czy HTTP

MCP obsługuje dwa tryby transportu:

STDIO — Narzędzie AI uruchamia serwer MCP jako proces potomny i komunikuje się przez stdin/stdout. To standardowy tryb dla narzędzi lokalnych. Claude Code, Codex CLI i Cursor obsługują serwery MCP działające przez STDIO.

{
  "mcpServers": {
    "obsidian": {
      "command": "python",
      "args": ["/path/to/obsidian_mcp.py"],
      "env": {
        "VAULT_PATH": "/path/to/vault",
        "DB_PATH": "/path/to/vectors.db"
      }
    }
  }
}

HTTP — Serwer MCP działa jako niezależna usługa HTTP. Jest przydatny w przypadku dostępu zdalnego, konfiguracji z wieloma klientami lub konfiguracji zespołowych, w których vault znajduje się na współdzielonym serwerze.

{
  "mcpServers": {
    "obsidian": {
      "url": "http://localhost:3333/mcp"
    }
  }
}

Rekomendacja: W przypadku osobistych vaultów należy używać STDIO. Jest prostszy, bezpieczniejszy (bez ekspozycji sieciowej), a cyklem życia serwera zarządza narzędzie AI. HTTP należy stosować tylko wtedy, gdy wiele narzędzi lub wiele komputerów potrzebuje równoczesnego dostępu do tego samego vaulta.

Ewolucja specyfikacji MCP. Specyfikacja MCP z czerwca 2025 r. dodała autoryzację OAuth 2.1, ustrukturyzowane wyniki narzędzi (typowane schematy zwracanych wartości) oraz elicitation (inicjowane przez serwer prompty dla użytkownika). Wydanie z listopada 2025 r. wprowadziło Streamable HTTP jako podstawowy tryb transportu, wykrywanie adresów URL .well-known do automatycznego przeglądania możliwości serwera, ustrukturyzowane adnotacje narzędzi deklarujące, czy narzędzie jest tylko do odczytu, czy modyfikuje dane, oraz system standaryzacji poziomów SDK.79 Kolejna rewizja jest już konkretna: specyfikacja z 2026-07-28 weszła w fazę Release Candidate 21 maja 2026 r. — to największa rewizja MCP od premiery. Jej najważniejsze zmiany to bezstanowy rdzeń protokołu (usunięto uzgadnianie initialize i nagłówek Mcp-Session-Id, więc serwery nie śledzą już stanu sesji dla poszczególnych połączeń), MCP Apps (serwery mogą zwracać renderowany po stronie serwera HTML, wyświetlany w sandboxowanych iframe’ach klienta), Tasks przechodzące z eksperymentalnego rdzenia do oficjalnego rozszerzenia (tasks/get, tasks/update, tasks/cancel dla długo działających operacji), wzmocnioną autoryzację OAuth 2.0 / OIDC oraz 12-miesięczną politykę cyklu wycofywania funkcji. Została wydana zgodnie z harmonogramem jako rewizja z 28 lipca 2026 r. — obecnie obowiązująca specyfikacja (zweryfikowano 14 sierpnia 2026 r.).24 W przypadku osobistych serwerów vaulta STDIO pozostaje najprostszą ścieżką, a bezstanowy rdzeń jeszcze bardziej upraszcza serwery STDIO dla jednego użytkownika. Transport Streamable HTTP, wykrywanie .well-known i MCP Apps przynoszą korzyści głównie wdrożeniom HTTP dla przedsiębiorstw, z routingiem wielodostępnym i równoważeniem obciążenia. Warto śledzić mapę rozwoju MCP, aby uzyskiwać aktualizacje wpływające na wybór transportu.

Projekt funkcji

Serwer MCP powinien udostępniać minimalny zestaw narzędzi:

search — Podstawowe narzędzie. Uruchamia hybrid retrieval i zwraca wyniki uszeregowane według trafności.

{
  "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 — Odczytuje pełną zawartość określonej notatki według ścieżki. Przydatne, gdy agent chce zobaczyć pełny kontekst wyniku wyszukiwania.

{
  "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 — Wyświetla listę notatek pasujących do filtra (według folderu, tagu, typu lub zakresu dat). Przydatne podczas eksploracji, gdy agent nie ma konkretnego zapytania.

{
  "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 — Narzędzie pomocnicze, które uruchamia wyszukiwanie i formatuje wyniki jako blok kontekstu odpowiedni do wstawienia do rozmowy.

{
  "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 }
  }
}

Granice uprawnień

Serwer MCP powinien egzekwować ścisłe granice:

  1. Tylko do odczytu. Serwer odczytuje vault i bazę danych indeksu. Nie tworzy, nie modyfikuje ani nie usuwa notatek. Operacje zapisu (przechwytywanie nowych notatek) obsługują oddzielne hooki lub skille, a nie serwer MCP.

  2. Ograniczenie do vaulta. Serwer odczytuje wyłącznie pliki w skonfigurowanej ścieżce vaulta. Próby przejścia poza ścieżkę (../../etc/passwd) muszą zostać odrzucone.

  3. Wyniki filtrowane pod kątem poświadczeń. Nawet jeśli baza danych zawiera wstępnie przefiltrowaną treść, należy stosować filtrowanie poświadczeń na wyjściu jako mechanizm defense-in-depth.

  4. Odpowiedzi ograniczone tokenami. Należy egzekwować max_tokens dla wszystkich odpowiedzi narzędzi, aby zapobiec otrzymywaniu przez narzędzie AI nadmiernie dużych bloków kontekstu.

Obsługa błędów

Narzędzia MCP powinny zwracać ustrukturyzowane komunikaty o błędach, które pomagają narzędziu AI odzyskać sprawność:

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,
    }

Integracja z Claude Code

Claude Code jest głównym odbiorcą systemu wyszukiwania Obsidian. Ta sekcja obejmuje konfigurację MCP, integrację hooków oraz wzorzec obsidian_bridge.py.

Konfiguracja MCP

Zarejestrować niestandardowy serwer za pomocą claude mcp add (zakres użytkownika zapisuje do ~/.claude.json; -s project zapisuje współdzielony plik .mcp.json~/.claude/settings.json nie jest powierzchnią konfiguracji MCP):

claude mcp add obsidian -s user \
  -e VAULT_PATH=/absolute/path/to/vault \
  -e DB_PATH=/absolute/path/to/vectors.db \
  -- python /path/to/obsidian_mcp.py

Odpowiedni wpis w .mcp.json, jeśli woli Pan/Pani utworzyć go ręcznie:

{
  "mcpServers": {
    "obsidian": {
      "command": "python",
      "args": ["/path/to/obsidian_mcp.py"],
      "env": {
        "VAULT_PATH": "/absolute/path/to/vault",
        "DB_PATH": "/absolute/path/to/vectors.db"
      }
    }
  }
}

Po dodaniu konfiguracji należy ponownie uruchomić Claude Code. Serwer MCP uruchomi się jako proces potomny. Warto sprawdzić, czy działa:

> What tools do you have from the obsidian MCP server?

Claude Code powinien wyświetlić dostępne narzędzia (obsidian_search, obsidian_read_note itd.).

Integracja hooków

Hooki rozszerzają zachowanie Claude Code w określonych punktach cyklu życia. Dwa hooki są istotne dla integracji z Obsidian:

Hooki są rejestrowane w ustawieniach (~/.claude/settings.json, pod kluczem hooks, z nazwą zdarzenia i matcherem) oraz otrzymują ładunek JSON przez stdin — nie istnieje katalog hooków automatycznie wykrywany przez Claude Code, a szczegóły narzędzia nigdy nie docierają jako argumenty $1/$2.

Hook UserPromptSubmit — przeszukuje vault po przesłaniu promptu i wstrzykuje istotny kontekst (stdout z tego zdarzenia jest dodawany do rozmowy):

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [{ "type": "command", "command": "/path/to/obsidian-context.sh" }]
      }
    ]
  }
}
#!/bin/bash
# obsidian-context.sh — read the JSON payload from stdin
PROMPT=$(jq -r '.prompt // empty')
[ -z "$PROMPT" ] && exit 0
CONTEXT=$(python /path/to/retriever.py search "$PROMPT" --limit 3 --max-tokens 1500)
if [ -n "$CONTEXT" ]; then
    printf 'Relevant vault context:\n%s\n' "$CONTEXT"   # stdout -> added as context
fi

Hook PostToolUse — zapisuje istotne wyniki narzędzi z powrotem do vault, aby można je było wyszukać w przyszłości (rejestrowany z matcherem, dzięki czemu uruchamia się tylko dla wybranych narzędzi):

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|Bash",
        "hooks": [{ "type": "command", "command": "/path/to/capture-insight.sh" }]
      }
    ]
  }
}
#!/bin/bash
# capture-insight.sh — tool name and response arrive as stdin JSON
PAYLOAD=$(cat)
TOOL_NAME=$(printf '%s' "$PAYLOAD" | jq -r '.tool_name')
OUTPUT=$(printf '%s' "$PAYLOAD" | jq -r '.tool_response // "" | tostring')
if [ ${#OUTPUT} -gt 500 ]; then
    python /path/to/capture.py --text "$OUTPUT" --source "claude-code-$TOOL_NAME"
fi

Wzorzec obsidian_bridge.py

Moduł pośredniczący zapewnia Python API, który mogą wywoływać hooki i umiejętności:

# 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)

Umiejętność /capture

Umiejętność Claude Code do zapisywania spostrzeżeń z powrotem do vault:

/capture "OAuth token rotation requires both access and refresh token invalidation"
  --domain security
  --tags oauth,tokens

Umiejętność tworzy nową notatkę w 00-inbox/ z poprawnym frontmatterem i uruchamia przyrostowe ponowne indeksowanie, dzięki czemu nową notatkę można od razu wyszukać.

Wzorce niestandardowych poleceń

Umiejętności Claude Code mogą opakowywać operacje na vault w nazwane polecenia. Praktycy stworzyli biblioteki poleceń specyficznych dla Obsidian, które traktują vault zarówno jako źródło odczytu, jak i cel zapisu.

Skanowanie sygnałów. Polecenie /scan-intel wyszukuje w źródłach zewnętrznych, ocenia wyniki względem osobistych zainteresowań badawczych i zapisuje kwalifikujące się sygnały jako notatki vault z frontmatterem:

/scan-intel --topics "agent infrastructure, security" --lookback 7d

Polecenie pobiera dane ze skonfigurowanych źródeł (arXiv, HN, RSS), stosuje model punktacji (istotność, użyteczność, głębia, autorytet) i zapisuje spełniające kryteria sygnały w folderach vault specyficznych dla danego tematu. Vault staje się dalszym odbiorcą zautomatyzowanego procesu pozyskiwania informacji.

Dziennik kapitana. Polecenie /captains-log agreguje codzienną aktywność git ze wszystkich repozytoriów, zapisuje ustrukturyzowany wpis dziennika w vault oraz uwzględnia podjęte decyzje, wnioski i otwarte wątki:

/captains-log

Polecenie pobiera historię commitów z GitHub, grupuje ją według repozytorium i formatuje jako narracyjny wpis dziennika. Z czasem codzienne logi tworzą przeszukiwalny zapis tego, co zostało dostarczone i dlaczego.

Przechwytywanie do Obsidian. Polecenie /obsidian-capture pobiera spostrzeżenie z bieżącej sesji Claude Code i zapisuje je bezpośrednio w vault z poprawnymi metadanymi:

/obsidian-capture "SAST gates in agent loops increase security degradation"
  --folder AI-Tools --tags security,agents

Wzorzec można rozszerzyć na każdą operację na vault: tworzenie MOC, aktualizowanie notatek o statusie projektu, łączenie powiązanych sygnałów lub generowanie tygodniowych podsumowań na podstawie zgromadzonych codziennych logów.

Przykłady społeczności. Praktycy publikują swoje biblioteki poleceń. Jeden programista udostępnił 22 niestandardowe polecenia Obsidian + Claude Code, obejmujące codzienne przeglądy, planowanie projektów, zapisywanie badań i procesy tworzenia treści.1 Inny stworzył umiejętność „Visual Explainer”, która generuje w vault notatki z diagramami na podstawie analizy kodu.2 Polecenia się różnią, ale architektura pozostaje spójna: umiejętności Claude Code jako interfejs, notatki vault jako warstwa przechowywania oraz infrastruktura wyszukiwania jako silnik zapytań.

Zarządzanie oknem kontekstowym

Integracja powinna uwzględniać okno kontekstowe Claude Code:

  • Ograniczyć wstrzykiwany kontekst do 1 500–2 000 tokenów na zapytanie. Większa ilość konkuruje z pamięcią roboczą agenta.
  • Uwzględniać atrybucję źródła. Zawsze należy uwzględnić ścieżkę pliku i nagłówek sekcji, aby agent mógł odwołać się do źródła.
  • Skracać tekst chunków. Długie chunki należy skracać za pomocą ..., zamiast całkowicie je pomijać. Pierwsze 300–500 znaków zwykle zawiera kluczowe informacje.
  • Nie wstrzykiwać kontekstu przy każdym prompcie. Wstrzykiwanie działa przez UserPromptSubmit (zdarzenie, którego stdout dociera do modelu), dlatego należy zarządzać tam budżetem: pomijać krótkie konwersacyjne prompty, wstrzykiwać kontekst tylko wtedy, gdy prompt wskazuje kod, pliki lub wcześniejsze decyzje, oraz ograniczać wstrzykiwany blok. Zdarzenia ograniczone do narzędzi, takie jak PreToolUse, mogą blokować lub rejestrować, ale ich stdout nigdy nie dociera do modelu.

Integracja Codex CLI

Codex CLI łączy się z serwerami MCP przez config.toml. Wzorzec integracji różni się od Claude Code składnią konfiguracji i sposobem dostarczania instrukcji.

Konfiguracja MCP

Dodać do ~/.codex/config.toml (Codex odczytuje $CODEX_HOME/config.toml; instrukcje na poziomie projektu powinny znajdować się w AGENTS.md, a nie w pliku konfiguracji projektu):

[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"

Wzorce AGENTS.md

Codex CLI odczytuje AGENTS.md jako instrukcje na poziomie projektu. Należy uwzględnić wskazówki dotyczące przeszukiwania vault:

## 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"

Różnice względem Claude Code

Funkcja Claude Code Codex CLI
Konfiguracja MCP claude mcp add~/.claude.json / projektowy .mcp.json ~/.codex/config.toml
Hooki Rejestrowane w ustawieniach, 31 zdarzeń cyklu życia, stdin JSON Obsługiwane (stabilna powierzchnia; własny zestaw zdarzeń)
Umiejętności ~/.claude/skills/ ~/.codex/skills/ (stabilne)
Plik instrukcji CLAUDE.md AGENTS.md
Powierzchnia uprawnień Tryby: Manual / acceptEdits / auto (domyślnie w Pro/Max/Team od 14 sierpnia 2026) / plan / bypassPermissions Polityka zatwierdzania untrusted / on-request / never × sandbox read-only / workspace-write / danger-full-access (--full-auto usunięto w wersji v0.147.0)

Kluczowa różnica: oba narzędzia obsługują teraz hooki i umiejętności; różni je ich forma. Codex łączy politykę zatwierdzania z trybem sandbox na poziomie systemu operacyjnego, zamiast trybów uprawnień Claude Code, a jego zdarzenia hooków są inne — należy przenieść wzorzec (przeszukiwanie vault przed pracą, zapisywanie po niej), a nie konfigurację. AGENTS.md pozostaje właściwym miejscem na stałe instrukcje „najpierw przeszukaj vault” w Codex.

Cursor i inne narzędzia

Cursor i inne narzędzia AI obsługujące MCP mogą łączyć się z tym samym serwerem Obsidian MCP. Ta sekcja obejmuje konfigurację popularnych narzędzi.

Cursor

Proszę dodać do .cursor/mcp.json w katalogu głównym projektu:

{
  "mcpServers": {
    "obsidian": {
      "command": "python",
      "args": ["/path/to/obsidian_mcp.py"],
      "env": {
        "VAULT_PATH": "/absolute/path/to/vault",
        "DB_PATH": "/absolute/path/to/vectors.db"
      }
    }
  }
}

Plik .cursorrules Cursor może zawierać instrukcje dotyczące korzystania z vault:

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.

Macierz zgodności

Narzędzie Obsługa MCP Transport Lokalizacja konfiguracji
Claude Code Pełna STDIO claude mcp add~/.claude.json / projektowy .mcp.json
Codex CLI Pełna STDIO ~/.codex/config.toml
Cursor Pełna STDIO .cursor/mcp.json
Windsurf Pełna STDIO ~/.codeium/windsurf/mcp_config.json
Continue.dev Pełna STDIO + HTTP ~/.continue/config.yaml (mcpServers)
Zed Pełna (serwery kontekstowe) STDIO settings.json (context_servers)
Claudian (wtyczka Obsidian) N/D (osadzone) Claude Code CLI ustawienia wtyczki Obsidian
Agent Client (wtyczka Obsidian) N/D (osadzone) ACP ustawienia wtyczki Obsidian

Rozwiązanie awaryjne dla narzędzi bez obsługi MCP

W przypadku narzędzi, które nie obsługują MCP, retriever można opakować jako CLI:

# 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

CLI zwraca ustrukturyzowany tekst, który można ręcznie wkleić do danych wejściowych dowolnego narzędzia AI. To rozwiązanie jest mniej eleganckie niż integracja MCP, ale działa uniwersalnie.


Cache promptów z ustrukturyzowanych notatek

Ustrukturyzowane notatki w vault mogą służyć jako bloki kontekstu wielokrotnego użytku, ograniczające zużycie tokenów w interakcjach AI. Ta sekcja omawia projektowanie kluczy cache i zarządzanie budżetem tokenów.

Wzorzec

Zamiast wyszukiwać kontekst przy każdej interakcji, należy wcześniej zbudować bloki kontekstu z dobrze ustrukturyzowanych notatek w vault i umieścić je w cache:

# 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
    },
}

Unieważnianie cache

Unieważnianie cache opiera się na dwóch sygnałach:

  1. Wygaśnięciu TTL. Każdy blok kontekstu ma okres ważności. Po wygaśnięciu TTL blok jest przebudowywany przez ponowne zapytanie vault.
  2. Wykrywaniu zmian w vault. Gdy indekser wykryje zmiany w plikach, które współtworzyły blok kontekstu w cache, blok jest unieważniany natychmiast.

Zarządzanie budżetem tokenów

Sesja rozpoczyna się od całkowitego budżetu kontekstu. Bloki z cache zużywają część tego budżetu:

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)

Bloki z cache są ładowane na początku sesji. Dynamiczne wyniki wyszukiwania wypełniają pozostały budżet dla każdego zapytania. To podejście hybrydowe zapewnia agentowi bazę często potrzebnego kontekstu, zachowując jednocześnie budżet na konkretne zapytania.

Zużycie tokenów przed i po

Bez cache: Każde istotne zapytanie uruchamia wyszukiwanie w vault, zwracając 1 500–2 000 tokenów kontekstu. W 10 zapytaniach podczas sesji agent zużywa 15 000–20 000 tokenów kontekstu vault.

Z cache: Trzy wcześniej utworzone bloki kontekstu zużywają łącznie 4 500 tokenów. Dodatkowe wyszukiwania dodają 1 500–2 000 tokenów na każde unikalne zapytanie. W 10 zapytaniach, z których 6 pokrywają bloki z cache, agent zużywa 4 500 + (4 * 1 500) = 10 500 tokenów — około połowy zużycia bez cache.


Przechwytywanie skompresowanych podsumowań rozwlekłych wyników

Wyniki narzędzi mogą być rozwlekłe: ślady stosu, listy plików, wyniki testów. Hook nie może zmniejszyć tego, co widzi model — gdy uruchamia się PostToolUse, pełny wynik jest już w oknie kontekstu, a żaden tekst wypisany przez hook go nie zastępuje. Hook może jednak zapisać skompresowane podsumowanie do vault, dzięki czemu przyszłe sesje pobiorą dwuwierszowy werdykt zamiast ponownie uruchamiać lub odczytywać oryginał mający 5 000 tokenów. Należy traktować to jako wzorzec przechwytywania pamięci między sesjami, a nie sposób na oszczędzanie kontekstu w trakcie sesji (w trakcie sesji właściwymi narzędziami są /compact, zawężone prompty oraz prośba o mniej rozwlekły wynik).

Problem

Wywołanie narzędzia Bash, które uruchamia testy, może zwrócić:

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

Pełny wynik ma 5 000 tokenów, ale kluczowa informacja mieści się w 2 wierszach: 200 zaliczonych, 1 niezaliczony.

Implementacja hooka

Zarejestrowane w PostToolUse z dopasowaniem Bash (rejestrowane w ustawieniach, stdin JSON — zobacz Hook Integration powyżej):

#!/bin/bash
# summarize-and-capture.sh — write a compressed summary to the vault
PAYLOAD=$(cat)
OUTPUT=$(printf '%s' "$PAYLOAD" | jq -r '.tool_response // "" | tostring')

# Only summarize large outputs
[ ${#OUTPUT} -lt 2000 ] && exit 0

if printf '%s' "$OUTPUT" | grep -q "PASSED\|FAILED"; then
    PASSED=$(printf '%s' "$OUTPUT" | grep -c "PASSED")
    FAILED=$(printf '%s' "$OUTPUT" | grep -c "FAILED")
    SUMMARY="Tests: $PASSED passed, $FAILED failed"
    [ "$FAILED" -gt 0 ] && SUMMARY="$SUMMARY
$(printf '%s' "$OUTPUT" | grep 'FAILED')"
    python /path/to/capture.py --text "$SUMMARY" --source "test-run-summary"
fi
exit 0

Każde wywołanie hooka to nowy proces, więc nie jest potrzebne zabezpieczenie przed rekurencją — własne zapisy hooka nie uruchamiają go ponownie, a wyeksportowane zmienne nigdy nie przetrwają do kolejnego wywołania.

Heurystyki kompresji

Typ wyniku Wykrywanie Strategia kompresji
Wyniki testów Słowa kluczowe PASSED / FAILED Zlicz zaliczone/niezaliczone, pokaż tylko niepowodzenia
Listy plików ls lub find w poleceniu Skróć do pierwszych 20 wpisów + liczba
Ślady stosu Słowo kluczowe Traceback Zachowaj pierwszą i ostatnią ramkę + komunikat błędu
Status Git modified: / new file: Podsumuj liczby według statusu
Wynik kompilacji warning: / error: Usuń wiersze informacyjne, zachowaj ostrzeżenia/błędy

Przepływ przyjmowania i triage sygnałów

Warstwa przyjmowania określa, co trafia do sejfu. Bez kuracji w seifie gromadzi się szum. Ta sekcja opisuje proces oceniania, który kieruje sygnały do folderów domenowych.

Źródła

Sygnały pochodzą z wielu kanałów:

  • Kanały RSS: Blogi techniczne, komunikaty bezpieczeństwa, informacje o wydaniach
  • Zakładki przez Web Clipper: Oficjalne rozszerzenie Obsidian Web Clipper (Chrome, Firefox, Safari) jest ścieżką przyjmowania o najwyższej wierności do przechwytywania treści po stronie przeglądarki. Cykl wydań z kwietnia 2026 r. znacząco zwiększył jego użyteczność w przepływach pracy z AI:22
    • 1.4.0 (9 kwietnia): Interaktywny interfejs transkrypcji YouTube — można przypiąć film, przewijać transkrypcję, korzystać z automatycznego przewijania i wyróżniać bieżącą pozycję. Dodano także domyślne „Open in Reader”, które jednym kliknięciem przechwytuje treść bezpośrednio w trybie Reader.
    • 1.5.0–1.5.1 (15 kwietnia): Przeglądarka wyróżnień — przeglądanie i wyszukiwanie przechwyconych wyróżnień w całym seifie. Przejście z pojawianiem się do Reader. Płynniejsze odtwarzanie/wstrzymywanie YouTube. Wersja 1.5.1 naprawiła regresję kompilacji webpack.
    • 1.6.0–1.6.2 (21–23 kwietnia): Przebudowa UX narzędzia Highlighter z obsługą urządzeń mobilnych. Defuddle 0.18 dodaje ekstraktory specyficzne dla źródeł LinkedIn, Threads, Bluesky, Discourse i Medium. Wersja 1.6.2 naprawia regresję schowka w osadzonym trybie Safari. Należy skonfigurować szablony dla poszczególnych domen źródłowych, aby transkrypcje YouTube, README GitHub i artykuły długiej formy trafiały do rozsądnie nazwanych notatek z odpowiednim frontmatter dla opisanego niżej procesu oceniania.
  • Newslettery: Kluczowe fragmenty newsletterów e-mail
  • Ręczne przechwytywanie: Notatki tworzone podczas czytania, rozmów lub badań
  • Wyniki narzędzi: Istotne wyniki narzędzi AI przechwytywane przez hooki
  • Rozszerzenie udostępniania iOS: Aplikacja Obsidian na iOS (zaktualizowana na początku 2026 r.) zawiera rozszerzenie udostępniania, które zapisuje treści z Safari, sieci społecznościowych i innych aplikacji bezpośrednio do sejfu bez otwierania Obsidian; linia 1.13 dodaje konfigurowalne cele arkusza udostępniania ze zmiennymi szablonów — w tym url, dzięki czemu przechwycona strona automatycznie zapisuje link źródłowy we frontmatter.19 Tworzy to wygodną ścieżkę przyjmowania na urządzeniach mobilnych — wystarczy udostępnić artykuł z Safari, a trafi jako notatka w seifie gotowa do oceny.
  • Obsidian CLI: Skrypty powłoki i hooki mogą tworzyć notatki za pomocą obsidian file create albo dopisywać do istniejących notatek przez obsidian file append, umożliwiając automatyczne procesy przyjmowania na komputerze.

Wymiary oceny

Każdy sygnał jest oceniany w czterech wymiarach (od 0,0 do 1,0 każdy):

Wymiar Pytanie Niski wynik (0,0–0,3) Wysoki wynik (0,7–1,0)
Trafność Czy dotyczy to moich aktywnych domen? Luźno powiązane, poza zakresem Bezpośrednio związane z aktywną pracą
Możliwość zastosowania Czy można wykorzystać tę informację? Czysta teoria, bez zastosowania Konkretna technika lub wzorzec, który można zastosować
Głębia Jak merytoryczna jest treść? Nagłówki, powierzchowne podsumowanie Szczegółowa analiza z przykładami
Wiarygodność Jak wiarygodne jest źródło? Anonimowy blog, niezweryfikowane Źródło pierwotne, recenzowane, uznany ekspert

Wynik łączny i kierowanie

composite = (relevance * 0.35) + (actionability * 0.25) +
            (depth * 0.25) + (authority * 0.15)
Zakres wyniku Działanie
0,55+ Automatycznie skieruj do folderu domenowego
0,40 - 0,55 Umieść w kolejce do ręcznej weryfikacji
< 0,40 Odrzuć (nie zapisuj)

Kierowanie domenowe

Sygnały z wynikiem powyżej 0,55 są kierowane do jednego z 12 folderów domenowych na podstawie dopasowania słów kluczowych i klasyfikacji tematu:

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

Statystyki produkcyjne

W ciągu 14 miesięcy działania:

Wskaźnik Wartość
Łączna liczba przetworzonych sygnałów 7 771
Automatycznie skierowane (>0,55) 4 832 (62%)
W kolejce do weryfikacji (0,40–0,55) 1 543 (20%)
Odrzucone (<0,40) 1 396 (18%)
Aktywne foldery domenowe 12
Średnia liczba sygnałów dziennie ~18

Wzorce grafu wiedzy

Graf wiki-link Obsidian koduje relacje między notatkami. Ta sekcja obejmuje semantykę linków, przechodzenie grafu w celu rozszerzania kontekstu oraz antywzorce obniżające jakość grafu.

Każdy wiki-link tworzy skierowaną krawędź w grafie. Obsidian śledzi zarówno linki wychodzące, jak i backlink:

  • Link wychodzący: Notatka A zawiera [[Note B]] → A linkuje do B
  • Backlink: Notatka B wskazuje, że odwołuje się do niej notatka A

Graf koduje różne typy relacji zależnie od kontekstu:

Wzorzec linku Semantyka Przykład
Link w tekście „Jest powiązany z” „Szczegóły znajdują się w [[OAuth Token Rotation]]”
Link w nagłówku „Ma podtemat” „## Powiązane\n- [[Token Rotation]]\n- [[Session Management]]”
Link podobny do tagu „Jest sklasyfikowany jako” [[type/reference]]
Link MOC „Jest częścią” Notatka Map of Content zawierająca listę powiązanych notatek

Maps of Content (MOCs)

MOC to notatki indeksowe organizujące powiązane notatki w strukturę, po której można nawigować:

---
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]]

MOC wspierają wyszukiwanie na dwa sposoby:

  1. Bezpośrednie dopasowanie. Wyszukiwanie „authentication overview” dopasowuje sam MOC, przekazując agentowi wyselekcjonowaną listę powiązanych notatek.
  2. Rozszerzanie kontekstu. Po znalezieniu konkretnej notatki mechanizm wyszukiwania może sprawdzić, czy notatka występuje w jakimkolwiek MOC, i uwzględnić strukturę MOC w wynikach, dając agentowi mapę szerszego tematu.

Przechodzenie grafu w celu rozszerzania kontekstu

Przyszłe ulepszenie mechanizmu wyszukiwania: po znalezieniu najlepszych wyników należy rozszerzyć kontekst, podążając za linkami:

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)

Nie zostało to zaimplementowane w obecnym mechanizmie wyszukiwania, ale stanowi naturalne rozszerzenie struktury grafu.

Antywzorce

Klastry osierocone. Grupy notatek, które linkują do siebie nawzajem, ale nie mają połączeń z resztą sejfu. Panel grafu w Obsidian pokazuje je jako odłączone wyspy. Klastry osierocone wskazują na brakujące MOC lub brakujące linki między domenami.

Rozrost tagów. Niespójne używanie tagów albo tworzenie zbyt wielu szczegółowych tagów. Sejf z 500 unikalnymi tagami w 5 000 notatek daje średnio 1 notatkę na 10 tagów — tagi nie są przydatne do filtrowania. Należy skonsolidować je do 20–50 tagów wysokiego poziomu odpowiadających folderom domenowym.

Notatki z dużą liczbą linków i małą ilością treści. Notatki składające się wyłącznie z wiki-link bez prozy. Takie notatki są słabo indeksowane, ponieważ chunker nie ma tekstu do osadzenia. Należy dodać co najmniej akapit kontekstu wyjaśniający, dlaczego połączone notatki są powiązane.

Dwukierunkowe linki do wszystkiego. Nie każde odwołanie wymaga wiki-link. Wzmianka o „OAuth” nie wymaga [[OAuth 2.0 Overview]]. Wiki-link należy rezerwować dla celowych relacji, po których można nawigować, gdy kliknięcie linku dostarczy użytecznego kontekstu.

przepisy dotyczące przepływu pracy dewelopera

Praktyczne przepływy pracy łączące wyszukiwanie w vault z codziennymi zadaniami programistycznymi.

poranne wczytanie kontekstu

Dzień warto zacząć od wczytania odpowiedniego kontekstu:

Search my vault for notes about [current project] updated in the last week

Retriever zwraca ostatnie notatki o aktywnym projekcie, dzięki czemu można szybko przypomnieć sobie, na czym przerwano pracę. To skuteczniejsze niż ponowne czytanie wczorajszych komunikatów commitów.

przechwytywanie wiedzy podczas kodowania

Podczas implementowania funkcji można zapisywać spostrzeżenia bez opuszczania edytora:

/capture "FastAPI dependency injection with async generators requires yield,
not return. The generator is the dependency lifecycle."
  --domain programming
  --tags fastapi,dependency-injection

Zapisane spostrzeżenie jest natychmiast indeksowane i dostępne do przyszłego wyszukiwania. Przez miesiące takie mikroprzechwycenia budują korpus wiedzy specyficznej dla implementacji.

rozpoczęcie projektu

Przy rozpoczynaniu nowego projektu lub funkcji:

  1. Przeszukać vault: „Co wiem o [technologia/wzorzec]?”
  2. Przejrzeć 5 najlepszych wyników pod kątem wcześniejszych decyzji i pułapek
  3. Sprawdzić, czy dla danej domeny istnieje MOC; jeśli nie, utworzyć go
  4. Wyszukać tryby awarii: „problemy z [technologia]”

debugowanie z użyciem wyszukiwania w vault

Po napotkaniu błędu lub nieoczekiwanego zachowania:

Search my vault for [error message or symptom]

Wcześniejsze notatki z debugowania często zawierają przyczynę źródłową i poprawkę. Jest to szczególnie wartościowe przy powtarzających się problemach w różnych projektach — vault pamięta to, o czym łatwo zapomnieć.

przygotowanie do code review

Przed sprawdzeniem PR:

Search my vault for patterns and conventions about [module being changed]

Vault zwraca wcześniejsze decyzje, ograniczenia architektoniczne i standardy kodowania istotne dla sprawdzanego kodu. Review opiera się wtedy na wiedzy instytucjonalnej, a nie tylko na diffie.


strojenie wydajności

Ta sekcja omawia strategie optymalizacji dla różnych rozmiarów vault i wzorców użycia.

zarządzanie rozmiarem indeksu

Rozmiar vault Chunks Rozmiar DB Pełne ponowne indeksowanie Przyrostowe
500 notatek ~1,500 3 MB 15 sekund <1 sekunda
2,000 notatek ~6,000 12 MB 45 sekund 2 sekundy
5,000 notatek ~15,000 30 MB 2 minuty 4 sekundy
15,000 notatek ~50,000 83 MB 4 minuty <10 sekund
50,000 notatek ~150,000 250 MB 15 minut 30 sekund

Przy ponad 50,000 notatek warto rozważyć: - Zwiększenie rozmiaru batcha z 64 do 128, aby przyspieszyć embedding - Użycie trybu WAL (domyślnie) do współbieżnego dostępu - Uruchamianie pełnego ponownego indeksowania poza godzinami pracy

optymalizacja zapytań

Tryb WAL. Tryb Write-Ahead Logging w SQLite umożliwia współbieżne odczyty, gdy indexer zapisuje dane:

db.execute("PRAGMA journal_mode=WAL")

Ma to krytyczne znaczenie, gdy serwer MCP obsługuje zapytania w czasie, gdy indexer wykonuje aktualizację przyrostową.

Pula połączeń. Serwer MCP powinien ponownie używać połączeń z bazą danych zamiast otwierać nowe połączenie dla każdego zapytania. Jedno długotrwałe połączenie z trybem WAL obsługuje współbieżne odczyty.

# 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. Pragma mmap_size informuje SQLite, aby używał memory-mapped I/O dla pliku bazy danych. W przypadku bazy danych o rozmiarze 83 MB zmapowanie całego pliku do pamięci eliminuje większość odczytów z dysku.

Optymalizacja FTS5. Po pełnym ponownym indeksowaniu należy uruchomić:

INSERT INTO chunks_fts(chunks_fts) VALUES('optimize');

Scala to wewnętrzne segmenty b-tree FTS5, zmniejszając opóźnienie zapytań dla kolejnych wyszukiwań.

benchmarki skalowania

Zmierzono na Apple M3 Pro, 36 GB RAM, NVMe SSD:

Operacja 500 notatek 5K notatek 15K notatek 50K notatek
Zapytanie BM25 2ms 5ms 12ms 25ms
Zapytanie wektorowe 1ms 3ms 8ms 20ms
Fuzja RRF <1ms <1ms 3ms 5ms
Pełne wyszukiwanie 3ms 8ms 23ms 50ms

Wszystkie benchmarki obejmują dostęp do bazy danych, wykonanie zapytania i formatowanie wyników. Opóźnienie sieciowe dla komunikacji MCP STDIO dodaje 1-2ms.


rozwiązywanie problemów

dryf indeksu

Objaw: Wyszukiwanie zwraca nieaktualne wyniki albo pomija niedawno dodane notatki.

Przyczyna: Indexer przyrostowy nie został uruchomiony po dodaniu notatek albo mtime pliku nie zostało zaktualizowane (np. plik zsynchronizowano z innego komputera z zachowaniem znaczników czasu).

Poprawka: Uruchomić pełne ponowne indeksowanie: python index_vault.py --full

zmiana modelu embeddings

Objaw: Po zmianie modelu embeddings wyszukiwanie wektorowe zwraca bezsensowne wyniki.

Przyczyna: Stare wektory (z poprzedniego modelu) są porównywane z nowymi wektorami zapytań. Wymiary albo semantyka przestrzeni wektorowej są niezgodne.

Poprawka: Indexer powinien wykryć niezgodność hasha modelu i automatycznie uruchomić pełne ponowne indeksowanie. Jeśli tego nie zrobi, należy ręcznie wyczyścić bazę danych i ponownie ją zindeksować:

rm vectors.db
python index_vault.py --full

konserwacja FTS5

Objaw: Zapytania FTS5 zwracają niepoprawne lub niepełne wyniki po wielu aktualizacjach przyrostowych.

Przyczyna: Wewnętrzne segmenty FTS5 mogą ulec fragmentacji po wielu małych aktualizacjach.

Poprawka: Odbudować i zoptymalizować:

INSERT INTO chunks_fts(chunks_fts) VALUES('rebuild');
INSERT INTO chunks_fts(chunks_fts) VALUES('optimize');

timeout MCP

Objaw: Narzędzie AI zgłasza, że serwer MCP przekroczył limit czasu.

Przyczyna: Pierwsze zapytanie uruchamia ładowanie modelu (lazy initialization), które trwa 2-5 sekund. Domyślny timeout MCP w narzędziu AI może być krótszy.

Poprawka: Wstępnie rozgrzać model podczas startu serwera:

# In MCP server initialization
retriever = HybridRetriever(db_path, vault_path)
retriever.search("warmup", limit=1)  # Trigger model load

blokady pliku SQLite

Objaw: Błędy SQLITE_BUSY lub SQLITE_LOCKED.

Przyczyna: Wiele procesów jednocześnie zapisuje do bazy danych. Tryb WAL pozwala na współbieżne odczyty, ale tylko jednego zapisującego.

Poprawka: Upewnić się, że tylko jeden proces (indexer) zapisuje do bazy danych. Serwer MCP i hooks powinny tylko czytać. Jeśli potrzebne są współbieżne zapisy, należy użyć trybu WAL i ustawić busy timeout:

db.execute("PRAGMA busy_timeout=5000")  # Wait up to 5 seconds

sqlite-vec się nie ładuje

Objaw: Wyszukiwanie wektorowe jest wyłączone; retriever działa tylko w trybie BM25.

Przyczyna: Rozszerzenie sqlite-vec nie jest zainstalowane, nie zostało znalezione w ścieżce biblioteki albo jest niezgodne z wersją SQLite.

Poprawka:

# Install via pip
pip install sqlite-vec

# Or compile from source
git clone https://github.com/asg017/sqlite-vec
cd sqlite-vec && make

Sprawdzić, czy rozszerzenie się ładuje:

import sqlite3
db = sqlite3.connect(":memory:")
db.enable_load_extension(True)
db.load_extension("vec0")
print("sqlite-vec loaded successfully")

problemy z pamięcią w dużym vault

Objaw: Błędy braku pamięci podczas pełnego ponownego indeksowania dużego vault (50,000+ notatek).

Przyczyna: Rozmiar batcha embeddings jest zbyt duży albo cała zawartość plików jest jednocześnie ładowana do pamięci.

Poprawka: Zmniejszyć rozmiar batcha i przetwarzać pliki przyrostowo:

BATCH_SIZE = 32  # Reduce from 64

Należy również upewnić się, że indexer przetwarza pliki pojedynczo (czytając, wykonując chunking i embedding każdego pliku przed przejściem do następnego), zamiast ładować wszystkie pliki do pamięci.


przewodnik migracji

z Apple Notes

  1. Wyeksportować Apple Notes przez opcję „Export All” (macOS) albo użyć narzędzia migracyjnego, takiego jak apple-notes-liberator
  2. Przekonwertować eksporty HTML na markdown za pomocą markdownify lub pandoc
  3. Przenieść przekonwertowane pliki do folderu 00-inbox/ w swoim vault
  4. Przejrzeć i dodać frontmatter do każdej notatki
  5. Przenieść notatki do odpowiednich folderów domenowych

z Notion

  1. Wyeksportować z Notion: Settings → Export → Markdown & CSV
  2. Rozpakować eksport do folderu 00-inbox/ w swoim vault
  3. Poprawić artefakty markdown specyficzne dla Notion:
  4. Notion używa - [ ] dla checklist — to standardowy markdown
  5. Notion uwzględnia tabele właściwości jako HTML — należy przekonwertować je na frontmatter YAML
  6. Notion osadza obrazy jako ścieżki względne — należy skopiować obrazy do folderu załączników
  7. Dodać standardowy frontmatter (type, domain, tags)
  8. Zastąpić linki stron Notion wiki-links Obsidian

z Google Docs

  1. Użyć Google Takeout, aby wyeksportować wszystkie dokumenty
  2. Przekonwertować pliki .docx na markdown: pandoc -f docx -t markdown input.docx -o output.md
  3. Wykonać konwersję batchową: for f in *.docx; do pandoc -f docx -t markdown "$f" -o "${f%.docx}.md"; done
  4. Przenieść do vault, dodać frontmatter i uporządkować w folderach

ze zwykłego Markdown (bez Obsidian)

Jeśli istnieje już katalog z plikami markdown:

  1. Otworzyć katalog jako vault Obsidian (Obsidian → Open Vault → Open folder)
  2. Dodać .obsidian/ do .gitignore, jeśli katalog jest objęty kontrolą wersji
  3. Utworzyć szablony frontmatter i zastosować je do istniejących plików
  4. Zacząć łączyć notatki za pomocą [[wiki-links]] podczas czytania i porządkowania
  5. Od razu uruchomić indexer — system wyszukiwania działa od pierwszego dnia

z innego systemu wyszukiwania

Jeśli migracja odbywa się z innego systemu embeddings/wyszukiwania:

  1. Nie należy próbować migrować wektorów. Różne modele tworzą niezgodne przestrzenie wektorowe. Należy uruchomić pełne ponowne indeksowanie z nowym modelem.
  2. Migrować należy treść, nie indeks. Pliki vault są źródłem prawdy. Indeks jest artefaktem pochodnym.
  3. Po migracji należy zweryfikować wyniki. Uruchomić 10-20 zapytań, na które odpowiedzi są znane, i sprawdzić, czy wyniki odpowiadają oczekiwaniom.

Dziennik zmian

Data Zmiana Źródło
2026-08-14 Pierwszy całościowy audyt bramkowy — pełna lektura przewodnika przez ewaluator; R1 uzyskał 8,29, z trzema ustaleniami CRITICAL i pięcioma MAJOR, wszystkie naprawione w tym wierszu. Ustalenia CRITICAL szkodziły czytelnikom: szybki start instalował npm obsidian-mcp-server jako „najprostszą opcję opartą na plikach” — ten pakiet to serwer cyanheads oparty na REST-API (wymaga wtyczki Local REST API oraz OBSIDIAN_API_KEY; nie ma flagi --vault), podczas gdy serwer oparty na plikach to npm obsidian-mcp (StevenStavrakis) — tabela serwerów zawierała tę samą kolizję nazw, a oba miejsca poprawiono, podając jawne nazwy npm; oba bloki konfiguracji Claude Code MCP uczyły umieszczania mcpServers w ~/.claude/settings.json, co Claude Code po cichu ignoruje — przepisano je na claude mcp add (zakres użytkownika → ~/.claude.json) z wariantem o zakresie projektu .mcp.json, a komórkę macierzy zgodności poprawiono; przykłady hooków używały pozycyjnych argumentów $1/$2 oraz katalogu automatycznego wykrywania ~/.claude/hooks/pre-tool-use/ — interfejsu, którego Claude Code nigdy nie miał — przepisano je na hooki rejestrowane w ustawieniach, odczytujące stdin JSON za pomocą jq (wstrzykiwanie kontekstu przeniesiono do UserPromptSubmit, którego stdout jest faktycznie dodawany do kontekstu), a założenie sekcji „PostToolUse context compression” (hook zmniejszający to, co widzi model) jest niemożliwe — przekształcono ją w przechwytywanie skompresowanego podsumowania do vaulta w celu ponownego użycia między sesjami, usuwając zbędną ochronę przed rekurencją (każde wywołanie hooka to świeży proces). Ustalenia MAJOR: 1.13.4 → 1.13.7 (zweryfikowano manifestem, wersje stable i beta się zrównały); nota o specyfikacji MCP z 2026-07-28 nadal mówiła „ostateczna specyfikacja zostanie wydana 28 lipca” siedemnaście dni po jej wydaniu jako rewizji Current (zmieniono na czas przeszły; 9 przepisano jako historyczne, wskazujące na 24); porównanie Codex uczyło usuniętych trybów zatwierdzania suggest/auto-edit/full-auto i twierdziło, że „hooki/skills nie są obsługiwane” — oba są stabilnymi powierzchniami Codex od połowy 2026 r., więc tabelę i akapit przebudowano (komórka CC wymienia teraz rzeczywiste tryby uprawnień, w tym automatyczny domyślny z 14 sierpnia); odświeżono wiersze macierzy dla Zed/Continue/Windsurf. Drobniejsze poprawki: usunięto projektowy wariant .codex/config.toml (tylko $CODEX_HOME), mcpvault 0.12.4 → 0.15.0, przestarzałe kotwice „stan na” zastąpiono bezwzględnymi oraz wdrożono obiecane uwzględnienie zmiennej url z iOS Share Sheet 1.13 w sekcji intake. Weryfikacja R2 potwierdziła naprawy, lecz wykryła pozostałości na ich obrzeżach, poprawione w drugim przebiegu: bloki szybkiego startu dla Codex/Cursor nadal wywoływały binarium z kolizją nazw (obecnie npx -y obsidian-mcp@2 serve we wszystkich trzech narzędziach, zgodnie ze składnią v2 zainstalowanego pakietu), jedno zdanie o PreToolUse wstrzykującym kontekst przetrwało poniżej przepisanej sekcji hooków (wskazówki dotyczące wstrzykiwania konsekwentnie prowadzą teraz przez UserPromptSubmit) oraz cztery jednolinijkowe błędy (niezrównoważony nawias, przestarzałe odniesienie do 1.13.4, wersja w 13, pozostałe zdanie roadmapy w 9). 24 26
2026-08-07 Obsidian 1.13 trafił do kanału publicznego: 1.13.4 awansował 30 lipca 2026 r. (zweryfikowano manifestem: desktop-releases.json latestVersion 1.13.4, beta.latestVersion 1.13.6). Zaktualizowano trzy odniesienia w tekście do „kanał publiczny pozostaje na 1.12.7”. Co linia 1.13 oferuje teraz, gdy jest ogólnie dostępna: przebudowę ustawień (osobne okno, wyszukiwanie według nazwy/opisu, nawigacja klawiaturą + Vim), pełnoekranową przeglądarkę obrazów z nawigacją po plikach i kontrolkami zmiany rozmiaru Live Preview, przeszukiwalne Bookmarks, wielokrotny wybór w Sync oraz — co najistotniejsze dla odbiorców tego przewodnika — bezpieczeństwo Obsidian URI: działania obsidian:// wymagają teraz okna potwierdzenia, chyba że znajdują się na liście dozwolonych. Opisana w tym przewodniku automatyzacja przebiega przez MCP i CLI, których to nie dotyczy, lecz każdy przepływ pracy sterujący Obsidian przez URI (Shortcuts, skrypty, inne programy uruchamiające) musi jednorazowo dodać działania do listy dozwolonych, w przeciwnym razie będzie wyświetlał monit za każdym razem. Dla deweloperów: nowe Settings API z przewodnikiem migracji, niekompatybilna zmiana --callout-color (wymaga prawidłowych kolorów CSS, a nie trójek RGB — motywy i snippets muszą zostać zaktualizowane), Electron 43.1.1 oraz aktualizacje CodeMirror i Mermaid 11.13.0. Brak zmian AI, MCP ani CLI. Śledzenie Catalyst przechodzi na 1.13.6. 26
2026-07-27 Przegląd wydań + korekta komunikatu. MCPVault przeszedł z 0.12.1 → 0.12.4 w trzech łatkach wydanych tego samego dnia, 23 lipca; wszystkie pominięto w przeglądzie z 22 lipca, ponieważ pojawiły się następnego dnia. v0.12.3 dodaje narzędzie wiki_link — rozwiązuje [[Document Name]], [[Name\|Display]], formy z escapowaniem tabel oraz #fragment, zwracając treść wraz z rozwiązaną ścieżką i niejednoznacznymi alternatywami — oraz wyklucza .trash/ ze wszystkich narzędzi przez domyślny filtr ścieżek; v0.12.4 rozszerza je na linki kwalifikowane ścieżką [[folder/Note]]; v0.12.2 naprawia patch_note, które uszkadzało wstawienia z wzorcem $, normalizuje ścieżki z prefiksem vaulta i usuwa ustalenia npm audit o wysokim poziomie ważności. Sekcja serwera MCP oraz [^24] opisują teraz wszystkie trzy wersje. Korekta: wiersz z 2026-07-07 stwierdzał, że v0.12.1 „zawiera dwa komunikaty o średniej ważności dotyczące filtra ścieżek”. To nieprawda. Komunikat GitHub Advisory API podaje dla GHSA-9c83-rr99-vfwj podatny zakres < 0.11.5, a dla GHSA-j99q-93c9-h869 < 0.11.4 — oba zostały naprawione przed otwarciem linii 0.12, więc 0.12.1 już nie był podatny, gdy pisano ten wiersz. Tekst i przypis podają teraz pierwsze wersje z poprawkami, zamiast sugerować otwartą ekspozycję zwrotem „uruchom bieżące wydanie”. Ponadto: Obsidian 1.13.4 na desktopie + urządzeniach mobilnych (27 lipca) to wczesny dostęp Catalyst; manifest desktop-releases.json nadal raportuje latestVersion 1.12.7 z beta.latestVersion 1.13.4, zatem kanał publiczny pozostaje bez zmian, a odniesienia do wersji tutaj są aktualne. Zawartość dotyczy UX (wyświetlanie nazwy pliku w lightboxie, wyrównanie i padding obrazów w Live Preview, wyścig zapisu z zablokowanym plikiem, układ ustawień), bez zmian AI, MCP ani CLI. 13 26
2026-07-22 Przegląd wydań, bez zmian w przepływie pracy. Obsidian 1.13.3 na desktopie + urządzeniach mobilnych (21 lipca) jest wyłącznie wczesnym dostępem Catalyst — zweryfikowany manifestem kanał publiczny pozostaje na 1.12.7; zawartość dotyczy UX (lightbox/zoom osadzonych obrazów, poprawka wysokości wiersza Live Preview, klawisze strzałek w File Recovery, poprawka paneType URI unique), bez zmian AI/MCP/CLI. Śledzenie Catalyst podnosi 1.13.2 → 1.13.3. Uwaga: 1.13.3 opublikowano później 21 lipca, po zakończeniu przeglądu z tego dnia — stwierdzenie w poprzednim wierszu o „braku nowych wydań” było prawidłowe w chwili zapisu. Web Clipper 1.7.1 (22 lipca, wydanie GitHub): Import highlights, zmienne szablonu Interpreter {{model}}/{{modelId}}/{{modelProvider}}, odświeżone presety dostawców, Defuddle 0.19.2, poprawki Interpreter dla niedawnych modeli Anthropic, natywne klucze Gemini API, obsługa DeepSeek i Azure OpenAI; wdrożenia w sklepie mogą nastąpić później niż data wydania GitHub. Brak oficjalnych wiadomości o serwerze MCP; bezstanowa specyfikacja nadal miała zostać wydana 28 lipca. 26
2026-07-21 Korekta dokładności: publiczny kanał desktopowy to 1.12.7, a nie 1.13.1. Wpis z 2026-06-10 (i odniesienia w tekście od tamtej pory) traktował 1.13.1 jako wydanie kanału publicznego; strona changelogu 1.13.1 ma oznaczenie Early access, a oficjalny manifest automatycznych aktualizacji (obsidianmd/obsidian-releases, desktop-releases.json) wskazuje publiczne latestVersion 1.12.7 oraz 1.13.2 w kanale beta — cała linia 1.13.x jest dostępna wyłącznie w Catalyst. Poprawiono odniesienia w tekście i 26. Przegląd wydań dla 2026-07-17 → 2026-07-21 nie znalazł nowych wydań: core pozostaje na 1.13.2 Catalyst, Clipper 1.7.0, brak oficjalnych wiadomości o serwerze MCP, bezstanowa specyfikacja MCP nadal miała zostać wydana 28 lipca. 26
2026-07-17 Przegląd wydań, bez zmian w przepływie pracy. Obsidian 1.13.2 (14 lipca) jest dostępny wyłącznie we wczesnym dostępie Catalyst — kanał publiczny pozostaje na 1.13.1, więc odniesienia do wersji tutaj pozostają aktualne; jedynym elementem związanym z przewodnikiem jest nowa zmienna url w szablonie iOS Share Sheet (wstawia udostępniony link do notatki), która zostanie włączona do sekcji ścieżki przechwytywania, gdy 1.13.2 trafi do wersji publicznej. Web Clipper 1.7.0 (16 czerwca, wcześniej nieobjęty): aktualizacja Defuddle 0.19.0, {{content}} zachowuje teraz markery ==highlight==, a zaznaczenia utrzymują się między aktywną stroną a widokiem Reader. Nie ogłoszono oficjalnego serwera Obsidian MCP ani integracji AI; bezstanowe wydanie specyfikacji MCP nadal zaplanowano na 28 lipca. Zweryfikowano względem obsidian.md/changelog, wydań github.com/obsidianmd/obsidian-clipper oraz blog.modelcontextprotocol.io.
2026-07-07 Korekty dokładności. MCPVault doprecyzowano jako osobny projekt (npm @bitbonsai/mcpvault, repozytorium bitbonsai/mcpvault), obecnie v0.12.1, zawierający dwa komunikaty o średniej ważności dotyczące filtra ścieżek (GHSA-9c83-rr99-vfwj, GHSA-j99q-93c9-h869) — wcześniejszy link [^24] wskazywał niewłaściwe repozytorium (MarkusPfundstein/mcp-obsidian). Skorygowano status MarkusPfundstein/mcp-obsidian: jest aktywnie utrzymywany (commity do 15 maja 2026 r., dodające search_by_tag/get_frontmatter), a nie „nieaktywny od czerwca 2025 r.”; nadal nie publikuje oznaczonych wydań. Zweryfikowano względem historii commitów GitHub, GitHub Security Advisories oraz npm.
2026-07-06 Redakcyjna restrukturyzacja dla lepszej znajdowalności: zmieniono tytuł „Quick Start: First AI-Connected Vault” na Obsidian MCP Setup (kotwica #obsidian-mcp-setup) oraz dodano podsumowanie możliwości „Co Claude może zrobić po połączeniu” (wyszukiwanie, odczyt, listowanie, sformatowany kontekst; granica tylko do odczytu, z zapisami obsługiwanymi przez hooki), skonsolidowane z sekcji architektury serwera MCP. Bez nowych faktów; zaktualizowano linki wewnętrzne.
2026-06-10 Aktualizacja bieżącej wersji. Obsidian 1.13.1 na desktopie trafił do kanału publicznego (9 czerwca 2026 r.) — to aktualizacja UX ustawień + CodeMirror względem 1.13.0, bez istotnych zmian AI/automatyzacji. Odniesienia do bieżącej wersji w tekście zmieniono z 1.13.0 na 1.13.1 (publiczna, 9 czerwca 2026 r.). 26
2026-06-09 Odświeżenie ekosystemu. Specyfikacja MCP 2026-07-28 weszła w Release Candidate (ogłoszono 21 maja 2026 r.) — największa rewizja MCP od premiery: bezstanowy rdzeń protokołu (usuwa handshake initialize oraz Mcp-Session-Id), MCP Apps (HTML renderowany po stronie serwera w sandboxowanych iframe), Tasks przechodzące z eksperymentalnego rdzenia do oficjalnego rozszerzenia, utwardzenie OAuth 2.0/OIDC oraz 12-miesięczna polityka cyklu wycofywania (ostateczna specyfikacja 28 lipca 2026 r.); zastąpiono spekulacyjne ujęcie roadmapy „wstępnie w połowie 2026 r.” w nocie o ewolucji specyfikacji MCP konkretnym RC. sqlite-vec v0.1.10-alpha (31 marca – 18 maja 2026 r.) dodaje typy indeksów approximate-nearest-neighbor (rescore, eksperymentalny ivf, oparty na dysku DiskANN) poza brute-force KNN — oznaczone jako perspektywiczne/eksperymentalne, ponieważ linia 0.1.10 nadal jest pre-release. Obsidian 1.13.0 na desktopie (wczesny dostęp, 28 maja 2026 r.) podniesiono do bieżącej wersji we wszystkich odniesieniach w tekście; jest to wydanie UX/bezpieczeństwa/narzędzi deweloperskich bez nowych możliwości AI/automatyzacji. 24 23 25
2026-06-08 Kontrola utrzymaniowa. Wydano Model2Vec v0.8.2 (29 maja 2026 r.): wydanie utrzymaniowe dodające opcję zamrożonych wag do treningu oraz poprawki tokenów wielowyrazowych, refaktoryzację treningu i poprawki obsługi wag niepoddanych kwantyzacji; zaktualizowano przypis. Nic innego nie jest nowsze od istniejącej bazy: najnowszy Obsidian nadal pozostaje na 1.13.0 (28 maja, już opisane poniżej), stabilne sqlite-vec nadal pozostaje na v0.1.9 (v0.1.10 wciąż alpha), a specyfikacja MCP nadal jest rewizją z 2025-11-25. Brak zmian w tekście poza notą o wersji Model2Vec. 10
2026-05-28 Wydano Obsidian 1.13.0 na desktopie + 1.13.0 na urządzeniach mobilnych (wczesny dostęp Catalyst). Desktop: odświeżony panel Settings otwierany w osobnym oknie z wbudowanym wyszukiwaniem i nawigacją klawiaturą; Obsidian URI wyświetlają teraz okno potwierdzenia przed uruchomieniem działań; nowe ostrzeżenie przed ładowaniem zasobów HTML z dysków sieciowych; dodano Search do widoku Bookmarks; ulepszono obsługę obrazów w edytorze; usprawnienia File Explorer / Properties / Sync; liczne poprawki deweloperskie-API i błędów. Urządzenia mobilne: nowy iOS Share Sheet z konfigurowalnymi lokalizacjami docelowymi; zmiana kolejności kart z przełącznika kart; gesty przytrzymania na tabletach do zmiany rozmiaru podziałów i przypiętych pasków bocznych; Bases zyskuje pozycję menu do zmiany szerokości kolumn w widokach tabeli; poprawki błędów iOS oraz wyszukiwania. Konsekwencje dla przepływów AI: okno potwierdzenia dla Obsidian URI dodaje celową bramkę do integracji MCP/agentów opartych na URI; menu zmiany rozmiaru kolumn Bases czyni Bases bardziej użytecznym jako indeks frontowy vaulta odpytywany przez agentów; konfigurowalny cel iOS Share Sheet sprawia, że ścieżkę przechwytywania z iPhone’a (już udokumentowaną jako główne wejście) można szybciej połączyć z pipeline’ami Claude/Codex.
2026-05-06 Odświeżono bieżący stan zweryfikowany źródłowo: Smart Connections v4.5.0 przeniósł footer connections do Core; stabilne wydania sqlite-vec v0.1.8/v0.1.9 zaktualizowały pakowanie i zachowanie DELETE; Model2Vec v0.8.x zaktualizował wewnętrzne elementy tokenizera/trwałości oraz tabele benchmarków; poprawiono chronologię Obsidian CLI z „1.12.7 wprowadził CLI” na „1.12.0 wprowadził CLI, a 1.12.7 ulepszył pakowanie instalacji/środowiska wykonawczego”.
2026-04-27 Kwietniowy cykl Web Clipper: 1.4.0 (interaktywny interfejs transkrypcji YouTube + domyślne Open in Reader), 1.5.0 (przeglądarka Highlights), 1.6.0 (gruntowna przebudowa UX Highlighter + ekstraktory źródeł Defuddle 0.18 dla LinkedIn/Threads/Bluesky/Discourse/Medium), 1.6.1 + 1.6.2 (poprawki Reader i Safari). Przeformułowano Web Clipper jako główną ścieżkę intake po stronie przeglądarki dla przepływów AI, zamiast przelotnej wzmianki o zakładkach. Brak wydań Obsidian desktop, Sync lub Bases w tym okresie.
2026-04-16 Smart Connections v4.3.0 (widok grafu, konfigurowalny dock, odzyskiwanie block-embedding, środowisko międzywtyczkowe Substrate). Udokumentowano falę wtyczek AI-native z kwietnia 2026 r. (Cortex, VaultSearch, LLM Wiki, Drift, EngramQuest, Hybrid Search MCP). Oznaczono MarkusPfundstein/mcp-obsidian jako działający w trybie utrzymaniowym (ostatni commit w czerwcu 2025 r.). Dataview jest nieaktywny; Bases to następca dla nowych prac. Obsidian CLI 1.12.7 pozostaje preferowanym mostem dla asystentów AI.
2026-04-01 Dodano sekcję Obsidian CLI (polecenia v1.12 dla przepływów AI). Dodano sekcję wtyczek agentów (Claudian, Agent Client). Udokumentowano podstawową wtyczkę Bases do organizacji vaulta. Zaktualizowano liczbę wtyczek do ponad 2 500. Dodano iOS Share Extension jako źródło intake. Zaktualizowano macierz zgodności o osadzone wtyczki agentów.
2026-03-30 MCPVault v0.11.0: narzędzie list_all_tags, obsługa .base/.canvas, zmiana nazwy na @bitbonsai/mcpvault. Obsidian Desktop v1.12.7 zawiera binarium CLI dla szybszych interakcji z terminalem.
2026-03-23 Udokumentowano stabilne sqlite-vec v0.1.7: obsługa DELETE dla tabel vec0, ograniczenia odległości KNN dla paginacji. Zapowiedziano indeks approximate nearest neighbor DiskANN dla nadchodzącego wydania.
2026-03-07 Dodano potion-multilingual-128M (101 języków, maj 2025 r.) do porównania modeli embedding. sqlite-vec na v0.1.7-alpha.10 (poprawki CI/CD, bez zmian funkcji). Potwierdzono aktualność specyfikacji MCP i technik retrieval.
2026-03-03 Zaktualizowano ewolucję specyfikacji MCP (wydano w listopadzie 2025 r.: Streamable HTTP, .well-known, adnotacje narzędzi). Dodano fine-tuning Model2Vec oraz obsługę tokenizera BPE/Unigram. Dodano tabelę porównawczą społecznościowych serwerów MCP. Zaktualizowano Smart Connections do v4.
2026-03-02 Dodano potion-base-32M i potion-retrieval-32M do porównania modeli. Dodano sekcję kwantyzacji/redukcji wymiarowości. Dodano notę o ewolucji specyfikacji MCP.
2026-03-01 Wydanie początkowe

Odniesienia


  1. Internet Vin, „22 commands I use with Obsidian and Claude Code,” marzec 2026, x.com/internetvin/status/2026461256677245131

  2. Nicopreme, umiejętność agenta „Visual Explainer” z poleceniami slash, x.com/nicopreme/status/2023495040258261460

  3. Cormack, G.V., Clarke, C.L.A. i Buettcher, S. Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods. SIGIR, 2009. Wprowadza RRF z k=60 jako bezparametrową metodę łączenia list rankingowych. 

  4. OpenAI Embeddings Pricing. text-embedding-3-small: 0,02 USD za milion tokenów. Szacowany koszt pełnego ponownego indeksowania vault: ~0,30 USD. 

  5. van Dongen, T. i in. Model2Vec: Turn any Sentence Transformer into a Small Fast Model. arXiv, 2025. Opisuje podejście destylacyjne tworzące statyczne embeddings z transformerów zdań. 

  6. potion-base-8M Model Card i Model2Vec results. Aktualne opublikowane tabele podają dla potion-base-8M wynik 51.32 Avg (All) / 51.08 Avg (MTEB), w porównaniu z 55.80 Avg (All) / 55.93 Avg (MTEB) dla all-MiniLM-L6-v2, czyli zachowanie około 92% wyniku dla wszystkich zadań. 

  7. Model Context Protocol Specification. Standard MCP do łączenia narzędzi AI ze źródłami danych. 

  8. Model2Vec Potion Models, potion-base-32M i potion-retrieval-32M. Aktualne karty modeli podają dla potion-base-32M wynik 52.83 Avg (All), a dla potion-retrieval-32M 35.06 w tabeli retrieval. 

  9. Update on the Next MCP Protocol Release. Historycznie: wydanie z listopada 2025 r. wprowadziło transport Streamable HTTP, wykrywanie adresów URL .well-known, ustrukturyzowane adnotacje narzędzi oraz standaryzację poziomów SDK. Zapowiedziany w nim cykl wydań zakończył się rewizją z 28 lipca 2026 r. — aktualną specyfikacją (zob. 24). 

  10. Model2Vec Releases. v0.4.0 (lut 2025): obsługa treningu/dostrajania. v0.5.0 (kwi 2025): przepisanie backendu, kwantyzacja, redukcja wymiarowości. v0.7.0 (paź 2025): kwantyzacja słownictwa, obsługa tokenizatorów BPE/Unigram. v0.8.0/v0.8.1 (mar 2026): refaktoryzacje tokenizatora i trwałego zapisu, wycofanie Python 3.9, aktualizacje wyników MTEB V2 oraz zgodność ze ścieżkami Windows. v0.8.2 (29 maja 2026): wydanie konserwacyjne dodające opcję zamrożonych wag dla treningu, a także poprawki tokenów wielowyrazowych, refaktoryzację treningu i poprawki obsługi niekwantyzowanych wag. 

  11. Smart Connections for Obsidian. Smart Connections v4: lokalne embeddings AI, wyszukiwanie semantyczne działa offline po początkowym indeksowaniu. 

  12. potion-multilingual-128M. Minish Lab, maj 2025. Model statycznych embeddings dla 101 języków, najlepiej działające wielojęzyczne statyczne embeddings. Ta sama zależność wyłącznie od numpy co w innych modelach potion. 

  13. MCPVault — bitbonsai/mcpvault. npm @bitbonsai/mcpvault, najnowsza v0.15.0 (opublikowana 2026-08-09); wszystkie wydania 0.12.2–0.12.4 ukazały się 2026-07-23 (0.12.2 o 09:51, 0.12.4 o 10:10 — 0.12.3 pojawia się w changelogu repozytorium między nimi, ale nigdy nie zostało opublikowane w npm); projekt odrębny od MarkusPfundstein/mcp-obsidian, a nie jego zmieniona nazwa. v0.11.0 (marzec 2026) dodała narzędzie list_all_tags do skanowania frontmatter i hashtagów wraz z liczbą wystąpień, usprawniła obsługę folderów z kropkami oraz obsługę plików .base/.canvas. Zawartość wersji 0.12.2–0.12.4 pochodzi z repozytoryjnego pliku CHANGELOG.md, który jest jedynym rejestrem wydań — endpoint wydań GitHub dla tego repozytorium zwraca pustą listę, więc podstawowymi źródłami są czasy publikacji npm i changelog. 0.12.2: patch_note wstawia newString dosłownie zamiast rozwijać $', $&, $`, $$ (issue #149 / PR #153); bezwzględne ścieżki z prefiksem vault lub w stylu ~/ normalizowane do ścieżek względnych względem vault (issue #122 / PR #151); ustalenia npm audit o wysokim poziomie istotności usunięto aktualizacjami wyłącznie lockfile (PR #154). 0.12.3: nowe narzędzie wiki_link (PR #101) oraz wykluczenie .trash/ ze wszystkich narzędzi za pomocą domyślnego filtra ścieżek. 0.12.4: wiki_link rozwiązuje odnośniki z kwalifikowaną ścieżką, takie jak [[folder/Note]], na podstawie pełnej ścieżki względnej względem vault, zamiast nazwy bazowej. Dwa ostrzeżenia GitHub Security Advisories o średnim poziomie istotności dotyczą jego filtra ścieżek: GHSA-9c83-rr99-vfwj (katalogi ograniczone tylko w katalogu głównym vault, nie w zagnieżdżeniach) oraz GHSA-j99q-93c9-h869 (obejście deny-list przez równoważność wielkości liter oraz końcowej kropki/spacji). Według API Advisory GitHub podatne zakresy to < 0.11.5 i < 0.11.4, a pierwsze poprawione wersje to odpowiednio 0.11.5 i 0.11.4 — obie poprzedzają 0.12.0, więc każda wersja 0.12.x, w tym 0.12.1, jest już poprawiona. Zakresy porad i znaczniki czasu npm ponownie zweryfikowano 2026-08-14. 

  14. sqlite-vec v0.1.7 Release. 17 marca 2026. Stabilne wydanie: obsługa DELETE dla tabel wirtualnych vec0, ograniczenia odległości KNN na potrzeby paginacji, usprawnienia testów fuzzingowych. Przybliżone indeksowanie najbliższych sąsiadów DiskANN zapowiedziano na przyszłe wydanie. 

  15. Introduction to Bases. Wtyczka podstawowa Obsidian wprowadzona w v1.9.10. Widoki podobne do baz danych (tabele, galerie, kalendarze, tablice kanban) dla plików vault, używające właściwości frontmatter jako pól. Pliki są zapisywane w formacie .base

  16. Obsidian Desktop v1.12.0 Changelog i Obsidian Desktop v1.12.7 Changelog. v1.12.0 wprowadziła CLI do automatyzacji vault z terminala; v1.12.7 usprawniła pakowanie instalacji/środowiska uruchomieniowego za pomocą samodzielnego pliku binarnego, TUI i obsługi plików socket. Zob. także dokumentację CLI

  17. Claudian. Wtyczka Obsidian, która osadza Claude Code jako współpracownika AI w vault. Udostępnia czat na pasku bocznym, prompty uwzględniające kontekst, obsługę vision, polecenia slash oraz tryby uprawnień. 

  18. Agent Client. Wtyczka Obsidian zapewniająca ujednolicony interfejs dla Claude Code, Codex CLI i Gemini CLI za pośrednictwem Agent Client Protocol (ACP). Obsługuje wzmianki o notatkach, wykonywanie powłoki i zatwierdzanie działań. 

  19. Obsidian iOS Changelog. Aktualizacje z początku 2026 r. obejmują Share Extension do zapisywania treści z innych aplikacji bezpośrednio w vault, poprawki widżetów Daily Note i Bookmark oraz usprawnienia odświeżania widżetu View Note. 

  20. MarkusPfundstein/mcp-obsidian. Aktywnie utrzymywany — commity do 15 maja 2026 r., a ostatnie prace dodały narzędzia, w tym search_by_tag i get_frontmatter, oraz rozszerzyły pokrycie testami (zweryfikowano względem historii commitów repozytorium i tools.py). Nadal nie oferuje oznaczonych wydań, dlatego należy instalować z przypiętego commitu. Oparty na Local-REST-API; dyskusje na forum (kwiecień 2026) wskazują na migrację społeczności ku pierwszorzędnemu mostowi Obsidian CLI (1.12.x) w nowych konfiguracjach, lecz mcp-obsidian pozostaje działającą i aktualizowaną opcją dla istniejących wdrożeń REST-API. 

  21. Smart Connections v4.5.0 Release. 5 maja 2026. Połączenia w stopce stały się funkcją Core; ostatnie wydania v4 obejmują również widoki grafu dla list połączeń, konfigurowalne lokalizacje panelu połączeń, lepsze odzyskiwanie block-embedding, stan między wtyczkami Substrate, poprawki fallbacku transformerów oraz ograniczenie zduplikowanych obliczeń połączeń. 

  22. obsidianmd/obsidian-clipper releases — źródło pierwotne mapowania wersji Web Clipper na funkcje. Cykl z kwietnia 2026: 1.4.0 (9 kwi, interfejs transkrypcji YouTube + domyślne Open in Reader), 1.5.0 (15 kwi, przeglądarka Highlights + zanikanie Reader), 1.5.1 (15 kwi, poprawka kompilacji webpack), 1.6.0 (21 kwi, UX Highlighter + Defuddle 0.18 z ekstraktorami LinkedIn/Threads/Bluesky/Discourse/Medium), 1.6.1 (22 kwi, poprawki konspektu Reader + wyszukiwanie highlights), 1.6.2 (23 kwi, poprawka schowka Safari w trybie osadzonym). Wymienione również w Mozilla Add-ons store i Chrome Web Store

  23. sqlite-vec v0.1.8, sqlite-vec v0.1.9, sqlite-vec v0.1.10-alpha.3 i sqlite-vec v0.1.10-alpha.4. v0.1.8 naprawiła pakowanie npm; v0.1.9 naprawiła błąd DELETE dla tekstowych kolumn metadanych dłuższych niż 12 znaków; v0.1.10-alpha.3 dodaje prawidłową obsługę INSERT OR REPLACE INTO; v0.1.10-alpha.4 (18 maja 2026) naprawia niepowodzenie ALTER TABLE RENAME w tabelach vec0 korzystających z nowych funkcji ivf/diskann oraz błąd czyszczenia buforowanych instrukcji w DiskANN. Linia 0.1.10 nadal ma status prerelease. 

  24. MCP 2026-07-28 Specification Release Candidate. Ogłoszono 21 maja 2026 r.; ostateczna specyfikacja została wydana 28 lipca 2026 r. Największa rewizja MCP od premiery: bezstanowy rdzeń protokołu (usuwa uzgadnianie initialize i nagłówek Mcp-Session-Id), MCP Apps (HTML renderowany po stronie serwera w sandboxowanych iframe klienta), Tasks przechodzące z eksperymentalnego rdzenia do oficjalnego rozszerzenia (tasks/get, tasks/update, tasks/cancel), wzmocnienie autoryzacji OAuth 2.0 / OIDC oraz polityka 12-miesięcznego cyklu wycofywania funkcji. 

  25. Obsidian Desktop v1.13.0 Changelog. Wczesny dostęp, 28 maja 2026. Wydanie dotyczące UX/bezpieczeństwa/narzędzi programistycznych: odświeżony panel Settings, otwierany w osobnym oknie z wyszukiwaniem i nawigacją klawiaturą, okna potwierdzenia przed uruchomieniem URI Obsidian, nowy API Settings dla twórców wtyczek oraz poprawka CLI dla instalacji flatpak. Brak znaczących nowych możliwości AI/automatyzacji poza powierzchnią CLI z wersji 1.12.x. 

  26. Obsidian Changelog. Obsidian 1.13.1 desktop wydano 9 czerwca 2026 r. jako wydanie Catalyst w ramach wczesnego dostępu — dopracowanie UX ustawień i aktualizację CodeMirror względem 1.13.0, bez nowych możliwości AI/automatyzacji. Sama strona changelogu 1.13.1 ma oznaczenie „Early access”, a oficjalny manifest automatycznych aktualizacji (obsidianmd/obsidian-releases, desktop-releases.json) wskazuje publiczne latestVersion 1.12.7 oraz 1.13.2 w kanale beta; zweryfikowano 2026-07-21. Ponownie zweryfikowano 2026-07-27: manifest nadal wskazuje latestVersion 1.12.7, a beta.latestVersion to teraz 1.13.4. Kanał Atom pod adresem obsidian.md/changelog.xml oznacza każdy wpis 1.13.x — od 1.13.1 do 1.13.4 — jako „(Early access)”; najnowszym wpisem zatytułowanym „(Public)” pozostaje 1.12.7 z datą 2026-03-23, co odpowiada liście wydań GitHub obsidian-releases. Ponownie zweryfikowano 2026-08-07: manifest wskazuje teraz latestVersion 1.13.4 (publiczna promocja 30 lipca 2026 r.) oraz beta.latestVersion 1.13.6 — linia 1.13 jest ogólnie dostępna, a powyższe historyczne wiersze poprawnie opisują okres wyłącznie Catalyst zgodnie z datami. Ponownie zweryfikowano 2026-08-14: manifest wskazuje latestVersion 1.13.7 oraz beta.latestVersion 1.13.7 — wersje stabilna i beta są zbieżne. 

VAULT obsidian.md INDEXED