// 4 min
SkillEvaluator i deterministyczny Kanban: jak sprawdzamy umiejętności agentów w AOC
W poprzednich wpisach pokazywałem, jak agenci w Agent Operations Center (AOC) wykonują zleconą pracę. Dziś poruszymy trudniejszy temat: skąd system wie, że dany bot faktycznie nadaje się do wykonania zadania, i co się dzieje, gdy użytkownik przez pomyłkę kliknie przycisk decyzyjny dwa razy z rzędu.
Problem: Wiara agentom na słowo i chaos podwójnego kliknięcia
W codziennej pracy systemu zderzyliśmy się z dwoma wyzwaniami:
- Deklaracje bez pokrycia: Bot frontendowy twierdzi w swoim opisie systemowym: „Świetnie piszę komponenty React i refaktoryzuję stan aplikacji”. Tyle że to tylko tekst wygenerowany przez człowieka. Gdy przychodziło trudniejsze zadanie, bot gubił się na skomplikowanych typach. Brakowało obiektywnego sprawdzianu umiejętności przed powierzeniem mu realnej pracy.
- Problem podwójnego kliknięcia (Race Condition): Operator przegląda tablicę Kanban na telefonie i klika przycisk „Zatwierdź” przy zablokowanym zadaniu. Jeśli zasięg sieci na sekundę przygaśnie i użytkownik kliknie przycisk nerwowo drugi raz (lub przeglądarka ponowi zapytanie), serwer przetwarzał żądanie dwukrotnie. Wcześniej kończyło się to błędem lub niespójnym statusem na tablicy.
Co zrobiłem: Egzamin z umiejętności i kuloodporne reguły decyzyjne
1. SkillEvaluator: praktyczny egzamin zamiast opinii
Zainspirowany podejściem NVIDIA SkillEvaluator wdrożyłem w AOC zamknięty cykl: definicja umiejętności → zestaw zadań testowych → benchmark → obiektywny wynik punktowy.
- Katalog umiejętności (
lib/skills-registry.ts): Każda umiejętność (np. pisanie formularzy, zapytania SQL, audyt bezpieczeństwa) ma jasną definicję i przypisany zestaw automatycznych testów sprawdzających. - Walidacja Zod (
lib/schemas.ts): Wszystkie wyniki testów i deklaracje przechodzą przez twarde schematy. Żaden wynik nie jest przyjmowany na wiarę. - Panel operatora (SkillsPanel): Zanim przydzielę zadanie agentowi, widzę na wykresie jego realną skuteczność w danej dziedzinie (np. 95/100 w benchmarku TypeScript).
2. Idempotentne reguły w Kanbanie (lib/kanban-policy.ts)
Aby wyeliminować problem podwójnego kliknięcia, zamieniłem luźne endpointy API na polityki decyzyjne jako jawne obiekty:
export const DECISION_POLICIES: Record<DecisionAction, DecisionPolicy> = {
approve: {
// 1. Z jakich stanów ta akcja jest w ogóle dozwolona:
allowedFrom: ["blocked", "scheduled"],
expected: null,
description: "Odblokowanie zadania i przekazanie do dalszej pracy",
// 2. Warunek idempotencji: jeśli zadanie już jest odblokowane,
// drugie kliknięcie traktujemy jako sukces bez wywoływania błędu:
isAlreadyResolved: (status) =>
status !== "blocked" && status !== "archived" && status !== "scheduled",
// 3. Weryfikacja po wykonaniu: czy stan faktycznie zmienił się tak, jak zakładaliśmy:
isPostConditionSatisfied: (status) => status !== "blocked" && status !== "archived",
},
reject: {
allowedFrom: ["blocked", "ready", "running"],
expected: "blocked",
},
};
Co to zmienia w praktyce?
- Odporność na duplikaty: Jeśli zapytanie przyjdzie dwa razy, funkcja
isAlreadyResolvedstwierdza: „To zadanie już jest zatwierdzone, nie rób nic i zwróć sukces”. - Pewność wyniku: Funkcja
isPostConditionSatisfiedupewnia się po transakcji, że baza danych faktycznie odzwierciedla zamierzoną decyzję. - Spójność wielu tablic: Gdy to samo zadanie wyświetla się na tablicy głównej i tablicy projektu, obie instancje korzystają z tej samej reguły i aktualizują się bezkolizyjnie.
Dlaczego to ważne (Use Case)
Dlaczego warto było poświęcić czas na te mechanizmy?
- Bezpieczna delegacja zadań: Operator nie ryzykuje, że przydzieli trudne zadanie refaktoryzacji modelowi, który nie przeszedł benchmarków dla danego frameworka.
- Spokój użytkownika: Interfejs staje się niewrażliwy na niestabilne łącza internetowe i wielokrotne klikanie. Nie musisz się bać, że przypadkowe kliknięcie popsuje porządek w projektach.
- Twarda specyfikacja w testach: Cała logika decyzyjna jest czystą funkcją matematyczną bez zewnętrznych zależności, co pozwoliło pokryć ją w 100% błyskawicznymi testami jednostkowymi.
Czego się nauczyłem
- Testy przed zaufaniem: W inżynierii systemów agentowych deklaracje modelu są bezwartościowe. Prawdziwe zaufanie buduje się na twardych wynikach benchmarków.
- Idempotencja to funkcja użyteczności (UX), a nie tylko backendu: Dobry system nie karze użytkownika komunikatem błędu za to, że kliknął przycisk dwa razy na wolnym łączu.
- Jawne obiekty reguł zamiast if-ologii: Zdefiniowanie przejść stanów w jednym przejrzystym słowniku sprawiło, że dodanie nowej akcji decyzyjnej to zaledwie kilka linijek i gotowe testy.