Perplexica, dziś Vane — własna wyszukiwarka AI na twoim sprzęcie
Perplexica zmieniła nazwę na Vane i od kwietnia 2026 nie ma nowych commitów, ale nadal jest to najkompletniejsza self-hostowana wyszukiwarka AI z cytowaniami: SearxNG, Ollama, tryby speed/balanced/quality i API do wpięcia w aplikację. Pokazujemy uruchomienie, integrację z Laravelem i jeden powód, dla którego nie wolno tego wystawić do internetu bez proxy.
Jeśli szukasz Perplexiki — samodzielnie hostowanej wyszukiwarki AI, która odpowiada na pytania z cytowaniami źródeł, korzystając z lokalnego modelu i własnej instancji SearxNG — to projekt istnieje, działa i nazywa się dziś Vane. Repozytorium ItzCrazyKns/Perplexica przekierowuje na github.com/ItzCrazyKns/Vane, a stara nazwa została w słowach kluczowych repozytorium i w kilku miejscach, których przy zmianie nazwy nie posprzątano.
To jest pierwsza rzecz, którą trzeba wiedzieć. Druga jest mniej przyjemna i o niej też będzie tu wprost: projekt od kwietnia 2026 nie ma nowych commitów. Nie jest zarchiwizowany, nie zniknął, oprogramowanie działa i ma licencję MIT — ale decyzja o postawieniu go u siebie wygląda inaczej niż pół roku temu. Ten wpis ma dać wszystko, co potrzebne do jej podjęcia: jak to działa, jak to uruchomić, jak wpiąć w aplikację i czego pod żadnym pozorem nie robić.
Stan projektu — bez upiększania
Liczby na dziś:
- 36 390 gwiazdek, 4 038 forków, licencja MIT, kod w TypeScripcie,
- ostatnie wydanie
v1.12.2z 10 kwietnia 2026, ostatni commit z 11 kwietnia 2026, - 347 otwartych zgłoszeń, przy czym nowe wpadają nadal — najnowsze z 20 sierpnia 2026,
- otwarte pull requesty z sierpnia 2026, żaden nie zmergowany,
- pozostałe repozytoria autora również zamilkły w kwietniu 2026.
Wniosek jest taki, jaki jest: to projekt jednego autora w przerwie o nieznanym końcu. Społeczność zgłasza błędy i przysyła łatki, tylko nikt ich nie scala. Nie znaczy to, że oprogramowanie przestało działać — obraz z kwietnia uruchamia się i odpowiada tak samo dobrze jak w kwietniu. Znaczy to trzy rzeczy praktyczne:
- Nie licz na łatki bezpieczeństwa. Przy narzędziu, które ma dostęp do Twoich kluczy API i wykonuje kod pobrany z internetu (o tym niżej), to nie jest detal,
- Przypnij wersję obrazu. Skoro nie ma nowych wydań, tag
latestnie daje żadnej korzyści, a zabiera przewidywalność, - MIT daje wyjście awaryjne. Jeśli to narzędzie stanie się u Ciebie krytyczne, fork jest legalny i tani — 4 tysiące forków oznacza, że kod jest zwielokrotniony w wielu miejscach.
Traktujemy Vane jako narzędzie wewnętrzne do postawienia i sprawdzenia, nie jako komponent produkcyjny, na którym opieramy usługę dla klienta. Przy tym pierwszym zastosowaniu przerwa w rozwoju kosztuje niewiele; przy drugim jest ryzykiem, którego nie warto brać.
Jak to jest zbudowane
Vane to jedna aplikacja Next.js 16 — front i API w tym samym procesie, bez osobnego backendu (wcześniejsze wersje Perplexiki miały rozdzielone usługi i LangChain; dziś tego nie ma). Dane siedzą w SQLite przez Drizzle ORM, w wolumenie /home/vane/data. Historia rozmów jest zapisywana lokalnie, więc da się do nich wrócić.
Ścieżka odpowiedzi na pytanie ma trzy etapy i to jest cała architektura:
- Klasyfikacja. Model decyduje, czy pytanie wymaga w ogóle szukania w sieci, czy pokazać jakiś widget i jak przepisać pytanie na samodzielnie zrozumiałą formę (bez tego „a ile to kosztuje?” w trzeciej wiadomości nie ma sensu jako zapytanie do wyszukiwarki),
- Badanie i widgety równolegle. Wyszukiwanie idzie przez SearxNG, treść stron jest pobierana i oczyszczana (
@mozilla/readabilityplus Playwright do stron wymagających JavaScriptu), a przy pytaniach o pogodę, kursy akcji czy obliczenia odpalają się osobne widgety — pokazywane od razu, jeszcze w trakcie generowania odpowiedzi, - Generowanie odpowiedzi z cytowaniami. Model dostaje zebrany kontekst i pisze odpowiedź z odnośnikami do numerowanych źródeł, które interfejs renderuje obok tekstu.
Do tego wyszukiwanie po plikach użytkownika: wgrane dokumenty (PDF, DOCX, XLSX, obrazy, pliki tekstowe — biblioteki pdf-parse, mammoth, officeparser) są indeksowane modelem embeddingowym i wchodzą do kontekstu obok wyników z sieci. Embeddingi mogą liczyć się lokalnie przez @huggingface/transformers, bez wychodzenia na zewnątrz.
Modele: Ollama i LM Studio lokalnie, Lemonade, dowolny serwer zgodny z API OpenAI, a z chmury OpenAI, Anthropic, Google Gemini i Groq. Trzy tryby pracy — speed, balanced, quality — regulują, ile roboty wykonuje się przed odpowiedzią. Źródła da się zawężać: sieć, dyskusje, prace naukowe, a także pojedyncza domena, gdy wiadomo, gdzie szukać.
Wystawione punkty końcowe: POST /api/chat (interfejs), POST /api/search (programistyczny), GET /api/providers, POST /api/images, POST /api/videos, plus /api/suggestions, /api/discover, /api/uploads i /api/weather.
Uruchomienie
Najprostsza droga to jeden obraz z SearxNG w środku:
docker run -d -p 3000:3000 \
-v vane-data:/home/vane/data \
--name vane itzcrazykns1337/vane:v1.12.2Po wejściu na http://localhost:3000 jest ekran konfiguracji — klucze API i modele ustawia się w interfejsie, nie w plikach. Jeśli masz już własną instancję SearxNG, jest wariant „slim”:
docker run -d -p 3000:3000 \
-e SEARXNG_API_URL=http://searxng:8080 \
-v vane-data:/home/vane/data \
--name vane itzcrazykns1337/vane:slim-v1.12.2Dwa wymagania po stronie SearxNG, bez których nie zadziała: włączony format JSON w ustawieniach i włączony silnik Wolfram Alpha. To drugie zaskakuje, bo nie jest oczywiste, dopóki nie zobaczy się pustych odpowiedzi przy pytaniach obliczeniowych.
Teraz rzecz, którą warto sprawdzić przed pobraniem, bo dokumentacja o niej nie mówi. Obraz pełny waży według Docker Huba blisko 4 GB (SearxNG, przeglądarki Playwrighta, modele do embeddingów lokalnych). Nazwa „slim” sugeruje coś znacznie mniejszego, ale tag slim-latest po ostatniej przebudowie z 11 kwietnia 2026 — tej, która dodała obsługę Playwrighta — ma około 3,67 GB. Wcześniejszy, wersjonowany slim-v1.12.2 to 578 MB. Różnica jest siedmiokrotna, a wynika z jednego commita. Jeśli zależy Ci na rozmiarze, bierz tag wersjonowany i sprawdź, czy scenariusze, których używasz, działają bez Playwrighta.
Przy modelach lokalnych dochodzi klasyczny problem sieciowy kontenera. Ollama pod Windowsem i macOS-em: http://host.docker.internal:11434. Pod Linuksem: prywatny adres IP hosta, a sam Ollama musi nasłuchiwać szeroko — Environment="OLLAMA_HOST=0.0.0.0:11434" w /etc/systemd/system/ollama.service, potem systemctl daemon-reload i restart. Przy serwerach zgodnych z API OpenAI dokumentacja dodaje trzy warunki: serwer musi słuchać na 0.0.0.0, nazwa modelu musi być dokładnie taka jak wczytana, a pole klucza API nie może zostać puste — jeśli serwer klucza nie wymaga, trzeba wpisać cokolwiek.
Vane da się też podpiąć jako wyszukiwarka w przeglądarce: adres http://localhost:3000/?q=%s dodany w ustawieniach jako własna wyszukiwarka daje odpowiedzi z cytowaniami wprost z paska adresu.
Własna instancja SearxNG
Jeśli idziesz wariantem „slim”, konfigurację SearxNG najprościej podejrzeć w repozytorium Vane — obraz pełny używa dokładnie takiej. Sedno to trzy rzeczy:
use_default_settings: true
search:
autocomplete: 'google'
formats:
- html
- json
engines:
- name: wolframalpha
disabled: falseFormat json obok html, bo domyślnie SearxNG oddaje tylko HTML, a Vane odpytuje /search?format=json. Silnik wolframalpha jawnie odblokowany, bo w domyślnej konfiguracji jest wyłączony. Do tego w obrazie Vane włączona jest ochrona przed botami metodą link_token (limiter.toml) i sekret nadpisywany zmienną SEARXNG_SECRET — o tym drugim warto pamiętać przy własnym wdrożeniu, bo klucz z repozytorium jest publiczny.
Jeden szczegół operacyjny, którego nie ma w dokumentacji, a który wychodzi z kodu: zapytania do SearxNG mają twardy limit 10 sekund i po jego przekroczeniu żądanie jest przerywane. Instancja SearxNG obciążona albo odpytująca wolne silniki będzie się objawiać jako „brak wyników”, nie jako błąd sieci. Przy własnej instancji warto ograniczyć listę silników do tych, które faktycznie odpowiadają szybko.
Bez Dockera i aktualizacje
Instalacja bez kontenera to standardowe npm i, npm run build, npm run start — z SearxNG do postawienia osobno. Dokumentacja rekomenduje Dockera i słusznie, bo w obrazie jest komplet: SearxNG, przeglądarki Playwrighta i zależności do parsowania dokumentów.
Aktualizacja wygląda jak przy każdej aplikacji trzymanej w jednym kontenerze — pobranie obrazu, zatrzymanie, usunięcie kontenera, uruchomienie nowego z tym samym wolumenem:
docker pull itzcrazykns1337/vane:slim-v1.12.2
docker stop vane && docker rm vane
docker run -d -p 127.0.0.1:3000:3000 \
-e SEARXNG_API_URL=http://searxng:8080 \
-v vane-data:/home/vane/data --name vane itzcrazykns1337/vane:slim-v1.12.2Ustawienia i historia rozmów przeżywają wymianę kontenera, bo siedzą w wolumenie, nie w obrazie. Przy projekcie w przerwie ta procedura ma dziś zresztą znaczenie teoretyczne — nie ma czego pobierać. To kolejny argument, żeby zamiast latest wpisać numer wersji: nic nie tracisz, a zyskujesz pewność, że przypadkowa przebudowa obrazu (jak ta, która powiększyła „slim” siedmiokrotnie) nie zmieni Ci środowiska w tle.
Ślady starej nazwy
Zmiana nazwy nie została dokończona i przy szukaniu pomocy trafisz na sprzeczne instrukcje. W samym README odnośnik sponsora prowadzi pod adres z członem perplexica, a szablony wdrożeń jednym kliknięciem na Sealos i ClawCloud nadal odwołują się do szablonu o nazwie perplexica. Na Docker Hubie żyją równolegle dwa zestawy obrazów: nowy itzcrazykns1337/vane (15 tagów, wszystkie z 10–11 kwietnia 2026) i stary itzcrazykns1337/perplexica (72 tagi, ostatni z 13 lutego 2026). Stare obrazy działają, ale są o dwa miesiące starsze od ostatniego wydania — jeśli zaczynasz dziś, bierz obrazy pod nową nazwą.
Widgety, obrazy i Discover
Trzy funkcje, które łatwo przeoczyć, a które odpowiadają za wrażenie „to nie jest tylko czat nad wyszukiwarką”. Widgety to małe karty pojawiające się obok odpowiedzi, gdy pytanie na nie zasługuje — pogoda, kursy akcji (biblioteka yahoo-finance2 i wykresy lightweight-charts), obliczenia (mathjs). Pokazują się od razu, w trakcie generowania odpowiedzi, i celowo nie wchodzą do materiału, który model ma cytować. Wyszukiwanie obrazów i wideo ma osobne punkty końcowe (POST /api/images, POST /api/videos): model najpierw przepisuje pytanie na zapytanie graficzne, potem lecą wyniki z metawyszukiwarki. Discover to przegląd ciekawych artykułów bez zadawania pytania — funkcja, której nie potrzebujesz w narzędziu wewnętrznym, ale która tłumaczy, skąd w zależnościach biorą się parsery treści.
Czego nie robić: to nie ma uwierzytelniania
To najważniejsza sekcja tego wpisu. Uwierzytelnianie jest w Vane pozycją na liście „planowane funkcje”, czyli nie ma go w ogóle. Kto dosięgnie portu, ten korzysta z aplikacji — i to jeszcze nie jest najgorsze.
W repozytorium jest otwarte zgłoszenie (#1180 z 7 sierpnia 2026) o wystawianiu kluczy API po stronie klienta. Sprawdziliśmy je w kodzie, bo to poważny zarzut. Punkt GET /api/config zwraca wynik configManager.getCurrentConfig(), czyli głęboką kopię całej konfiguracji. W kodzie zarządzania konfiguracją nie ma ani maskowania, ani pojęcia wartości tajnej — nie występuje tam słowo „redact”, „mask” ani „secret”. Konfiguracja dostawców modeli to swobodna mapa, do której ekran konfiguracji wpisuje między innymi klucz API. Całości nie chroni żadne uwierzytelnienie, bo takiego w aplikacji nie ma.
Praktyczne tłumaczenie: publicznie wystawiona instancja Vane oddaje Twoje klucze OpenAI, Anthropic czy Groq każdemu, kto zna adres i potrafi wysłać jedno żądanie GET. Rachunek przyjdzie do Ciebie. README zachęca przy tym do wystawienia aplikacji w sieci i wspomina, że działa poprawnie za przekierowaniem portów — te dwa zdania z tego samego pliku trzeba czytać razem.
Co z tym zrobić, w kolejności od najprostszego:
- Nie publikuj portu.
-p 127.0.0.1:3000:3000zamiast-p 3000:3000— do lokalnego użycia to wystarcza i jest darmowe, - Reverse proxy z uwierzytelnianiem. Caddy albo nginx z basic auth przed kontenerem, a jeśli macie już OIDC — proxy uwierzytelniające. Wszystko poza
/i tak nie jest publiczne, więc uwierzytelnienie na całości niczego nie psuje, - Sieć prywatna zamiast internetu. Tailscale albo WireGuard i instancja widoczna tylko dla zespołu. To rozwiązanie, które przy narzędziach wewnętrznych bez logowania jest najuczciwsze,
- Osobne klucze API z limitem wydatków — nie ten sam klucz, którym jeżdżą usługi produkcyjne. Limity miesięczne u dostawcy zamieniają katastrofę w niedogodność,
- Albo w ogóle bez kluczy chmurowych. Vane z samym Ollamą i lokalnymi embeddingami nie ma czego wyciekać — to najlepszy tryb pracy, jeśli sprzęt pozwala, i zgodny z tym, co projekt obiecuje w pierwszym zdaniu opisu.
API, czyli po co to komu w aplikacji
Interfejs czatu jest przyjemny, ale dla nas ciekawsze jest to, że Vane wystawia wyszukiwanie z cytowaniami jako endpoint HTTP. Najpierw pobiera się identyfikatory dostawców:
curl http://localhost:3000/api/providersOdpowiedź zawiera dostawców z listami modeli czatowych i embeddingowych; z niej bierze się providerId (UUID) oraz key modelu — nie nazwę wyświetlaną. Potem jedno żądanie na zapytanie:
$response = Http::timeout(120)->post('http://vane:3000/api/search', [
'chatModel' => [
'providerId' => config('services.vane.provider_id'),
'key' => 'gpt-4o-mini',
],
'embeddingModel' => [
'providerId' => config('services.vane.provider_id'),
'key' => 'text-embedding-3-large',
],
'optimizationMode' => 'balanced',
'sources' => ['web'],
'query' => $pytanie,
'systemInstructions' => 'Odpowiadaj po polsku, zwięźle, wyłącznie na podstawie źródeł.',
'stream' => false,
]);
$odpowiedz = $response->json('message');
$zrodla = $response->json('sources'); // content + metadata.title + metadata.urlParametry, które warto znać: sources przyjmuje web, academic i discussions; optimizationMode to speed, balanced albo quality; history to tablica par ['human', '…'] i ['assistant', '…'], dzięki której kolejne pytania rozumieją kontekst; systemInstructions to instrukcje użytkownika o niższym priorytecie niż instrukcje systemowe aplikacji — nie da się nimi obejść zachowania rdzenia.
Przy stream: true odpowiedź przychodzi jako strumień zdarzeń (text/event-stream), gdzie każda linia to samodzielny obiekt JSON z polem type: init, potem sources z całą listą źródeł, potem seria response z fragmentami tekstu i na końcu done. Wygodne, bo źródła dostajesz przed pierwszym fragmentem odpowiedzi — można je pokazać użytkownikowi od razu.
Zastosowania, które w tej formie mają sens u nas: wewnętrzna wyszukiwarka po dokumentacji i publicznych źródłach z cytowaniami (bez cytowań nie ma czego weryfikować, więc to jest warunek, a nie ozdoba), wsparcie researchu przy tekstach, sprawdzanie faktów z listą odnośników do przejrzenia przez człowieka. Zastosowanie, którego byśmy nie budowali: odpowiadanie klientom bez nadzoru. Nie z powodu Vane, tylko z powodu tego, że odpowiedź modelu z cytowaniami nadal wymaga kogoś, kto te cytowania otworzy.
Alternatywy, skoro projekt stoi
Skoro rekomendujemy ostrożność, wypada powiedzieć, co jest obok. Wszystkie poniższe miały commity w ciągu ostatniej doby albo dwóch:
- SearXNG (35 956 gwiazdek, AGPL-3.0) — sama metawyszukiwarka, bez warstwy AI. Jeśli celem jest prywatne szukanie bez profilowania, to jest właściwe narzędzie i wystarczające. Uwaga na AGPL, jeśli planujesz modyfikacje i udostępnianie usługi na zewnątrz,
- Open WebUI (149 621 gwiazdek) — interfejs do modeli z wbudowanym wyszukiwaniem w sieci, uwierzytelnianiem i kontami użytkowników; pod tym względem jest po prostu dojrzalszy. Licencja nie jest już czystym BSD-3: dochodzi klauzula zakazująca usuwania oznaczeń „Open WebUI”, z wyjątkiem wdrożeń do 50 użytkowników w 30-dniowym okresie albo osobnej zgody. Przy białoetykietowym wdrożeniu u klienta trzeba to przeczytać w całości,
- LibreChat (42 350 gwiazdek, MIT) — rozbudowana platforma czatowa z wieloma dostawcami, uwierzytelnianiem i RAG-iem,
- Morphic (9 056 gwiazdek, Apache-2.0) — najbliższy odpowiednik samego pomysłu Perplexiki, mniejszy i prostszy.
Jeżeli interesuje Cię wyłącznie odpowiadanie z cytowaniami na własnym sprzęcie i lubisz obecny interfejs — Vane nadal jest najbliżej celu. Jeżeli narzędzie ma obsłużyć zespół, z kontami i logowaniem, to brak uwierzytelniania jest różnicą, której nie nadrobi żadna inna zaleta.
Podsumowanie
Vane, wcześniej Perplexica, to dobrze zaprojektowana wyszukiwarka odpowiedzi, którą da się w całości uruchomić u siebie i w całości zrozumieć — trzy etapy, jedna aplikacja Next.js, SQLite, SearxNG obok. Problemem nie jest jakość kodu, tylko to, że od kwietnia 2026 nikt go nie dotyka.
Co dostajesz:
- odpowiedzi z cytowaniami źródeł, z wyszukiwaniem przez SearxNG i bez wysyłania zapytań do komercyjnej wyszukiwarki,
- modele lokalne (Ollama, LM Studio, Lemonade, dowolny serwer zgodny z API OpenAI) albo chmurowe (OpenAI, Anthropic, Gemini, Groq) — do wyboru, również per zapytanie,
- trzy tryby pracy, zawężanie źródeł do dyskusji, prac naukowych albo jednej domeny, wyszukiwanie obrazów i wideo, widgety pogodowe, giełdowe i obliczeniowe,
- wgrywanie dokumentów i pytania do nich, z embeddingami liczonymi lokalnie,
POST /api/searchz opcjonalnym strumieniowaniem — wyszukiwanie z cytowaniami jako zwykły endpoint HTTP do wpięcia w aplikację,- uruchomienie jedną komendą Dockera, z SearxNG w obrazie albo z własnym.
O czym pamiętać: projekt jest w przerwie (ostatni commit i wydanie z 10–11 kwietnia 2026, 347 otwartych zgłoszeń, niescalone łatki z sierpnia) i zmienił nazwę, więc stare wpisy i tutoriale o „Perplexice” opisują to samo narzędzie pod inną nazwą. Nie ma uwierzytelniania, a GET /api/config zwraca konfigurację bez maskowania — instancja wystawiona do internetu oddaje klucze API każdemu, kto ją znajdzie. Przypnij wersję obrazu, a jeśli zależy Ci na rozmiarze, sprawdź slim-v1.12.2 (578 MB) zamiast slim-latest (3,67 GB). Do SearxNG trzeba włączyć format JSON i silnik Wolfram Alpha.
Licencja: MIT — bez zastrzeżeń przy użyciu komercyjnym, także u klienta, i to jest w tym przypadku realna wartość, nie formalność. Przy projekcie bez aktywnego opiekuna licencja permisywna oznacza, że wolno go rozwidlić, poprawić samodzielnie i wdrożyć własną wersję bez pytania kogokolwiek o zgodę. Jeśli Vane ma u Ciebie robić coś ważnego, to jest właściwy plan awaryjny — i warto go mieć przygotowany, zanim stanie się potrzebny.