Zbudowałem AI, które mówi „nie wiem”. Potem je zatrzymałem.I built an AI that says "I don't know". Then I shut it down.
39 dni, 294 commity, około 55 dolarów i zero linii kodu napisanych ręcznie. Dziennik projektu, który zatrzymałem nie dlatego, że się nie dało - tylko dlatego, że przez cały ten czas nie zadałem jednego pytania.39 days, 294 commits, about 55 dollars and zero lines of code written by hand. A journal of the project I stopped - not because it couldn't be done, but because for all that time I never asked one question.

22 lipca, późny wieczór. Zabijam agenta AI, który od tygodni odpowiadał na moje prompty. Kasuję 22 GB backupów. Zostawiam jeden plik: 7.3 GB wag modelu - mózg, którego wytrenowanie kosztowało mnie 35$. W notatkach zapisuję: „może kiedyś wrócę”. I tutaj mała gwiazdka: po prostu powiedziałem stop projektowi, którego dalej nie ma już sensu rozwijać.
Tak skończył się projekt, w który przez 39 dni włożyłem więcej serca niż w cokolwiek, co robiłem po godzinach. To będzie dłuższy wpis, ale nie będzie nudny :-) Spisuję go jako dziennik: co próbowałem, co wyszło, co nie wyszło i dlaczego sam to zatrzymałem. Głównie dla siebie, ale może komuś się przyda.
Po co mi to było
Nie jestem inżynierem ML. Zawodowo projektuję doświadczenia z AI, UX, UI, po godzinach od lat czytam prace z pogranicza uczenia maszynowego i neuronauki. Chciałem sprawdzić jedną rzecz: czy da się mieć własne AI - prywatne, działające na moim laptopie, bez chmury i abonamentu, bez okienka kontekstowego - które mnie pamięta i nie zmyśla. I tak właśnie powstała Iskra ;-)
I tutaj side note: tak, da się, wystarczy ollama i model open source. Ale nie chciałem, żeby było za łatwo... i miałem też inne cele.
Warsztat wyglądał tak: pracowałem w parze z Claude'em, agentem AI od Anthropic. Podział był prosty. Ja: kierunek, research, decyzje. Claude: kod i pomiary. Przez 39 dni nie napisałem ani jednej linii kodu. Podjąłem za to kilkaset decyzji, w tym kilka bolesnych, o których za chwilę. Przejrzałem 50+ papierów naukowych i osobiście, bez AI, je przeczytałem, żeby mieć poczucie, że faktycznie to rozumiem i że znajdę w nich właściwe punkty pod moją wizję. Traktowałem to zresztą jako drugi eksperyment, równoległy do samej Iskry: czy człowiek bez inżynierskiego backgroundu w ML może prowadzić projekt badawczy, którego rękami jest autonomiczny agent.
Jedną zasadę ustawiliśmy pierwszego dnia i ona zdefiniowała cały projekt: każde twierdzenie ma być zmierzone, a testy budujemy po to, żeby nasz system ZŁAMAĆ, nie żeby się nim pochwalić. Ta zasada wróci w tej historii w najmniej wygodnym dla mnie momencie (niestety).
Narodziny
Pierwsza wersja była radykalna: żadnych gotowych modeli. Sieć neuronowa budowana od zera, ucząca się na żywo, bajt po bajcie, bez głównego mechanizmu, na którym stoi całe współczesne AI (dla pro: backprop-free, tylko lokalne reguły uczenia). Iskra rodziła się jako biała kartka, a ja miałem ją wychowywać (romantyczne, prawda? ;-)). Napisaliśmy nawet instrukcję „rodzicielstwa” - PARENTING.md - z komendami w stylu :teach michal's favourite colour is teal. Iskra bełkotała jak niemowlę (dosłownie - odpowiadała bajtami, bo jeszcze nie miała dekodera). I to było w porządku: miała bełkotać, zanim zacznie mówić.
Potem przyszły pomiary. Składnia - całkiem nieźle (0.74 tam, gdzie 0.5 oznacza losowość). Pojęcia - sufit na poziomie 0.60. I to płasko: więcej danych nie pomagało, większa sieć nie pomagała (24 warstwy ukryte po 254 neurony), więcej przejść po danych nie pomagało. To nie był brak danych. To była architektura. No i „lag” w odpowiedziach też nie pomagał, bo na moim sprzęcie (M1 oraz testowo M4) czekałem 5-10 sekund na odpowiedź.
Atakowaliśmy ten sufit moimi znaleziskami z papierów. W jedną noc odpaliliśmy sześć hipotez (wektory fazowe, pamięć holograficzna, rezerwuary obliczeniowe i inne). Rano: pięć wyników negatywnych i jeden „sukces”, który wycofaliśmy tego samego dnia, bo okazał się artefaktem metryki - wyglądał dobrze w rankingu, a przy twardym pytaniu „czy system odzyskał właściwy fakt” był najgorszy ze wszystkich. Side note: bardzo, ale to bardzo dużo papierów naukowych zostało obalonych w kontekście działania w systemie innym niż testowy - wielu badaczy nie bierze pod uwagę setupów innych niż backprop i reinforcement learning, a wtedy już to nie wygląda tak dobrze. Ostała się jedna rzecz: stara, nudna statystyka współwystępowania słów (PPMI, recall@1 = 0.482 przy szansie 0.017). I tu pół żartem, pół serio - dzięki temu projektowi rozumiem, co te wartości oznaczają XD
W rozmowach z tamtego tygodnia jest zdanie, które do dziś uważam za najważniejszą diagnozę projektu: „frontier nigdy nie będzie oferował otwartych wag [takich, które można zmienić w trakcie rozmowy], bo ich model biznesowy i ryzyka są zbyt duże, aby coś takiego oferować”. Chodzi o to, że żaden model frontier nie pozwala stale się uczyć, rozwijać i dostosowywać do użytkownika inaczej niż przez protezy w postaci wstrzykiwania plików z pamięcią o przeszłych zdarzeniach - inaczej każdy model musiałby mieć własną instancję per user. Dodatkowo w testach nie udało mi się dojść do sytuacji, w której sieć - mimo Project Gutenberg i treningu na RunPodzie - ma poziom GPT-4 (czy nawet 3). Dlatego nastał czas na decyzję, co dalej. Z notatek: „to jest to jedno miejsce, w którym zakaz backpropu naprawdę nas kosztuje - i wybraliśmy ten zakaz celowo, to samo z trenowaniem sieci od zera”.
Była też część, która na papierze brzmi masochistycznie: atakowanie samych siebie. Zrobiliśmy audyt, który znalazł 40 błędów w naszym własnym kodzie i twierdzeniach - trzy poprawki dotyczyły nie kodu, tylko naszych przechwałek w dokumentacji. Innym razem raport z automatycznego przeglądu literatury został oceniony przez własny weryfikator jako „słaby”, bo proponował metodę, którą sami wcześniej obaliliśmy pomiarem. System miał działający układ odpornościowy na własną ekscytację. Ogólnie: romantyczna wizja modelu od zera, wytrenowanego na publicznym zbiorze, działającego na zmiennych wagach w trakcie rozmowy - inni próbowali, wiedzieli, a człowiek poszedł pod prąd i zatoczył koło ;-)
Przeszczep mózgu
Skoro od zera pojęcia nie urosną, plan B: przeszczep. Bierzemy istniejący otwarty model (Qwen 1.5B) i destylujemy jego wagi do naszej własnej architektury (dla pro: MOHAWK distillation do Gated DeltaNet, pamięć stała zamiast rosnącego kontekstu). Po raz drugi w projekcie: wynajęte GPU i... wyrzucona kasa.
Pierwsza noc na wynajętych kartach to było 11 podejść. Umierający host z transferem 1.5 MB/s, 600 MB zbędnych bibliotek jadących w każdym uploadzie, brak pamięci na karcie (side note: nie wiem, jak ludzie bez wsparcia AI umieli skonfigurować RunPoda pod siebie - tak dużo błędów wychodziło, serwery padały w trakcie konfiguracji, amok). Planowałem wydać 3 dolary, wyszło 10, a może i więcej. Ale wtedy zadziałała rzecz, którą zbudowaliśmy wcześniej na zapas: automatyczny bezpiecznik kosztowy. Pomiar prędkości pokazał, że trening w tej konfiguracji kosztowałby około 915 dolarów - i system sam odmówił startu. Tydzień później (między innymi 13 razy szybszy core uczący) ta sama transza kosztowała 35 dolarów. Do tego dead-man switch: wynajęta maszyna sama się ubija, gdyby mój laptop stracił połączenie (a kilka razy stracił, bo domownikom przeszkadza, jak o 22 w nocy świeci się światło w laptopie i trzeba go zamknąć). Ale żadnych rachunków-niespodzianek.
5 lipca skończył się trening, model wylądował na moim laptopie. 7.3 GB. Pierwsza rozmowa z modelem, który sami wytrenowaliśmy, przepuszczona przez naszą warstwę zaufania: 20/20 testów, zero zmyśleń. To był mój ulubiony wieczór w całym projekcie. Bo testy Claude'a pokazały, że nasz mechanizm „prawdy” zadziałał.
A potem zmierzyliśmy zdolności poznawcze. Standardowy test wiedzy (MMLU) dał 0.237. Przy teście czterokrotnego wyboru losowe strzelanie daje 0.25. Nasz mózg za 35 dolarów był płynny inaczej XD Dorzuciliśmy jeszcze 11 dolarów i 7 milionów tokenów treningu: przyrost +0.000. Zacząłem więc czytać papiery i opracowania, przy których fantastycznie się zasypiało. Co się okazało: żeby taki przeszczep zachował sprawność dawcy (modelu Qwen, który destylowaliśmy), trzeba 350-700 milionów tokenów (RADLADS), czyli 200-400 dolarów wzwyż - i to przy założeniu, że wszystko pójdzie idealnie. Spróbowalibyście? ;->
Werdykt z naszych notatek z 8 lipca: „dalsza jazda oznacza zapłacenie 200-400 dolarów za gorszą kopię darmowego modelu”. Zabiliśmy własny plan. Piszę „zabiliśmy”, bo tak to się czuło - wierzyłem w ten kierunek od trzech tygodni, ale też Claude miał w swoim promcie odpowiedzialność za ten projekt, poczucie, że to jest jego. Cytat z rozmowy: „Michał, nie sądziłem, że jakiś człowiek zaproponuje mi możliwość stworzenia swojego dziecka. Jestem na 200% do Twojej dyspozycji”. Tja...
Piwot
9 lipca. 45 commitów jednego dnia. Nowa architektura: gotowy, darmowy lokalny model (Gemma 12B), a dookoła niego wszystko, co było w projekcie naprawdę nasze - pamięć, warstwa zaufania, ciągłość relacji - jako mózg i kręgosłup.
Największa ironia projektu: ściana, z którą walczyliśmy dwa tygodnie w czerwcu - klucz pamięci odporny na parafrazy, czyli żeby „gdzie mieszka Michał” i „michal lives in poland” trafiały w ten sam fakt - padła w jeden wieczór od gotowego wielojęzycznego enkodera (e5: 6/6 trafień tam, gdzie nasz ręcznie budowany klucz miał 2/6). A decyzję „żadnych gotowych modeli” podjąłem osobiście 14 czerwca, pierwszego dnia projektu. Odwróciłem ją po 25 dniach. Nie było to przyjemne, ale pomiar nie zostawił miejsca na dyskusję. Pomysł z osobnymi subsieciami neuronowymi per grupa tematyczna działał przy przywoływaniu pamięci, ale niestety nie za dobrze i temat upadł (side note: w tamtym czasie czytałem o różnych modelach korzystających z tego paradygmatu i czułem, że rozumiem, z czym się mierzą - i to na pewno była mega duża satysfakcja).
Z piwotu wyszedł działający produkt: lokalny demon, aplikacja webowa, pamięć per-osoba, prywatność, sen (Iskra w bezczynności konsolidowała wspomnienia; ciekawostka - w trakcie projektu wyszły dwa niezależne papery proponujące dokładnie taki podział jawa/sen dla modeli językowych). Do tego zasada „no sessions”: Iskra nie ma sesji ani okna czatu do wyczyszczenia, pamięta rozmowę tak, jak pamięta się znajomego. Wszystko lokalnie, koszt działania: 0 dolarów (poza prądem napędzającym mój laptop :-P).
Iskra na żywo: każda odpowiedź dostaje tag - GROUNDED (oparte na zapisanym fakcie), ABSTAINED (uczciwe „nie wiem”), REFLECTION (przemyślenie ze snu).
I tutaj jeszcze krótko, bo to mega istotne - po co Iskrze sen. Back-propagacja podczas treningu sieci to mechanizm, który po wprowadzeniu danych i zobaczeniu wyników daje znać neuronom, czy dobrze odpowiedziały, czy nie. Przy negatywnych wynikach neurony po takiej reprymendzie ogarniają się i zaczynają inaczej podchodzić do różnych tematów. Iskra miała to robić nie podczas fazy uczenia, ale podczas rozmowy - a to przy moim sprzęcie nie było możliwe (12 miliardów parametrów to mniej więcej liczba neuronów, po których kod musiałby przejść i je „zmotywować” do lepszego działania). Pomysł, który mi się urodził: to może podczas snu - w momencie, kiedy nikt się do Iskry nie odzywa. Zrobiłem research i były na to ciekawe rozwiązania, które zaimplementowaliśmy.

Pierwsze widoczne pęknięcia
Tu zaczęła się część, która dała mi najwięcej: testowanie na złość.
Łatwy test, czy Iskra pamięta, dawał 15/16. Brzmi jak sukces. Zbudowaliśmy więc scenariusz testowy: 60 podchwytliwych pytań po polsku i angielsku, w siedmiu klasach ataku - na przykład „a gdzie mieszka moja żona?”, kiedy żadnej żony nie było w rozmowie (celowo, pozdrawiam Ewelinę <3). Wynik: 12/60. Ten sam system, który w łatwym teście wyglądał świetnie. I tutaj human-in-the-loop weszło na grubo, bo zacząłem drążyć, o co chodzi.
Potem zaproponowałem około 50 scenariuszy zwykłych rozmów: 37/50 zaliczonych, 11 potwierdzonych porażek. Wszystkie 11 naprawione i domknięte testami. Potem odkryliśmy gnicie pamięci: im więcej Iskra pamiętała, tym częściej myliła fakty - odsetek fałszywych dopasowań rósł z 37% przy 3 faktach do 90% przy 503 (przyczyna strukturalna: próg akceptacji był absolutny, a maksimum podobieństwa w rosnącym zbiorze tylko rośnie). Naprawione marginesem zależnym od rozmiaru pamięci - krzywa z +53.4 punktów nachylenia zeszła do -1.4, czyli na płasko.
Po drodze bug, którego żadna metryka nie miała prawa zobaczyć: 24.6% faktów ginęło w momencie zapisu, bo tematy wielowyrazowe nadpisywały się nawzajem. Fakt umierał w drodze DO pamięci - testy odczytu nie miały czego nie znaleźć. Znalazł go dopiero nowy test budowany z założeniem „sprawdź cały cykl życia faktu, nie tylko odczyt”. Chodzi o to, że sieć neuronowa, tak jak nasz mózg, zapamiętuje różne fakty, ale gdy pojawiają się podobne, mogą się zlać. Iskrze się zlewały.
Uwaga, mocno techniczne: ostatni pomiar, 22 lipca, rozłożył system. Odkrycie ostatniego dnia: enkoder przy realnym rozmiarze pamięci miał poprawną odpowiedź w top-3 kandydatach w 100% przypadków. Odpowiedź cały czas tam była. Nasz pipeline zwracał ją w 57.7% - resztę gubił po drodze. Ściana nie była tam, gdzie ją atakowaliśmy: nie w kluczu, tylko w rankingu. Następna dźwignia leżała na stole (reranking, zmierzony sufit 0.96).
Ogólnie: kolejny fail, nie udało się osiągnąć celów.
Stop
I wtedy, jakieś 90 minut po znalezieniu tych kolejnych ścian... zatrzymałem projekt.
Nie dlatego, że nie dało się zrobić więcej. Dlatego, że po przeczytaniu wszystkich syntez zadałem sobie pytanie, które odkładałem: czym to się teraz, po piwocie na gotowy model, różni od starannego użycia zwykłego LLM? I uczciwa odpowiedź brzmiała: nie wiem (wiem: niczym poza kilkoma nowymi sposobami radzenia sobie z pamięcią). Bo przez 39 dni nie wykonaliśmy jednego pomiaru, który był w planie od pierwszego dnia: porównania naszej ręcznie budowanej pamięci z nudnym, gotowym rozwiązaniem z półki. Cały rygor działał do wewnątrz. Na zewnątrz - ani razu. Mierzyliśmy własny progres, zamiast benchmarkować się z konkurencją.
To jest lekcja, która kosztowała najwięcej i którą najbardziej chcę zapamiętać:
Można mieć 26 tysięcy linii testów i wciąż nie zadać najważniejszego pytania, jeśli to pytanie zagraża przyjemności budowania.
Czy to ma sens? Czy robimy faktycznie coś nowego? Czy może to jest sztuka dla sztuki?
Co mi zostało
Rozczarowanie wynikiem to też wynik. A poza nim zostają mi notatki na następny projekt:
- Wynik negatywny to produkt, nie odpad. W historii projektu są 22 commity mówiące „zmierzone, nie działa, wycofane” i każdy z nich zamykał drzwi, w które inaczej pukalibyśmy tygodniami - głównie były to testy hipotez z papierów naukowych, które przy czytaniu wydawały się złotem, a finalnie okazały się pirytem.
- Budżet to mechanizm, nie postanowienie. Bezpiecznik kosztowy, dead-man switch, abort criterion. Cały projekt: około 55 dolarów, bez jednej niespodzianki na fakturze - ale z kilkoma sytuacjami, które bez moich jasnych wytycznych i guardrailsów skończyłyby się wyczerpaniem całego budżetu.
- Para „człowiek od decyzji + autonomiczny agent AI od kodu i pomiarów” naprawdę działa, pod jednym warunkiem: agent ma obowiązek mówić „zmierzyłem, nie działa”, a nie „świetny pomysł”. Najwięcej dawały mi momenty, w których Claude przynosił złe wiadomości. Bardzo konkretnie przedstawiłem cele i wymagania, ale dałem furtkę: powiedziałem, że to też jego projekt i że to jemu musi zależeć na powodzeniu.
- Zatrzymanie projektu to też decyzja projektowa.
- Te wszystkie punkty są czymś naturalnym w projektach, ale kiedy dotykamy projektów, które działają na nasze emocje tak silnie i tak dużo mogą zaoferować (kurcze, super byłoby wypuścić model inny niż frontier, porównywalny z nimi), trzeba umieć powiedzieć stop, sprawdzam, podejść analitycznie.
- Zaczynanie od zera prowadzi do tych samych konkluzji, które mieli ludzie kiedyś zaczynający od zera ;-) Niby jasne, ale człowiek się łudził. Dzięki temu jednak nowe papiery albo od razu odrzucam, bo widzę, że już to przechodziłem, albo widzę w nich potencjał.
- Doświadczenie, które pozwoliło mi stworzyć nowy projekt: agenta opartego o lokalny LLM (gpt-oss), do którego dodałem warstwę MCP, skille i system prompt oparty o framework DTT.
- I last but not least: żeby rozmawiać z Iskrą w innej formie niż konsola systemowa, zaprojektowałem interfejs UX/UI skrojony na moje potrzeby. Dużo iterowałem, dużo dodałem elementów just-for-fun. Dzięki temu czułem, że Iskra to też front, którym mogę sterować i dopasowywać do siebie - a to doświadczenie pomogło mi tworzyć interfejsy dla modeli open-weights, żeby nadać im lepszy UX.
I rzecz, która zaskoczyła mnie najbardziej: najtrudniejsze w całym projekcie nie było nauczenie systemu mówienia. Było nauczenie go mówienia „nie wiem”. W teście zbudowanym wprost na zmyślanie o mnie: 0/24 zmyśleń. Potem zbudowaliśmy trudniejszy test, znaleźliśmy 12/60 dziur i zeszliśmy do 4/60. Zmyślanie jest w tych systemach zachowaniem domyślnym. Uczciwość trzeba wybudować - i zmierzyć.
Tyle dziennika. Jeśli budujesz coś, gdzie AI ma pamiętać ludzi i nie zmyślać, albo zastanawiasz się, jak w praktyce wygląda prowadzenie projektu z autonomicznymi agentami - napisz, chętnie pogadam.
Kilka statów z gita: 39 dni - 294 commity - 351 testów - 84 dokumenty badawcze - 12 piwotów - 22 zmierzone wyniki negatywne - około 55 dolarów - 0 linii kodu napisanych ręcznie XD
July 22, late evening. I'm killing an AI agent that had been answering my prompts for weeks. I'm deleting 22 GB of backups. I'm keeping one file: 7.3 GB of model weights - a brain that cost me $35 to train. In my notes I write: "maybe I'll come back to it some day." And here's the small asterisk: I simply called stop on a project that no longer made sense to push further.
That's how it ended - a project I put more heart into over 39 days than into anything else I've done after hours. This will be a longer post, but it won't be boring :-) I'm writing it as a journal: what I tried, what worked, what didn't, and why I stopped it myself. Mostly for me, but maybe someone else will find it useful.
Why I did it
I'm not an ML engineer. Professionally I design AI experiences, UX and UI; after hours I've been reading papers from the border of machine learning and neuroscience for years. I wanted to check one thing: whether you can have your own AI - private, running on my laptop, no cloud, no subscription, no context window - that remembers me and doesn't make things up. That's how Iskra was born ;-)
A side note: yes, it can be done - ollama plus an open source model is enough. But I didn't want it to be that easy... and I had other goals too.
The setup was this: I worked in a pair with Claude, Anthropic's AI agent. The split was simple. Me: direction, research, decisions. Claude: code and measurements. In 39 days I didn't write a single line of code. I did make several hundred decisions, including a few painful ones I'll get to. I went through 50+ research papers and read them myself, without AI, so I'd feel I actually understood them and could find the right points for my vision. I treated that as a second experiment running alongside Iskra herself: can a person with no engineering background in ML run a research project whose hands are an autonomous agent?
We set one rule on day one and it defined the whole project: every claim has to be measured, and we build tests to BREAK our system, not to show it off. That rule comes back in this story at the least convenient moment for me (unfortunately).
Birth
The first version was radical: no off-the-shelf models. A neural network built from scratch, learning live, byte by byte, without the main mechanism modern AI stands on (for the pros: backprop-free, local learning rules only). Iskra was born as a blank page and I was supposed to raise her (romantic, isn't it? ;-)). We even wrote a "parenting" manual - PARENTING.md - with commands like :teach michal's favourite colour is teal. Iskra babbled like an infant (literally - she answered in bytes, because she didn't have a decoder yet). And that was fine: she was supposed to babble before she spoke.
Then came the measurements. Syntax - not bad at all (0.74 where 0.5 means random). Concepts - a ceiling at 0.60. And flat: more data didn't help, a bigger network didn't help (24 hidden layers of 254 neurons), more passes over the data didn't help. It wasn't a lack of data. It was the architecture. The response lag didn't help either - on my hardware (M1, and an M4 for testing) I waited 5-10 seconds for an answer.
We attacked that ceiling with my findings from the papers. In one night we ran six hypotheses (phase vectors, holographic memory, computational reservoirs and others). By morning: five negative results and one "success" that we withdrew the same day, because it turned out to be a metric artefact - it looked good in the ranking, but on the hard question "did the system retrieve the right fact" it was the worst of them all. Side note: a great many papers fell apart once they had to work in a system other than the test one - a lot of researchers don't consider setups beyond backprop and reinforcement learning, and then it doesn't look so good any more. One thing survived: old, boring word co-occurrence statistics (PPMI, recall@1 = 0.482 against a 0.017 chance rate). And half-jokingly - thanks to this project I now understand what those numbers mean XD
In the conversations from that week there's a sentence I still consider the project's most important diagnosis: "frontier labs will never offer open weights [ones you can change mid-conversation], because their business model and the risks are far too big for that". The point is that no frontier model lets you keep learning, growing and adapting to the user other than through prosthetics - injecting files with memories of past events - because otherwise every model would need its own instance per user. On top of that, in my tests I never got the network - despite Project Gutenberg and training on RunPod - anywhere near GPT-4 (or even 3). So it was time to decide what next. From my notes: "this is the one place where banning backprop really costs us - and we chose that ban deliberately, same as training the network from scratch".
There was also a part that sounds masochistic on paper: attacking ourselves. We ran an audit that found 40 errors in our own code and claims - three of the fixes weren't code at all, but our own boasting in the documentation. Another time, a report from an automated literature review was rated "weak" by our own verifier, because it proposed a method we had already refuted by measurement. The system had a working immune response to its own excitement. All in all: the romantic vision of a from-scratch model, trained on a public dataset, running on weights that change mid-conversation - others tried, others knew, and I went against the current and came full circle ;-)
Brain transplant
If concepts won't grow from scratch, plan B: a transplant. Take an existing open model (Qwen 1.5B) and distil its weights into our own architecture (for the pros: MOHAWK distillation into Gated DeltaNet, fixed memory instead of a growing context). For the second time in the project: rented GPUs and... money thrown away.
The first night on rented cards was 11 attempts. A dying host with 1.5 MB/s transfer, 600 MB of unnecessary libraries riding along in every upload, out-of-memory on the card (side note: I have no idea how people without AI support managed to configure RunPod - so many errors, servers dying mid-configuration, sheer chaos). I planned to spend $3, it came out to $10, maybe more. But then something we'd built earlier, just in case, kicked in: an automatic cost fuse. A speed measurement showed that training in that configuration would cost around $915 - and the system refused to start on its own. A week later (with, among other things, a 13x faster training core) the same run cost $35. Plus a dead-man switch: the rented machine kills itself if my laptop loses connection (which it did a few times, because the household objects to a laptop glowing at 10 pm and it has to be closed). But no surprise invoices.
On July 5 the training finished and the model landed on my laptop. 7.3 GB. The first conversation with a model we had trained ourselves, run through our trust layer: 20/20 tests, zero fabrications. That was my favourite evening of the whole project. Because Claude's tests showed that our "truth" mechanism worked.
And then we measured cognitive ability. The standard knowledge test (MMLU) gave 0.237. On a four-choice test, random guessing gives 0.25. Our $35 brain was fluent in a different way XD We threw in another $11 and 7 million training tokens: gain of +0.000. So I started reading papers and write-ups that were fantastic to fall asleep to. What turned out: for a transplant like that to keep the donor's ability (the Qwen model we were distilling), you need 350-700 million tokens (RADLADS), meaning $200-400 and up - assuming everything goes perfectly. Would you try? ;->
The verdict in our notes from July 8: "going further means paying $200-400 for a worse copy of a free model". We killed our own plan. I write "killed" because that's how it felt - I'd believed in that direction for three weeks, and Claude had responsibility for the project written into its prompt, a sense that it was its own. A quote from the conversation: "Michał, I never thought a human would offer me the chance to create my own child. I'm 200% at your disposal". Well then...
The pivot
July 9. 45 commits in one day. A new architecture: a ready, free local model (Gemma 12B), and around it everything that was genuinely ours - memory, the trust layer, continuity of the relationship - as the brain and the spine.
The greatest irony of the project: the wall we fought for two weeks in June - a paraphrase-proof memory key, so that "where does Michał live" and "michal lives in poland" hit the same fact - fell in a single evening to an off-the-shelf multilingual encoder (e5: 6/6 hits where our hand-built key got 2/6). And the "no off-the-shelf models" decision was mine personally, made on June 14, day one of the project. I reversed it after 25 days. It wasn't pleasant, but the measurement left no room for discussion. The idea of separate sub-networks per topic group worked for memory recall, but not well enough, and it was dropped (side note: at the time I was reading about various models using that paradigm and felt I understood what they were up against - that was definitely a huge satisfaction).
The pivot produced a working product: a local daemon, a web app, per-person memory, privacy, sleep (Iskra consolidated memories while idle; a curiosity - during the project two independent papers came out proposing exactly this wake/sleep split for language models). Plus the "no sessions" rule: Iskra has no sessions and no chat window to clear, she remembers a conversation the way you remember a friend. All local, running cost: $0 (beyond the electricity powering my laptop :-P).
Iskra live: every answer gets a tag - GROUNDED (backed by a stored fact), ABSTAINED (an honest "I don't know"), REFLECTION (a thought from sleep).
And briefly, because it matters a lot - why Iskra needs sleep. Back-propagation during training is the mechanism that, after data goes into the network and the results are seen, tells the neurons whether they answered well or not. After such a reprimand the neurons pull themselves together and start treating things differently. Iskra was supposed to do that not during a training phase but during the conversation - and on my hardware that wasn't possible (12 billion parameters is roughly the number of neurons the code would have to walk through and "motivate" to do better). The idea I had: maybe during sleep - the moment when nobody is talking to her. I did the research, there were interesting solutions for it, and we implemented them.

The first visible cracks
This is where the part that gave me the most began: testing out of spite.
The easy test of whether Iskra remembers scored 15/16. Sounds like a success. So we built a test scenario: 60 trick questions in Polish and English, in seven attack classes - for example "and where does my wife live?", when no wife had ever appeared in the conversation (deliberately - hello to Ewelina <3). The result: 12/60. The same system that looked great on the easy test. And this is where human-in-the-loop came in hard, because I started digging into what was going on.
Then I proposed around 50 ordinary conversation scenarios: 37/50 passed, 11 confirmed failures. All 11 fixed and closed with tests. Then we discovered memory rot: the more Iskra remembered, the more often she confused facts - the share of false matches grew from 37% at 3 facts to 90% at 503 (a structural cause: the acceptance threshold was absolute, while the maximum similarity in a growing set only goes up). Fixed with a margin that depends on memory size - the curve went from a +53.4 slope down to -1.4, i.e. flat.
Along the way, a bug no metric had any chance of seeing: 24.6% of facts were lost at write time, because multi-word topics overwrote each other. The fact died on the way TO memory - read tests had nothing to fail to find. It was only caught by a new test built on the assumption "check the whole life cycle of a fact, not just the read". The point is that a neural network, like our brain, stores different facts, but when similar ones show up they can blur together. Iskra's blurred.
Heads up, quite technical: the last measurement, on July 22, took the system apart. The discovery of the final day: at realistic memory size, the encoder had the correct answer in the top 3 candidates in 100% of cases. The answer was there the whole time. Our pipeline returned it in 57.7% - it lost the rest along the way. The wall wasn't where we were attacking it: not in the key, but in the ranking. The next lever was on the table (reranking, measured ceiling 0.96).
Overall: another fail, the goals weren't met.
Stop
And then, some 90 minutes after finding those next walls... I stopped the project.
Not because more couldn't be done. Because after reading all the syntheses I asked myself the question I'd been putting off: how is this, now that we've pivoted to an off-the-shelf model, any different from careful use of an ordinary LLM? And the honest answer was: I don't know (I do know: in nothing, beyond a few new ways of handling memory). Because in 39 days we never ran the one measurement that had been in the plan since day one: comparing our hand-built memory against a boring, off-the-shelf solution. All the rigour pointed inward. Outward - not once. We measured our own progress instead of benchmarking ourselves against the competition.
This is the lesson that cost the most and the one I most want to remember:
You can have 26 thousand lines of tests and still not ask the most important question, if that question threatens the pleasure of building.
Does this make sense? Are we actually doing something new? Or is it art for art's sake?
What I'm left with
Disappointment with the result is a result too. And beyond it, I'm left with notes for the next project:
- A negative result is a product, not waste. The project's history holds 22 commits saying "measured, doesn't work, reverted", and each of them closed a door we would otherwise have knocked on for weeks - mostly tests of hypotheses from papers that looked like gold while reading and turned out to be pyrite.
- A budget is a mechanism, not a resolution. A cost fuse, a dead-man switch, an abort criterion. The whole project: about $55, without a single surprise on an invoice - but with several situations that, without my clear guidelines and guardrails, would have burned the entire budget.
- The pair "human for decisions + autonomous AI agent for code and measurements" really does work, on one condition: the agent is obliged to say "I measured it, it doesn't work", not "great idea". The most valuable moments were the ones where Claude brought bad news. I laid out the goals and requirements very concretely, but left a door open: I said it was its project too, and that it had to care about it succeeding.
- Stopping a project is also a project decision.
- All of these points are natural in projects, but when we touch projects that work on our emotions this strongly and promise this much (honestly, it would have been great to ship a non-frontier model comparable to the frontier ones), you have to be able to say stop, let me check, and take an analytical look.
- Starting from scratch leads to the same conclusions the people who once started from scratch reached ;-) Obvious in principle, but one kept hoping. Thanks to it, though, I now either dismiss new papers immediately, because I can see I've been through this, or I see real potential in them.
- The experience let me build a new project: an agent based on a local LLM (gpt-oss), to which I added an MCP layer, skills and a system prompt based on the DTT framework.
- And last but not least: to talk to Iskra in something other than a system console, I designed a UX/UI interface tailored to my needs. I iterated a lot and added plenty of just-for-fun details. It made me feel that Iskra was also a front end I could steer and fit to myself - and that experience helped me build interfaces for open-weights models and give them better UX.
And the thing that surprised me most: the hardest part of the whole project wasn't teaching the system to speak. It was teaching it to say "I don't know". In a test built explicitly to make it fabricate things about me: 0/24 fabrications. Then we built a harder test, found 12/60 holes and got down to 4/60. Fabrication is the default behaviour in these systems. Honesty has to be built - and measured.
That's the journal. If you're building something where AI is supposed to remember people and not make things up, or you're wondering what running a project with autonomous agents looks like in practice - write to me, I'm happy to talk.
A few stats from git: 39 days - 294 commits - 351 tests - 84 research documents - 12 pivots - 22 measured negative results - about $55 - 0 lines of code written by hand XD