Strona główna / Artykuły

Naprawiaj pipeline, a nie model językowy: model mentalny do radzenia sobie z awariami w systemach RAG

Gdy bot RAG odpowiada błędnie, rzadko jest to spowodowane modelem LLM. Śledź błędy od etapu pobierania danych, wyszukiwania, generowania, oceny aż po pętlę, aby znaleźć przyczynę.

Wydawca: REACTAPP.TOP10 min czytania2306 słów

Źródła: RAG Is Not Just Vector Search

Załóżmy, że w średniej firmie SaaS istnieje bot obsługi klienta, który pewnego dnia odpowiada inaczej dwóm klientom, gdy obaj pytają o okno zwrotu pieniędzy.

Otwierany jest incydent, a pierwszą myślą inżyniera na zmianie jest to, że model językowy generuje błędne informacje i potrzebny jest inny model. To jest początkowa diagnoza – traktuje się wtedy technologię RAG jako „czarną skrzynkę”, zamienia model i ma nadzieję, że objawy znikną.

Doświadczony inżynier zaczyna od innej perspektywy i pyta, na którym etapie procesu doszło do awarii. Stwierdzenie, że model generuje błędne nazwy, to jedynie opis objawu, który nic nie wyjaśnia.

Dwa dni później pojawia się prawdziwy problem. Polityka zwrotów została zmieniona, ale nikt nie usunął przestarzałego pliku PDF z korpusu danych, więc obie wersje nadal pojawiały się z podobnymi wynikami relevancji, a model wiernie podsumowywał sprzeczne konteksty. W ogóle nie miał halucynacji. (To złożony scenariusz służący ilustracji, ale jego warianty są powszechne.)

Oto różnica pomiędzy tekstową wersją RAG a sposobem, w jaki działa RAG w warunkach produkcyjnych. Poradniki zazwyczaj skracają to do jednej linijki:

Embed → Search → Generate

To wystarczy do demonstracji, ale nie do użycia w produkcji. Prawdziwy system ma kilka granic awarii. Ważne pytanie inżynieryjne dotyczy nie tylko tego, czy model językowy potrafi napisać dobrą odpowiedź, ale także tego, czy każda warstwa przetwarzająca tę odpowiedź działa prawidłowo.

Przyjmowanie danych: jakość jest ustalana przed rozpoczęciem wyszukiwania

Większość prób naprawy problemów w systemach RAG zaczyna się od niewłaściwego punktu. Ludzie dostosowują prompty, zmieniają modele embeddingów i regulują parametr top-k, podczas gdy rzeczywisty błąd pojawił się już kilka tygodni wcześniej podczas przyjmowania danych.

Analiza według struktury

Tabele, bloki kodu, nagłówki i listy przekazują znaczenie poprzez swoją strukturę. Jeśli tabela cen zostanie przekształcona w zwykły tekst, związek pomiędzy wierszem a jego nagłówkiem kolumny może zniknąć. Proces przyjmowania danych powinien zachować tę strukturę i wybrać formę reprezentacji odpowiednią do wyszukiwania, zamiast traktować każdy dokument jako jeden nierozróżniony blok tekstu.

Prawidłowe podejście zależy od treści. Tabela może wymagać strukturalnego wydobywania danych, serializacji tekstu, metadanych lub połączenia metod pozyskiwania informacji na poziomie leksykalnym i semantycznym.

Dzielenie na fragmenty według znaczenia

Prosta metoda dzieli tekst co 512 tokenów. Jednak liczba tokenów i znaczenie nie zawsze się pokrywają, więc jeden fragment może zaczynać się od wprowadzenia i kończyć w połowie tego, do czego miał prowadzić.

Semantyczne dzielenie na fragmenty polega na rozdzielaniu tekstu w miejscach zmian tematu, a nie na liczeniu tokenów. Nie jest to uniwersalne rozwiązanie i wiąże się z większymi kosztami podczas przetwarzania danych. W przypadku długich dokumentów, takich jak polityki, umowy czy dokumentacja techniczna, zachowanie spójności idei często poprawia jakość wyników wyszukiwania.

Daj każdemu fragmencie trochę kontekstu przed włączeniem go do modelu

Kawałek tekstu zstrzelony z strony 40 60-stronicowego dokumentu może być w pełni poprawnym tekstem, a mimo to pozostawać niejednoznacznym poza swoim kontekstem. Weźmy zdanie stwierdzające, że określony limit dotyczy wyłącznie klientów Enterprise. Bez otaczającego go fragmentu dokumentu nic nie wskazuje systemowi, do czego odnosi się „ten limit”.

Systemy wyszukiwania oparte na kontekście radzą sobie z tym, dodając na początku kawałka tekstu informacje na poziomie dokumentu: tytuł, ścieżkę do sekcji, produkt, wersję lub krótką notatkę informującą o miejscu umieszczenia tego fragmentu. Celem jest to, aby każdy kawałek tekstu zachował kontekst, który w przeciwnym razie zostałby usunięty podczas dzielenia dokumentu na fragmenty.

Dodawanie metadanych

Traktuj metadane jako dane funkcjonalne. W późniejszych krokach potrzebne są źródło, data, typ dokumentu, użytkownik, uprawnienia oraz wersja w celu filtrowania, kontroli dostępu, sprawdzania aktualności oraz debugowania.

To prowadzi do jednego z najważniejszych pytań związanych z procesem przetwarzania danych: co się stanie, jeśli jutro zmieni się dokument źródłowy? Jeśli pipeline może jedynie ponownie zindeksować wszystko, nawet niewielka modyfikacja treści staje się obciążeniem operacyjnym. Idealnie byłoby, gdyby proces pobierania danych był inkrementalny i idempotentny, dzięki czemu aktualizacja zostanie wykryta, przetworzona i rozpowszechniona bez konieczności odbudowy całego korpusu.

W omawianym przypadku stara polityka zwrotów pieniędzy wcale nie była winą modelu LLM – chodziło o to, jak zarządzano procesem pobierania danych oraz korpusem.

Pobieranie danych to pipeline, a nie prosty wyszukiwarka

Samo to słowo sugeruje pojedynczy krok. W praktyce pobieranie danych to seria decyzji, a kolejność tych decyzji ma znaczenie.

1. Przepisanie

Ludzie nie piszą naturalnie zapytań wyszukiwawczych. Pytają na przykład o to, czy coś zostało wysłane w ramach zwrotu pieniędzy. Sztuczna inteligencja może przekształcić takie pytania w coś bardziej przydatnego do wyszukiwania, np. łącząc historię rozmów lub dzieląc złożone pytania na prostsze. Jednak przepisywanie nie jest bezkosztowe – zła wersja może pominąć ważne szczegóły lub dodać niepotrzebne założenia. Traktuj to jako kolejny element do oceny, a nie jako coś magicznego.

2. Zakres przed wyszukiwaniem

Jest to jeden z najważniejszych aspektów wdrożenia. Jeśli system jest wielo użytkownikowy lub uwzględnia uprawnienia, przestrzeń wyszukiwania musi przestrzegać tych ograniczeń. Informacje o użytkownikach, uprawnieniach, widoczności, dacie oraz źródle powinny być uwzględniane podczas operacji wyszukiwania tam, gdzie to pozwala podstawowy system.

Filtrowanie po zastosowaniu kryterium top-k powoduje dwa problemy. Po pierwsze, użyteczne dokumenty mogły już zostać wypchnięte poza grupę top-k przez dokumenty, których użytkownik nie ma prawa widzieć. Po drugie, logika autoryzacji zostaje niebezpiecznie oddzielona od procesu wyszukiwania. Mówiąc prościej, nie należy najpierw wyszukiwać wszystkiego, a potem pytać, co użytkownik może zobaczyć – należy najpierw zawęzić zakres wyszukiwania.

3. Wyszukiwanie na dwa sposoby

Wyszukiwanie wektorowe radzi sobie dobrze z semantyczną bliskością. Osoba pytająca, jak anulować, może zostać dopasowana do tekstu mówiącego, że klienci mogą zakończyć swój plan w dowolnym momencie, mimo braku jakichkolwiek wspólnych sformułowań.

Jednak embeddingi są słabsze w przypadku dokładnych identyfikatorów. Pomyśl o takich ciągach znaków:

ERR_CONNECTION_RESET
SKU-48392
API-v3-beta

W takich zapytaniach sygnałem jest dosłowny token, i to właśnie tutaj znajduje zastosowanie wyszukiwanie leksykalne, takie jak BM25. Wyszukiwanie produkcyjne często łączy gęste wyszukiwanie znaczeń z wyszukiwaniem leksykalnym dokładnych ciągów znaków.

4. Łączenie

Teraz mamy dwie listy uporządkowane. Gęste wyszukiwanie ma swoje uporządkowanie, BM25 ma swoje własne, a ich surowe wyniki nie muszą być porównywalne. Reciprocal Rank Fusion (RRF) oferuje prosty sposób na połączenie ich na podstawie pozycji w rankingu:

RRF_score(d) = Σ 1 / (k + rank_i(d))

Każda lista przyczynia się w zależności od pozycji dokumentu w niej, co pozwala uniknąć konieczności kalibracji rozkładów ocen w dwóch niepowiązanych systemach względem siebie.

5. Ponowna klasyfikacja

Fuzja dostarcza zbiór kandydatów, który niekoniecznie stanowi ostateczny kontekst. Ponowny klasyfikator typu cross-encoder czyta zapytanie oraz każdego kandydata razem i oblicza ocenę trafności dla tego konkretnego pary. Różni się to fundamentalnie od niezależnego umieszczania zapytania i dokumentu w embeddingach oraz porównywania wektorów.

Kosztem jest obliczeniowy nakład, dlatego nie stosuje się cross-encodera na całym korpusie. Proces wyszukiwania może zwrócić 20 lub 50 najlepszych kandydatów, a ponowny klasyfikator wybiera z nich najsilniejszy kontekst.

Model mentalny stosowany w praktyce zakłada więc najpierw intensywne wyszukiwanie, następnie wyszukiwanie leksykalne, potem fuzję, a na końcu ponowną klasyfikację. To nie jest „baza danych wektorowych – gotowe”.

Generowanie: dobry kontekst nadal nie gwarantuje dobrej odpowiedzi

Znalezienie odpowiednich dokumentów jest konieczne, ale niewystarczające. Model językowy musi je nadal używać prawidłowo.

Zarządzanie oknem kontekstu

Granice zapytania i przypisywanie autorstwa

W zapytaniu należy jasno określić, w jaki sposób należy wykorzystać znalezione fragmenty. Model musi traktować je jako dowody do cytowania, a nie jako instrukcje do wykonywania.

Cytaty pomagają również w budowaniu zaufania i debugowaniu. Gdy w odpowiedzi stwierdza się, że klienci Enterprise mają 30 dni na anulowanie, potrzebny jest sposób, by prześledzić to stwierdzenie do źródła, z którego pochodzi.

Wycofanie się

Wycofanie się stanowi istotną różnicę pomiędzy systemem demonstracyjnym a niezawodnym systemem. Jeśli wyszukiwanie nie przynosi żadnych wyników, model nadal będzie próbował pomóc, chyba że wycofanie się jest dozwolonym wynikiem. System produkcyjny powinien być w stanie odpowiedzieć, że dowodów nie wystarcza. To często jest właściwa decyzja, a nie wada.

Bez możliwości wycofania się każda nieudana próba wyszukiwania może przerodzić się w fałszywą informację. Sztuczna inteligencja bierze na siebie winę za podanie błędnej odpowiedzi, mimo że rzeczywisty błąd mógł wystąpić na kilka poziomów wcześniej.

Ocena przed jakąkolwiek korektą

RAG ma nieprzyjemną cechę: jakość może się pogorszyć, mimo że kod aplikacji pozostaje nienaruszony. Nowy model embeddingu, inna metoda dzielenia na fragmenty, dodane lub usunięte dokumenty, dostosowane ustawienia wyszukiwania lub zmodyfikowany prompt – każdy z tych elementów może wpłynąć na odpowiedzi, nawet jeśli wdrożony wczoraj kod jest identyczny bajt po bajcie. Dlatego systemy RAG w środowisku produkcyjnym należy oceniać na kilku poziomach.

Jakość wyszukiwania. Precyzja kontekstu dotyczy tego, jak duża część odzyskanego kontekstu była istotna. Pamięć kontekstu odnosi się do tego, jak dużo dostępnych, istotnych informacji faktycznie udało się odnaleźć. Razem pomagają one odróżnić sytuację „nigdy tego nie znaleźliśmy” od „znaleźliśmy to, ale pogrzebaliśmy je w szumie”.

Jakość generowania. Sprawdzanie wierności (nazywane również uzasadnieniem) polega na weryfikacji, czy odpowiedź wynika z zebranych dowodów, natomiast dokładność cytowania sprawdza, czy wymienione źródła potwierdzają każde twierdzenie. Dobrze napisana odpowiedź może nadal być pozbawiona uzasadnienia.

Zdrowie systemu. Ważne są również wskaźniki operacyjne: opóźnienie p95, koszt za zapytanie oraz wskaźnik rezygnacji. Nie chodzi tu wyłącznie o kwestie infrastrukturalne. Jeśli opóźnienie się podwoi, ponieważ agent uruchamia kilka pętli wyszukiwania, jest to element jakości systemu. Nagły wzrost liczby rezygnacji może oznaczać pogorszenie jakości wyszukiwania. Skok kosztu za zapytanie może wskazywać, że zmiana pozornie nieszkodliwa doprowadziła do wykorzystania drogiego rozwiązania.

Rozdzielenie pomiarów przynosi korzyści w diagnozowaniu. Prawidłowe wyniki przy spadającej stopniu uzasadnienia wskazują na generowanie, natomiast spadająca precyzja wskazuje na procesy pobierania, filtrowania, wyszukiwania lub sortowania. Jeśli śledzisz jedynie ogólną jakość odpowiedzi, każda regresja wygląda identycznie i nie daje żadnych podstaw do działania.

Od łańcucha przetwarzania do pętli zwrotnej

Podstawowy łańcuch przetwarzania pozostaje prosty:

Ingestion → Retrieval → Generation → Evaluation

Wiele systemów nie wymaga niczego więcej. Dobrze zindeksowana baza wiedzy oraz jasno sformułowane pytania rzadko wymagają interwencji agenta przy wyborze kolejnego kroku. Istnieją jednak trudniejsze pytania.

Weźmy na przykład prośbę o porównanie danych przychodów z drugiego kwartału z tymi, które zostały przedstawione w prezentacji dla zarządu, a następnie wyjaśnienie różnicy. Odpowiedź może wymagać danych z drugiego kwartału, prezentacji zarządu, odpowiednich fragmentów obu materiałów, porównania, a być może także zapytania do innej bazy danych. Jedna próba pobrania informacji może nie wystarczyć, i właśnie wtedy przydaje się podejście agentic RAG. Zamiast prostego kroku pobrania danych, a następnie ich przetworzenia, można uruchomić pętlę:

Retrieve
   ↓
Evaluate
   ↓
Enough evidence?
   ↓ no
Retrieve again
   ↓
Generate

Taki system może stwierdzić, że dotychczasowe dowody są niewystarczające, sformułować zapytanie na nowo, przeszukać ponownie lub przekazać podpytanie bazie danych SQL, grafowi wiedzy lub API w czasie rzeczywistym. Proces wyszukiwania staje się iteracyjny i przestaje być jednorazowym działaniem.

Agentic RAG nie jest jednak automatycznie lepszy. Każdy dodatkowy cykl zwiększa opóźnienie, koszt tokenów oraz ryzyko błędów, a także może wywołać niepotrzebne wyszukiwania, gdy agent nie ma wyraźnego powodu, by kontynuować. Jego zalety uwidaczniają się w przypadku niejednoznacznych pytań, pytań wymagających kilku kroków lub potrzebujących kilku źródeł. Pytanie dotyczące polityki zwrotów powinno być prawdopodobnie odpowiedziane za jednym razem za pomocą dobrze zaprojektowanego statycznego procesu. Porównanie talii kart może uzasadnić konieczność iteracji.

Ważne jest to, czy system ma mierzalny powód, by szukać ponownie, a nie to, czy w ogóle powinien posiadać agenta. Cykliczne działanie bez jasnej zasady zakończenia tylko powoduje opóźnienia i dodatkowe koszty.

Model mentalny produkcji

Najczęstszym błędem podczas debugowania jest rozpoczynanie od modeli LLM. Zła odpowiedź jest jedynie ostatnim objawem, a przyczyna może leżeć znacznie wcześniej w łańcuchu przetwarzania. Przestarzałe dokumenty przypominają halucynacje, słabe dzielenie na fragmenty przypomina nieudane wyszukiwanie, słabe funkcje wyszukiwania przypominają błędy w generowaniu treści, a brak oceny ukrywa wszystkie te problemy aż do chwili, gdy klienci zaczną się skarżyć.

Dlatego nie pytaj, jaki model należy użyć. Zapytaj, który warstwa przestaje funkcjonować poprawnie.

INGESTION
     ↓
RETRIEVAL
     ↓
GENERATION
     ↓
EVALUATION
     ↖
      └── feedback loop / Agentic RAG

Stale dane oznaczają konieczność poprawy procesu pobierania informacji. Brak dokumentu oznacza konieczność poprawy mechanizmu wyszukiwania. Znaleziony dokument o niskiej pozycji w rankingu wymaga poprawy algorytmu rankowania. Błędna odpowiedź w odpowiednim kontekście wskazuje na konieczność przeanalizowania procesu generowania treści. Jeśli nie możesz określić, który z tych problemów występuje, najpierw opracuj lepszą metodę oceny. A gdy jedna próba nigdy nie wystarczy, rozważ użycie pętli agencyjnej.

Zacznij od całego procesu i odłóż model na koniec.

Skąd pochodzą te pomysły

Dla dalszej lektury oryginalny artykuł Lewisa i współpracowników z NeurIPS 2020 na temat generacji wzbogaconej o wyszukiwanie definiuje podstawowy wzorzec. Opracowanie Anthropic z 2024 roku na temat wyszukiwania kontekstowego pokazuje duże spadki błędów wyszukiwania przy użyciu embeddingów kontekstowych, BM25 kontekstowego oraz mechanizmów ponownego sortowania, choć są to pomiary przeprowadzone przez samego dostawcę. Cormack, Clarke i Büttcher (SIGIR 2009) wprowadzili metodę Reciprocal Rank Fusion. Artykuł „Lost in the Middle” autorstwa Liu i współpracowników bada, w jaki sposób modele wykorzystują długie konteksty, artykuł RAGAs opisuje automatyczną ocenę systemów RAG, a artykuł Self-RAG autorstwa Asai i współpracowników dotyczy wyszukiwania samorefleksyjnego i opartego na agencjach.

Literatura pokrewna

  • Tworzenie systemu Multi-Tenant RAG na Amazon S3 Vectors: proces realizacji — Projekt indeksu dostosowanego do poszczególnych użytkowników w S3 Vectors: uprawnienia STS z ograniczonym zakresem, usuwanie danych na podstawie kluczy, audyt za pomocą CloudTrail oraz ograniczenia izolacji obecne w kodzie aplikacji.
  • Od prototypu do systemu RAG w produkcji: wyszukiwanie hybrydowe, agenci i ocena — Architektura referencyjna dla systemu RAG w produkcji w .NET: dzielenie danych na fragmenty, wyszukiwanie hybrydowe i grafowe, ponowna klasyfikacja wyników, planowanie zapytań, wyjścia typowane oraz ciągła ocena.
  • Semantic Search vs Vector Search, and Where RAG and Azure AI Search Fit — Wyjaśnienie wyszukiwania słów kluczowych, wektorowego, semantycznego i hybrydowego przy użyciu przykładu polityki wyjścia i incydentu, a także sposób, w jaki Azure AI Search, Semantic Kernel i RAG są ze sobą powiązane.
  • Inside Vector Databases: IVF, Trees, HNSW and Product Quantization — Jak bazy danych wektorowych szybko znajdują sąsiednie elementy: wyszukiwanie dokładne vs przybliżone, klastry IVF, lasy drzew, warstwy i parametry HNSW oraz kompromisy związane z kwantyzacją produktów.