Strona główna / Artykuły

Gdy panel sterowania pokazuje zielony kolor, a agent się myli: śledzenie stanu

Panel sterowania ma kolor zielony, a agent się myli: błędy ukrywają się w stanie przekazywanym pomiędzy prawidłowo działającymi etapami. Jakie zapisy śledzenia, routingu oraz ocen muszą być rejestrowane.

Wydawca: REACTAPP.TOP12 min czytania2749 słów

Źródła: When the Dashboard Is Green and the Agent Is Wrong: Tracing Multi-Step Failures Past the LLM Call

Zielona karta kontrolna i błędna odpowiedź

Debugowanie agentów AI ma irytującą cechę: ekran monitoringu może twierdzić, że wszystko jest w porządku. Wywołanie modelu zakończyło się pomyślnie, narzędzia działają poprawnie, API odpowiada kodem 200, opóźnienia są normalne, a zużycie tokenów mieści się w oczekiwanych granicach. Z punktu widzenia infrastruktury nic się nie dzieje, a mimo to ostateczny wynik może być całkowicie błędny.

To nie jest ten oczywisty rodzaj błędu, przy którym model wymyśla coś absurdalnego. Takie awarie są łatwiejsze do rozwiązania, ponieważ przynajmniej wiadomo, od czego zacząć. Trudniejszy jest przypadek, gdy każdy krok wydaje się rozsądny, technicznie nic się nie zawaliło, a odpowiedź jest na tyle wiarygodna, że ktoś może na jej podstawie podjąć decyzję.

Problem nasila się w miarę rozwoju systemów, które przechodzą od zwykłych wywołań LLM do agentów i wieloetapowych procesów pracy. Zanim pojawi się odpowiedź, dane, na których się opiera, mogły przejść przez kilka modeli, narzędzi, API, procesów transformacji i routery, więc ostateczny model może wykonywać doskonałą pracę na danych uszkodzonych już pięć kroków wcześniej. Ten aspekt obserwowalności agentów wymaga znacznie większej uwagi, niż otrzymuje.

Zmiana schematu, której nikt nie zauważa

Rozważmy rutynową pracę związaną z sukcesem klienta. Od agenta wymaga się znalezienia klientów, których odnowienia przypadają na okres 30 dni, oznaczenia kont, które mogą zostać porzucone, oraz przygotowania raportu dla zespołu ds. sukcesu klienta. W trakcie tej pracy agent może wysyłać zapytania do CRM, obliczać wskaźnik ryzyka, pobierać najnowsze tematy wsparcia, sprawdzać użycie produktu, a na końcu poprosić LLM o napisanie raportu.

Załóżmy teraz, że CRM zmienia jeden ze swoich schematów odpowiedzi. Wczoraj treść odpowiedzi wyglądała w ten sposób.

{
  "health_score": 42
}

Dziś wygląda tak.

{
  "health": {
    "score": 42
  }
}

API nadal działa, żądanie jest realizowane pomyślnie, a JSON nadal jest parsowany. W zależności od kodu integracji nie ma konieczności rzucania żadnych wyjątków. Problemy pojawiają się później, gdy warstwa normalizacji nadal szuka wartości health_score, a w następnym kroku otrzymuje null.

Być może mechanizm oceny ryzyka traktuje brakującą wartość jako neutralną, albo instrukcja mówi o użyciu tego, co jest dostępne. W obu przypadkach proces kontynuuje się i kończy wiarygodnym raportem, który pomija konto, o którym zespół powinien wiedzieć.

Skupienie się na końcowym wyniku sprawia, że model staje się łatwym winowajcą, więc ludzie zaczynają przepisywać instrukcje, zmieniać modele lub dostosowywać parametry temperatury, nie dotykając prawdziwej przyczyny. Lepie jest zadać pytanie o to, kiedy stan po raz pierwszy stał się błędny – dzięki takiemu pytaniu debugowanie agenta wygląda zupełnie inaczej.

Wydarzenia sukcesu nie dowodzą zrozumienia

Jeden z najnowszych esejów na temat przekształcania sieci w API dla agentów opisuje, jak oprogramowanie przechodzi od prezentowania informacji do podejmowania działań w imieniu użytkownika. Autor twierdzi, że udostępnianie narzędzi modelowi to tylko część procesu, ponieważ intencje, uprawnienia, kontrole w czasie wykonywania oraz możliwość audytu stają się istotne, gdy agenty podejmują rzeczywiste działania.

To samo dotyczy debugowania tych działań. Informacja o tym, które narzędzie zostało wykonywane, jest pomocna, ale nie ujawnia, czy reszta procesu zrozumiała wynik działania tego narzędzia. Wyobraźmy sobie ślad wykonywania z takimi danymi.

crm.search_accounts
status: success
duration: 184ms
records: 47

Okazuje się, że CRM zwrócił 47 rekordów. Nie wiadomo jednak, czy wszystkie 47 dotarły nienaruszone do następnego etapu. Być może istniało jeszcze sześć stron, a paginacja skończyła się po pierwszej. Być może kwota została przeliczona z dolarów na centy, albo timestamp w formacie UTC został później odczytany jako czas lokalny. Być może wartość typu enum zmieniła się z „cancelled” na „canceled”, albo API zaczęło raportować błędy na poziomie aplikacji w odpowiedziach, których status HTTP wydawał się w porządku.

To zwykłe błędy oprogramowania, nic więcej. W przypadku agentów problem polega na tym, że podobny model zazwyczaj kontynuuje pracę, przyjmując dane, które wydają się wiarygodne, i na ich podstawie podejmując decyzje. Dlatego lepszy model niekoniecznie coś naprawi. Jeśli dane wejściowe są błędne od samego początku, model po prostu rozwiązuje błędny problem z większą skutecznością.

W kluczowych punktach powinieneś móc sprawdzić dane wejściowe, wynik, przekształcenie zastosowane do odpowiedzi oraz to, co otrzymał następny krok. Nie jest konieczne przechowywanie wszystkich surowych danych na zawsze, ale istotne jest zachowanie wystarczającej ilości informacji, aby móc odtworzyć proces po awarii.

Śledzenie braku konkurenta

Narzędzia stale się udoskonalają. Semantyczne konwencje GenAI w OpenTelemetry zaczynają standaryzować sposób opisywania wywołań modeli i wykonywania narzędzi, a frameworki takie jak OpenAI Agents SDK śledzą procesy generowania, wywoływania narzędzi, przekazywania danych oraz zasad bezpieczeństwa. To przydatny surowy materiał, ale nadal trudno jest uczynić ten zapis użytecznym, gdy proces został zakończony, a rzeczywista awaria kryje się w danych przekazywanych pomiędzy dwoma prawidłowo działającymi krokami.

Rozważmy uproszczony proces, jak ten przedstawiony na rysunku.

Załóżmy, że w końcowym raporcie brakuje konkurenta, który ewidentnie powinien tam być. Dawny sposób polegał na otwarciu końcowego zapytania i sprawdzeniu odpowiedzi modelu. Być może instrukcje nie były wystarczająco jasne, model zignorował część kontekstu albo inny model poradziłby sobie lepiej. Rozpoczynanie od tego już nie jest właściwym krokiem.

Zamiast tego pracujmy wstecz. Czy model ostateczny uzyskał brakującego konkurenta? Jeśli nie, to czy doszło do kroku rankingu? Jeśli zniknął przed rankowaniem, to czy był obecny po ekstrakcji? Obecność po ekstrakcji, ale brak po normalizacji oznacza, że problem leży dokładnie na jednej z granic.

{
  "company": "Example Corp",
  "website": {
    "url": "https://example.com"
  }
}

chociaż krok normalizacji tego oczekiwał.

{
  "company": "Example Corp",
  "website": "https://example.com"
}

Nic w tym nie było dramatyczne. W połowie procesu obiekt zmienił formę, a jeden z kroków został źle obsłużony, mimo to większość operacji w pobliżu nadal wyglądała prawidłowo. Takie błędy wymagają śledzenia, ponieważ w przeciwnym razie winę ponosi ten komponent, który jest najbardziej widoczny, bez względu na to, co wydarzyło się wcześniej.

Prawdziwa lekcja polega nie na konieczności użycia jakiegoś konkretnego narzędzia do obserwowalności, ale na tym, że śledzenie powinno umożliwić śledzenie stanu w całym procesie pracy i nie powinno jedynie wymieniać komponentów, które zostały uruchomione. Istnieje duża różnica pomiędzy wiedzą o tym, że uruchomiono krok 4, a wiedzą o tym, co krok 5 od niego otrzymał.

Plan drift wydaje się sensowny

Gdy już zlokalizujesz błąd związaný z ograniczeniami narzędzia, jest on dość oczywisty. Problemem jest jednak odchylenie od planu, ponieważ agent może opuścić pierwotne zadanie poprzez kroki, które każdy z osobna wydają się sensowne. Wyobraź sobie agenta, któremu polecono zbadać pięciu dostawców, ocenić ich ceny i niezawodność oraz przygotować rekomendację, z instrukcją, by nie kontaktować się z nimi.

Agent znajduje dostawców i zaczyna zbierać dane. Dwóch z nich nie podaje cen, więc szuka innego sposobu na rozwiązanie tego problemu. W końcu znajduje dostępne narzędzie do korespondencji e-mail. Jego logika nie jest absurdalna: potrzebne są ceny, które nie są publiczne, a wiadomość do dostawcy mogłaby to rozstrzygnąć. Jednocześnie narusza to jedną z najważniejszych zasad zadania.

Gdy reguła to zwykłe zdanie znajdujące się na górze rosnącego okna kontekstowego, wszystko zależy od tego, czy model nadal będzie ją traktować jako ważną po tym, jak pojawią się tysiące tokenów wyników wyszukiwania, wyników narzędzi oraz stanów pośrednich. Ograniczenia, które mają rzeczywiste konsekwencje, wymagają wyraźnej formy przedstawienia.

{
  "objective": "Compare suppliers and prepare a recommendation",
  "constraints": [
    "Do not contact suppliers"
  ],
  "completed_steps": [
    "discover_suppliers",
    "collect_public_pricing"
  ],
  "next_action": "request_missing_prices",
  "requested_tool": "send_email"
}

Teraz aplikacja ma coś do sprawdzenia przed wykonaniem jakiejś akcji. Może odrzucić żądanie narzędzia, zażądać ludzkiej aprobaty lub wysłać agenta w poszukiwaniu innego rozwiązania. Odpowiednia reakcja zależy od procesu pracy, ale kluczowe jest to, że ograniczenie to nie występuje już wyłącznie w sformułowaniach instrukcji.

Zasady takie jak limit wydatków, „przygotuj, ale nie wysyłaj” czy „nigdy nie ingeruj w produkcję” działają w ten sam sposób. Prosty język jest przydatny do przekazania intencji użytkownika, ale uprawnienia i ograniczenia, które są istotne, powinny również być realizowane poprzez kontrole w czasie rzeczywistym.

Oprogramowanie radzi sobie z tym we wszystkich innych przypadkach. Nikt nie napisałby w komentarzu „proszę, nie pozwól nieuprawnionym użytkownikom usunąć bazy danych” i nazywałby to kontrolą dostępu, a agenci nie zasługują na wyjątek tylko dlatego, że ich instrukcje są w języku angielskim.

Model routingu wprowadza granicę

Ukierunkowywanie ruchu powoduje podobny problem. Wybór modelu przestaje być prostą wartością konfiguracyjną, gdy trzeba zrównoważyć jakość, koszt, opóźnienie, wykorzystanie narzędzi oraz różne możliwości modeli w systemie produkcyjnym, a decyzja o ukierunkowaniu staje się częścią śladu potrzebnego do debugowania.

Załóżmy, że krok 6 zwykle jest wykonywany przy użyciu modelu A. Podczas rzeczywistego działania usługi występuje ograniczenie przepustowości, więc router przechodzi na model B. To właśnie jest mechanizm awaryjny działający zgodnie z projektem, ponieważ proces pozostaje aktywny, zamiast zawieść się. Jednak model B nieco inaczej formatuje strukturalne argumenty przeznaczone dla następnego narzędzia. Argumenty te pozostają ważne i narzędzie działa poprawnie, ale jedno pole jest odczytywane w taki sposób, że zmienia to ostateczny wynik.

Jeśli raporty dotyczące obserwowalności pokazują tylko model skonfigurowany dla procesu pracy, ktoś może spędzić godziny na próbach odtworzenia błędu w modelu A, podczas gdy to model B obsłużył żądanie, które spowodowało awarię. Dlatego ślad powinien rejestrować żądany model, ten, który odpowiedział, ewentualne rozwiązania awaryjne, aktywną politykę routingu oraz to, czy wywołanie było próbą ponowną. To nie są ekscytujące informacje, ale większość przydatnych narzędzi do debugowania w środowisku produkcyjnym też nimi nie jest. Poza demonstracjami duża część pracy polega na ustaleniu, który niepozorny szczegół uległ zmianie niezauważenie.

Stan śladu, a nie tylko wydarzenia

Narzędzia agentów doskonale pokazują teraz strukturę wykonywania zadań, prezentując wywołania modeli, użyte narzędzia, przeniesienia danych, próby ponowne oraz inne zdarzenia w coraz bardziej przydatnych widokach śledzenia. Błędem byłoby założenie, że rejestracja większej liczby zdarzeń automatycznie zapewnia dobrą możliwość obserwacji. Wykonanie zadań z dziesięcioma dobrze skonfigurowanymi elementami nadal może być problematyczne, jeśli nie można zrozumieć, jaki stan istniał pomiędzy nimi.

Krótki wykaz pytań pomaga w analizie nieudanych wykonań. Czego pierwotnie chciał użytkownik? Jakie były obowiązujące ograniczenia? Jakiego planu trzymał się system? Co zwróciło każde narzędzie i co otrzymał następny krok? Który model podjął każdą decyzję? Czy coś w otoczeniu zewnętrznym uległo zmianie? Gdzie wyniki przestały odpowiadać oczekiwaniom?

Odpowiedź na te pytania wymaga mniej danych niż ich pełne zebranie, a rejestrowanie wszystkiego niesie ze sobą własne problemy. Pytania, argumenty narzędzi oraz ich odpowiedzi mogą zawierać prywatne dane klientów, dane uwierzytelniające lub inne wrażliwe informacje, które nie powinny trafiać na platformę do obserwacji bez odpowiedniej analizy. Wytyczne GenAI od OpenTelemetry wskazują na to zagrożenie, a ich szczegółowe specyfikacje pozwalają na rejestrowanie wyłącznie danych wejściowych i wyjściowych modelu na żądanie, a nie automatycznie.

Celem jest zatem umożliwienie odtworzenia tylko tych części procesu, które są istotne, a nie rejestrowanie całego procesu. Czasami wystarczy zredagowana odpowiedź, czasami wersja schematu wraz z identyfikatorem obiektu, a czasami konieczne jest zrobienie zrzutu stanu wyniku pośredniego, ponieważ nic innego nie może odtworzyć tego procesu. Podjąć decyzję należy celowo, aby w przypadku incydentu nie okazało się, że jedyną zachowaną informacją jest status: success.

Co to oznacza dla oceny

Ślad wyjaśnia, co się stało, ale nie określa, czy wynik był dobry, dlatego ocena pozostaje konieczna. Anthropic argumentuje w ten sam sposób w swoim artykule o ocenie agentów. Agentów trudniej ocenić niż pojedyncze odpowiedzi, ponieważ działają one przez kilka rund, korzystają z narzędzi, zmieniają stan i dostosowują się do tego, co wydarzyło się wcześniej.

Część wyników można sprawdzić bez dodatkowego modelu. Agent, któremu powiedziano, aby nie wysyłać e-maila, a który go wysyła, poniósł porażkę, a zadanie wydobywania danych, które miało zwrócić 27 rekordów, ale zwraca 11, wykazuje znaczącą odchylkę. Inne przypadki są bardziej niejednoznaczne: Czy raport badawczy był wystarczająco szczegółowy? Czy źródła były jakościowe? Czy odpowiedź obsługi klienta rozwiązała problem klienta? W takich sytuacjach mogą być potrzebne ludzka ocena, opinie użytkowników, zestawy danych lub narzędzia oceny oparte na modelach.

Prawdziwa wartość wynika z połączenia oceny z śledzeniem procesu. Oznaczenie negatywne obok zapisanej ostatecznej odpowiedzi jedynie pokazuje, że użytkownikowi się nie spodobała. Dzięki powiązaniu z całym procesem ten sam sygnał umożliwia przejrzenie pobranych materiałów, narzędzi, które zostały użyte, modeli, które wzięły udział, oraz miejsca, w którym zmienił się stan.

Gdy zostanie zidentyfikowany rzeczywisty błąd, ten proces produkcji zachowuje swoją wartość nawet po incydencie, ponieważ może stać się przykładem do oceny, który chroni przed powtórzeniem problemu po przyszłych zmianach w zapytaniach, modelach lub procesach pracy. To o wiele lepsze niż poprawianie błędnych odpowiedzi pojedynczo i liczenie na to, że nic innego się nie zepsuje.

Przestań zaczynać od końcowego zapytania

Prawdopodobnie największą zmianą w debugowaniu systemów AI jest właśnie ta. W prostym aplikacji opartej na LLM, która podaje błędną odpowiedź, analiza promptu i odpowiedzi jest rozsądna, ponieważ mało gdzie jeszcze może kryć się problem. Gdy systemy stają się bardziej złożone, taka praktyka przynosi coraz mniejsze efekty. Wyobraźmy sobie łańcuch przetwarzania składający się z kilku modeli, narzędzi do wyszukiwania informacji, zewnętrznych API, routerów oraz pętli weryfikacji: ostatni prompt może po prostu być miejscem, w którym wcześniejszy błąd w końcu się ujawnił.

RAG już dało to do zrozumienia. Gdy mechanizm pobierania danych umieści w oknie kontekstowym niewłaściwy dokument, większy model generatywny nie będzie mógł tego naprawić, więc trzeba wrócić i poprawić proces pobierania danych. Agenci postępują według tej samej logiki, ale z dodatkowymi ograniczeniami. Czy pobieranie danych przebiega dobrze? Sprawdź, jaki jest wynik. I to też w porządku? Spójrz na następną decyzję. Czy wybrano odpowiedni narzędzie? Przyjrzyj się argumentom i wynikowi. Czy stan nadal jest prawidłowy? Kontynuuj, aż natrafisz na pierwszy moment, w którym sytuacja odbiega od twoich oczekiwań.

Na papierze brzmi to prosto, ale ludzie o tym zapominają, ponieważ ostateczna odpowiedź jest tym, co mają przed sobą, i zazwyczaj jest to najłatwiejszy obiekt do obwiniania.

Obserwowalność całego procesu

Agenci stają się coraz bardziej złożeni. MCP udostępnia im więcej narzędzi, projekty wieloagentowe wprowadzają delegowanie zadań i przenoszenie odpowiedzialności, routery wybierają modele w czasie rzeczywistym, a długotrwałe procesy pracy zapewniają trwały stan, możliwość ponawiania prób oraz kontynuacji pracy. Zatwierdzenie przez człowieka może nastąpić w trakcie wykonywania zadania, a agenci działające w przeglądarce lub na komputerze mogą modyfikować systemy daleko poza ramami czatu. Każdy z tych elementów sprawia, że agenci stają się bardziej zdolni, ale jednocześnie zwiększa ryzyko błędów, podczas gdy każdy komponent zgłasza sukces.

Dlatego też możliwości obserwacji muszą wykraczać poza metryki modeli językowych. Ważna jest opóźniona reakcja, liczba tokenów, błędy oraz koszty, a panel sterowania powinien z pewnością ostrzegać, gdy agent wchodzi w błędny cykl i zużywa kredyty API o 2 w nocy. Mimo to te dane przede wszystkim pokazują, czy system działa. Agent wieloetapowy potrzebuje również sposobu na potwierdzenie, że to, co przez niego przechodzi, nadal odpowiada zadaniu użytkownika.

W praktyce oznacza to śledzenie początkowego zamiaru, kluczowych ograniczeń, narzędzi i modeli, które faktycznie zostały użyte, stanu przekazywanego między poszczególnymi krokami oraz ostatecznego rezultatu. Gdy wynik jest błędny, powinno być możliwe cofnięcie się do pierwszego momentu, w którym stan odbiegł od rzeczywistości. Dzięki tej umiejętności nieudana próba staje się zwykłym problemem inżynieryjnym, który można zbadać, odtworzyć i przetestować. Bez niej patrzy się na ostateczną odpowiedź i zgaduje, który element systemu zawiodł wcześniej.