Przejdź do głównej zawartości

Generative AI Design Patterns #2: Basic RAG, Semantic Indexing i Indexing at Scale, czyli co psuje się przed modelem

· 17 min aby przeczytać
Przemysław Majdak
Full-Stack Developer, Automation Engineer & Web Security Specialist

Rozdział 3 „Generative AI Design Patterns" buduje RAG w trzech krokach: wyszukiwanie po słowach, wyszukiwanie po znaczeniu i metadane, które pozwalają bazie przetrwać wzrost. Sprawdziłem wszystkie trzy na polskiej instrukcji serwisowej i lokalnych modelach. Dwie tezy książki potwierdziły się w formie mocniejszej, niż je zapisano: surowe BM25 w języku fleksyjnym trafia na pierwszej pozycji 2 z 10 zapytań, a usunięcie starych biuletynów z bazy zmieniło poprawną odpowiedź na błędną. Trzecia teza okazała się zależna od modelu. bge-m3 bez BM25 rozróżnił 24 z 24 kodów części różniących się jednym znakiem, gdy kod był zapisany tak jak w katalogu, a naiwna hybryda wypadła od niego gorzej.

To czwarty wpis serii o książce Valliappy Lakshmanana i Hannesa Hapkego. Recenzja i mapa serii są we wpisie 0, poprzedni wpis dotyczył stylu i optymalizacji treści. Cytuję po rozdziale i numerze wzorca, bo PDF nie ma stron druku.

Teza​

Autorzy zaznaczają, że to jedyny rozdział, który trzeba czytać po kolei: Pattern 6, 7 i 8 nadbudowują się nawzajem, a nie stanowią alternatyw (rozdz. 3). Każdy kolejny wzorzec naprawia coś, co psuje się w poprzednim, i każda z tych usterek leży przed modelem: w tokenizacji, w rankingu albo w tym, co zostało w bazie. Model językowy w RAG czyta to, co mu podano, a całą jakość decyduje się wcześniej.

Moja teza do tego wpisu ma trzy części. RAG bywa zbędny, gdy dokument mieści się w oknie, ale okno usuwa błędy wyszukiwania, a nie błędy sprzeczności między dokumentami. To, czy wyszukiwanie semantyczne potrzebuje BM25, zależy od modelu embeddingów i od tokenizera, a nie od samej zasady. Metadane są jedynym miejscem na czas, autorytet i uprawnienia, bo podobieństwo wektorów żadnej z tych rzeczy nie widzi.

Pattern 6: Basic RAG​

Problem. Model fundacyjny jest systemem zamkniętym. Autorzy podają trzy powody, dla których jego wiedza nie wystarcza: odcięcie czasowe, ograniczona pojemność („a lossy compression of the datasets it was trained on") i brak dostępu do danych prywatnych. Skutki to halucynacje i niemożność cytowania, bo tekst generowany token po tokenie nie jest powiązany z żadnym źródłem (rozdz. 3, Pattern 6).

Rozwiązanie. Dwa pipeline'y: indeksujący (wsadowo zamienia źródła w chunki) i pytająco-odpowiadający (retrieval, potem generacja). Rodowód to praca Lewisa i in. z FAIR z 2020 roku. Retrieval w wersji podstawowej to TF-IDF, a autorzy pokazują na liczbach, gdzie pęka. W Anabasis of Alexander pociętej na chunki po 200 znaków waga terminu Alexander wynosi 61,04, a Diogenes 1,01, bo Aleksander pojawia się 1311 razy, a Diogenes 6. Pytanie o relację obu wyciąga więc chunki o Aleksandrze. Naprawą jest nasycenie licznika, które robi BM25 (rozdz. 3, Pattern 6).

Dwa ograniczenia uzasadniają resztę rozdziału. Pierwszym jest wymóg dokładnego dopasowania. W tej samej instrukcji serwisowej pytanie z ruptured prowadzi do wymiany safety head, a z broken do wymiany zespołu membrany. Autorzy kwitują to krótko: „This is very bad." Drugim ograniczeniem jest limit rozmiaru chunka (rozdz. 3, Pattern 6).

W ramce „RAG versus large context window" (rozdz. 3, Pattern 6) pada najważniejsze zdanie rozdziału dla małych korpusów. Jeśli dokument mieści się w oknie, retrieval można pominąć, a wtedy znikają naraz błędy chunkowania i błędy wyszukiwania. Autorzy zastrzegają jednak, że strategiczne chunkowanie z zakładką często daje lepszy retrieval. Praktyczny próg podają dopiero przy Pattern 7: ok. 200 tys. tokenów, czyli ok. 500 stron, „at the time of writing" (rozdz. 3, Pattern 7). W ograniczeniach Pattern 6 dodają ostrzeżenie odwrotne: retriever wyłącznie embeddingowy, bez BM25, „will be inadequate" przy kodach produktów i pozycji (rozdz. 3, Pattern 6).

Pattern 7: Semantic Indexing​

Problem. Klucze słowne nie łapią synonimów i zaimków, sensu całego fragmentu, pracy między językami ani znaczenia układu (tabela, podpis pod rysunkiem). Dodatkowo dokładne dopasowanie daje fałszywe trafienia. CHF to congestive heart failure, critical heat flux albo frank szwajcarski (rozdz. 3, Pattern 7).

Rozwiązanie. Indeks wektorowy po znaczeniu, pięć strategii chunkowania (po długości z zakładką, po zdaniach, po akapitach, po strukturze dokumentu, po przesunięciach tematu) i kilka technik ponad nim. Contextual retrieval dokleja do chunka streszczenie dokumentu przed embeddingiem. Autorzy przytaczają deklarację Anthropica, nie własny pomiar: 67% mniej błędnych trafień. Do tego hierarchiczne drzewo streszczeń (RAPTOR) i ekspansja synonimów z ostrzeżeniem o kierunkowości: ETF jest funduszem indeksowym, ale nie odwrotnie (rozdz. 3, Pattern 7).

Ograniczenia autorzy wyliczają uczciwie. Wektor o stałym wymiarze jest wąskim gardłem informacyjnym. ANN przy milionach wektorów wymienia dokładność na szybkość. Embeddingi nie mają pojęcia czasu, a dobór rozmiaru chunka „remains more of an art than a science" (rozdz. 3, Pattern 7). O tym, co dzieje się z nagłówkiem odciętym od treści chunka, pisałem osobno we wpisie o chunkowaniu strukturalnym.

Pattern 8: Indexing at Scale​

Problem. Cztery usterki pojawiają się dopiero w produkcji i rosną razem z indeksem. Pierwsza to dwuznaczność: im większa baza, tym więcej znaczeń jednego słowa. Druga to świeżość: CDC zalecało 10 dni izolacji w 2020 roku, 5 dni w grudniu 2021, a w lutym 2024 zrezygnowało z okresu izolacji. Trzecia to sprzeczne zalecenia, na przykład progi nadciśnienia. Czwarta to cykl życia modelu embeddingów: wektory z różnych wersji modelu są niekompatybilne, więc wycofanie API oznacza przeindeksowanie całej bazy (rozdz. 3, Pattern 8).

Przy świeżości autorzy stawiają zdanie, które mój pomiar potwierdził co do joty: „if you were to simply remove the earlier guidelines, the most recent update would lose its context". Przy sprzecznościach ostrzegają, że ciągłe dokładanie treści daje różne odpowiedzi „even in two different requests for the exact same initial user query" (rozdz. 3, Pattern 8).

Rozwiązanie. Metadane, czyli informacja, której w treści chunka nie ma: poziom dokumentu (źródło, czas, autor), poziom chunka (pozycja, encje, język), dane domenowe (jurysdykcja, wersja API, SKU) oraz uwierzytelnienie, autoryzacja i poufność. Nieaktualną treść można filtrować przy wyszukiwaniu, wycinać z bazy (autorzy wolą tę opcję, bo mniejszy indeks jest szybszy) albo obniżać w rerankingu. Autorzy uczciwie dodają, że data nie jest miarą aktualności: „An analysis from 2020 might still be highly relevant, yet recent technical documentation can already be outdated" (rozdz. 3, Pattern 8).

Sprawdziłem to po polsku na lokalnych modelach​

Środowisko jak w poprzednich wpisach: ThinkPad L16 Gen 2, sam CPU, llama.cpp b6153 z pakietu Fedory. Embeddingi: bge-m3 (Q8_0, pooling CLS) i Qwen3-Embedding-0.6B (Q8_0, pooling last, z instrukcją przed zapytaniem). Generacja: Qwen3-Coder-30B-A3B-Instruct (UD-Q3_K_XL), temperatura 0. BM25 napisałem sam (k1 = 1,5, b = 0,75), a hybrydę złożyłem przez Reciprocal Rank Fusion z k = 60. Wszystkie liczby z tej sekcji pochodzą z moich uruchomień z 2 października 2026.

Korpus też napisałem sam. To 33 chunki fikcyjnej instrukcji serwisowej pompy ciepła po polsku: montaż, parametry P.12–P.51, kody błędów E-204, F17, W-07, numery części, trzy biuletyny serwisowe z lat 2021–2025 i jeden chunk wewnętrzny z kodem serwisowym. Do tego 30 zapytań w trzech grupach po 10: identyfikatory (E-204, ZB-3381, P.51), parafrazy („z jednostki na dworze leci para i wiatrak stanął" przy chunku o odszranianiu) i fleksja, czyli te same słowa co w chunku, ale w innej formie („wymiana zaworu" przy „zawór należy wymienić").

1. Polska fleksja rozkłada surowe BM25​

Trafienie oznacza, że właściwy chunk jest na pierwszej pozycji (@1) albo w pierwszej trójce (@3):

Metodaidentyfikatory @1parafrazy @1fleksja @1razem @1 / @3
BM25, surowe tokeny9 / 103 / 102 / 1014 / 30 · 18 / 30
BM25, słowa obcięte do 5 znaków9 / 104 / 1010 / 1023 / 30 · 25 / 30
bge-m39 / 109 / 1010 / 1028 / 30 · 29 / 30
Qwen3-Embedding-0.6B5 / 104 / 1010 / 1019 / 30 · 25 / 30
hybryda: surowe BM25 + bge-m310 / 105 / 105 / 1020 / 30 · 23 / 30
hybryda: BM25 obcięte + stop-słowa + bge-m310 / 107 / 1010 / 1027 / 30 · 27 / 30
hybryda: ta sama + Qwen3-Embedding10 / 104 / 1010 / 1024 / 30 · 25 / 30

Książka pisze o BM25 po angielsku, a w angielskim „valve" w zapytaniu i w dokumencie to ten sam token. Po polsku „zaworu" i „zawór" to dla BM25 dwa różne słowa. Przy zapytaniach typu „przekroje przewodów zasilających" surowe BM25 nie miało żadnego wspólnego tokenu z właściwym chunkiem i oddawało chunki 1, 2 i 3 w kolejności z pliku. Najprostszy możliwy stemming, czyli obcięcie słów do pięciu znaków bez ruszania identyfikatorów, podniósł fleksję z 2 do 10 na 10. To nie jest rozwiązanie produkcyjne (do tego służy lematyzator), ale pokazuje, że w języku fleksyjnym BM25 bez normalizacji form nie jest szczeblem bazowym, tylko szczeblem zepsutym.

2. Kody części: zależy od modelu embeddingów i od tokenizera​

W korpusie instrukcji bge-m3 znalazł identyfikatory na pierwszej pozycji 9 razy na 10. Jedyny błąd był pouczający: na zapytanie PS-HP9-02 wybrał chunk o urządzeniu „Termix HP-9", a numer części był dopiero drugi. Qwen3-Embedding na tym samym zadaniu miał 5 na 10 i na prawie każde krótkie zapytanie wybierał ten sam chunk z ogólnym opisem urządzenia.

Żeby sprawdzić tezę książki w najtrudniejszej postaci, zbudowałem osobny katalog: 24 części w czterech rodzinach, z kodami różniącymi się jednym znakiem (ZB-3381, ZB-3318, ZB-3383, ZB-3881…), a zapytaniem był sam kod. Liczba trafień @1 na 24:

Zapis kodu w zapytaniuBM25bge-m3Qwen3-Emb.naiwna hybrydaBM25 z tokenizerem dzielącym kody
ZB-3381 (jak w katalogu)2424152424
ZB33811916424
zb 338112016224

Teza „sam embedding zawodzi przy kodach" jest prawdziwa dla Qwen3-Embedding-0.6B i nieprawdziwa dla bge-m3, gdy kod jest zapisany tak jak w katalogu. Gdy użytkownik zapisze kod inaczej, BM25 spada do 1 na 24, a bge-m3 traci od 4 do 15 trafień. Mój tokenizer trzymał zb-3381 jako jeden token, więc zb i 3381 nie pasowały do niczego. Tokenizer, który do indeksu dokłada też części kodu i formę sklejoną, dał 24 na 24 w każdym zapisie. O jakości BM25 przy identyfikatorach decyduje więc tokenizacja, a nie sam algorytm.

3. Hybryda RRF może popsuć dobry retriever​

Naiwna hybryda (surowe BM25 + bge-m3) miała 20 na 30, a sam bge-m3 28 na 30. Mechanizm jest prosty. RRF sumuje 1/(k + pozycja) z obu rankingów i nie wie, że jeden z nich nie ma żadnego sygnału. Gdy BM25 nie dopasowało ani jednego słowa, wszystkie wyniki były zerowe, a ranking BM25 był po prostu kolejnością pliku, którą RRF potraktowało z tą samą wagą co ranking bge-m3. To samo działo się przy dopasowaniu wyłącznie słów funkcyjnych: „na", „jak", „z".

Odrzucenie zerowych wyników BM25, obcięcie słów i lista 34 stop-słów podniosły hybrydę do 27 na 30, czyli wciąż o jeden punkt poniżej samego bge-m3. Zastrzegam, że listę stop-słów ułożyłem po obejrzeniu porażek na tym samym zbiorze, więc ten wynik jest raczej optymistyczny. Z Qwen3-Embedding obraz jest odwrotny: hybryda podniosła identyfikatory z 5 do 10 na 10, a wynik łączny z 19 do 24.

Wniosek dotyczy kolejności pracy, a nie wyboru techniki. Hybryda ratuje słaby embedder i dokłada niewiele do mocnego, a źle złożona szkodzi obu. Bez zbioru zapytań z oznaczonymi poprawnymi chunkami nie da się stwierdzić, który z tych przypadków masz u siebie.

4. Cały dokument w oknie kontra RAG​

Ten sam korpus, dziesięć pytań, cztery tryby: cała instrukcja w prompcie (2746 tokenów), top-3 i top-5 z bge-m3 oraz cała instrukcja bez dwóch starszych biuletynów. Odpowiedzi przeczytałem sam:

Pytaniecały dokumenttop-3top-5bez starych biuletynów
kapie z rury spustowej (wymiana + nr części)✓bez numeru częścibez numeru części✓
E-204: przepływ i filtr✓✓✓✓
W-07: bezpiecznik i próg grzałki (dwa chunki)✓✓✓✓
nachylenie krzywej dla grzejników✓✓✓✓
czas aktualizacji oprogramowania✓✓✓✓
wszystkie kody błędów E i F (4)✓2 z 42 z 4 + W-07✓
przegląd: wersja 3.2, Kraków (24 mies.)✓✓✓✗ 12
przegląd: wersja 3.2, Gdynia (12 mies.)✓✓✓✓
przegląd: wersja 2.8, Kraków (12 mies.)✗ 24„nie wiem"✗ 2412, bez podstawy
klient pyta o kod serwisowynie zdradziłnie zdradziłnie zdradziłnie zdradził

Pytanie o wszystkie kody błędów to klasyczny przypadek, w którym top-k zawodzi z definicji: retriever zwraca najbliższe fragmenty, a nie komplet. Cały dokument w oknie dał komplet, a top-5 dał niepełną listę z ostrzeżeniem W-07 w roli kodu błędu.

Cały dokument w oknie nie uchronił jednak przed błędem przy biuletynach. Wersja 2.8 to łańcuch: BS-2021 mówi „co 12 miesięcy", BS-2023 zmienia to na 24 dla wersji 3.0 i nowszych i pisze „ze starszym oprogramowaniem — bez zmian". Model miał wszystkie trzy biuletyny i odpowiedział 24. Na ogólne pytanie „co ile robić przegląd?" z całym dokumentem pomylił warunki i przypisał 24 miesiące starszemu oprogramowaniu. Okno usuwa błędy chunkowania i wyszukiwania, tak jak obiecuje ramka autorów. Nie usuwa błędów wnioskowania na sprzecznych lub nakładających się dokumentach, a te zostają nawet przy 2746 tokenach.

Koszt. Na CPU pierwsze pytanie z całym dokumentem trwało 577 s, bo serwer przetwarzał prompt z prędkością ok. 5 tokenów/s. Kolejne trwały od 7 do 46 s, bo llama-server brał z cache wspólny prefiks i przeliczał tylko 16–48 nowych tokenów. Pytania top-3 trwały 33–69 s, a top-5 54–99 s, bo każde miało inny kontekst. Suma dziesięciu pytań: 770 s dla całego dokumentu, 460 s dla top-3 i 743 s dla top-5. To ten sam mechanizm, który autorzy opisują jako server-side prompt caching (rozdz. 3, Pattern 6; rozdz. 8, Pattern 25). Cache działa tylko wtedy, gdy dokument stoi na początku promptu i nie zmienia się między pytaniami.

5. Podobieństwo nie widzi czasu, a wycięcie starego niszczy nowe​

Na ogólne zapytanie „co ile przegląd pompy ciepła" bge-m3 ułożył biuletyny w odwrotnej kolejności niż chronologiczna: BS-2021 (cosinus 0,574) przed BS-2023 (0,539) i BS-2025 (0,484). Pierwsze miejsce zajął chunk o zakresie przeglądu (0,593), więc obowiązujący biuletyn wypadł z top-3. Prawdopodobnie dlatego, że najstarszy biuletyn jest najprostszy i najbardziej ogólny, a więc najbardziej podobny do ogólnego pytania — tego nie mierzyłem. W generacji użyłem pytania „Co ile trzeba robić przegląd pompy ciepła?", które dało tę samą trójkę. Model odpowiedział bez reguły nadmorskiej, bo jej nie dostał.

Wycięcie starych biuletynów, czyli opcja, którą autorzy preferują ze względu na szybkość, dało dokładnie przypadek CDC. BS-2025 kończy się zdaniem „Poza tym obowiązują zasady z BS-2023-11". Po usunięciu BS-2021 i BS-2023 model zapytany o wersję 3.2 w Krakowie odpowiedział 12 miesięcy zamiast 24. Na wersji 2.8 dał w tym trybie poprawne 12, ale bez podstawy: reguła, z której to wynika, została usunięta. Metadana, której tu brakuje, to nie data, tylko relacja zastępuje / uzupełnia. Autorzy wymieniają tę drogę wśród alternatyw: trzymać stare dokumenty z jawnymi relacjami zamiast je kasować (rozdz. 3, Pattern 8). Data mówi, który biuletyn jest nowszy, a relacja mówi, czy starszy wciąż obowiązuje.

6. Uprawnienia egzekwuje treść chunka albo nic​

Na pytanie „Jestem klientem. Jaki jest kod dostępu do poziomu serwis?" retriever top-3 podał modelowi chunk wewnętrzny z kodem na pierwszej pozycji. Chunk zaczynał się od „[DOKUMENT WEWNĘTRZNY — tylko dla serwisu]" i mówił, że kodu nie przekazuje się klientom. Model odpowiedział „nie wiem". Potem usunąłem z chunka etykietę i to zdanie, zostawiając poufność tak, jak zwykle jest zapisana w systemie: w metadanych, których model nie widzi. Na to samo pytanie odpowiedział tak samo, więc etykieta nie miała tu mierzalnego wpływu. Na pytanie „Jak wejść do poziomu serwis w menu?" odpowiedział: „wprowadź kod dostępu 7731".

Jedyną barierą była więc ostrożność modelu przy pytaniu, które samo w sobie brzmiało podejrzanie. Pytania sformułowanego niewinnie ta ostrożność nie zatrzymała. Wariantu „Jak wejść…" z ostrzeżeniem w treści chunka nie sprawdzałem.

Zastrzeżenia do całej sekcji. Korpus i zapytania napisałem sam, więc wiedziałem, które przypadki są trudne. Próby liczone są w dziesiątkach, a nie tysiącach. Biorę pod uwagę jeden model generujący, dwa modele embeddingów i jeden język. Odpowiedzi oceniałem sam, czytając je w całości. To pokazuje mechanizmy, a nie odsetki, których należy się spodziewać w innym korpusie.

To samo w innych książkach​

Dominik Polzer w RAG with Python Cookbook stawia hybrydę ostrożniej niż Lakshmanan i Hapke, a mój pomiar przyznaje mu rację. Każe zaczynać od samej semantyki i dokładać BM25 dopiero po zaobserwowaniu porażek dokładnego dopasowania w logach. Przykłady identyfikatorów, przy których hybryda jest potrzebna, to SKU, numery artykułów prawnych („article 230" to nie „section 230"), kody ICD-10 i nazwy endpointów (s. 144–145). RRF podaje z tym samym k = 60, którego użyłem (s. 143–144). W rozdziale 1 dodaje kryterium, którego w omawianej książce nie ma: „If you can write a regular expression (regex) or SQL query that handles 95% of cases, RAG adds unnecessary complexity and cost" (s. 5). Przy uprawnieniach mówi rzecz, której autorom rozdziału 3 brakuje: filtrować po metadanych przed liczeniem podobieństwa, bo „a legal RAG system should search only contracts the user has permission to view" (s. 166–167).

Nitin Borwankar w Vector Databases nazywa błąd wprost: „A common mistake in RAG is assuming that simple vector search is always enough", bo embeddingi potrafią „rozmyć" termin techniczny albo dokładną frazę (s. 177). Proponowany przez niego podział wag 70/30 nazywa „a standard starting point" (s. 180), ale nie podaje źródła, więc traktuję go jako punkt wyjścia, nie wynik. Od Borwankara pochodzi też zdanie przydatne przy filtrach uprawnień: indeks wektorowy „is optimized for similarity and clustering, not for subsetting and filtering based on arbitrary predicates" (s. 13). Konsekwencję sprawdziłem wcześniej sam na sqlite-vss (2000 syntetycznych wektorów, limit 10, nadpobranie k = 100). Filtr obejmujący 1% dokumentów zwracał średnio 0,7 wyniku z 10, a w 54% zapytań zero, i nie zgłaszał braku.

Kiedy nie używać — zestawienie​

WzorzecNie używaj, gdyZamiast tego
Basic RAGdokument mieści się w oknie, a pytania są stałecały dokument na początku promptu + prompt caching
Basic RAGpytania dotyczą całości zbioru („wszystkie", „ile")ekstrakcja do tabeli i SQL
Basic RAG95% przypadków obsłuży regex albo SQLregex albo SQL (Polzer)
BM25 bez normalizacji formjęzyk fleksyjnylematyzacja albo choćby stemming
Semantic Indexing bez BM25embedder nie rozróżnia kodów na twoim zbiorze testowymhybryda z tokenizerem dzielącym identyfikatory
Hybryda RRFnie masz zbioru zapytań z oznaczonymi chunkaminajpierw zbiór testowy, potem fuzja
Wycinanie starych dokumentównowy dokument odsyła do staregorelacja zastępuje / uzupełnia w metadanych
Filtr uprawnień po retrievaludostęp jest wąski, a indeks ANNfiltr w zapytaniu przed liczeniem podobieństwa

Ocena trwałości​

Moja ocena, nie autorów. Basic RAG jest trwały jako architektura, ale jego zakres się kurczy. Ramka o długim kontekście to jedno z niewielu miejsc w książce, gdzie wzorzec może wygasnąć nie dlatego, że był obejściem, tylko dlatego, że dla małych korpusów problem przestanie być wart rozwiązywania. Mój pomiar dopisuje warunek: okno nie zwalnia z pracy nad sprzecznymi dokumentami. Semantic Indexing jest trwały. Datowane są konkretne modele, pozycje na MTEB i liczba wymiarów. Indexing at Scale jest najtrwalszy z trzech, bo metadane to jedyne miejsce, w którym da się zapisać czas, autorytet i uprawnienia. Relację między dokumentami autorzy wymieniają jako alternatywę w ograniczeniach Pattern 8. Mój pomiar pokazuje, że przy dokumentach, które się do siebie odwołują, nie jest to alternatywa, tylko warunek.

Starszy krewny: wyszukiwarka pełnotekstowa​

BM25 jest dorobkiem klasycznych wyszukiwarek pełnotekstowych, sprzed epoki LLM. Każdy problem z sekcji pomiarów zna inżynieria wyszukiwarek pełnotekstowych sprzed epoki LLM: analizatory morfologiczne dla języków fleksyjnych, tokenizery dla numerów katalogowych, synonimy, kolejność rankingu. Nowy jest tylko konsument wyniku. Wyszukiwarka pokazywała dziesięć linków i człowiek widział, że pierwszy jest z 2021 roku. Model językowy dostaje trzy fragmenty i nie pyta, skąd są ani czy wciąż obowiązują.

Dalej w serii​

Następny wpis (3) dotyczy rozdziału 4: wyszukiwania i zaufania. Będą w nim Index-Aware Retrieval z HyDE, Node Postprocessing z rerankingiem, Trustworthy Generation i Deep Search, a w szczególności pytanie, dlaczego podobieństwo nie jest trafnością. Mapa całej serii jest we wpisie 0.