Gdy cytaty wyglądają idealnie, a liczba osób wciąż jest błędna
RAG wycenił pensje, używając właściwego pliku PDF, ale nadal zaliczył dwunastu pracowników jako jednego – po naprawieniu tego problemu za pomocą hybrydowego wyszukiwania, kompresji uwzględniającej tabelki oraz śledzenia procesów.
Kwestia związana z wypłatami powinna być nudna. Jeśli zapytasz, ilu osób figuruje w rejestrze płac z kwietnia 2025 roku, oczekujesz jedynie liczby, odniesienia do źródła i niczego ciekawego. System zwrócił dopracowany zdanie: jeden pracownik, nazwa pliku PDF, data na stronie. Rejestr wskazywał dwunastu.
To właśnie taki sposób awarii sprawia, że generowanie wzbogacone o dane z bazy jest niebezpieczne w praktyce. Proces się nie zawiesił, logi pozostały ciche. Odpowiedź przypominała każdą poprawną odpowiedź z tej samej tygodnia. Delikatna awaria z przypisem jest gorsza od poważnego załamania, ponieważ nikt nie traktuje uprzejmego akapitu poważnie.
To opracowanie rekonstruuje proces, który doprowadził do powstania kłamstwa, metody diagnostyczne, które je ujawniły, oraz konkretne zmiany, które przywróciły liczbę do dwunastu. Wykorzystane narzędzia są celowo zwyczajne: pdfplumber do obsługi tekstu w plikach PDF z uwzględnieniem układu, LangChain do dzielenia tekstu na fragmenty, embeddingi MiniLM, Qdrant do przechowywania wektorów, hybrydowy system wyszukiwania oparty na metodach dense-plus-BM25, narzędzie cross-encoder do ponownego sortowania wyników oraz kompresor, który miał zmniejszyć objętość kontekstu przed uruchomieniem generatora. Żadna z tych opcji nie była wyjątkowa. Problemy pojawiły się w sposobie ich współdziałania przy obsłudze tabel i identyfikatorów.
Jednorazowe przetworzenie, odpowiedzi za każdym razem
Dokumenty trafiają tylko raz. Pytania pojawiają się nieustannie. Rozdzielenie tych ścieżek ma znaczenie podczas debugowania, ponieważ błędna odpowiedź może wynikać ze starych wektorów, nieprawidłowych filtrów lub generatora, który w ogóle nie widział odpowiednich rekordów.
Proces przetwarzania przechodzi przez każdy plik PDF, wydobywa tekst z uwzględnieniem układu, dzieli go na nakładające się fragmenty, wstawia je do Qdrant wraz z metadanymi, które mogą być później wykorzystane do filtrowania:
PDF → extract text per page → cut into chunks
→ convert each chunk to 384 numbers → store in a vector database
Odpowiadanie to zupełnie inna struktura grafowa. Wstawia się pytanie, wyszukuje kandydatów, opcjonalnie łączy wyniki z kluczowymi słowami, ponownie sortuje je, kompresuje, a następnie zadaje pytanie modelowi z dołączonymi cytatami:
question → search → rerank → compress → ask the LLM → cited answer
↓ ↓ ↓
5 chunks 3 chunks ~600 chars
Na papierze taki proces wygląda jak z podręcznika. W warunkach produkcyjnych te uproszczone założenia zawodzą w przypadku rejestrów pracowników, tabel faktur oraz wszelkich dokumentów, gdzie odpowiedź ma charakter strukturalny, a nie jedynie hasła.
Dlaczego każda z tych części znalazła swoje miejsce
pdfplumber nie jest najszybszą biblioteką do obsługi plików PDF. Należy do nielicznych, które zachowują wystarczająco dużo informacji o układzie tekstu, by wiersze zawierające dane o pensjach nie łączyły się w jeden długi akapit. Szybsze narzędzia do wydobywania danych, które spłaszczają tabele w jedne długie zdania, utrudniają późniejsze zadania typu „liczenie pracowników”, ponieważ model w ogóle nie widzi granic poszczególnych wierszy.
Dla tego projektu do dzielenia tekstu na fragmenty użyto rekurencyjnego narzędzia do rozdzielania znaków z LangChain, a nie żadnych innych elementów tego frameworku. Celem było uzyskanie przewidywalnej wielkości okien z nakładaniem się ich treści, a nie użycie konkretnego łańcucha RAG. Po krótkim testowaniu jako modele do embeddingów wybrano all-MiniLM-L6-v2 – mniejsze modele pomijały specjalne tokeny identyfikujące elementy tekstu, natomiast większe powodowały opóźnienia bez rozwiązania istotnego problemu. Qdrant okazał się najlepszy ze względu na ciągłość działania w środowisku lokalnym i chmurze oraz filtry treści, które odpowiadały sposobowi, w jaki aplikacja już traktowała różne typy dokumentów.
Poszukiwanie hybrydowe łączyło podobieństwo semantyczne z oceną słów kluczowych w stylu BM25 w stosunku około 0,65 / 0,35. Czyste poszukiwanie semantyczne radziło sobie doskonale z pytaniem „jaka jest polityka urlopu rodzicielskiego”, ale fatalnie z STL/2025-26/003. Ponowna sortacja przy użyciu kodera krzyżowego poprawiła listę kandydatów. Kompresja miała na celu zachowanie tylko tych zdań o wysokiej wartości przed wywołaniem modelu LLM. To właśnie na tym ostatnim etapie naprawdę rozpoczęła się historia, w której dwanaście przekształciło się w jedno.
Pewna, ale błędna odpowiedź
Na pytanie o pensję znaleziono wiarygodną stronę, ją przytoczono, ale ocena była zaniżona. Przyjrzenie się surowym wynikom wyszukiwania ujawniło pierwsze problemy: sąsiednie pod względem semantycznym treści wydawały się „dość bliskie”, podczas gdy dokładne wpisy konkuruje słabo z narracyjnym tekstem HR znajdującym się w innych częściach korpusu.
0.781 Invoice_INV2025001_Arvind.pdf <- returned
0.779 Invoice_INV2025002_Trident.pdf
0.776 Invoice_INV2025003_Welspun.pdf <- actually wanted
Podobieństwo znaczeniowe nie może wykonywać dokładnej obróbki tokenów. Dodanie metody BM25 oraz połączenie wyników zmieniło ranking, w wyniku czego wzrosły pozycje identyfikatorów oraz fragmentów zawierających tabele:
0.854 Invoice_INV2025003_Welspun.pdf <- correct
0.549 Invoice_INV2025001_Arvind.pdf
0.545 Invoice_INV2025002_Trident.pdf
Samo to nie przywróciło poprawnej liczby wyników. Doprowadziło jedynie do uwzględnienia właściwego dokumentu. Kolejne pułapki znajdowały się wewnątrz samego dokumentu.
ID pracowników jako eksperyment przetrwania
Zamiast dyskutować o subtelnych aspektach, ID pracowników ST001 do ST012 były śledzone na każdym etapie: wyodrębnianie, dzielenie na fragmenty, wyszukiwanie, ponowne rankowanie, kompresja oraz ostateczne tworzenie promptu.
retrieved chunk ST001 ST002 ST003 ST004 ST005 ... ST012 (12 present)
after rerank ST001 ST002 ST003 ST004 ST005 ... ST012 (12 present)
after compression ST001 ST002 (2 present)
prompt sent ST001 ST002 (2 present)
Kilka identyfikatorów zniknęło pomiędzy procesem kompresji a modelem. Kompresor utrzymywał stały budżet na „najlepsze zdania”. Jedna wiersz w tabeli liczy się jako jedno zdanie. Gęsta tabela płac zużywa budżet na wczesnych wierszach, podczas gdy późniejsze wiersze – oraz tekst wyjaśniający je – nigdy nie trafiają do promptu. Model następnie uczciwie raportuje ten podzbiór, który widział.
# before — keep the top N
best = scored[:40]
# after — keep the best until the character budget runs out
budget = MAX_CONTEXT_CHARS // TOP_K_AFTER_RERANK
for sentence, score in ranked:
if best and len(sentence) + 2 > budget:
continue
best.append(sentence)
budget -= len(sentence) + 2
Gdy kompresja przetasowała i skróciła wiersze, tabela płac pojawiła się jako talia kart rozdanych w niewłaściwej kolejności. Każda liczba może istnieć gdzieś w oknie kontekstowym, jednak struktura potrzebna do zliczenia odrębnych pracowników zniknęła. Liczenie osób w tabeli, którą ktoś podzielił na uszeregowane fragmenty, to inna zadanie niż czytanie samej tabeli.
Oceny Reranker, które wydawały się w porządku, ale nadal szkodzą
Oceny kodera krzyżowego dla wierszy krytycznych wyglądały „rozsądnie”. Rozsądne nie oznacza jednak zachowania pełnej tabeli.
0.446 keep ST001 Rajesh Kumar M CFO 75,000 ...
0.323 keep ST002 Priya Sundaram Finance Mgr 45,000 ...
0.420 keep ST003 Murugan K Sr Accountant 28,000 ...
0.259 DROP ST005 Selvam R Production Mgr 38,000 ... ← below 0.30
0.422 keep ST006 Karthik P Supervisor 18,000 ...
# pick the best by score…
chosen = set(id(p) for p in best)
# …then put them back in document order before joining
best = [p for p in scored if id(p) in chosen]
Naprawa nie polegała na „podnoszeniu progu wszędzie”. Chodziło o wykrywanie wierszy przypominających tabelę i zwalnianie ich z agresywnej kompresji. Praktyczna heurystyka: jeśli wiersz zawiera cztery lub więcej liczb i znajduje się wśród co najmniej trzech podobnych wierszy w tym samym fragmencie, należy potraktować go jako wiersz tabeli i zachować, niezależnie od oceny zdania.
ROW_MIN_NUMBERS = 4
TABULAR_MIN_ROWS = 3
def is_row(sentence):
return len(NUMBER_RE.findall(sentence)) >= ROW_MIN_NUMBERSif looks_tabular(sentences):
survivors = [p for p in scored if is_row(p[0]) or p[1] >= threshold]
else:
survivors = [p for p in scored if p[1] >= threshold]
Dzięki wyłączeniu wierszy tabeli wszystkie dwanaście identyfikatorów przetrwało do promptu w kolejnym uruchomieniu. Generator w końcu miał strukturę, którą mógł policzyć.
Niewielkie poprawki, które usunęły inne pułapki
Gdy ścieżka do tabeli była otwarta, kilka powiązanych problemów zostało potraktowanych w ten sam sposób: puste zmienne środowiskowe, które cicho zastępowały zamierzone wartości domyślne, filtry typu dokumentu, które zachowywały się inaczej w lokalnej instancji Qdrant i w Qdrant Cloud, oraz treści odpowiedzi, które zwracały jedynie tekst prozatorski, podczas gdy operatorzy potrzebowali śladu przetwarzania.
# the context cap must be at least CHUNK_SIZE × TOP_K_AFTER_RERANK
MAX_CONTEXT_CHARS = 5000 # was 2000 while 1200 × 3 = 3600
Każda odpowiedź zwraca teraz cały proces przetwarzania, a nie tylko ostatnie zdanie – zidentyfikowane ID, wyniki oceny, decyzje dotyczące kompresji oraz filtry – dzięki czemu kolejny błędny wynik można analizować bez domysławania się.
{
"answer": "12 employees are listed...",
"citations": [{"doc": "Salary_Register_April_2025.pdf", "page": 1}],
"pipeline": {
"retrieved": 5,
"after_rerank": 3,
"chars_before_compression": 3847,
"chars_after_compression": 2103
}
}
Filtrowanie według typu dokumentu działało poprawnie w lokalnej instancji Qdrant, ale w ten sam sposób zawodziło w Qdrant Cloud, dopóki indeksy treści odpowiedzi oraz struktury filtrów nie pasowały do tego, co faktycznie było indeksowane w wersji chmurowej.
500 — Index required but not found for "doc_type"
Powiązany przykład w Pythonie: os.getenv("KEY", "default") zwraca pustą ścieżkę, gdy zmienna istnieje, ale jest pusta. To nie jest wartość domyślna. Lepiej użyć or, gdy pustka musi zostać przekazana dalej:
QDRANT_URL = os.getenv("QDRANT_URL") or "http://localhost:6333"
Gdzie skończyła się ścieżka wykonywania
Po hybrydowym pobieraniu danych, kompresji uwzględniającej tabelę oraz wyraźnej telemetrii łańcucha przetwarzania, pytanie dotyczące rejestru z kwietnia przyniosło wynik dwanaście, przy czym odniesienia wskazywały na wiersze uzasadniające tę liczbę.
Retrieval: hybrid, 0.65 semantic + 0.35 BM25
Reranking: cross-encoder, 5 in → 3 out
Compression: sentence-level, table-aware, ~35% reduction
Grounding: prompt + threshold + temperature 0.0
Evaluation: 13/15 on the golden set, refusals tested
Latency: ~4s end to end
Cost: ~$0.003 per fifteen-question run
Wszystko to nie wymagało nowego modelu podstawowego. Wymagało jedynie traktowania RAG jako łańcucha przetwarzania danych z mierzalnymi wskaźnikami przetrwania dla ważnych tokenów. Tutorials promują „umieszczenie, pobranie, generowanie”. W warunkach produkcyjnych kluczowe jest „udowodnienie, że wiersze dotarły do promptu”.
Habity operacyjne zapewniające wiarygodność liczb
Zachowaj zbiór złotych pytań, który obejmuje co najmniej jedno pytanie oparte na czystym liczeniu w tabeli, jedno pytanie dotyczące dokładnego wyszukiwania identyfikatorów oraz jedno pytanie związane z polityką semantyczną. Jeśli przechodzą tylko pytania semantyczne, demo kłamie co do gotowości.
Zapisuj identyfikatory fragmentów danych podczas kompresji. Jeśli identyfikator obecny po pobraniu znika po kompresji, jest to błąd, nawet jeśli ostateczna odpowiedź okazuje się dziś poprawna.
W przypadku korpusów łączących prozę z różnymi stylami pisania preferuj wyraźne hybrydy. Samo intensywne wyszukiwanie będzie skuteczne przy tekstach opisowych, ale nieprzy kodach.
Traktuj cytaty jako coś koniecznego, ale niewystarczającego. Numer strony obok błędnego podsumowania liczby elementów nadal oznacza błędne podsumowanie.
Przenosząc system z lokalnego Qdrant do chmury, ponownie sprawdź indeksy danych i zachowanie filtrów przy użyciu tych samych narzędzi testowych. Kompatybilność API nie oznacza identycznych domyślnych ustawień indeksowania.
Kontekst budżetowy dotyczy struktury, a nie tylko „ważnych zdań”. Tabele stanowią część struktury. Ich kompresowanie na wzór akapitów w blogu sprawia, że dwanaście staje się jednym.
Dlaczego łagodne błędy wymagają surowszych zasad weryfikacji
Zespoły często decydują o uruchomieniu RAG na podstawie kryterium „odpowiedzi wyglądają dobrze w tabeli z przykładowymi zapytaniami”. To kryterium pomija błędy istotne w obszarze wypłat, zapasów i przestrzegania regulacji: niedoszacowanie kwot. Należy dodać automatyczne sprawdzenia, które upewniają się, że wyekstrahowane zbiory danych przetrwają w zapytaniu dla znanych elementów. Proces budowy powinien zostać przerwany, jeśli po kompresji w elemencie dotyczącym pensji nie pojawią się wszystkie wartości od ST001 do ST012.
To samo kryterium weryfikacji może sprawdzać, czy w aktualnej konfiguracji rzeczywiście są aktywne wagi hybrydowych połączeń, a nie tylko w dokumencie README. Rozbieżności pomiędzy eksperymentami w notatnikach a konfiguracją usługi to częsty powód, dla którego algorytm BM25 „znika” po refaktoryzacji.
Na koniec należy nauczyć operatorów, by nie ufać atrakcyjnym cytatom. Interfejs produktu powinien pokazywać ślady wyszukiwania i kompresji obok odpowiedzi dla użytkowników wewnętrznych, dopóki zbiór „golden set” pozostaje na kolorze zielonym w ramach cyklu wydawniczego. Użytkownicy zewnętrzni mogą zachować czysty akapit; użytkownicy wewnętrzni potrzebują narzędzi do dokładnej analizy.
Zakończenie
Rejestr nigdy nie stwierdzał, że jest jeden pracownik. Pipeline tak to zrobił, po cichu odrzucając wiersze, które mogłyby to sprostować. Naprawa tego problemu wymagała hybrydowego wyszukiwania identyfikatorów, kompresji uwzględniającej strukturę tabeli oraz odpowiedzi zawierających własne ślady dowodowe. Gdy te elementy zostały wdrożone, dwanaście pozostało dwunastoma – a kolejny pewny cytat miał rzeczywiste podstawy.
To jest standard, który warto utrzymać: nie chodzi o to, czy model może brzmieć pewnie, ale o to, czy system potrafi udowodnić fakty uzasadniające tę pewność.
Głębsze spojrzenie na zastosowanie hybrydowego oceniania w praktyce
Dense retrieval koduje pytanie oraz każdy fragment w tym samym przestrzeni wektorowej i sortuje wyniki na podstawie iloczynu kosinowego lub iloczynu skalarnego. Metoda ta działa, gdy język użytkownika odpowiada językowi dokumentu – np. w przypadku urlopu rodzicielskiego, odszkodowania za rozwiązanie umowy czy polityki pracy zdalnej. Nie działa natomiast, gdy użytkownik wkleja nieprzejrzysty token, który prawie w ogóle nie występuje w danych treningowych i rzadko współwystępuje z sąsiednimi słowami w przestrzeni embeddingów. Kody pracowników, numery faktur oraz identyfikatory umów należą dokładnie do tej kategorii tokenów.
BM25 oraz powiązane narzędzia oceny leksykalnej odwracają ten problem. Liczy się dla nich to, czy dany token występuje, jak rzadki jest w korpusie oraz jak często pojawia się w kandydującym fragmencie. Nie obchodzi ich to, że „STL/2025-26/003” jest semantycznie niemal bez znaczenia. Mieszanie tych dwóch wyników nie ma charakteru filozoficznego; jest to uznanie faktu, że korpusy z danymi płacowymi zawierają zarówno teksty przypominające eseje, jak i tabele przypominające rejestry.
Mieszanka 0,65 / 0,35 użyta tutaj stanowi punkt wyjścia, a nie prawo natury. Korpusy bogate w kody mogą wymagać większej wagi leksykalnej, natomiast te bogate w narracje – mniejszej. Ważne jest mierzenie obu typów zadań w zbiorze referencyjnym oraz unikanie tworzenia mieszanki, która odpowiada jedynie na zadania narracyjne.
Podczas wdrażania metody blendowania należy najpierw znormalizować wyniki przed ich łączeniem. Surowe wartości podobieństwa oraz surowe wyniki BM25 odnoszą się do różnych skali. Zespoły, które używają nienormalizowanych liczb, często odkrywają przypadkowo, że jeden kanał dominuje nad innymi. Zarówno metoda min-max, jak i fuzja rankowa (RRF) są akceptowalne, o ile zostały przetestowane z przykładami zawierającymi dokładne identyfikatory.
Kompresja jako kodownik ze stratami dla tabel
Kompresja kontekstowa istnieje dlatego, że modele mają ograniczone okna uwagi oraz dlatego, że nieistotne zdania rozpraszają jej zasoby. Standardowe podejście polega na ocenie zdań pod kątem istotności, zachowaniu najlepszych k z nich i odrzuceniu reszty. Takie podejście zakłada, że zdania są wymiennymi jednostkami znaczenia. Wiersze w tabelach nie są takimi wymiennymi jednostkami. Wiersz 7 bez wierszy 1–6 to nie tabela nieco gorszej jakości – to zepsuta tabela.
Heurystyka zwalniania – wiele liczb na jednej linii, kilka takich linii w pobliżu – jest celowo prosta. Pozwala ona zachować niektóre linie, które nie są tabelami, ale wyglądają liczbowo, co jest do przyjęcia. Fałszywie pozytywne wyniki kosztują tokeny, a fałszywie negatywne – poprawność. W przypadku wypłat i zapasów kluczowa jest poprawność.
Bardziej zaawansowane detektory mogą wykorzystywać strukturę PDF z pdfplumber: ramki obszaru komórek, wyrównane kolumny, powtarzające się współrzędne x. Te sygnały są doskonałe, gdy są dostępne. Heurystyka zdań pozostaje przydatna jako rozwiązanie awaryjne, gdy tekst został już przekształcony na markdown lub zwykły tekst przed uruchomieniem kompresji.
Kolejnym modelem awarii jest przetasowywanie. Nawet jeśli wszystkie wiersze przejdą, ich ponowne uporządkowanie według wyniku relevancji może zniszczyć sumy i liczby. Dla wierszy tabel zwolnionych z obowiązków lepiej zachować stabilny porządek dokumentu. Prozę można uporządkowywać swobodnie; tabele należy zachować w porządku lektorskim.
Cytaty broniące błędnej odpowiedzi
Citation UX często wskazuje PDF oraz stronę, które dostarczyły największy fragment danych. Gdy kompresja później skraca tabelę o połowę, odnośnik nadal wskazuje na właściwy plik. Użytkownicy postrzegają to jako potwierdzenie. Projekt produktu powinien albo wskazać konkretne wiersze użyte we wniosku końcowym, albo pokazać ślad wyszukiwania. W przeciwnym razie interfejs staje się wspólnikiem w błędzie.
Dla domen regulowanych należy przechowywać dokładny hash kontekstu wniosku razem z odpowiedzią. Jeśli audytor zapyta, dlaczego system podał „jeden pracownik”, można odtworzyć skróconą tabelę i pokazać błąd, zamiast dyskutować o charakterystyce modelu.
Bazy wektorowe lokalne versus chmurowe
Filtr typu dokumentu, który działał lokalnie, ale zawodził w Qdrant Cloud, przypomina nam, że „ta sama API” nie oznacza „tej samej konfiguracji indeksu”. Indeksy ładunkowe, filtry słów kluczowych oraz obsługa wartości null różnią się w zależności od trybu implementacji. Testy powinny być przeprowadzane na tym samym typie implementacji, który jest używany w środowisku produkcyjnym. Zielony wynik testów lokalnych przy czerwonym wyniku w chmurze oznacza, że puste wyniki wyszukiwania są dostarczane bez żadnych problemów.
Puste zmienne środowiskowe wymagają takiej samej ostrożności. Systemy konfiguracji, które eksportują puste łańcuchy dla nieustawionych haseł, obejdą domyślne wartości w językach, w których puste wartości są uznawane za prawdziwe. Normalizuj konfigurację na początku procesu: traktuj puste wartości jako brakujące, następnie zastosuj domyślne wartości, a jeśli niezbędne klucze nadal są brakujące, zakończ proces z błędem.
Mierzenie wytrzymałości, a nie „nastroju”
Eksperyment z identyfikatorami pracowników służy jako szablon. Wybierz entytety, które muszą się pojawić, aby uzyskać poprawną odpowiedź. Sprawdź, czy istnieją po ekstrakcji, po podziale na fragmenty, po wyszukiwaniu, po ponownym rankowaniu oraz po kompresji. Narysuj wykres spadków jakości. Pierwszy gwałtowny spadek zazwyczaj wynika z błędu.
Rozszerz tę koncepcję na agregaty liczbowe. Jeśli pytanie dotyczy sumy, upewnij się, że każdy wiersz składowy dotarł do promptu. Jeśli pytanie dotyczy liczby unikalnych elementów, sprawdź, czy zbiór kluczy unikalnych jest kompletny. Te kontrole są tanie w porównaniu z incydentami w produkcji.
Czego nie należy winić na początku
Kuszące jest obwinianie modeli LLM, gdy liczby są błędne. Czasami model rzeczywiście nie potrafi liczyć. Częściej jednak model w ogóle nie otrzymał struktury nadającej się do liczenia. Zamień modele dopiero wtedy, gdy wykres przeżywalności będzie w kolorze zielonym. W przeciwnym razie „naprawisz” błąd liczenia, przechodząc na większy model, który wygeneruje fałszywą liczbę, której oczekiwałeś — aż przyjdzie kolejny zapis.
Podobnie unikaj usuwania całego frameworku tylko dlatego, że jeden kompresor zachował się niewłaściwie. Izoluj daną część, dodaj wyjątek, przeprowadź test i idź dalej. Rozległe przeredagowania wydają się skuteczne, ale często ponownie wprowadzają te same problemy pod nowymi nazwami.
Minimalna lista kontrolna wzmocnień bezpieczeństwa
- Kluczowe pytania: liczba w tabeli, dokładny identyfikator, zasady semantyczne.
- Hibrydowe wyszukiwanie z normalizowaną kombinacją lub RRF.
- Kompresja z uwzględnieniem struktury tabeli przy zachowaniu stabilnego porządku wierszy.
- Śledzenie procesów w każdej wewnętrznej odpowiedzi.
Zastosuj tę listę kontrolną przed uznaniem systemu RAG do wypłat za „gotowy”. Rejestr z kwietnia nie będzie ostatnim dokumentem, który wydaje się prosty, a w rzeczywistości zawodzi.
Konsekwencje dla zespołu
Gdy rozwiązanie dla dwunastu pracowników się ustabilizowało, ta sama telemetria wykryła dwa mniej widoczne błędy: przestarzały alias kolekcji po ponownym zaimportowaniu oraz timeout w procesie ponownego rankowania, który sprowadzał się do użycia niezrankowanych wyników hybrydowych bez oznaczenia odpowiedzi jako uszkodzonej. Oba te problemy pozostałyby niewidoczne, gdyby API zwracało tylko ciąg znaków. Zwracanie struktury — wyników, czasów wykonywania, opcji awaryjnych — sprawiło, że asystent stał się czymś, w co operatorzy mogli wystarczająco zaufać, by debugować go o 2 w nocy.
To jest prawdziwa lekcja związana z produktami. Systemy RAG to nie tylko „skórki” do czatów nad PDF-ami – to przepływy danych, które komunikują się za pomocą akapitów. Traktuj je jak takie przepływy: mierz straty, zachowuj strukturę i nigdy nie pozwól, by cytat zastąpił dowód.
Jeszcze jedna analiza błędnej odpowiedzi
Ponowne odtworzenie złej odpowiedzi wraz z dołączonymi śladami sprawia, że historia staje się niemal nudna. System wyszukiwania prawie znalazł właściwy PDF; system oceny hybrydowej dokończył tę pracę. Następnie kompresja wykorzystała swój budżet na pierwsze liczbowe wiersze i odrzuciła resztę. Model policzył to, co pozostało, i odwołał się do pliku. Każdy etap sam w sobie wykonywał działania uzasadnione, ale razem stworzyły one wrażenie pewności.
Dlatego właśnie metryki lokalne na etapie przetwarzania wprowadzają w błąd. Retrieval@k może wyglądać na sprawny, podczas gdy kompresja niszczy odpowiedź. Prawdziwą miarą jest przeżywalność entytetów od początku do końca procesu, która odpowiada temu, jak bardzo użytkownik zostaje poszkodowany. Należy ją wdrożyć wcześnie, szczególnie gdy dokumenty to tabele przykryte warstwą PDF.
Jeśli z incydentu z dwunastoma pracownikami chcesz zaczerpnąć choć jedną rzecz, to tę: nieudane działanie systemu RAG traktuje się jako błąd w procesie, dopóki nie udowodni się inaczej. Należy monitorować cały proces, chronić strukturę danych i upewnić się, że system pokazuje swoje działanie, zanim zaufamy jego wynikom. Delikatne awarie wymagają rygorystycznych kontrol, powtarzanych testów oraz operatorów, którzy mogą sprawdzić każdy detal, zanim użytkownicy ponownie zaufają podanym danym.
Przeżywalność entytetów po kompresji pozostaje najprostszą i najbardziej wiarygodną miarą dla korpusów bogatych w tabele.
Gdy pojawi się kolejny zapis, należy ponownie przeprowadzić analizę przeżywalności identyfikatorów, zanim zaufamy jakimkolwiek nowym danym.
Literatura pokrewna
- Kiedy bot RAG podaje niezgodną kwotę dedukcji ubezpieczeniowej — Narzędzie do dzielenia tekstu na fragmenty o stałej wielkości rozkłada kwotę w dolarach na poszczególne linie; konieczne jest ponowne przetworzenie danych i przejście przez cztery poziomy dzielenia na fragmenty – od rekurencyjnych bazowych metod po wyszukiwanie w dokumentach nadrzędnych – zanim można zaufać uzyskanym odpowiedziom.
- RAG w produkcji na Azure: dzielenie fragmentami, hybrydowe wyszukiwanie, filtry i cytaty — Wymagania przedsiębiorstw dotyczące wyszukiwania wymagają fragmentów uwzględniających strukturę tekstu, hybrydowego wyszukiwania, filtrów ACL, ponownego sortowania wyników, spersonalizowanych zapytań oraz metody oceny – a nie tylko demonstracji w formacie PDF.