Prywatny „drugi mózg” AI: lokalny system RAG z wykorzystaniem AnythingLLM, Ollamy i Obsidian.
Prywatny drugi mózg: AnythingLLM oraz model embeddingowy na maszynie wirtualnej Proxmox umożliwiają lokalnemu modelowi Mistral 7B wyszukiwanie notatek w Obsidian za pomocą Ollama RAG, przy rzeczywistym zużyciu zasobów.
Źródła: Giving My Local AI a Memory: Turning It Into a Private AI Second Brain with RAG and AnythingLLM
Błyskotliwy amnezik
Lokalny model językowy potrafi prowadzić rozmowy, wyjaśniać koncepcje i pomagać w przemyśleniu pomysłów, przy czym ani jeden bajt nie opuszcza budynku. Nie potrafi jednak automatycznie przywołać niczego, co zostało zapisane.
Wyobraź sobie rok zgromadzonych notatek w Obsidianie: linki zaznaczone o północy, nieukończone myśli, długi artykuł o silnikach wyszukiwania, ogłoszenia o pracę oraz notatki z warsztatów. Wszystko to znajduje się w folderze na laptopie, niewidoczne dla sztucznej inteligencji, która potrzebowała całego weekendu, by działać offline.
Pamięć przechowywania nigdy nie była problemem. Problemem jest dostęp do danych. Wybór właściwej notatki we właściwym momencie to to, co zamienia folder pełen linków w wiedzę, a nie w dobrze zorganizowaną skrzynkę na śmieci. Dlatego naturalnym następnym krokiem w prywatnym setupie sztucznej inteligencji jest umożliwienie jej dostępu do tych notatek.
Czym jest RAG i dlaczego jest ważne
Większość przewodników dotyczących „uruchamiania AI lokalnie” pomija tę część, prawdopodobnie dlatego, że embeddingi wydają się nudne. Rzeczywiście są nieco nudne, ale warto je zrozumieć.
RAG to skrót od Retrieval-Augmented Generation. Umożliwia modelowi językowemu korzystanie z twoich własnych dokumentów bez konieczności ponownego szkolenia ani przesyłania ich na serwer third party.
Pomyśl o zatrudnieniu bardzo szybkiego bibliotekarza zamiast prośeniu AI o zapamiętanie każdej książki. Bibliotekarz nie zna twoich notatek na pamięć, wie tylko, którą wybrać, gdy zadasz pytanie.
Oto co dzieje się w tle:
- Dokumenty są dzielone na fragmenty i przekształcane w embeddingi, czyli liczbowe reprezentacje znaczenia, które są przechowywane w bazie danych wektorowej.
- Pytanie również jest przekształcane w embedding.
- Baza danych znajduje fragmenty o znaczeniu najbliższym pytaniu.
- Te fragmenty trafiają do modelu językowego jako kontekst.
Narzędzie: AnythingLLM
AnythingLLM nadaje się do tego zastosowania z kilku powodów:
- Przestrzenie robocze przechowują oddzielne bazy wiedzy dla różnych kontekstów, takich jak notatki, badania czy szkice blogów.
- Czyta pliki w formacie Markdown natywnie, więc notatki w Obsidianie nie wymagają konwersji.
- Łączy się bezpośrednio z Ollamą.
- Jest uruchamiany lokalnie jako kontener Docker, bez konieczności posiadania konta ani korzystania z chmury.
- Posiada również aplikację na komputer stacjonarny, która pomaga osobom, które nie mają homelabu.
To nie jest jedyna opcja. Open WebUI również ma wbudowany mechanizm RAG. Jednak model przestrzeni roboczej AnythingLLM lepiej odpowiada koncepcji „drugiego mózgu”, a jego interfejs jest na tyle przyjazny, że można go polecić osobom niebędącym specjalistami technicznymi.
Budowanie środowiska
Punkt wyjścia
Ustawienie zakłada następującą bazę:
- host Proxmox VE działający bez systemu operacyjnego;
- jedna maszyna wirtualna Ubuntu 24.04 z Ollamą i modelami Mistral 7B;
- Open WebUI jako interfejs do rozmów.
W procesie konfiguracji dodaje się drugą maszynę wirtualną obok niej.
Nowa maszyna wirtualna w Proxmox
Stwórz nową maszynę wirtualną Ubuntu 24.04 LTS przeznaczoną dla AnythingLLM. Utrzymywanie jej oddzielnie od maszyny z Ollamą umożliwia tworzenie zrzutów stanu, celowe uszkadzanie konfiguracji oraz jej przywracanie bez wpływu na rzeczywiste ustawienia inferencji. Celowe uszkadzanie jest lepsze niż przypadkowe awarie później.
Zalecane specyfikacje:
- 4 vCPUs
- 8 GB RAM
- 40 GB dysku, ponieważ bazy wektorowe zajmują dużo miejsca
Nic tutaj nie jest trudne. Dokumentacja to omawia, a dodatkowo trochę prób i błędów wystarczy, szczególnie dla tych, którzy już uruchomili maszynę wirtualną Ollama. Prawdziwym ograniczeniem jest dostępny sprzęt, a praca w ramach tych ograniczeń stanowi sedno tego ćwiczenia.
Instalowanie modelu embedding
Większość przewodników pomija ten krok, co powoduje najwięcej problemów.
RAG wymaga dwóch modeli. Jeden to model inferencji, który już dostarcza Mistral 7B. Drugi to model embedding, który przekształca tekst na wektory. Są to różne rzeczy, a niewiele przewodników informuje o tym od razu.
Na istniejącej maszynie wirtualnej Ollama pobierz model embedding:
ollama pull nomic-embed-text
nomic-embed-text ma niewielką objętość, około 270 MB, szybko działa na procesorze i dobrze radzi sobie z tekstem w języku angielskim – jest więc rozsądnym wyborem dla sprzętu bez karty graficznej.
Kolejny problem: Ollama domyślnie słucha tylko na localhost. Aby AnythingLLM działający na innej maszynie wirtualnej mógł do niego uzyskać dostęp, Ollama musi być dostępny na wszystkich interfejsach. Zacznij od edycji usługi:
sudo systemctl edit ollama
Następnie dodaj tę modyfikację:
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
Przeładowaj systemd i uruchom ponownie usługę:
sudo systemctl daemon-reload
sudo systemctl restart ollama
Następnie otwórz port 11434 w firewallu Proxmox pomiędzy dwoma maszynami wirtualnymi. Lekcja się powtarza: usługa była w porządku, model również. Problemem była założenie, że wszystko może komunikować się ze sobą domyślnie.
Zasady sieciowe mogłyby być bardziej restrykcyjne i prawdopodobnie tak powinno być w końcu. To typowe podejście amatorów: sprawić, by coś działało, zrozumieć, co zostało zbudowane, a potem to zdemontować i zrobić to poprawnie od nowa.
AnythingLLM przez Docker
Na nowej maszynie wirtualnej najpierw zainstaluj Docker:
# Install Docker
curl -fsSL <https://get.docker.com> | sh
sudo usermod -aG docker $USER
newgrp docker
Następnie uruchom AnythingLLM:
# Run AnythingLLM
docker run -d \
-p 3001:3001 \
--name anythingllm \
-v ~/.anythingllm:/app/server/storage \
mintplexlabs/anythingllm
Otwórz w przeglądarce http://<new-vm-ip>:3001. Konfiguracja przy pierwszym uruchomieniu jest następująca:
- Dostawca LLM: Ollama, pod adresem
http://<ollama-vm-ip>:11434 - Model do czatowania: Mistral 7B
- Dostawca embeddingów: Ollama, z użyciem
nomic-embed-text - Baza wektorowa: LanceDB, wbudowana w system i nie wymagająca dodatkowej konfiguracji
Dostarczanie mu notatek
Stwórz przestrzeń roboczą o nazwie „Second Brain” i skieruj AnythingLLM na schowek Obsidian. Jego menedżer dokumentów przyjmuje pliki z folderów, więc podaj mu katalog z notatkami i pozwól mu je przetworzyć.
Przetwarza pliki typu .md, .txt, .pdf, .docx oraz .csv. Pliki Obsidian Canvas są w rzeczywistości plikami JSON, więc nie spowodują błędu, ale też nie dostarczą żadnych użytecznych informacji.
Po przyjęciu tekstu przestrzeń robocza pokazuje liczbę fragmentów oraz status ich embedowania. Każda notatka jest dzielona na nakładające się fragmenty po około 500 tokenów, co oznacza, że długi artykuł o silnikach wyszukiwania staje się dziesiątkami oddzielnie dostępnych fragmentów.
Moment kliknięcia
Prawdziwą próbą jest zwykła prośba, na przykład poproszenie asystenta o sprawdzenie konkretnej notatki o nazwie „ulepszenia w homelabie”.
Asystent znajduje właściwy plik, podaje jego nazwę i przytacza dokładny fragment wraz z datą i godziną. Odniesienie zawiera nazwę dokumentu źródłowego oraz datę publikacji. Funkcja wyszukiwania działa zgodnie z obietnicami: plik jest nazwany i odnaleziony, bez wymyślonego treści ani niejasnej parafrazy – tylko właściwe informacje wraz z odniesieniem.
Zabawne jest to, gdy model próbuje wyjaśnić tę notatkę. Opisuje Claude Code jako swego rodzaju asystenta osobistego lub usługę. Mistral 7B, działający offline na urządzeniu domowym z samym procesorem, nie ma pojęcia, czym jest Claude Code ani serwer MCP. Potrafi pobrać słowa, ale nie potrafi ich w pełni zrozumieć.
To jest ważniejsza lekcja. Pobieranie informacji i ich rozumienie to odrębne problemy. RAG umieszcza odpowiedni kontekst przed modelem, ale zrozumienie tego kontekstu nadal zależy od samego modelu. Przy małym modelu 7B i braku dostępu do Internetu te ograniczenia pojawiają się szybko.
Co poszło nie tak i co to nauczyło
Kilka założeń nie przetrwało procesu budowy.
- RAG to nie magia. Jest tak użyteczny, jak to, co mu dostarczono, a nieuporządkowane notatki dają nieuporządkowane wyniki. Co włożysz, to i dostaniesz.
- Tworzenie sieci staje się częścią projektu już na wczesnym etapie. Gdy usługi są rozproszone na kilku maszynach, kluczowe jest zapewnienie ich niezawodnej komunikacji, co ma takie samo znaczenie jak konfiguracja każdej z nich.
- Nie winić zbyt szybko modelu. Czasami problem leży w dostarczonym kontekście. Dobre mechanizmy wyszukiwania mogą sprawić, że mały model okaże się zaskakująco przydatny, ale nie mogą dostarczyć wiedzy, której model nigdy nie posiadał.
Co ostatecznie otrzymujemy i jaki jest to koszt
Rok zapisanych linków, pomysłów i nieukończonych myśli staje się dostępny do wyszukiwania, i to nie tylko za pomocą słów kluczowych, ale także semantycznie. Zadaj pytanie dotyczące jakiegoś pojęcia, a pojawią się powiązane notatki, o których zapomniałeś, że są powiązane, każda z nich z odniesieniem do pliku źródłowego.
Maszyna testowa to EliteDesk z procesorem i5, 32 GB pamięci RAM i bez karty graficznej, a wszystko działało offline. Wyniki z tego jednego testu:
| Pozycja | Wynik |
|---|---|
| Czas przetwarzania zapytania od początku do końca | 1 min 35,9 s, przy czym AnythingLLM podaje 41,9 s na generowanie |
| Pamięć AnythingLLM w stanie spoczynku | około 440 MB z przydzielonych 7,76 GB |
| Pamięć używana przez wirtualną maszynę Ollama | 7,8 GB z 19 GB |
| Pamięć potrzebna do działania Mistral | około 6,5 GB |
| nomic-embed-text | około 360 MB |
| Open WebUI | około 1 GB |
Około 54-sekundowa różnica pomiędzy tymi dwoma czasami nie ma wyjaśnienia. Prawdopodobną przyczyną może być ponowne ładowanie modelu przez Ollamę z dysku twardego.
Żadna z tych wartości nie jest szybka i tak też nie powinno być. To dopiero pierwszy dzień pracy konfiguracji RAG w domowym laboratorium, która wciąż szuka swojej formy, a nie jest to benchmark do porównywania z poważnymi rozwiązaniami. Będzie ciekawie spojrzeć w przyszłości na te liczby, gdy lokalny sprzęt będzie mógł przetwarzać znacznie więcej tokenów na sekundę.
Gdzie to was prowadzi
Projekt zaczyna się od prostego celu – umożliwienia lokalnej sztucznej inteligencji przeglądania waszych notatek – ale uczy również wielu innych rzeczy. W trakcie nauki poznajecie, jak działa RAG, czym są bazy danych wektorowych, co sprawia, że wyszukiwanie jest skuteczne, oraz dlaczego odpowiedni kontekst może być ważniejszy niż większy model.
Co ważniejsze, rezultatem jest coś, czego rzeczywiście będziecie używać. Dwanaście miesięcy zgromadzonej wiedzy przestaje być rozproszona w folderach i staje się czymś, o co można po prostu zapytać. Wszystko to działa na używanym laptopie stojącym w kącie pokoju, co nie jest złe jak na maszynę przeznaczoną do odstawienia.
RAG faktycznie działa. Zrozumienie to już inna historia.
Dalsza lektura
Dokumentacja dotycząca AnythingLLM, Ollamy, LanceDB i Obsidian zawiera szczegółowe informacje. Oryginalny artykuł na temat RAG, „Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks”, wyjaśnia ideę leżącą u podstaw tego rozwiązania. Wszystko to działa na przekształconym sprzęcie, bez użycia chmury, bez subskrypcji i bez wychodzenia danych poza sieć.