SecondBrain
Samohostowany, prywatny asystent życiowy w .NET 10, który 24/7 zbiera sygnały z całego życia, prowadzi automatyczny kalendarz i odzywa się we właściwym momencie — z twardą, egzekwowaną w kodzie regułą fail-closed, że dane wrażliwe nigdy nie opuszczają domu.
Przegląd projektu
SecondBrain to samohostowany, prywatny asystent życiowy zbudowany w .NET 10, który 24/7 zbiera sygnały z całego życia — lokalizację (GPS→Reitti), aktywność PC, dane zdrowotne z Health Connect, opisy posiłków i obecność w domu z beaconów BLE — składa z nich automatyczny kalendarz życia oraz bi-temporalną pamięć długoterminową, a następnie odzywa się we właściwym momencie, nie oddając najbardziej wrażliwych danych nikomu w chmurze. Sercem systemu jest router prywatności fail-closed: zadania wrażliwe interpretuje wyłącznie lokalna gemma4:26b na Mac mini, a gdy model padnie, zapytanie kończy się wyjątkiem zamiast cichego fallbacku do chmury. Całość działa produkcyjnie na homelabie (serwer Dell R620) w rozproszonej topologii pięciu węzłów pod adresem https://sb.aidamian.uk. Architektura konsekwentnie realizuje zasadę „kod liczy, model interpretuje" — arytmetyka, korelacje i proweniencja są deterministyczne w C#, a lokalny LLM domyka rozmowę po polsku na gotowych wynikach narzędzi.
Wyzwanie
Komercyjny lifelogging okazał się nietrwały i ryzykowny — Rewind/Limitless trafiły do Meta (XII 2025, ~2 tygodnie na eksport, potem kasacja), Bee do Amazona, Dot się zamknął. Dane życiowe są przy tym niereprodukowalne: snu i lokalizacji z 2026 roku nie da się pobrać ponownie, a Google Timeline żyje tylko na telefonie z domyślną retencją 3 miesięcy i po cichu się przycina. Jednocześnie chmurowe LLM z definicji oznaczają wyciek danych wrażliwych, płaska pamięć wektorowa „gnije" (stare, nieaktualne fakty wracają równie pewnie jak bieżące), a proaktywni asystenci szybko stają się spamem i lądują w koszu (73% ludzi wycisza push przez złe wyczucie czasu). Wyzwaniem było zbudowanie systemu, który jednocześnie: gwarantuje prywatność architektonicznie (nie obietnicą w promptcie), utrzymuje niezawodny tool-calling na małym, lokalnym modelu, koreluje sygnały z wielu rozproszonych sensorów bez halucynowania przyczynowości i traktuje proaktywność jak budżet, a nie strumień powiadomień.
- Prywatność egzekwowalna strukturalnie, nie promptem — dane wrażliwe fizycznie nieosiągalne dla chmury nawet przy błędnym configu (wrażliwe = przymusowa degradacja do lokalnego + health-check przed użyciem)
- Niezawodny tool-calling na małym, lokalnym modelu (gemma4:26b, MoE ~3,8 mld aktywnych parametrów): płaskie schematy, constrained JSON, walidacja argów w C#
- Jedna oś czasu z rozproszonych sensorów (GPS, PC, zdrowie, BLE) + korelacje bez zmyślania związków przyczynowych (statystyka grup, nie r Pearsona)
- Proaktywność jako budżet, nie spam: deterministyczny digest-first (działa nawet gdy model leży) i okna anty-spam zamiast obietnicy w promptcie
Rozwiązanie
Zbudowałem monolit modularny (14 projektów .NET, jeden root kompozycji SecondBrain.Gateway) wokół kilku zasad egzekwowanych w kodzie, nie w promptcie. LlmRouter to router prywatności fail-closed: zadanie oznaczone jako wrażliwe (a domyślnie wrażliwe jest wszystko) wskazujące w configu chmurę jest przymusowo degradowane do profilu lokalnego, a health-check Ollamy (GET /api/tags) rzuca LlmUnavailableException zamiast cichego fallbacku. LlmConversationRunner utrzymuje mały model w ryzach — detekcja zapętlenia po skrócie SHA-256 argumentów, limit 5 tur, jeden tool na turę i constrained JSON decoding — a AgentToolset udostępnia 28 płaskich narzędzi z jednym źródłem prawdy o tym, które z nich tylko czytają (13 czytających, 13 piszących, 2 wychodzące na zewnątrz). Silnik CorrelationJob + InsightMath liczy korelacje międzydomenowe deterministycznie (porównanie grup dni w oknie 60 dni, progi effect-size, minimum n≥5) i sam formułuje polskie zdania z podanym n, a ReflectionJob co noc aktualizuje wersjonowany profil (encja ProfileVersion) z wymuszonym cytowaniem faktów — refleksja bez cytatu odpada. Głosowy sandbox na kiosku RPi5 (Vosk gramatyka hasła → Whisper → odcisk głosu) degraduje niepewną turę do trybu tylko-odczyt, a BleScanner + IndoorVisitBuilder robią mikro-lokalizację w domu z recyklingu cudzych beaconów BLE. Całość spina append-only RawEventStore (idempotencja INSERT … ON CONFLICT po kliencie-UUID) i offline-first Outbox (SQLite) w kolektorze.
Wykorzystane technologie
Rezultaty
Samohostowane na homelabie R620 pod https://sb.aidamian.uk (systemd + nginx + Cloudflare Tunnel, port 127.0.0.1:5080)
R620 + Mac mini + laptop + telefon + RPi5; 14 projektów .NET, ~37 tys. linii C#, 75 endpointów HTTP, 28 narzędzi agenta
Fail-closed w kodzie: lokalizacja/zdrowie/PC/kamera/rozmowy interpretuje wyłącznie lokalny model; awaria = wyjątek, nigdy chmura
Masz podobny projekt?
Porozmawiajmy o tym, jak mogę pomóc Twojej firmie osiągnąć podobne rezultaty.
💬 Komentarze (0)
Zostaw komentarz
Bądź pierwszy, który skomentuje!