Co logować w pętli agenta

przez Łukasz | sie 24, 2026

W drugim artykule padło, że pętla powinna zwracać nie samą odpowiedź, lecz odpowiedź razem z powodem zakończenia, liczbą kroków i zużytym budżetem. To był zalążek. Tu jest pełna wersja.

Typowy dziennik agenta zapisuje pytanie i odpowiedź. To akurat najmniej użyteczna część — odpowiedź widzi użytkownik, a pytanie i tak znasz. Wartość diagnostyczna leży w tym, co działo się pomiędzy.

Ślad przebiegu

Jeden rekord na całe zadanie, z polami, które pozwalają odpowiedzieć na pytanie „co się właściwie stało” bez zaglądania w szczegóły.

Identyfikator przebiegu. Co go wyzwoliło — użytkownik, zdarzenie, cykl. Model i jego wersja. Powód zakończenia — czy model odpowiedział, czy wyczerpał limit, czy wykryto zapętlenie. Liczba kroków. Tokeny wejściowe i wyjściowe osobno, plus koszt. Czas trwania. Liczba wykonanych operacji nieodwracalnych.

Zapis wersji modelu wygląda na formalność, a jest jedynym sposobem powiązania spadku jakości z aktualizacją po stronie dostawcy. Bez niego cicha regresja jest niewykrywalna — masz gorsze wyniki i żadnego kandydata na przyczynę.

Ślad kroku

Jeden rekord na obrót pętli, dowiązany do przebiegu.

Numer kroku. Wywołane narzędzie i argumenty. Wynik — w skrócie albo jako uchwyt, zgodnie z tym, co ustaliliśmy w artykule o stanie. Czas wykonania. Tokeny tego obrotu. Liczba ponowień. Odrzucenia wraz z powodem.

To ostatnie jest najczęściej pomijane i najbardziej wartościowe. Dzienniki zapisują, co się wykonało; odrzucenia znikają, bo formalnie nic się nie stało. A rosnąca liczba odrzuceń tego samego typu oznacza jedną z trzech rzeczy: myląca definicja narzędzia, zbyt ostra walidacja albo ktoś próbuje czegoś, czego nie powinien.

Czego nie logować

Log jest miejscem wycieku równie realnym jak kontekst modelu — z tą różnicą, że zostaje na dłużej i bywa dostępny szerszemu gronu.

Nie zapisuj pełnych kontekstów z danymi osobowymi, poświadczeń, treści dokumentów objętych poufnością ani surowych śladów wyjątków ze ścieżkami i nazwami hostów.

Zasada praktyczna: redakcja przy zapisie, nie przy odczycie. Jeśli dane wrażliwe trafiają do dziennika i są ukrywane dopiero w interfejsie, to one tam są — a założenie, że nikt nie zajrzy do surowych plików, nie jest zabezpieczeniem.

Wzorzec z artykułu siódmego działa tu bez zmian: w logu zostaje uchwyt, wartość zostaje w miejscu, do którego dostęp jest kontrolowany osobno.

Pięć sygnałów

Same dane niczego nie mówią. Poniższe pięć wykresów wychwytuje praktycznie wszystkie wykolejenia opisane w tej serii.

Rozkład liczby kroków. Nie średnia — rozkład. Wykolejenia siedzą w prawym ogonie: przebiegi, które zamiast trzech kroków wzięły dwanaście. Średnia je ukrywa.

Udział zakończeń wymuszonych. Ile przebiegów kończy się limitem albo wykrytym zapętleniem zamiast odpowiedzią modelu. To jest miara zdrowia agenta i najszybszy wskaźnik, że coś się zmieniło.

Koszt na przebieg w percentylach. Znowu nie średnia. Interesuje cię, ile kosztuje najdroższe pięć procent przebiegów, bo to one robią rachunek.

Odrzucenia według typu. Sygnał opisany wyżej.

Ponowienia według narzędzia. Wskazuje niestabilne zależności, zanim zaczną psuć wyniki. Warto pamiętać, że ponowienia bywają rozliczane, a w typowym logu nie zostawiają śladu.

Jeden identyfikator przez wszystkie warstwy

Identyfikator przebiegu powinien przechodzić dalej niż twój kod: do wywołań API, do systemów docelowych, do klucza idempotencji.

Dzięki temu odpowiedź na pytanie „skąd wziął się ten mail w skrzynce klienta” jest do znalezienia w jednym zapytaniu, a nie przez zestawianie znaczników czasu. Przy operacjach nieodwracalnych to nie wygoda, tylko warunek prowadzenia jakiegokolwiek dochodzenia.

Log jako materiał do ewaluacji

To jest zwrot, dla którego warto zbierać ślady nawet wtedy, gdy nic się nie psuje.

Przebiegi z produkcji są najlepszym możliwym zestawem testowym. Realne pytania, realne dane, realne przypadki graniczne — czyli dokładnie to, czego nie da się wymyślić przy biurku i czego nie dostarczy żaden publiczny benchmark.

Wystarczy wybrać kilkadziesiąt przebiegów, dopisać oczekiwany wynik i masz zestaw, którego szukaliśmy w Anatomii LLM przy okazji kontaminacji benchmarków: własny, niepublikowany, mierzący dokładnie twoje zadanie. Ten sam materiał zasila ewaluację trajektorii — bo ślad kroków to zapis drogi, nie tylko wyniku.

Jak to sprawdzić u siebie

Prosty zbieracz śladu, który da się nałożyć na pętlę z pierwszego artykułu.

python
import json, time, uuid, statistics

class Slad:
    def __init__(self, wyzwalacz, model):
        self.rekord = {
            "id": str(uuid.uuid4())[:8], "wyzwalacz": wyzwalacz,
            "model": model, "start": time.time(), "kroki": [],
            "tokeny_we": 0, "tokeny_wy": 0,
            "nieodwracalne": 0, "odrzucenia": 0, "powod": None,
        }

    def krok(self, nr, narzedzie, argumenty, tokeny_we, tokeny_wy,
             ponowienia=0, odrzucenie=None, skutek=False):
        self.rekord["kroki"].append({
            "nr": nr, "narzedzie": narzedzie,
            "argumenty": redaguj(argumenty),
            "tokeny_we": tokeny_we, "ponowienia": ponowienia,
            "odrzucenie": odrzucenie,
        })
        self.rekord["tokeny_we"] += tokeny_we
        self.rekord["tokeny_wy"] += tokeny_wy
        if odrzucenie: self.rekord["odrzucenia"] += 1
        if skutek and not odrzucenie: self.rekord["nieodwracalne"] += 1

    def zamknij(self, powod):
        self.rekord["powod"] = powod
        self.rekord["czas_s"] = round(time.time() - self.rekord["start"], 2)
        self.rekord["liczba_krokow"] = len(self.rekord["kroki"])
        return self.rekord

WRAZLIWE = {"adres", "email", "pesel", "karta", "token"}

def redaguj(d):
    return {k: ("***" if k.lower() in WRAZLIWE else v) for k, v in d.items()}

# --- przykład użycia ---
s = Slad("uzytkownik", "gpt-4o-mini@2026-05")
s.krok(1, "status_zamowienia", {"numer_zamowienia": "ZAM-9999"},
       1200, 40, odrzucenie="zamówienie nie istnieje")
s.krok(2, "szukaj_zamowien", {"numer_klienta": "KL-0012"}, 1800, 60, ponowienia=1)
s.krok(3, "wyslij_mail", {"adres": "kontakt@firma.pl"}, 2400, 80, skutek=True)
print(json.dumps(s.zamknij("model odpowiedział"), ensure_ascii=False, indent=2))

Zwróć uwagę na trzy rzeczy. Argumenty przechodzą przez redaguj przy zapisie — adres nigdy nie trafia do rekordu. Odrzucenie z pierwszego kroku jest zapisane jako pełnoprawne zdarzenie, nie pominięte. A tokeny wejściowe rosną z każdym krokiem, co widać w rekordzie gołym okiem.

Ćwiczenie: zbierz ślady z dwudziestu przebiegów i policz dwie rzeczy — medianę oraz maksimum liczby kroków, a potem koszt w percentylu dziewięćdziesiątym. Jeśli maksimum jest trzykrotnie wyższe od mediany, masz zapętlenia. Jeśli percentyl dziewięćdziesiąty jest wielokrotnie wyższy od mediany kosztu, masz kilka przebiegów robiących cały rachunek.

Drugie ćwiczenie: weź dziesięć śladów z realnych przebiegów, dopisz do każdego oczekiwany wynik i zapisz jako plik. Właśnie zbudowałeś zestaw testowy, którym sprawdzisz następną zmianę modelu.

Koniec serii

Dziesięć artykułów o warstwie, która nie jest ani modelem, ani promptem — o kodzie między jednym wywołaniem a drugim.

Wracając do zdania, od którego zaczynaliśmy: model niczego nie wykonuje, wykonuje pętla. Wszystko, co przez tę serię przewijało się jako problem — koszt kumulacyjny, zapętlenie, przeciążenie narzędziami, awarie, uprawnienia, wstrzyknięcia — mieszka po tej samej stronie granicy. I dlatego wszystko da się tam rozwiązać.

Jeśli interesuje cię, co jest pod tą warstwą — dlaczego model halucynuje, skąd bierze się koszt kontekstu, czym różni się model rozumujący — to opisuje Anatomia LLM. Jeśli interesuje cię, z czego agent jest zbudowany jako całość, razem z pamięcią, RAG-iem i wdrożeniem — Anatomia agenta AI.

A jeśli po tej lekturze wydaje ci się, że w twoim przypadku wystarczyłby zwykły skrypt — to prawdopodobnie dobry wniosek i też ma swój tekst: Kiedy nie budować agenta.

Agent kończy, ale zadania nie wykonał

Agent kończy, ale zadania nie wykonał

Objawy Agent odpowiada: „Przygotowałem i wysłałem potwierdzenie do klienta." Potwierdzenie nie zostało wysłane. Albo: „Zaktualizowałem wszystkie rekordy" — zaktualizował trzy z dwunastu. Albo: „Nie znalazłem żadnych zamówień" — bo narzędzie zwróciło błąd, którego nikt...

Agent zrobił coś, o co nikt nie prosił

Agent zrobił coś, o co nikt nie prosił

Objawy Operacja, której nikt nie zlecił. Dane wysłane pod adres, którego nie ma w żadnej konfiguracji. Rekord zmieniony poza zakresem zadania. Odpowiedź, z której wynika, że agent dostał instrukcje od kogoś innego niż ty. Cecha wspólna: technicznie wszystko zadziałało...

Agent zrobił to samo dwa razy

Agent zrobił to samo dwa razy

Objawy Ten syndrom różni się od pozostałych jedną rzeczą: objaw widzi klient, nie ty. Trzy identyczne wiadomości w skrzynce. Dwa zamówienia zamiast jednego. Podwójne obciążenie. Duplikaty rekordów, które ktoś zauważa tydzień później. W twoim dzienniku wszystko wygląda...

Agent gubi wątek w długim zadaniu

Agent gubi wątek w długim zadaniu

Objawy Pierwsze kroki idą wzorowo. Po kilkunastu agent zaczyna się rozjeżdżać. Przestaje przestrzegać reguły z promptu systemowego, której trzymał się na początku. Zmienia format odpowiedzi w połowie zadania. Wraca do czegoś, co już ustalił, i ustala to inaczej....

Agent podaje dane, których nie ma

Agent podaje dane, których nie ma

Objawy Numer zamówienia w idealnym formacie, którego nie ma w bazie. Kwota, której w dokumencie nie ma. Nazwa pola API, które nigdy nie istniało. Cytat z regulaminu, brzmiący dokładnie jak reszta regulaminu i w nim nieobecny. Cecha wspólna wszystkich tych przypadków:...

Działał wczoraj, dziś nie działa

Działał wczoraj, dziś nie działa

Objawy Nic się nie wywala. Nie ma wyjątków, nie ma timeoutów, dziennik wygląda tak samo jak zawsze. Po prostu odpowiedzi są gorsze. Postacie, w jakich to się objawia: Jakość. Agent zaczyna pomijać kroki, które wcześniej wykonywał, albo odpowiada ogólniej. Format....

Agent wybiera złe narzędzie

Agent wybiera złe narzędzie

Objawy Agent odpowiada nie na to pytanie. Pobiera listę zamówień, gdy pytano o jedno konkretne. Odpowiada z pamięci, choć miał sprawdzić w bazie. Albo sięga po właściwe narzędzie i wpisuje w argumenty coś, czego nie da się użyć. Sygnał, który odróżnia ten syndrom od...

Agent kręci się w kółko

Agent kręci się w kółko

Objawy Agent wykonuje kolejne obroty pętli, nie zbliżając się do zakończenia zadania. W dzienniku widać jedną z trzech postaci. Powtórzenie. To samo narzędzie, te same argumenty, raz za razem — czasem dziesiątki razy pod rząd. Oscylacja. Agent wywołuje na przemian dwa...