Przejdź do treści
V-Smart.

Własna wyszukiwarka dla modelu, bez kont u pośredników

Model językowy zna świat do dnia, w którym skończono go trenować. Żeby odpowiadał na pytania o rzeczy dzisiejsze, musi umieć poszukać. Zbudowaliśmy do tego własną wyszukiwarkę na tej samej maszynie — i przy okazji zmierzyliśmy, ile pracy trzeba włożyć, żeby wyniki były po polsku.

Jak model w ogóle szuka

Wbrew pozorom model nie ma dostępu do internetu. Działa to inaczej i warto to zrozumieć, bo wpływa na prywatność całego rozwiązania.

Model dostaje na starcie informację, że istnieją dwa narzędzia: jedno zwraca listę wyników wyszukiwania, drugie pobiera treść wskazanej strony. Kiedy uzna, że pytanie wymaga świeżych danych, nie wykonuje niczego sam — wypisuje prośbę: „wywołaj wyszukiwanie z frazą X”. Program po stronie użytkownika wykonuje tę prośbę, odpytuje naszą wyszukiwarkę i wkleja wyniki z powrotem do rozmowy. Model czyta je jak zwykły tekst i formułuje odpowiedź.

Cały ruch idzie więc przez naszą maszynę. Żaden dostawca modelu nie widzi ani pytania, ani tego, co z odpowiedzią zrobiono.

Co siedzi pod spodem

Warstwą wyszukującą jest SearXNG — otwarta metawyszukiwarka, którą uruchamiamy u siebie. Odpytuje zewnętrzne źródło (u nas oficjalne API wyszukiwarki Brave, na kluczu) i zwraca ujednoliconą listę wyników. Zewnętrzny dostawca widzi zapytanie, ale nie widzi ani kto pyta, ani po co, ani co działo się wcześniej w rozmowie. Nie ma tu konta użytkownika, historii ani profilowania.

Jedna pułapka konfiguracyjna warta odnotowania, bo kosztowała nas trochę czasu: wybraliśmy silnik korzystający z oficjalnego API, a nie z automatycznego czytania strony wyników. Ten drugi sposób bywa domyślny w podobnych instalacjach i dostaje blokadę po kilkunastu zapytaniach.

Wyniki po polsku wymagają dwóch ustawień, nie jednego

Domyślnie taka instalacja odpowiada wynikami anglojęzycznymi, nawet na polskie zapytanie. Zmierzyliśmy to na frazie technicznej, licząc polskie wyniki wśród dwudziestu pierwszych:

Ustawienie językaPolskie wyniki na 20
brak / „wszystkie”0
sam kod języka („pl”)10
pełne locale („pl-PL”)17

Różnica między „pl” a „pl-PL” to nie kosmetyka, tylko siedem wyników na dwadzieścia. Ustawić trzeba przy tym dwie warstwy: domyślną wartość serwera oraz parametry przekazywane do samego silnika. Zmiana tylko jednej z nich nie wystarcza, bo drugą nadpisuje klient.

Model może to nadpisać przy pojedynczym zapytaniu — i robi to sensownie, przełączając się na angielski, gdy szuka dokumentacji technicznej.

Domyślny wynik był zbyt ubogi — poprawiliśmy silnik

Standardowa wersja silnika zapisuje z każdego wyniku wyłącznie krótki opis — dwa zdania, często urwane w połowie zdania kluczowego. Tymczasem dostawca zwraca przy okazji dodatkowe fragmenty z treści strony, których nikt nie prosił i które były po prostu wyrzucane.

Podmieniliśmy ten fragment na własną wersję, która te fragmenty sklei i dołącza do wyniku. Efekt to około 4,7 raza więcej tekstu na wynik. Model dostaje realną treść zamiast zajawki, więc częściej odpowiada od razu, bez pobierania całych stron.

Druga zmiana jest drobna, a rozwiązuje częsty problem: przed każdym wynikiem doklejamy datę publikacji. Bez niej model nie ma jak odróżnić poradnika sprzed pięciu lat od tegorocznego i regularnie mylił wersje oprogramowania.

Kiedy model schodzi głębiej

W instrukcji systemowej mamy regułę: jeśli fragmenty są urwane, sprzeczne albo nie zawierają szukanego konkretu — pobierz całą stronę. To rozwiązuje sytuacje, w których sama lista wyników udaje odpowiedź, ale jej nie zawiera.

Drobiazg wart naśladowania: regułę opisujemy rolą narzędzia, a nie jego nazwą („przyjmuje adres, zwraca treść”). Różne programy nazywają to narzędzie inaczej, a instrukcja odwołująca się do nazwy przestaje działać po zmianie klienta.

Ile to kosztuje kontekstu

Świeże dane nie są darmowe — zajmują miejsce w pamięci rozmowy:

  • jedno wyszukiwanie z pełnymi fragmentami: około 4 tysiące tokenów,
  • pobranie całej strony: nawet kilkanaście tysięcy.

Przy kontekście 262 tysięcy tokenów to komfortowa sytuacja: kilkanaście wyszukiwań w jednej rozmowie nie robi wrażenia. Na maszynie z małym kontekstem właśnie tutaj kończyłaby się zabawa — i to jest jeden z tych powodów, dla których warto było walczyć o pojemność kontekstu.

Co to daje w praktyce

Trzy rzeczy, w kolejności ważności dla użytkownika domowego:

Aktualność. Model przestaje zmyślać przy pytaniach o rzeczy nowe, bo ma jak sprawdzić.

Prywatność. Zapytania nie budują profilu reklamowego ani historii przypisanej do konta. Wychodzi z domu samo hasło wyszukiwania, bez kontekstu rozmowy.

Niezależność. Wyszukiwarka jest wymienna — źródło da się zmienić bez ruszania modeli i bez czekania, aż dostawca zmieni zdanie na temat cennika czy regulaminu.


Konfiguracja własna, na tej samej maszynie co modele. Pomiary języka wyników wykonane na naszej instancji.