Dlaczego odpowiedzi RAG wyglądają na kompletną, podczas gdy wyszukiwanie w Azure DevOps pokazuje, że tak nie jest?
Zamykanie luk w kompletności w systemie RAG Azure DevOps opartym na grafach: deterministyczne sprawdzanie tagów, przemierzanie grafów, ograniczenia kontekstowe oraz narzędzia do zapytań tylko do odczytu.
System, który załadowuje historię z Azure DevOps do bazy danych grafowych, może odpowiadać na pytania dotyczące projektów, osób odpowiedzialnych oraz zrealizowanych zadań, przy użyciu czytelnego tekstu i linków do źródeł. Przez jakiś czas wydawało się to wystarczające — dopóki odpowiedzi nie były sprawdzane według prostego kryterium: surowej zapytania w Azure DevOps. To właśnie pomiędzy dopracowaną odpowiedzią a wyczerpującym wykazem „kompletne” odzyskiwanie informacji po cichu zawodzi. Zamykanie tej luki wymagało określonych kroków, mierzalnych testów oraz kilku poprawek, które same stworzyły nowe problemy.
Pytanie, które ujawniło tę lukę
Pierwotne pytania przynosiły czyste, źródłowe odpowiedzi bez większych dodatków. Szerzej sformułowane pytanie – „Jakie prace związane z AI są wykonywane w tej organizacji?” – również wyglądało dobrze: kilka akapitów, kilka odnośników, nic oczywiście nie tak. To samo pytanie wprowadzone do funkcji az boards query, czyli wyszukiwania siłowego bez żadnej inteligencji sortującej, zwróciło dziesiątki wyników, o których w dopracowanej odpowiedzi nie było mowy. Brakowało tematów dotyczących oceny asystentów programistycznych, porównywania kosztów modeli czy naprawiania błędów w konkretnych narzędziach, ponieważ miały one mało wspólnego z treścią pytania i nigdy nie trafiały na czoło wyników wyszukiwania semantycznego.
Ten rodzaj błędu łatwo przeoczyć: dobrze uporządkowana odpowiedź to nie to samo co kompletna odpowiedź, a system nie daje żadnych wskazówek, które z nich otrzymałeś.
Prompt, który czasami tylko pomagał
Pierwszym pomysłem było polecenie modelowi, by był bardziej ostrożny – w przypadku szerokich pytań miał sprawdzać tagi kategorii przed udzieleniem odpowiedzi, zamiast polegać wyłącznie na wyszukiwaniu. Pomagało to czasami. To samo sformułowanie powodowało różne zachowania podczas kolejnych prób: czasami model sprawdzał tagi, a czasami je pomijał. Nic w pytaniu się nie zmieniało – jedynie to, czy w danym momencie zostało ono wykonane.
Polecenie skierowane do modelu językowego to jedynie zachęta, a nie gwarancja. Gdy ważna jest kompletność, dokładność nie może zależeć od decyzji modelu o tym, czy w danym momencie być dokładnym.
Czynienie ścieżki deterministyczną
Następna zmiana polegała na zaprzestaniu zadawania pytań. Kod zawsze sprawdza tagi przy każdym szerokim pytaniu, niezależnie od tego, czy model uważa to za konieczne. Już to spowodowało zmianę w grupie danych o pewnej prawdziwości – z około połowy znalezionych elementów na około siedem z szesnastu; lepiej, ale wciąż niekompletnie. Dalsze kroki wynikały z konkretnych luk stwierdzonych podczas testów, a nie z spekulacji:
Jednym z kroków jest analiza wyników wyszukiwania tagami w poszukiwaniu powtarzających się nazw i fraz pojawiających się dwa lub trzy razy, a następnie bezpośrednia wyszukiwanka tych nazw – dzięki temu nazwa produktu pojawia się nawet wtedy, gdy nikt jej wyraźnie nie zapytał, o ile mała grupa zawierająca ją jest już widoczna.
Krok, który bierze pod uwagę relacje między elementami grafu, a nie tylko sformułowania, ponieważ elementy pracujące razem mogą dzielić tego samego rodzica, nie mając przy tym żadnych wspólnych słów tytułowych. Element o tytule przypominającym repozytorium testowe z przykładowymi zadaniami programistycznymi może w swoim tekście nic nie mówić o sztucznej inteligencji i łączyć się jedynie poprzez hierarchię.
Krok przeznaczony dla repozytoriów, które nie posiadają tych samych tagów kategorii co elementy prac, i które w przeciwnym razie pozostałyby niewidoczne dla ścieżek opartych na tagach.
Krok przeznaczony dla ludzi, po tym jak pytania dotyczące częstotliwości współpracy dwóch osób przynosiły pewne się błędne odpowiedzi.
Każdy z tych kroków zamknął jakiś brak. W końcu najtrudniejszy przypadek składający się z szesnastu elementów został w pełni rozwiązany – nie częściowo, lecz całkowicie.
Dodatkowy uzyskany kontekst pogorszył odpowiedzi
Wbrew intuicji, gdy jakość wyszukiwania poprawiła się na tyle, że zasób modelu wzrósł z kilkuset elementów do ponad tysiąca, odpowiedzi stały się krótsze i mniej kompletnie. Model nie uległ awarii; po prostu w milczeniu tworzył mniej treści, mimo dostępności większej ilości prawdziwych danych. Po przekroczeniu określonego progu objętości jakość odpowiedzi nie rośnie wraz z rozmiarem kontekstu – wręcz się pogarsza. W tym samym teście wskaźniki wyszukiwania poprawiły się, podczas gdy wskaźniki jakości końcowych odpowiedzi spadły. Rozwiązaniem nie było „dodawanie więcej”, lecz znalezienie górnego limitu i jego przestrzeganie.
Rozwiązanie problemu przejrzystości, które przytłaczało proste pytania
Gdy model streszczał rzeczywisty materiał zamiast go nazwać, nowy rozdział odpowiedzi wymieniał elementy znalezione, lecz nienazwane, dzięki czemu nic nie znikało bez śladu. Pierwsza wersja umieszczała w odpowiedziach na konkretne pytania ponad tysiąc słabo powiązanych elementów, ponieważ generator list nie potrafił odróżnić dokładnych dopasowań od ogólnych, nieprecyzyjnych tagów. Szeroka kategoria obejmowała wszystko, co było choćby w odległym związku, traktując to jako równie istotne do pokazania.
Trwałe rozwiązanie polegało nie tylko na ustaleniu liczbowego limitu. Chodziło o rozróżnienie dwóch rodzajów „znalezionych, lecz nienazwanych”: małej grupy dokładnych dopasowań, które zawsze powinny być pokazywane, oraz dużego zbioru elementów o luźnych tagach, które wymagają rzetelnego ograniczenia oraz informacji o tym, że istnieje ich więcej. To rozróżnienie było ważniejsze niż sam limit.
Dostarczanie modelowi narzędzi – z ograniczeniami
Kluczowe pytanie określiło dalszy tok pracy: dlaczego człowiek może odpowiedzieć na to, czego nie potrafi system, skoro oba widzą te same dane? Ludzie mogą stworzyć nowy zapytanie, gdy dostępne narzędzia nie nadają się do zadania, a także sprawdzać ponownie odpowiedzi, które wydają się nieprawidłowe. Model nie posiadał żadnej z tych umiejętności. Otrzymał narzędzie do tworzenia własnych zapytań do bazy danych o dostępie tylko do odczytu – dostęp ten był kontrolowany przez bazę danych, miał ograniczony czas trwania oraz limit wielkości wyników.
Potrzebne były jeszcze dwa rundy. Gdy zapytano o częstotliwość współpracy dwóch nazwanych osób, model najpierw założył, że mają to samo nazwisko ze względu na wspólne wzmianki, otrzymał pusty wynik i zamiast zakwestionować ten fakt, odgadnął odpowiedź na podstawie niepowiązanych komentarzy. Zasada stała się następująca: najpierw należy sprowadzić każde imię do dokładnego wpisu w bazie danych, a pusty wynik z własnego zapytania należy traktować jako dowód na błąd w zapytaniu, a nie na to, że liczba współprac jest zerowa.
Przy następnej próbie udało się rozwiązać problem obu osób, wykonać właściwą zapytanie i uzyskać dwadzieścia pięć wspólnych elementów – mimo to nie podano tej liczby, ponieważ każde twierdzenie wymagało identyfikatora źródła, a liczba obliczona go nie posiadała. Zgodnie z literą zasady dotyczącej źródeł odrzucono prawidłową odpowiedź. Potrzebna była wyraźna wyjątek: liczbę obliczoną można było podać bezpośrednio, bez identyfikatora źródła.
Ani jedno z tych niepowodzeń nie wynikało z braku umiejętności; oba były wynikiem prawidłowego przestrzegania instrukcji, które nie obejmowały tej sytuacji. Ta różnica ma większe znaczenie, niż się na pierwszy rzut oka wydaje.
Jak testy pozostały uczciwe
Prawda obiektywna nie była sprawdzaniem nastroju. W przypadku najtrudniejszego klastra szesnaście znanych elementów zostało na początku wymienionych z wyników wyczerpującego zapytania, a następnie ocenionych po każdej zmianie w procesie wyszukiwania: ile z nich pojawiło się w ostatecznej odpowiedzi, ile zostało przytoczonych, a ile po prostu pominiętych. To właśnie ten system ocen sprawił, że wyrażenia „siedem z szesnastu”, a później „szesnaście z szesnastu” nabrały znaczenia. Bez zewnętrznej, wyczerpującej listy stwierdzenie „wygląda na kompletny” jest jedynie kwestią estetyki.
Kierowanie procesem bez przytłaczania modelu
Kroki deterministyczne nadal wymagają określonej kolejności. Najpierw rozszerzanie tagów powiększa zbiór kandydatów; następnie wydobywanie nazw pogłębia ten zbiór; przechodzenie po grafach dodaje sąsiednie elementy strukturalne; kroki związane z repozytorium i osobami wypełniają luki w modalnościach. Dopiero po utworzeniu tego zbioru górna granica rozmiaru ogranicza to, co trafia do promptu. Odwrócenie tej kolejności – proszenie modelu o dokładność przed utworzeniem zbioru – powraca do problemu nudge’owania. Praca nad kompletnością polega na projektowaniu procesów, a nie na używaniu lepszych przymiotników w promptzie systemowym.
Cytaty versus fakty obliczone
Zasada cytowania każdego twierdzenia chroni przed sfabrykowaniem treści, gdy model cytuje elementy tekstu. Staje się szkodliwa, gdy model wykonywa operacje arytmetyczne lub łączy wyniki uzyskane za pomocą narzędzi. Rozdzielenie „cytowanego twierdzenia” od „obliczonej sumy” w instrukcjach przywróciło liczbę dwudziestu pięciu współprac w sposób nie osłabiający dyscypliny dotyczącej cytowania w przypadku twierdzeń narracyjnych. Systemy RAG wykorzystujące narzędzia potrzebują obu tych zasad, co zostało wyraźnie określone.
Sytuacja obecna
Prosta zapytanie do bazy danych jest ze swej natury wyczerpujące: żadnych dopasowanych wierszy nie można przeoczyć. Nie potrafi ono również wyjaśniać, grupować ani opowiadać o znaczeniu – zwraca jedynie listę, a nie odpowiedź. System teraz porównuje pełność tego zapytania z trudnymi przypadkami, które zostały znalezione i przetestowane, jednocześnie wyjaśniając wyniki w prozie z wiarygodnymi źródłami. Ten rezultat jest mierzony, a nie zakładany.
To nie jest problem rozwiązany. Każde z powyższych rozwiązań istnieje dlatego, że pojawił się konkretny błąd podczas sprawdzania odpowiedzi w oparciu o jakąś kompletną bazę danych. Ta metoda wykrywa luki, ale nie dowodzi, że żadne już nie pozostały. Po wprowadzeniu powyższych zmian pojawił się nowy typ pytania dotyczący cytatu używanego do poparcia twierdzenia o danej osobie, podczas gdy cytowana źródło nic o tej osobie nie mówiło – został on odnaleziony, ale w momencie pisania jeszcze nie naprawiony. Ten wzorzec się powtarza: sprawdza się coś, co wydaje się kompletnym, a potem pojawia się coś nowego.
Szczerym podsumowaniem nie jest stwierdzenie, że „kompletność RAG została rozwiązana”. Chodzi raczej o to, że każda konkretna luka, którą udało się znaleźć i przetestować, została zamknięta, przy podaniu danych przed i po interwencji. Nie ma sposobu, by zagwarantować brak kolejnych luk, a żaden system tego typu nie powinien takie obietnice składać. Stwierdzenie „model zazwyczaj ma rację” nie stanowi podstawy dla niezawodności — właśnie słowo „zazwyczaj” okazuje się kluczowe w kwestiach najważniejszych.