Firma wdraża asystenta RAG na bazie dokumentacji produktowej i po tygodniu pilotażu odkrywa problem: zapytania zawierające kody SKU, symbole części zamiennych albo wewnętrzne nazwy systemów (np. „moduł INTAKE-3B") zwracają semantycznie podobne, ale nie właściwe dokumenty. Wyszukiwanie wektorowe „rozumie intencję", lecz gubi identyfikatory. Klienci serwisu dostają opis podobnego produktu zamiast karty technicznej konkretnego. To jeden z najczęstszych powodów, dla których RAG działa świetnie na demo i słabiej na produkcji.
Dlaczego sama semantyka zawodzi
#Wyszukiwanie semantyczne działa na zasadzie geometrii znaczeń: model embeddingów przelicza tekst na wektor i szuka dokumentów o zbliżonej reprezentacji. Siła tej metody jest zarazem jej słabością: model uśrednia znaczenie, kompresuje informację i traci precyzję leksykalną.
Trzy konkretne klasy zapytań, przy których semantyka regularnie zawodzi:
Kody i identyfikatory. SKU-4521, P/N 7742-A, numer zamówienia ZAM-2024-08811 — to ciągi znaków bez semantycznego kontekstu. Embedding traktuje je jak szum i przypisuje im wektory blisko dokumentów o ogólnej tematyce produktowej, zamiast zwrócić dokument z dokładnym dopasowaniem.
Akronimy i skróty branżowe. „IFRS 17", „KSeF", „CMMS" — model może nie mieć dobrego kontekstu dla rzadkich skrótów, zwłaszcza polskich, specjalistycznych. Zwraca dokumenty o finansach lub systemach utrzymania, ale nie ten konkretny standard.
Nazwy własne i wersje. „Comarch ERP XL 2024.2.1" vs „Comarch ERP Optima" — dla embeddingu to bliscy sąsiedzi. Dla użytkownika to różne produkty. Mylenie wersji w odpowiedzi generuje realne błędy operacyjne.
BM25 (Best Match 25) rozwiązuje te przypadki inaczej: liczy częstotliwość terminu w dokumencie, normalizuje względem długości dokumentu i promuje wyniki, w których zapytane tokeny dosłownie wystąpiły. Dla kodu SKU-4521 BM25 zwraca dokument zawierający ten ciąg na pierwszej pozycji. Dla ogólnego pytania „jak skonfigurować integrację?" semantyka radzi sobie lepiej, bo użytkownik opisuje intencję, a nie identyfikator.
Jak działa fuzja RRF
#Reciprocal Rank Fusion to algorytm scalania rankingów z niezależnych silników wyszukiwania. Wzór na wynik dokumentu d jest prosty:
RRF(d) = Σ 1 / (k + rank_i(d))
gdzie k to stała wygładzająca (domyślnie 60), a rank_i(d) to pozycja dokumentu w i-tym rankingu. Dokument na pozycji 1 w obu silnikach dostaje wynik 1/(60+1) + 1/(60+1) ≈ 0.033. Dokument na pozycji 1 w BM25, ale 50 w semantyce, dostaje 1/61 + 1/110 ≈ 0.025. Fuzja nagradza konsekwencję: jeśli obydwa silniki zgadzają się, że dokument jest trafny, trafia on wysoko. Jeśli tylko jeden go wskazuje, wciąż ma szansę, ale z niższym wynikiem.
Zaleta RRF nad ważoną sumą punktów: nie trzeba normalizować wyników z BM25 (liczby całkowite, zależne od korpusu) i z cosine similarity (liczby [-1, 1]). RRF operuje wyłącznie na pozycjach, więc skale nie mają znaczenia. To szczególnie ważne przy dynamicznych korpusach, gdzie zakresy wyników BM25 zmieniają się wraz z rozrostem bazy dokumentów.
Po fuzji RRF warto dodać etap rerankingu: model cross-encoder ocenia każdy kandydat w kontekście całego zapytania. Reranker poprawia precyzję przy złożonych pytaniach wieloczłonowych. Więcej o architekturze rerankingu w artykule o jakości wyszukiwania RAG.
Tabela: typ zapytania vs lepsza metoda
#| Typ zapytania | Przykład | Lepsza metoda | Uzasadnienie |
|---|---|---|---|
| Identyfikator / kod | „SKU-4521", „P/N 7742-A" | BM25 | Dokładne dopasowanie tokenu |
| Akronim branżowy | „KSeF 2026", „IFRS 17" | BM25 + hybryda | BM25 dla tokenu, semantyka dla kontekstu |
| Pytanie opisowe | „jak złożyć reklamację online" | Semantyka | Intencja ważniejsza niż słowa |
| Pytanie mieszane | „procedura zwrotu SKU-4521" | Hybryda RRF | Oba sygnały potrzebne |
| Nazwa własna + wersja | „Comarch ERP XL 2024.2.1" | BM25 + hybryda | Wersja wymaga precyzji |
| Pytanie koncepcyjne | „różnica między leasingiem a najmem" | Semantyka | Brak unikalnych tokenów |
| Zapytanie wielojęzyczne | kod PL + opis EN | Hybryda + BGE-M3 | Semantyczny most językowy |
Konfiguracja krok po kroku
#Wdrożenie hybrydowego wyszukiwania w istniejącym stosie RAG wymaga kilku precyzyjnych kroków. Zakładamy Qdrant jako bazę wektorową i Elasticsearch lub Postgres z pg_trgm / tsvector jako silnik BM25.
Krok 1: Indeksuj korpus podwójnie. Ten sam tekst trafia do bazy wektorowej (embeddingi BGE-M3 lub innego modelu) i do indeksu pełnotekstowego. Oba indeksy muszą używać tych samych identyfikatorów dokumentów, żeby fuzja mogła scalić wyniki po kluczu.
Krok 2: Wykonaj oba zapytania równolegle. Dla każdego zapytania użytkownika wyślij je jednocześnie do silnika semantycznego (top-k=50-100 kandydatów) i do BM25 (top-k=50-100). Ograniczaj liczbę kandydatów, bo reranker na dalszym etapie ma ograniczony budżet tokenów.
Krok 3: Fuzja RRF. Scal dwie listy kandydatów przez RRF. Zacznij od k=60 (wartość domyślna). Jeśli zapytania w Twoim systemie są głównie leksykalne (dużo kodów i SKU), obniż k do 20-30, co wzmacnia wpływ silnego lidera w jednym rankingu. Eksperymentuj na golden secie co najmniej 100 zapytań z oczekiwanymi odpowiedziami.
Krok 4: Reranker (opcjonalnie, ale zalecany). Przekaż top-20 z RRF do modelu cross-encoder (np. bge-reranker-v2-m3 lokalnie). Reranker oblicza parę (zapytanie, fragment) i wystawia precyzyjny wynik. Opóźnienie wzrośnie o 100-300 ms, ale precyzja przy złożonych zapytaniach poprawia się o 10-20 punktów MAP.
Konfigurację optymalnego stosu technicznego warto przejść przez narzędzie doboru stacku, które uwzględnia skalę korpusu, wymagania latency i środowisko hostingowe.
Kiedy hybryda nie pomaga
#Hybryda nie jest darmowa. Dwa zapytania zamiast jednego, fuzja, opcjonalny reranker: łączne opóźnienie systemu wzrasta o 80-200 ms (szacunek zależny od hardware i wielkości kandydatów). W systemach wymagających odpowiedzi poniżej 200 ms end-to-end (np. czat na żywo z klientem) może to być za dużo.
Nie wdrażaj hybridy, gdy:
- Korpus jest jednorodny i opisowy (np. tylko FAQ w języku potocznym) — czysta semantyka wystarcza.
- Wszystkie zapytania mają charakter koncepcyjny, a baza nie zawiera identyfikatorów.
- Masz mniej niż 1000 dokumentów i prosta semantyka daje recall powyżej 0.9 na golden secie.
- Opóźnienie jest twardym wymogiem, a nie ma możliwości cache'owania wyników.
Dobrą praktyką jest zmierzenie recall@5 i recall@10 osobno dla BM25, dla semantyki i dla hybrydy na reprezentatywnym golden secie przed podjęciem decyzji. Więcej o budowie golden setu i pomiarze jakości w artykule o ewaluacji jakości RAG.
Spróbuj na żywo
#FAQ
#Czy BM25 wymaga osobnej bazy danych?
#Nie zawsze. Jeśli już używasz PostgreSQL, możesz uruchomić BM25 przez wbudowane tsvector i ts_rank — bez dodatkowej infrastruktury. Elasticsearch lub OpenSearch dają więcej opcji tuningu (boosting pól, custom tokenizer dla kodów produktów), ale dla małych i średnich korpusów (do kilkuset tysięcy dokumentów) Postgres BM25 w zupełności wystarcza. Qdrant od wersji 1.10 ma wbudowany sparse vector search (SPLADE), który zbliża się funkcjonalnością do BM25.
Jak dobrać proporcje BM25 do semantyki?
#Przez RRF nie dostosujesz bezpośrednio „wagi" — algorytm operuje na pozycjach. Możesz jednak regulować liczbę kandydatów z każdego silnika (top-k) albo zastosować ważoną fuzję z normalizacją wyników (linear interpolation), gdzie parametr alpha określa udział semantyki. Zacznij od alpha=0.5 (równy udział) i eksperymentuj na golden secie. Typowe wnioski z wdrożeń: przy dużej liczbie kodów i SKU alpha=0.3 (mocniejszy BM25) poprawia wyniki, przy tekstach opisowych alpha=0.7 lepiej radzi sobie semantyka.
Czy hybryda działa przy wielojęzycznych zapytaniach?
#Tak, pod warunkiem użycia wielojęzycznego modelu embeddingów (BGE-M3 obsługuje ponad 100 języków) i tokenizatora BM25 obsługującego morfologię danego języka. W polskim ważne jest lematyzowanie przed indeksowaniem BM25 (np. przez Morfologik lub Stemmers), bo „zamówień", „zamówieniu", „zamówienie" to ten sam token po lematyzacji. Bez lematyzacji recall BM25 spada o 20-40% na polskich zapytaniach.
Kiedy warto dodać reranker po hybrydzieRRF?
#Reranker jest szczególnie wartościowy przy zapytaniach wieloczłonowych i pytaniach wymagających zrozumienia pełnego kontekstu (np. „jaka jest procedura zwrotu towaru zakupionego w promocji w grudniu 2024 dla klientów B2B"). RRF scala rankingowy sygnał, ale nie rozumie zapytania całościowo. Cross-encoder ocenia każdą parę (zapytanie, fragment) niezależnie i wychwytuje subtelne dopasowania. Architektura wyszukiwania semantycznego w firmie szczegółowo opisuje, kiedy reranker warto wbudować w pipeline.
Jak ocenić, czy hybryda rzeczywiście poprawiła wyniki?
#Zbuduj golden set: minimum 100 zapytań z oczekiwanymi dokumentami (możesz zacząć od 50 i rozszerzać). Zmierz recall@5 (czy właściwy dokument jest w top 5) i MRR (Mean Reciprocal Rank, jak wysoko pojawia się pierwszy trafny wynik). Porównaj trzy warianty: BM25 solo, semantyka solo, hybryda RRF. W systemach z mieszanym słownictwem technicznym hybryda poprawia recall@5 o 15-35% względem samej semantyki. Jeśli poprawa jest mniejsza niż 5%, sprawdź najpierw jakość chunkowania — często problem leży tam. Przydatnym startem jest audyt strony i systemu, który wskaże wąskie gardła przed wdrożeniem.