Problem, o którym nikt nie ostrzega
Po trzech miesiącach pracy z modelami AI nad marką trafiłem na problem, o którym nikt mnie nie uprzedził: zmęczenie wklejaniem kontekstu.
Każdy nowy czat z Claudem zaczynał się tak samo. Wklej ostatnie decyzje. Wklej próbki głosu. Wklej stan bieżącego sprintu. Wklej plik, nad którym pracuję. Wklej constraints. Wyślij. Poczekaj, aż model potwierdzi, że ma kontekst. Dopiero teraz zadaj właściwe pytanie.
Dla kogoś, kto codziennie shippuje case studies, sprint reporty i decision logi - to są godziny tygodniowo na sam copy-paste. To nie skaluje się.
Cloudowe RAG-i istnieją, ale rozjeżdżają się z punktem. Mój korpus marki jest prywatny, dopóki czegoś nie opublikuję. Notatki o pricing, decyzje wewnętrzne, eksperymenty z głosem w trakcie iteracji - żadna z tych rzeczy nie powinna opuszczać laptopa.
Zbudowałem to, czego potrzebowałem.
Co to jest, w jednym akapicie
sdet-brain to jeden trwały indeks nad moim korpusem Markdown, eksponowany jako narzędzia MCP. Każdy klient z obsługą MCP (Claude Desktop, Claude Code, OpenCode) widzi ten sam kontekst równolegle. Embeddingi są liczone lokalnie na Apple Silicon przez MLX. Vector store to Qdrant w Dockerze. Serwer to FastAPI plus FastMCP 3.0 z transportami stdio, SSE i streamable HTTP. Markdown zostaje na dysku jako jedno źródło prawdy - w Qdrancie żyją tylko derywaty.
Architektura
graph TB
subgraph Clients
CD[Claude Desktop<br/>MCP stdio]
CC[Claude Code<br/>MCP HTTP]
OC[OpenCode<br/>MCP HTTP]
WEB[Web client<br/>REST + SSE]
end
subgraph Server
FAPI[FastAPI app]
FMCP[FastMCP 3.0 wrapper]
TOOLS[MCP tools<br/>core + domain]
end
subgraph Pipeline
ING[Ingestion<br/>parser + chunker]
EMB[Embeddings<br/>MLX + Gemini]
WTC[Watchdog<br/>auto-reindex]
end
subgraph Storage
QD[(Qdrant<br/>vectors + payload)]
FS[(Markdown corpus<br/>on disk)]
end
CD --> FMCP
CC --> FMCP
OC --> FMCP
WEB --> FAPI
FAPI --> TOOLS
FMCP --> TOOLS
TOOLS --> ING
TOOLS --> EMB
TOOLS --> QD
FS --> WTC
WTC --> ING
ING --> EMB
EMB --> QD
Cztery warstwy, cztery top-level pakiety:
- server/ - FastAPI plus FastMCP 3.0. Eksponuje 11 narzędzi MCP.
- ingestion/ - parser frontmatteru, semantyczny chunker, watchdog.
- embeddings/ - MLX lokalnie (główny), Gemini jako fallback.
- storage/ - klient Qdrant z hybrid search (BM25 + dense + RRF fusion).
Wejścia CLI siedzą w cli/. Korpus Markdown żyje tam, gdzie go trzymam - w Qdrancie tylko derywaty.
Jak płynie zapytanie
- Klient (powiedzmy Claude Code) woła narzędzie MCP
searchpo HTTP. - FastMCP dispatch’uje do warstwy tools.
- Embedder (MLX) liczy wektor zapytania. Lazy-load przy pierwszym wywołaniu (kilka sekund), poniżej 100 ms potem.
- Qdrant odpala hybrid search - BM25 + dense, RRF fusion, opcjonalny cross-encoder rerank.
- Narzędzie zwraca chunki z payloadem - ścieżka, source type, score, snippet.
- Klient dostaje JSON, model cytuje wyniki w odpowiedzi.
Do bogatszych pytań nakładają się trzy narzędzia LLM-backed: query_rewrite (rozszerzanie zapytań w stylu HyDE), multi_query_search (dekompozycja plus RRF fusion po sub-zapytaniach) i summarize_results (podsumowanie z cytatami).
Dlaczego lokalnie, a nie w chmurze
Trzy powody w kolejności priorytetu.
Prywatność z architektury. Korpus marki jest prywatny, dopóki czegoś z niego nie opublikuję. Embeddingi i reasoning na Macu oznaczają, że żaden ruch inference nie opuszcza laptopa. Nie ma przełącznika “obiecujemy że nie będziemy trenować na twoich danych”, któremu trzeba by zaufać.
Zero kosztu per query. Apple Silicon ciągnie Qwen3-Embedding-0.6B i Qwen3-Next-80B lokalnie. Każde zapytanie kosztuje prąd z laptopa, nie tokeny w API. Przy stu-plus pytaniach w dniu pracy to ma większe znaczenie, niż brzmi.
Latency. Round-trip do hostowanego serwisu embeddingowego dokłada 100-300 ms na zapytanie. Lokalne MLX to 20-50 ms. Dla narzędzia, którego używa się interaktywnie, to różnica między flow a tarciem.
Sześć tierów release’u w dwa dni
Tu wchodzi historia z velocity AI. Cały stack - od MVP po DX polish - został zshippowany między 30 kwietnia a 1 maja 2026 w trzech autonomicznych sesjach Claude Code.
| Tier | Tag | Wkład |
|---|---|---|
| 1 | v0.1.0 | MVP - Qdrant + MLX + 4 core narzędzia MCP + watcher |
| 1.1 | v0.1.1 | Polish - healthcheck, env-driven paths, perf |
| 2 | v0.2.0 | Hybrid search (BM25 + RRF) + cross-encoder rerank + 5 domain tools |
| 3 | v0.3.0 | Lokalny MLX LLM (Qwen3-Next-80B) + /chat + streaming SSE |
| 4 | v0.4.0 | Qwen3-Embedding-8B + tiered LLM router + multi-query agentic retrieval |
| 5 | v0.5.0 | DX - REPL CLI + inline citations + saved templates |
Każdy tier miał swój atomic plan, atomic commity i re-run quality gates: 213 testów przechodzi, mypy —strict na 70 plikach, ruff clean - zanim ruszamy dalej.
Dlaczego source-available, a nie OSS (na razie)
Repo jest tu po to, żeby było transparentne - do czytania, do uczenia się, do uruchomienia lokalnie nad swoim korpusem. Czego nie można zrobić: forka komercyjnego ani wrapnięcia tego w hostowany produkt bez wcześniejszej rozmowy ze mną.
Formalna decyzja o licencji OSI (prawdopodobnie AGPL-3.0 albo coś podobnego) przyjdzie z ustrukturyzowanym launchem publicznym - kiedy dokumentacja, demo dataset i tutorial wdrożeniowy będą gotowe. To osobny sprint, zaplanowany na późniejszy kamień milowy.
Co dalej
Pełen case study z tutorialem wdrożenia, demo korpusem Markdown i deep-dive po architekturze planuję jako odcinek serii “From the field” w nadchodzących tygodniach.
Na teraz: source jest na GitHubie, architektura w README, a wzorce są codziennie testowane na mojej własnej pracy nad marką.