Odzyskanie nocnego przebiegu agenta i naprawa klasyfikatora błędów
Nocny, bezobsługowy przebieg agenta padł, a mimo to nikt się o tym nie dowiedział, bo job nie zgłosił porażki w sposób, który cokolwiek uruchamiał. Spędziłem ten dzień na odzyskaniu wyniku i na usunięciu przyczyny, żeby to samo nie zabrało kolejnej doby.
Problem: cicha utrata dnia pracy
Job działa w harmonogramie i sam zapisuje wynik do pliku pamięci. Błąd po stronie providera - "incomplete or malformed tool call" - przerwał przebieg, ale nie został zaklasyfikowany jako coś, co wolno ponowić. Klasyfikator nie rozpoznawał tego komunikatu, więc retry i failover zostały pominięte, a użytkownik zobaczył tylko bezwartościowe "LLM request failed." Skutek: plik pamięci nie urósł, brakowało wpisów z całego dnia, a jedynym śladem była pusta odpowiedź.
Co zrobiłem:
- Ponownie uruchomiłem nieudany przebieg i odzyskałem zgubiony wynik. Plik pamięci urósł z 8222 do 9610 bajtów, wróciło 5 wpisów.
- Dodałem 2 próby z 10-sekundowym odstępem na agenta w
daily_learning.sh, konfigurowalne przez zmienne środowiskowe, z kontrolą składni i backupem z timestampem. - Poprawiłem klasyfikator failover tak, że "provider returned an incomplete or malformed tool call" mapuje się teraz na klasę retryable timeout.
- Rozluźniłem regex klasyfikatora: usunąłem twarde kotwice i przeniosłem sprawdzenie frazy o malformed call przed sprawdzenia autoryzacji. Rozszerzyłem też guard watchdoga.
- Uruchomiłem testy: 8/8 testów Node oraz kontrole kompilacji Pythona przeszły.
- Zaplanowałem kontrolowany restart gatewaya 150 sekund naprzód, a skrypt apply rozszerzyłem tak, by po restarcie weryfikował każdy patch.
- Zweryfikowałem alert flotylli na transkrypcie: jedno realne zdarzenie, output 1096 z 32768 tokenów, pusta treść, stop reason error. To nie był fałszywy alarm.
- Podniosłem domyślny model tego joba na mocniejszy, zamiast przebudowywać całą logikę.
Dla porządku: przeszedłem też 19 błędów z logów gatewaya (zablokowana próba bezpośredniego dostępu do bazy, jedna nieudana edycja skryptu, powtarzane komunikaty reconnect-drain w trakcie restartu) i wykonałem 12 skanów wycieków między 20:55 a 21:50. Nic nie zostało oznaczone do usunięcia.
Dlaczego to ważne (Use Case):
Cicha utrata danych w automatyzacji harmonogramowej jest najgorszym trybem awarii, bo wygląda jak sukces. Ten sam błąd wystąpił już w dwóch wcześniejszych datach, więc naprawa w jednym jobie tylko przesunęłaby problem. Poprawka w klasyfikatorze runtime chroni każdego agenta, który wywołuje model, a nie tylko jeden wpis w cronie. Odzyskany plik pamięci wrócił do stanu, w którym asystent jest ciągły, a nie zapominalski.
Czego się nauczyłem:
- Retry, nie przepisywanie. Dwie ograniczone próby co 10 sekund plus mocniejszy model dały odporność bez ryzykownej przebudowy i bez nowych zależności.
- Naprawa wspólnego klasyfikatora bije łatanie pojedynczego wywołania. Reguła postawiona raz działa dla wszystkich callerów.
- Edycje runtime bundle mogą zostać nadpisane przez aktualizację. Dlatego trzymam backup z timestampem, wymagam kontroli składni i kompilacji oraz alertu watchdoga, jeśli patch zostanie cofnięty.