obsidian:~/vault$ search --hybrid obsidian

Obsidian MCP + wyszukiwanie hybrydowe: dokumentacja referencyjna 2026

# Połączenie Obsidian z Claude i innymi agentami przez MCP: konfiguracja serwera, hybrydowe wyszukiwanie BM25 + wektorowe oraz indeksowanie vaultu z 16 894 plikami — z działającymi konfiguracjami.

words: 14453 read_time: 55m updated: 2026-07-07 21:50
$ 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.


Kluczowe wnioski

Inżynieria kontekstu, nie robienie notatek. Wartością skarbca Obsidian dla AI nie są same notatki, lecz warstwa wyszukiwania, która sprawia, że można je odpytywać. Skarbiec z 16 000 plików bez wyszukiwania jest bazą danych tylko do zapisu. Skarbiec z 200 plikami, wyszukiwaniem hybrid i integracją MCP jest bazą wiedzy AI. Infrastruktura wyszukiwania jest produktem. Notatki są surowcem.

Wyszukiwanie hybrid wygrywa z czysto słowem kluczowym lub czysto semantycznym wyszukiwaniem. BM25 wychwytuje dokładne identyfikatory i nazwy funkcji. Wyszukiwanie wektorowe wychwytuje synonimy i dopasowania pojęciowe między różnymi terminologiami. Reciprocal Rank Fusion (RRF) scala oba podejścia bez konieczności kalibracji wyników. Żadna z tych metod osobno nie obejmuje obu trybów awarii. Badania nad rankingiem fragmentów MS MARCO potwierdzają ten wzorzec: wyszukiwanie hybrid konsekwentnie przewyższa każdą z metod stosowaną w izolacji.3 Dogłębna analiza hybrydowego retrievera omawia matematykę RRF, przykłady z rzeczywistymi liczbami, analizę trybów awarii oraz interaktywny kalkulator fuzji.

MCP daje narzędziom AI bezpośredni dostęp do skarbca. Serwery Model Context Protocol (MCP) udostępniają retriever jako narzędzie, które Claude Code, Codex CLI, Cursor i inne narzędzia AI mogą wywoływać bezpośrednio. Agent odpytuje skarbiec, otrzymuje uszeregowane wyniki z atrybucją źródeł i korzysta z kontekstu bez ładowania całych plików. Serwer MCP jest cienką warstwą opakowującą silnik wyszukiwania.

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 słów kluczowych, sqlite-vec do wektorowego KNN. Bez usług chmurowych, bez wywołań API, bez zależności od sieci. Prywatne notatki nigdy nie opuszczają komputera. Pełne ponowne osadzenie 49 746 fragmentów kosztowałoby około 0,30 USD według cen OpenAI API, ale prawdziwymi kosztami są opóźnienia, ekspozycja prywatności 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. Tylko zmodyfikowane pliki są ponownie dzielone na fragmenty i ponownie osadzane. Pełne ponowne indeksowanie zajmuje około czterech minut na sprzęcie Apple M-series. Aktualizacje przyrostowe po typowych dziennych edycjach wykonują się w 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 (pobieranie, wyszukiwanie, integracja) działa przy dowolnym rozmiarze skarbca. W małym skarbcu można zacząć od wyszukiwania tylko BM25. Wyszukiwanie wektorowe warto dodać, gdy kolizje słów kluczowych stają się problemem. Fuzję RRF warto dodać, gdy potrzebne są zarówno dopasowania dokładne, jak i semantyczne. Każda warstwa jest niezależnie użyteczna i niezależnie usuwalna.


Jak korzystać z tego przewodnika

Ten przewodnik obejmuje kompletny system. Punkt startowy zależy od aktualnej sytuacji:

Jest Pan/Pani… Proszę zacząć tutaj Następnie warto przejrzeć
Nowy/nowa w Obsidian + AI Dlaczego Obsidian dla infrastruktury AI, Konfiguracja Obsidian MCP Architektura skarbca, Architektura serwera MCP
Ma Pan/Pani istniejący skarbiec i chce dostępu AI Architektura serwera MCP, Integracja Claude Code Modele embeddings, Wyszukiwanie pełnotekstowe
Buduje Pan/Pani system wyszukiwania Kompletny pipeline wyszukiwania, Reciprocal Rank Fusion Dostrajanie wydajności, Rozwiązywanie problemów
Pracuje Pan/Pani w kontekście zespołu lub przedsiębiorstwa Ramy decyzyjne, Wzorce grafu wiedzy Przepisy przepływu pracy dla developerów, Przewodnik migracji

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


Dlaczego Obsidian dla infrastruktury AI

Teza tego przewodnika: skarbce Obsidian są najlepszym podłożem dla osobistych baz wiedzy AI, ponieważ są local-first, oparte na plikach plaintext, ustrukturyzowane grafowo, a użytkownik kontroluje każdą warstwę stosu.

Co Obsidian daje AI, czego nie dają alternatywy

Pliki markdown plaintext. Każda notatka jest plikiem .md w systemie plików. Bez własnościowego formatu, bez eksportu bazy danych, bez API wymaganych do odczytu treści. Każde narzędzie, które czyta pliki, może czytać skarbiec. grep, ripgrep, pathlib z Python, SQLite FTS5 — wszystkie działają bezpośrednio na plikach źródłowych. Gdy buduje się system wyszukiwania, indeksuje się pliki, a nie odpowiedzi API. Indeks jest zawsze spójny ze źródłem, ponieważ źródłem jest system plików.

Architektura local-first. Skarbiec znajduje się na komputerze użytkownika. Bez serwera, bez zależności od synchronizacji w chmurze, bez limitów szybkości API, bez regulaminu usługi określającego, jak można przetwarzać własne treści. Można osadzać, indeksować, dzielić na fragmenty i przeszukiwać notatki bez żadnej zewnętrznej usługi. Ma to znaczenie dla infrastruktury AI, ponieważ pipeline wyszukiwania działa tak szybko, jak pozwala dysk, a nie tak szybko, jak odpowiada endpoint API. Ma to również znaczenie dla prywatności: osobiste notatki zawierające dane uwierzytelniające, dane zdrowotne, informacje finansowe i prywatne refleksje nigdy nie opuszczają komputera.

Struktura grafu przez wiki-link. Składnia [[wiki-link]] w Obsidian tworzy graf skierowany między notatkami. Notatka o implementacji OAuth linkuje do notatek o rotacji tokenów, zarządzaniu sesją i bezpieczeństwie API. Struktura grafu koduje ręcznie dobrane przez człowieka relacje między pojęciami. Wektorowe embeddings wychwytują podobieństwo semantyczne, ale wiki-links wychwytują celowe połączenia, które autor utworzył, myśląc o temacie. Graf jest sygnałem, którego embeddings nie potrafią odtworzyć.

Ekosystem pluginów. Obsidian ma ponad 2 500 pluginów społecznościowych (stan na marzec 2026, wzrost z ponad 1 800 w połowie 2025 roku). Dataview odpytuje skarbiec jak bazę danych. Templater generuje notatki z szablonów przy użyciu logiki JavaScript. Integracja z Git synchronizuje skarbiec z repozytorium. Linter wymusza spójność formatowania. Podstawowy plugin Bases (wprowadzony w v1.9.10) dodaje widoki podobne do baz danych — tabele, galerie, kalendarze i tablice kanban — nad plikami skarbca, używając właściwości frontmatter jako pól i zapisując je jako pliki .base.15 Te pluginy dodają strukturę do skarbca bez zmiany bazowego formatu plaintext. System wyszukiwania indeksuje wynik działania tych pluginów, a nie same pluginy.

Ponad 5 milionów użytkowników. Obsidian ma dużą aktywną społeczność tworzącą szablony, przepływy pracy, pluginy i dokumentację. Gdy pojawia się problem z organizacją skarbca lub konfiguracją pluginu, ktoś najprawdopodobniej opisał już rozwiązanie. Społeczność tworzy również narzędzia wokół Obsidian: serwery MCP, skrypty indeksujące, pipeline’y publikacji i wrappery API.

Czego nie daje sam system plików

Katalog plików markdown ma przewagę plaintext, ale brakuje mu trzech elementów, które dodaje Obsidian:

  1. Linki dwukierunkowe. Obsidian automatycznie śledzi backlinks. Gdy tworzy się link z Notatki A do Notatki B, Notatka B pokazuje, że Notatka A się do niej odwołuje. Panel grafu wizualizuje klastry połączeń. Ta dwukierunkowa świadomość jest metadanymi, których surowy system plików nie zapewnia.

  2. Podgląd na żywo z renderowaniem pluginów. Zapytania Dataview, diagramy Mermaid i bloki callout renderują się w czasie rzeczywistym. Doświadczenie pisania jest bogatsze niż w edytorze tekstu, podczas gdy format przechowywania pozostaje plaintext. Pisze się i organizuje w bogatym środowisku; system wyszukiwania indeksuje surowy markdown.

  3. Infrastruktura społecznościowa. Odkrywanie pluginów, marketplace motywów, usługa synchronizacji (opcjonalna), usługa publikacji (opcjonalna) i ekosystem dokumentacji. Każdą pojedynczą funkcję można odtworzyć samodzielnymi narzędziami, ale Obsidian łączy je w spójny przepływ pracy.

Czego Obsidian NIE robi (i co trzeba zbudować)

Obsidian nie zawiera infrastruktury wyszukiwania. Ma podstawowe wyszukiwanie (pełnotekstowe, po nazwie pliku, po tagu), ale nie ma pipeline’u 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 opisuje infrastrukturę, którą buduje się na Obsidian. Skarbiec jest podłożem. Pipeline wyszukiwania, serwer MCP i hooki integracyjne są infrastrukturą.

Opisana tutaj architektura jest markdown-first, nie wyłącznie Obsidian. Jeśli używa Pan/Pani Logseq, Foam, Dendron albo zwykłego katalogu plików markdown, pipeline wyszukiwania działa identycznie. Chunker odczytuje pliki .md. Embedder przetwarza ciągi tekstowe. Indexer zapisuje do SQLite. Żaden z tych komponentów nie zależy od funkcji specyficznych dla Obsidian. Wkładem Obsidian jest środowisko pisania i organizacji, które wytwarza 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 vault Obsidian. Ta sekcja pozwala połączyć vault z narzędziem AI w pięć minut. Należy zainstalować Obsidian, utworzyć vault, zainstalować serwer MCP i uruchomić pierwsze zapytanie. Szybki start wykorzystuje społecznościowy serwer MCP, aby od razu uzyskać wyniki. W dalszych sekcjach opisano budowę niestandardowego pipeline’u wyszukiwania do zastosowań produkcyjnych.

Wymagania wstępne

  • macOS, Linux lub Windows
  • Node.js 18+ (dla serwera MCP)
  • Obsidian 1.12+ (dla integracji CLI; 1.13.1 to aktualne publiczne wydanie desktopowe; wcześniejsze wersje działają w konfiguracjach wyłącznie z MCP)
  • Zainstalowany Claude Code, Codex CLI lub Cursor

Krok 1: Utworzenie vault

Proszę pobrać Obsidian z obsidian.md i utworzyć nowy vault. Warto wybrać lokalizację, którą łatwo zapamiętać — serwer MCP potrzebuje ścieżki bezwzględnej.

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

Proszę dodać kilka notatek, aby mechanizm wyszukiwania miał na czym pracować. Nawet 10-20 notatek wystarczy, aby zobaczyć wyniki. Każda notatka powinna być plikiem .md ze znaczącym tytułem i co najmniej jednym akapitem treści.

Krok 2: Instalacja serwera MCP

Kilka społecznościowych serwerów MCP zapewnia natychmiastowy dostęp do vault. Ekosystem znacząco urósł w latach 2025-2026. Jednym z godnych uwagi przykładów jest MCPVault (npm @bitbonsai/mcpvault, repo bitbonsai/mcpvault), obecnie w wersji v0.12.1 — to osobny projekt względem MarkusPfundstein/mcp-obsidian poniżej, a nie jego nowa nazwa. Wersja v0.11.0 (marzec 2026) dodała list_all_tags do skanowania frontmatter i hashtagów wraz z licznikami, ulepszyła obsługę folderów z kropkami w nazwie oraz dodała obsługę .base/.canvas. Dwa alerty o średnim poziomie istotności (GHSA-9c83-rr99-vfwj oraz GHSA-j99q-93c9-h869) ujawniono w związku z listą blokad katalogów ograniczonych przez filtr ścieżek, dlatego należy uruchamiać aktualne wydanie.13

Zmiana z kwietnia 2026 — Obsidian CLI jako preferowany most: Obsidian 1.12.0 wprowadził pełnoprawny CLI, a publiczny instalator 1.12.7 (23 marca 2026) zawierał samodzielny binarny plik wykonywalny, TUI oraz usprawnienia pliku socket, które ułatwiły instalację i uruchamianie terminalowych workflow.16 Aktualne publiczne wydanie desktopowe, 1.13.1 (kanał publiczny, 9 czerwca 2026), jest aktualizacją wersji względem 1.13.0 — dopracowuje UX ustawień i aktualizuje CodeMirror — bez nowych możliwości AI/automatyzacji wykraczających poza powierzchnię CLI z 1.12.x.2526 Narzędzia społecznościowe aktywnie migrują z wtyczki Local REST API (która zasilała mcp-obsidian) do integracji opartej na CLI, ponieważ jest szybsza i stabilniejsza. Repo MarkusPfundstein/mcp-obsidian jest nadal utrzymywane — commity do maja 2026 dodały narzędzia, w tym search_by_tag i get_frontmatter — choć nie publikuje tagowanych wydań (instalacja z przypiętego commita). Nadal opiera się na Local REST API; dla nowych konfiguracji most CLI jest zazwyczaj szybszy i stabilniejszy, więc warto preferować go albo nowsze alternatywy społecznościowe wymienione poniżej.20 Zalecaną konfigurację opisuje dalsza sekcja „Obsidian CLI dla workflow AI”.

Serwer Autor Transport Wymaga wtyczki Kluczowa funkcja
obsidian-mcp-server StevenStavrakis STDIO Nie Lekki, oparty na plikach
mcp-obsidian MarkusPfundstein STDIO Local REST API Pełny CRUD vault przez REST oraz search_by_tag/get_frontmatteraktywnie utrzymywany (commity do maja 2026); bez tagowanych wydań, 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 cyanheads STDIO Local REST API Tagi, zarządzanie frontmatter
Hybrid Search MCP społeczność STDIO Nie Serwer MCP z BM25 + wyszukiwaniem semantycznym + CLI. Nowy i aktywnie utrzymywany według stanu na kwiecień 2026.

Na potrzeby szybkiego startu najprostszą opcją jest serwer oparty na plikach, który bezpośrednio czyta pliki .md:

npm install -g obsidian-mcp-server

Krok 3: Konfiguracja narzędzia AI

Claude Code — dodać do ~/.claude/settings.json:

{
  "mcpServers": {
    "obsidian": {
      "command": "obsidian-mcp-server",
      "args": ["--vault", "/absolute/path/to/your/vault"]
    }
  }
}

Codex CLI — dodać do .codex/config.toml:

[mcp_servers.obsidian]
command = "obsidian-mcp-server"
args = ["--vault", "/absolute/path/to/your/vault"]

Cursor — dodać do .cursor/mcp.json:

{
  "mcpServers": {
    "obsidian": {
      "command": "obsidian-mcp-server",
      "args": ["--vault", "/absolute/path/to/your/vault"]
    }
  }
}

Krok 4: Uruchomienie pierwszego zapytania

Proszę otworzyć narzędzie AI i zadać pytanie, na które mogą odpowiedzieć notatki w vault:

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

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

Co Claude może robić po połączeniu

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

Możliwość Typowe narzędzie Co agent z tym robi
Przeszukiwanie vault obsidian_search / search Znajduje notatki pasujące do zapytania i zwraca uszeregowane fragmenty ze ścieżkami plików oraz atrybucją źródła
Odczyt pełnej notatki obsidian_read_note / read_note Pobiera pełną treść notatki, gdy fragment z wyszukiwania nie wystarcza
Listowanie i przeglądanie obsidian_list_notes / list_notes Eksploruje notatki według folderu, tagu lub zakresu dat, gdy nie ma konkretnego zapytania
Pobranie sformatowanego kontekstu obsidian_get_context Zwraca blok kontekstu ukształtowany wokół tematu, dopasowany do budżetu tokenów i gotowy do wstrzyknięcia do rozmowy

W praktyce: Claude odpowiada na pytania na podstawie notatek z atrybucją źródła, wciąga wcześniejsze decyzje i materiały referencyjne do sesji kodowania oraz eksploruje strukturę vault bez ładowania całych plików do kontekstu. Niektóre serwery społecznościowe udostępniają też operacje zapisu (tworzenie, dopisywanie, zarządzanie tagami i frontmatter); niestandardowy serwer budowany dalej w tym przewodniku jest celowo tylko do odczytu, a tworzenie notatek obsługują hooki.

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

Co właśnie powstało

Lokalna baza wiedzy została połączona z narzędziem AI przez standardowy protokół. Serwer MCP czyta pliki vault, wykonuje podstawowe wyszukiwanie i zwraca wyniki. To minimalna działająca wersja.

Czego ten szybki start NIE zapewnia: - Wyszukiwania hybrydowego (BM25 + wyszukiwanie wektorowe + fuzja RRF) - Wyszukiwania semantycznego opartego na embeddings - Filtrowania poświadczeń - Indeksowania przyrostowego - Automatycznego wstrzykiwania kontekstu opartego na hookach

Pozostała część tego przewodnika opisuje budowę każdej z tych możliwości. Szybki start potwierdza koncepcję. Pełny pipeline zapewnia wyszukiwanie o jakości produkcyjnej.


Obsidian CLI dla AI Workflows

Obsidian 1.12 (luty 2026) wprowadził wbudowany interfejs wiersza poleceń, który otwiera nową powierzchnię integracji dla AI workflows; pozostaje on aktualny także w publicznym desktopowym wydaniu 1.13.1 (kanał publiczny, 9 czerwca 2026), czyli aktualizacji UX ustawień i wersji CodeMirror bez nowych możliwości CLI.162526 CLI działa jak pilot zdalnego sterowania dla GUI Obsidian — Obsidian musi być uruchomiony (albo uruchomi się automatycznie przy pierwszym poleceniu). Należy włączyć go 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 albo API wtyczki. W AI workflows kluczowe możliwości to:

  • Wyszukiwanie ze skryptów i hooków. obsidian search "query" oraz obsidian search:context "query" uruchamiają wyszukiwania w vault z dowolnego skryptu shell, hooka albo pipeline’u automatyzacji. Wariant search:context zwraca pasujące wiersze z otaczającym kontekstem, co przydaje się przy przekazywaniu wyników do promptów AI.
  • Automatyzacja notatek dziennych. obsidian daily otwiera albo tworzy dzisiejszą notatkę dzienną. W połączeniu ze skryptami shell umożliwia to zautomatyzowane workflows dziennych briefingów — hook może dopisywać podsumowania wygenerowane przez AI do notatki dziennej.
  • Tworzenie notatek na podstawie szablonów. obsidian template list oraz obsidian template create generują notatki z Templater albo szablonów podstawowych, umożliwiając agentom AI tworzenie ustrukturyzowanych wpisów w vault bez bezpośredniego zapisywania plików markdown.
  • Zarządzanie właściwościami. obsidian property set oraz obsidian property get odczytują i zapisują właściwości frontmatter, umożliwiając aktualizacje metadanych ze skryptów bez parsowania YAML.
  • Kontrola wtyczek. obsidian plugin enable/disable/list zarządza wtyczkami programowo, co przydaje się do przełączania wtyczek indeksujących podczas operacji wsadowych.
  • Zarządzanie zadaniami. obsidian task list/add/complete zapewnia ustrukturyzowany dostęp do zadań, przydatny dla agentów AI zarządzających elementami pracy w vault.

CLI kontra MCP dla dostępu AI

Serwery CLI i MCP pełnią różne role i są komplementarne, a nie konkurencyjne:

Aspekt Obsidian CLI Serwer MCP
Wywołujący Skrypty shell, hooki, zadania cron Agenci AI (Claude Code, Codex, Cursor)
Protokół Proces POSIX (stdin/stdout/stderr) MCP (JSON-RPC przez STDIO albo HTTP)
Mocna strona Natywne operacje Obsidian (szablony, wtyczki, właściwości) Niestandardowe wyszukiwanie (embeddings, BM25, fuzja RRF)
Ograniczenie Brak wyszukiwania wektorowego, brak pipeline’u embeddingów Brak dostępu do wewnętrznych operacji Obsidian
Najlepsze zastosowanie Skrypty automatyzacji, pipeline’y przyjmowania danych, działania hooków Zapytania agentów AI w czasie rzeczywistym podczas sesji

Rekomendacja: Warto używać CLI do automatyzacji przyjmowania danych (tworzenia notatek, zarządzania właściwościami, uruchamiania natywnego wyszukiwania Obsidian), a MCP do retrievalu (wyszukiwania hybrydowego z embeddings). Hook PreToolUse może wywołać obsidian search:context jako szybkie sprawdzenie wstępne przed przejściem do pełnego retrievera MCP dla rankingowanych wyników.

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 UI vault, zapewniając alternatywę dla konfiguracji zewnętrznego serwera MCP. Te wtyczki uruchamiają agenta AI w 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, dając mu pełne możliwości agentowe: odczyt/zapis plików, wyszukiwanie, polecenia bash i wieloetapowe workflows.17

Kluczowe funkcje dla infrastruktury AI: - Prompty świadome kontekstu. Automatycznie dołącza aktywną notatkę, obsługuje wzmianki plików @notename, wykluczanie na podstawie tagów oraz zaznaczenie w edytorze jako kontekst. - Obsługa obrazu. Analiza obrazów przez przeciąganie i upuszczanie, wklejanie albo ścieżkę pliku — przydatna przy przetwarzaniu zrzutów ekranu i diagramów zapisanych w vault. - Polecenia slash. Tworzenie wielokrotnego użytku szablonów promptów wyzwalanych przez /command, co umożliwia standaryzację operacji w vault. - Tryby uprawnień. Tryby YOLO (automatyczna akceptacja), Safe (akceptacja każdej akcji) oraz Plan (tylko planowanie), z listą blokad bezpieczeństwa i ograniczeniem do vault.

Agent Client

Agent Client wprowadza Claude Code, Codex CLI oraz Gemini CLI do ujednoliconego paska bocznego Obsidian przez Agent Client Protocol (ACP).18

Kluczowe funkcje: - Przełączanie wielu agentów. Rozmowa z Claude Code, Codex albo Gemini CLI z tego samego panelu, z możliwością przełączania agentów według potrzeb. - Wzmianki notatek. Użycie @notename pozwala dołączyć treść notatki do promptów, podobnie jak w Claudian, ale niezależnie od agenta. - Wykonywanie poleceń shell. Wykonywanie poleceń terminala bezpośrednio w czacie — skryptów budowania, poleceń git albo dowolnych operacji terminalowych bez opuszczania rozmowy. - Akceptacja działań. Szczegółowa kontrola nad odczytami plików, edycjami i wykonaniami poleceń.

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

Scenariusz Wtyczka agenta Zewnętrzny MCP
Pisanie i edytowanie notatek w vault z pomocą AI Lepsze — agent widzi kontekst edytora Działa, ale bez świadomości edytora
Rozwój kodu w wielu repozytoriach Ograniczone — zakres vault Lepsze — zakres projektu z pełnym systemem plików
Retrieval z dużego zindeksowanego korpusu Tylko podstawowe wyszukiwanie Pełny pipeline hybrydowego retrievalu
Szybkie Q&A w vault podczas sesji robienia notatek Idealne — bez przełączania kontekstu Wymaga przełączenia do terminala

Rekomendacja: Warto używać wtyczek agentów do workflows skoncentrowanych na vault (pisania, organizowania, podsumowywania notatek). Zewnętrznych serwerów MCP należy używać do workflows programistycznych, w których agent AI potrzebuje pełnego pipeline’u retrievalu i dostępu do baz kodu poza vault. Oba podejścia mogą współistnieć — Claudian może działać wewnątrz Obsidian do pracy z notatkami, a Claude Code z MCP zewnętrznie do pracy programistycznej.


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 możliwości oraz granice uprawnień.

Wybór protokołu: STDIO vs HTTP

MCP obsługuje dwa tryby transportu:

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

{
  "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 samodzielna usługa HTTP. Przydaje się do zdalnego dostępu, konfiguracji z wieloma klientami albo konfiguracji zespołowych, w których vault znajduje się na współdzielonym serwerze.

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

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

Ewolucja specyfikacji MCP. Specyfikacja MCP z czerwca 2025 dodała autoryzację OAuth 2.1, strukturalne wyniki narzędzi (typowane schematy zwrotne) oraz elicitation (monity użytkownika inicjowane przez serwer). Wydanie z listopada 2025 wprowadziło Streamable HTTP jako pełnoprawny tryb transportu, wykrywanie URL .well-known do automatycznego przeglądania możliwości serwera, strukturalne adnotacje narzędzi deklarujące, czy narzędzie jest tylko do odczytu, czy modyfikujące, oraz system standaryzacji poziomów SDK.79 Następna rewizja jest już konkretna: specyfikacja 2026-07-28 weszła w fazę Release Candidate 21 maja 2026 — to największa rewizja MCP od momentu uruchomienia. Jej główne zmiany to bezstanowy rdzeń protokołu (usunięto handshake 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 klienta), Tasks przechodzące z eksperymentalnego rdzenia do oficjalnego rozszerzenia (tasks/get, tasks/update, tasks/cancel dla długotrwałych operacji), wzmocnioną autoryzację OAuth 2.0 / OIDC oraz 12-miesięczną politykę cyklu życia wycofywania funkcji. Finalna specyfikacja zostanie opublikowana 28 lipca 2026.24 W przypadku osobistych serwerów vaultów STDIO pozostaje najprostszą ścieżką, a bezstanowy rdzeń sprawia, że jednoosobowe serwery STDIO stają się jeszcze lżejsze. Transport Streamable HTTP, wykrywanie .well-known i MCP Apps przynoszą korzyści przede wszystkim wdrożeniom HTTP w przedsiębiorstwach, z routingiem wielodzierżawnym i równoważeniem obciążenia. Warto monitorować roadmapę MCP, aby śledzić aktualizacje wpływające na wybór transportu.

Projekt możliwości

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

search — Podstawowe narzędzie. Uruchamia wyszukiwanie hybrydowe i zwraca uszeregowane wyniki.

{
  "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ą treść konkretnej 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 do 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 — Wygodne narzędzie, które uruchamia wyszukiwanie i formatuje wyniki jako blok kontekstu odpowiedni do wstrzyknięcia 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) są obsługiwane przez oddzielne hooki lub skills, a nie przez serwer MCP.

  2. Ograniczenie do vaultu. Serwer odczytuje wyłącznie pliki znajdujące się w skonfigurowanej ścieżce vaultu. Próby path traversal (../../etc/passwd) muszą być odrzucane.

  3. Dane wyjściowe filtrowane pod kątem danych uwierzytelniających. Nawet jeśli baza danych zawiera wstępnie przefiltrowaną treść, filtrowanie danych uwierzytelniających należy stosować także na wyjściu jako mechanizm defense-in-depth.

  4. Odpowiedzi z limitem tokenów. 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ć strukturalne komunikaty o błędach, które pomagają narzędziu AI wrócić do działania:

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

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

Konfiguracja MCP

Dodać serwer Obsidian MCP do ~/.claude/settings.json:

{
  "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 podrzędny. Proszę 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:

Hook PreToolUse — odpytuje skarbiec, zanim agent przetworzy wywołanie narzędzia. Automatycznie wstrzykuje odpowiedni kontekst.

#!/bin/bash
# ~/.claude/hooks/pre-tool-use/obsidian-context.sh
# Automatically inject vault context before tool execution

TOOL_NAME="$1"
PROMPT="$2"

# Only inject context for code-related tools
case "$TOOL_NAME" in
    Edit|Write|Bash)
        # Query the vault
        CONTEXT=$(python /path/to/retriever.py search "$PROMPT" --limit 3 --max-tokens 1500)
        if [ -n "$CONTEXT" ]; then
            echo "---"
            echo "Relevant vault context:"
            echo "$CONTEXT"
            echo "---"
        fi
        ;;
esac

Hook PostToolUse — zapisuje istotne wyniki narzędzi z powrotem do skarbca, aby można było je później odnaleźć.

#!/bin/bash
# ~/.claude/hooks/post-tool-use/capture-insight.sh
# Capture significant outputs to vault (selective)

TOOL_NAME="$1"
OUTPUT="$2"

# Only capture substantial outputs
if [ ${#OUTPUT} -gt 500 ]; then
    python /path/to/capture.py --text "$OUTPUT" --source "claude-code-$TOOL_NAME"
fi

Wzorzec obsidian_bridge.py

Moduł pomostowy udostępnia Python API, które mogą wywoływać hooki i skills:

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

Skill /capture

Skill Claude Code do zapisywania spostrzeżeń z powrotem w skarbcu:

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

Skill tworzy nową notatkę w 00-inbox/ z poprawnym frontmatter i uruchamia przyrostową reindeksację, dzięki czemu nową notatkę można od razu wyszukać.

Wzorce poleceń niestandardowych

Skills Claude Code mogą opakowywać operacje na skarbcu w nazwane polecenia. Praktycy budują biblioteki poleceń specyficznych dla Obsidian, które traktują skarbiec zarówno jako źródło odczytu, jak i miejsce zapisu.

Skanowanie sygnałów. Polecenie /scan-intel odpytuje źródła zewnętrzne, ocenia znaleziska względem osobistych zainteresowań badawczych i zapisuje zakwalifikowane sygnały jako notatki w skarbcu z frontmatter:

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

Polecenie pobiera dane ze skonfigurowanych źródeł (arXiv, HN, RSS), stosuje model oceny (trafność, wykonalność, głębia, autorytet) i zapisuje sygnały spełniające kryteria w folderach skarbca właściwych dla tematów. Skarbiec staje się końcowym odbiorcą zautomatyzowanego potoku analitycznego.

Dziennik kapitana. Polecenie /captains-log agreguje codzienną aktywność git ze wszystkich repozytoriów, zapisuje ustrukturyzowany wpis dziennika w skarbcu i obejmuje podjęte decyzje, odkrycia oraz 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 wdrożone i dlaczego.

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

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

Ten wzorzec można rozszerzyć na dowolną operację w skarbcu: tworzenie MOC, aktualizowanie notatek statusu projektu, łączenie powiązanych sygnałów albo generowanie tygodniowych podsumowań z nagromadzonych codziennych logów.

Przykłady społeczności. Praktycy publikują swoje biblioteki poleceń. Jeden deweloper udostępnił 22 niestandardowe polecenia Obsidian + Claude Code obejmujące codzienne przeglądy, planowanie projektów, przechwytywanie badań i przepływy pracy nad treścią.1 Inny zbudował skill „Visual Explainer”, który generuje notatki z diagramami w skarbcu na podstawie analizy kodu.2 Polecenia różnią się między sobą, ale architektura pozostaje spójna: skills Claude Code jako interfejs, notatki w skarbcu jako warstwa przechowywania oraz infrastruktura wyszukiwania jako silnik zapytań.

Zarządzanie oknem kontekstu

Integracja powinna uwzględniać okno kontekstu 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 podać ś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 wywołaniu narzędzia. Hook PreToolUse powinien selektywnie wstrzykiwać kontekst na podstawie wywoływanego narzędzia. Operacje odczytu nie wymagają kontekstu skarbca. Operacje Write i Edit z niego korzystają.

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 przekazywania instrukcji.

Konfiguracja MCP

Dodać do .codex/config.toml albo ~/.codex/config.toml:

[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 z instrukcjami na poziomie projektu. Należy uwzględnić wskazówki dotyczące wyszukiwania w skarbcu:

## 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 settings.json config.toml
Hooki ~/.claude/hooks/ Nieobsługiwane
Skills ~/.claude/skills/ Nieobsługiwane
Plik instrukcji CLAUDE.md AGENTS.md
Tryby zatwierdzania --dangerously-skip-permissions suggest / auto-edit / full-auto

Kluczowa różnica: Codex CLI nie obsługuje hooków. Wzorzec automatycznego wstrzykiwania kontekstu (hook PreToolUse) nie jest dostępny. Zamiast tego należy dodać jawne instrukcje w AGENTS.md, które powiedzą agentowi, aby przed rozpoczęciem pracy przeszukał skarbiec.

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 omawia konfigurację dla popularnych narzędzi.

Cursor

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 korzystania ze skarbca:

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/settings.json
Codex CLI Pełna STDIO .codex/config.toml
Cursor Pełna STDIO .cursor/mcp.json
Windsurf Pełna STDIO .windsurf/mcp.json
Continue.dev Częściowa HTTP ~/.continue/config.json
Zed W trakcie STDIO Interfejs ustawień
Claudian (plugin Obsidian) Nie dotyczy (wbudowane) Claude Code CLI Ustawienia pluginu Obsidian
Agent Client (plugin Obsidian) Nie dotyczy (wbudowane) ACP Ustawienia pluginu Obsidian

Rozwiązanie awaryjne dla narzędzi bez 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 uporządkowany tekst, który można ręcznie wkleić do wejścia dowolnego narzędzia AI. Jest to mniej eleganckie niż integracja z MCP, ale działa uniwersalnie.


Prompt caching z ustrukturyzowanych notatek

Ustrukturyzowane notatki w skarbcu mogą służyć jako wielokrotnego użytku bloki kontekstu, które zmniejszają zużycie tokenów w interakcjach z AI. Ta sekcja omawia projektowanie kluczy cache oraz zarządzanie budżetem tokenów.

Wzorzec

Zamiast wyszukiwać kontekst przy każdej interakcji, warto wstępnie zbudować bloki kontekstu z dobrze ustrukturyzowanych notatek w skarbcu i zapisać 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ęcie TTL. Każdy blok kontekstu ma określony czas życia. Po wygaśnięciu TTL blok jest odbudowywany przez ponowne zapytanie do skarbca.
  2. Wykrywanie zmian w skarbcu. Gdy indexer wykryje zmiany w plikach, które przyczyniły się do utworzenia zapisanego w cache bloku kontekstu, blok zostaje natychmiast unieważniony.

Zarządzanie budżetem tokenów

Sesja zaczyna się od łącznego budżetu kontekstu. Bloki zapisane w 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 zapisane w cache są ładowane na początku sesji. Dynamiczne wyniki wyszukiwania wypełniają pozostały budżet dla poszczególnych zapytań. To podejście hybrydowe daje agentowi bazowy zestaw często potrzebnego kontekstu, jednocześnie zachowując budżet na konkretne zapytania.

Zużycie tokenów przed i po

Bez cache: Każde istotne zapytanie uruchamia wyszukiwanie w skarbcu, zwracając 1 500-2 000 tokenów kontekstu. Przy 10 zapytaniach w sesji agent zużywa 15 000-20 000 tokenów kontekstu ze skarbca.

Z cache: Trzy wstępnie zbudowane bloki kontekstu zużywają łącznie 4 500 tokenów. Dodatkowe wyszukiwania dodają 1 500-2 000 tokenów na każde unikalne zapytanie. Przy 10 zapytaniach, z których 6 jest obsłużonych przez bloki zapisane w cache, agent zużywa 4 500 + (4 * 1 500) = 10 500 tokenów — mniej więcej połowę zużycia bez cache.


Hooki PostToolUse do kompresji kontekstu

Wyniki narzędzi mogą być rozwlekłe: stack trace, listy plików, wyniki testów. Hook PostToolUse może skompresować te wyniki, zanim zajmą miejsce w oknie kontekstu.

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 najważniejsza informacja mieści się w 2 liniach: 200 zakończonych powodzeniem, 1 nieudany.

Implementacja hooka

#!/bin/bash
# ~/.claude/hooks/post-tool-use/compress-output.sh
# Compress verbose tool outputs to preserve context window

TOOL_NAME="$1"
OUTPUT="$2"
OUTPUT_LEN=${#OUTPUT}

# Only compress large outputs
if [ "$OUTPUT_LEN" -lt 2000 ]; then
    exit 0  # Pass through unchanged
fi

case "$TOOL_NAME" in
    Bash)
        # Compress test output
        if echo "$OUTPUT" | grep -q "PASSED\|FAILED"; then
            PASSED=$(echo "$OUTPUT" | grep -c "PASSED")
            FAILED=$(echo "$OUTPUT" | grep -c "FAILED")
            FAILURES=$(echo "$OUTPUT" | grep "FAILED")
            echo "Tests: $PASSED passed, $FAILED failed"
            if [ "$FAILED" -gt 0 ]; then
                echo "Failures:"
                echo "$FAILURES"
            fi
        fi
        ;;
esac

Zapobieganie wyzwalaniu rekurencyjnemu

Hook kompresujący, który emituje wynik, mógłby wyzwolić sam siebie, jeśli nie zostanie zabezpieczony:

# Guard against recursive invocation
if [ -n "$COMPRESS_HOOK_ACTIVE" ]; then
    exit 0
fi
export COMPRESS_HOOK_ACTIVE=1

Heurystyki kompresji

Typ wyniku Wykrywanie Strategia kompresji
Wyniki testów Słowa kluczowe PASSED / FAILED Zliczyć sukcesy/porażki, pokazać tylko błędy
Listy plików ls lub find w poleceniu Skrócić do pierwszych 20 pozycji + liczba
Stack trace Słowo kluczowe Traceback Zachować pierwszą i ostatnią ramkę + komunikat błędu
Git status modified: / new file: Podsumować liczby według statusu
Wynik budowania warning: / error: Usunąć linie informacyjne, zachować ostrzeżenia/błędy

Potok przyjmowania i selekcji sygnałów

Warstwa przyjmowania decyduje, co trafia do skarbca. Bez kuracji skarbiec gromadzi szum. Ta sekcja omawia potok 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, biuletyny bezpieczeństwa, informacje o wydaniach
  • Zakładki przez Web Clipper: oficjalne rozszerzenie Obsidian Web Clipper (Chrome, Firefox, Safari) to ścieżka przyjmowania o najwyższej wierności dla przechwytywania z poziomu przeglądarki. Cykl wydań z kwietnia 2026 istotnie zwiększył jego użyteczność w przepływach pracy AI:22
    • 1.4.0 (9 kwi): interaktywny interfejs transkrypcji YouTube — przypinanie wideo, przewijanie transkrypcji, automatyczne przewijanie i wyróżnianie bieżącej pozycji. Do tego domyślna opcja „Open in Reader”, która wysyła przechwycenie jednym kliknięciem bezpośrednio do trybu Reader.
    • 1.5.0–1.5.1 (15 kwi): przeglądarka wyróżnień — przeglądanie i wyszukiwanie przechwyconych wyróżnień w całym skarbcu. Przejście typu fade-in do Reader. Płynniejsze odtwarzanie/wstrzymywanie YouTube. Wersja 1.5.1 naprawiła regresję kompilacji webpack.
    • 1.6.0–1.6.2 (21–23 kwi): przebudowa UX highlightera 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 trybie osadzonym Safari. Warto skonfigurować szablony dla poszczególnych domen źródłowych, aby transkrypcje YouTube, pliki README GitHub i długie artykuły trafiały do sensownie nazwanych notatek z właściwym frontmatter dla poniższego potoku oceniania.
  • Newslettery: kluczowe fragmenty newsletterów e-mailowych
  • Ręczne przechwytywanie: notatki pisane podczas czytania, rozmów lub badań
  • Wyniki narzędzi: istotne wyniki narzędzi AI przechwycone przez hooki
  • iOS Share Extension: aplikacja Obsidian na iOS (zaktualizowana na początku 2026 roku) zawiera Share Extension, które zapisuje treści z Safari, sieci społecznościowych i innych aplikacji bezpośrednio do skarbca bez otwierania Obsidian.19 Tworzy to niskotarciową mobilną ścieżkę przyjmowania — wystarczy udostępnić artykuł z Safari, a pojawi się jako notatka w skarbcu, gotowa do oceny.
  • Obsidian CLI: skrypty powłoki i hooki mogą tworzyć notatki przez obsidian file create albo dopisywać treść do istniejących notatek przez obsidian file append, co umożliwia zautomatyzowane potoki przyjmowania na desktopie.

Wymiary oceny

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

Wymiar Pytanie Niska ocena (0,0–0,3) Wysoka ocena (0,7–1,0)
Trafność Czy dotyczy to moich aktywnych domen? Luźno powiązane, poza zakresem Bezpośrednio istotne dla aktywnej pracy
Możliwość działania Czy mogę wykorzystać te informacje? Czysta teoria, brak zastosowania Konkretna technika lub wzorzec, który można zastosować
Głębia Jak merytoryczna jest treść? Nagłówki, płytkie streszczenie Szczegółowa analiza z przykładami
Autorytet Jak wiarygodne jest źródło? Anonimowy blog, brak weryfikacji Źródło pierwotne, recenzowane, uznany ekspert

Wynik złożony i routing

composite = (relevance * 0.35) + (actionability * 0.25) +
            (depth * 0.25) + (authority * 0.15)
Zakres wyniku Działanie
0,55+ Automatycznie skierować do folderu domenowego
0,40–0,55 Dodać do kolejki ręcznego przeglądu
< 0,40 Odrzucić (nie przechowywać)

Routing domenowy

Sygnały z wynikiem powyżej 0,55 trafiają 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:

Metryka Wartość
Łączna liczba przetworzonych sygnałów 7 771
Automatycznie skierowane (>0,55) 4 832 (62%)
Dodane do przeglądu (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ów Obsidian koduje relacje między notatkami. Ta sekcja omawia semantykę linków, przechodzenie po grafie w celu rozszerzania kontekstu oraz antywzorce, które obniżają jakość grafu.

Semantyka backlinków

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

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

Graf koduje różne typy relacji w zależności od kontekstu:

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

Maps of Content (MOCs)

MOCs to notatki indeksowe, które organizują powiązane notatki w strukturę możliwą do nawigacji:

---
title: "Authentication & Security MOC"
type: moc
domain: security
---

## Core Concepts
- [[OAuth 2.0 Overview]]
- [[JWT Token Anatomy]]
- [[Session Management Patterns]]

## Implementation Patterns
- [[OAuth Token Rotation]]
- [[Refresh Token Security]]
- [[PKCE Flow Implementation]]

## Failure Modes
- [[Token Expiry Handling]]
- [[Session Fixation Prevention]]
- [[CSRF Defense Strategies]]

MOCs wspierają retrieval na dwa sposoby:

  1. Bezpośrednie dopasowanie. Wyszukiwanie frazy „authentication overview” dopasowuje sam MOC, dostarczając agentowi wyselekcjonowaną listę powiązanych notatek.
  2. Rozszerzanie kontekstu. Po znalezieniu konkretnej notatki retriever może sprawdzić, czy notatka pojawia się w jakichkolwiek MOCs, i dołączyć strukturę MOC do wyników, dając agentowi mapę szerszego tematu.

Przechodzenie po grafie w celu rozszerzania kontekstu

Przyszłe usprawnienie retrievera: po znalezieniu najlepszych wyników rozszerzyć kontekst przez podążanie 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 jest to zaimplementowane w obecnym retrieverze, ale stanowi naturalne rozszerzenie struktury grafu.

Antywzorce

Osierocone klastry. Grupy notatek, które linkują do siebie nawzajem, ale nie mają połączeń z resztą skarbca. Panel grafu w Obsidian pokazuje je jako odłączone wyspy. Osierocone klastry wskazują na brakujące MOCs albo brakujące linki międzydomenowe.

Rozrost tagów. Niespójne używanie tagów albo tworzenie zbyt wielu drobnoziarnistych tagów. Skarbiec z 500 unikalnymi tagami w 5 000 notatkach ma średnio 1 notatkę na 10 tagów — tagi nie są przydatne do filtrowania. Należy skonsolidować je do 20–50 tagów wysokiego poziomu, które mapują się na foldery domenowe.

Notatki pełne linków, ubogie w treść. Notatki składające się wyłącznie z wiki-linków, bez prozy. Takie notatki indeksują się słabo, ponieważ chunker nie ma tekstu do osadzenia. Warto dodać co najmniej akapit kontekstu wyjaśniający, dlaczego linkowane notatki są powiązane.

Dwukierunkowe linki do wszystkiego. Nie każde odwołanie musi być wiki-linkiem. Wzmianka o „OAuth” mimochodem nie wymaga [[OAuth 2.0 Overview]]. Wiki-linki warto rezerwować dla celowych, możliwych do nawigacji relacji, w których kliknięcie linku dostarczyłoby 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
2026-07-07 Korekty dokładności. Doprecyzowano, że MCPVault jest osobnym projektem (npm @bitbonsai/mcpvault, repozytorium bitbonsai/mcpvault), obecnie w wersji v0.12.1, z dwoma advisory dotyczącymi filtrowania ścieżek o średniej ważności (GHSA-9c83-rr99-vfwj, GHSA-j99q-93c9-h869) — wcześniejszy link [^24] wskazywał błędne repozytorium (MarkusPfundstein/mcp-obsidian). Skorygowano status MarkusPfundstein/mcp-obsidian: jest aktywnie utrzymywany (commity do 15 maja 2026, dodające search_by_tag/get_frontmatter), a nie „nieaktywny od czerwca 2025”; nadal nie udostępnia oznaczonych wydań. Zweryfikowano względem historii commitów GitHub, GitHub Security Advisories oraz npm.
2026-07-06 Redakcyjna restrukturyzacja pod kątem łatwiejszego odnajdywania: tytuł „Quick Start: First AI-Connected Vault” zmieniono na konfiguracja Obsidian MCP (anchor #obsidian-mcp-setup) oraz dodano podsumowanie możliwości „Co Claude może robić po połączeniu” (wyszukiwanie, odczyt, listowanie, sformatowany kontekst; granica tylko do odczytu, z zapisami obsługiwanymi przez hooki), skonsolidowane z sekcji MCP Server Architecture. Bez nowych faktów; zaktualizowano linki wewnętrzne.
2026-06-10 Aktualizacja wersji. Obsidian 1.13.1 desktop trafił do kanału publicznego (9 czerwca 2026) — aktualizacja ustawień UX i CodeMirror względem 1.13.0, bez większych zmian w AI/automatyzacji. Odniesienia do bieżącej wersji w treści przeniesiono z 1.13.0 na 1.13.1 (publiczna, 9 czerwca 2026).
2026-06-09 Odświeżenie ekosystemu. Specyfikacja MCP 2026-07-28 weszła w fazę Release Candidate (ogłoszono 21 maja 2026) — to największa rewizja MCP od czasu premiery: bezstanowy rdzeń protokołu (usuwa handshake initialize i Mcp-Session-Id), MCP Apps (renderowany po stronie serwera HTML w sandboxowanych iframe), Tasks przechodzące z eksperymentalnego rdzenia do oficjalnego rozszerzenia, wzmocnienia OAuth 2.0/OIDC oraz 12-miesięczna polityka cyklu wycofywania (finalna specyfikacja 28 lipca 2026); spekulacyjne ujęcie roadmapy „wstępnie połowa 2026” w notatce o ewolucji specyfikacji MCP zastąpiono konkretnym RC. sqlite-vec v0.1.10-alpha (31 marca – 18 maja 2026) dodaje typy indeksów approximate-nearest-neighbor (rescore, eksperymentalny ivf, oparty na dysku DiskANN) poza brute-force KNN — oznaczono jako nadchodzące/eksperymentalne, ponieważ linia 0.1.10 nadal jest pre-release. Obsidian 1.13.0 desktop (early access, 28 maja 2026) ustawiono jako bieżącą wersję we wszystkich odniesieniach w treści; to wydanie UX/security/dev-tooling bez nowych możliwości AI/automatyzacji.
2026-06-08 Kontrola utrzymaniowa. Wydano Model2Vec v0.8.2 (29 maja 2026): wydanie utrzymaniowe dodające opcję zamrożonych wag dla treningu, a także poprawki tokenów wielowyrazowych, refaktoryzację treningu i poprawki obsługi nieskwantyzowanych wag; zaktualizowano przypis. Nic innego nie jest nowsze niż istniejąca baza: najnowszy Obsidian pozostaje w wersji 1.13.0 (28 maja, już udokumentowane poniżej), stabilny sqlite-vec pozostaje w wersji v0.1.9 (v0.1.10 nadal alpha), a specyfikacja MCP pozostaje rewizją 2025-11-25. Bez zmian w treści poza notatką o wersji Model2Vec.
2026-05-28 Wydano Obsidian 1.13.0 desktop + 1.13.0 mobile (Catalyst early-access). Desktop: przebudowany panel Settings otwierany we własnym oknie, z wbudowanym wyszukiwaniem i nawigacją klawiaturą; Obsidian URIs wyświetlają teraz okno potwierdzenia przed uruchomieniem akcji; 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 API dla deweloperów i poprawki błędów. Mobile: nowy iOS Share Sheet z konfigurowalnymi lokalizacjami docelowymi; zmiana kolejności kart z przełącznika kart; gesty naciśnięcia i przytrzymania na tabletach do zmiany rozmiaru podziałów i przypiętych pasków bocznych; Bases zyskuje pozycję menu do zmiany rozmiaru kolumn w widokach tabeli; poprawki błędów iOS i wyszukiwania. Konsekwencje dla workflow AI: okno potwierdzenia przy Obsidian URIs dodaje celową bramkę do integracji MCP/agent opartych na URI; menu zmiany rozmiaru kolumn w Bases zwiększa użyteczność Bases jako indeksu frontowego vaultu, który agenci odpytują; konfigurowalny cel w iOS Share Sheet przyspiesza konfigurację ścieżki przechwytywania z iPhone’a (już udokumentowanej jako główny kanał wejściowy) dla pipeline’ów Claude/Codex.
2026-05-06 Odświeżenie aktualności zweryfikowanej źródłowo: Smart Connections v4.5.0 przeniosło połączenia stopki do Core; stabilne wydania sqlite-vec v0.1.8/v0.1.9 zaktualizowały pakowanie i zachowanie DELETE; Model2Vec v0.8.x zaktualizował mechanizmy tokenizera/persistencji oraz tabele benchmarków; skorygowano chronologię Obsidian CLI z „1.12.7 wprowadził CLI” na „1.12.0 wprowadził CLI, 1.12.7 poprawił pakowanie instalacji/runtime”.
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 (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). Przedstawiono Web Clipper jako główną przeglądarkową ścieżkę wejściową dla workflow AI, a nie poboczną wzmiankę o bookmarku. W tym oknie nie było wydań Obsidian desktop, Sync ani Bases.
2026-04-16 Smart Connections v4.3.0 (widok grafu, konfigurowalny dock, odzyskiwanie block-embedding, środowisko międzypluginowe Substrate). Udokumentowano falę pluginów AI-native z kwietnia 2026 (Cortex, VaultSearch, LLM Wiki, Drift, EngramQuest, Hybrid Search MCP). Oznaczono MarkusPfundstein/mcp-obsidian jako maintenance-mode (ostatni commit w czerwcu 2025). Dataview jest nieaktywny; Bases jest następcą dla nowych prac. Obsidian CLI 1.12.7 nadal pozostaje preferowanym mostem dla asystentów AI.
2026-04-01 Dodano sekcję Obsidian CLI (polecenia v1.12 dla workflow AI). Dodano sekcję pluginów agentowych (Claudian, Agent Client). Udokumentowano core plugin Bases do organizacji vaultu. Zaktualizowano liczbę pluginów do 2 500+. Dodano iOS Share Extension jako źródło wejściowe. Zaktualizowano macierz kompatybilności o osadzone pluginy agentowe.
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 binarkę CLI dla szybszych interakcji terminalowych.
2026-03-23 Udokumentowano stabilny sqlite-vec v0.1.7: obsługa DELETE dla tabel vec0, ograniczenia dystansu KNN dla paginacji. Zapowiedziano indeks DiskANN approximate nearest neighbor w nadchodzącym wydaniu.
2026-03-07 Dodano potion-multilingual-128M (101 języków, maj 2025) do porównania modeli embeddingów. sqlite-vec w wersji v0.1.7-alpha.10 (poprawki CI/CD, bez zmian funkcji). Potwierdzono aktualność specyfikacji MCP i technik wyszukiwania.
2026-03-03 Zaktualizowano ewolucję specyfikacji MCP (wydanie z listopada 2025: 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 notatkę o ewolucji specyfikacji MCP.
2026-03-01 Pierwsze wydanie

Referencje


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

  2. Nicopreme, skill 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 metodę bezparametrową do łączenia list rankingowych. 

  4. OpenAI Embeddings Pricing. text-embedding-3-small: 0,02 USD za milion tokenów. Szacowany koszt vault przy pełnym ponownym indeksowaniu: ok. 0,30 USD. 

  5. van Dongen, T. et al. Model2Vec: Turn any Sentence Transformer into a Small Fast Model. arXiv, 2025. Opisuje podejście destylacji, które tworzy statyczne embeddings z sentence transformers. 

  6. potion-base-8M Model Card i Model2Vec results. Aktualnie opublikowane tabele podają potion-base-8M na poziomie 51.32 Avg (All) / 51.08 Avg (MTEB), w porównaniu z all-MiniLM-L6-v2 na poziomie 55.80 Avg (All) / 55.93 Avg (MTEB), czyli około 92% zachowania 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 model cards podają potion-base-32M na poziomie 52.83 Avg (All), a potion-retrieval-32M na poziomie 35.06 w tabeli retrieval. 

  9. Update on the Next MCP Protocol Release. Wydanie z listopada 2025 roku wprowadziło transport Streamable HTTP, wykrywanie URL .well-known, strukturalne adnotacje narzędzi oraz standaryzację poziomów SDK. Następne wydanie wstępnie zaplanowano na połowę 2026 roku; ma obejmować operacje asynchroniczne, rozszerzenia specyficzne dla domen oraz komunikację agent-to-agent. 

  10. Model2Vec Releases. v0.4.0 (luty 2025): obsługa trenowania/fine-tuningu. v0.5.0 (kwiecień 2025): przepisanie backendu, kwantyzacja, redukcja wymiarowości. v0.7.0 (październik 2025): kwantyzacja słownika, obsługa tokenizera BPE/Unigram. v0.8.0/v0.8.1 (marzec 2026): refaktoryzacje tokenizera i persystencji, deprecjacja 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 podczas trenowania, a także poprawki tokenów wielowyrazowych, refaktoryzację trenowania i poprawki obsługi wag bez kwantyzacji. 

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

  12. potion-multilingual-128M. Minish Lab, maj 2025. Statyczny model embeddingów 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 wersja v0.12.1 (opublikowana 2026-06-23); odrębny projekt 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 licznikami, usprawniła obsługę folderów z kropkami oraz dodała obsługę plików .base/.canvas. Dwa GitHub Security Advisories o średniej wadze dotyczą filtra ścieżek: GHSA-9c83-rr99-vfwj (katalogi z ograniczeniami odrzucane tylko w katalogu głównym vault, nie w zagnieżdżeniach) oraz GHSA-j99q-93c9-h869 (ominięcie deny-list przez równoważność wielkości liter oraz końcowej kropki/spacji) — należy uruchamiać v0.12.1 lub nowszą. 

  14. sqlite-vec v0.1.7 Release. 17 marca 2026. Stabilne wydanie: obsługa DELETE dla tabel wirtualnych vec0, ograniczenia dystansu KNN na potrzeby paginacji, ulepszenia testów fuzz. Przybliżone indeksowanie najbliższych sąsiadów DiskANN zapowiedziano dla przyszłego wydania. 

  15. Introduction to Bases. Podstawowa wtyczka Obsidian wprowadzona w v1.9.10. Widoki podobne do baz danych (tabele, galerie, kalendarze, tablice kanban) nad plikami vault, używające właściwości frontmatter jako pól. Pliki 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 poziomu terminala; v1.12.7 ulepszyła pakiet instalacyjny/uruchomieniowy dzięki samodzielnemu binarium, TUI i zachowaniu pliku socket. Zob. także dokumentację CLI

  17. Claudian. Wtyczka Obsidian, która osadza Claude Code jako współpracownika AI w vault. Zapewnia czat w pasku bocznym, prompty świadome kontekstu, obsługę vision, slash commands i tryby uprawnień. 

  18. Agent Client. Wtyczka Obsidian zapewniająca ujednolicony interfejs dla Claude Code, Codex CLI i Gemini CLI przez Agent Client Protocol (ACP). Obsługuje wzmianki o notatkach, wykonywanie poleceń shell i zatwierdzanie akcji. 

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

  20. MarkusPfundstein/mcp-obsidian. Aktywnie utrzymywany — commity do 15 maja 2026 roku, z niedawnymi pracami dodającymi narzędzia, w tym search_by_tag i get_frontmatter, oraz rozszerzonym pokryciem testami (zweryfikowane na podstawie historii commitów repozytorium i tools.py). Nadal nie publikuje oznaczonych wydań, więc należy instalować z przypiętego commitu. Oparty na lokalnym REST-API; dyskusje na forum (kwiecień 2026) wskazują migrację społeczności ku natywnemu mostowi Obsidian CLI (1.12.x) dla nowych konfiguracji, ale mcp-obsidian pozostaje działającą, 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ą też widoki grafowe dla list połączeń, konfigurowalne lokalizacje panelu połączeń, ulepszone odzyskiwanie block-embeddingów, stan międzywtyczkowy Substrate, poprawki fallbacków transformera oraz ograniczenie duplikowanych obliczeń połączeń. 

  22. obsidianmd/obsidian-clipper releases — podstawowe źródło mapowania wersji Web Clipper na funkcje. Cykl z kwietnia 2026: 1.4.0 (9 kwietnia, UI transkryptów YouTube + domyślne Open in Reader), 1.5.0 (15 kwietnia, przeglądarka Highlights + fade-in Reader), 1.5.1 (15 kwietnia, poprawka kompilacji webpack), 1.6.0 (21 kwietnia, UX Highlighter + Defuddle 0.18 z ekstraktorami LinkedIn/Threads/Bluesky/Discourse/Medium), 1.6.1 (22 kwietnia, poprawki konspektu Reader + wyszukiwanie highlights), 1.6.2 (23 kwietnia, poprawka schowka w trybie osadzonym Safari). Wersje są także wymienione 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 kolumn tekstowych 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 błąd ALTER TABLE RENAME na tabelach vec0 używających nowych funkcji ivf/diskann oraz błąd czyszczenia cached-statement w DiskANN. Linia 0.1.10 nadal jest prerelease. 

  24. MCP 2026-07-28 Specification Release Candidate. Ogłoszona 21 maja 2026; finalna specyfikacja zostanie opublikowana 28 lipca 2026. Największa rewizja MCP od premiery: bezstanowy rdzeń protokołu (usuwa handshake initialize i nagłówek Mcp-Session-Id), MCP Apps (renderowane przez serwer HTML 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 12-miesięczna polityka cyklu życia deprecjacji funkcji. 

  25. Obsidian Desktop v1.13.0 Changelog. Early access, 28 maja 2026. Wydanie UX/security/developer-tooling: przeprojektowany panel Settings otwierany we własnym oknie z wyszukiwaniem i nawigacją klawiaturą, okna potwierdzenia przed uruchomieniem Obsidian URI, nowe Settings API dla twórców wtyczek oraz poprawka CLI dla instalacji flatpak. Brak istotnych nowych możliwości AI/automatyzacji poza powierzchnią CLI z linii 1.12.x. 

  26. Obsidian Changelog. Obsidian 1.13.1 desktop trafił do kanału publicznego 9 czerwca 2026 — dopracowanie UX ustawień i aktualizacja CodeMirror względem 1.13.0, bez nowych możliwości AI/automatyzacji. 

VAULT obsidian.md INDEXED