PABLO.ENGINEERING
// WRÓĆ DO WSZYSTKICH WPISÓW
// 4 min

SkillEvaluator i deterministyczny Kanban: jak sprawdzamy umiejętności agentów w AOC

#ai-agents#aoc#evaluation#kanban#typescript#architecture

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 isAlreadyResolved stwierdza: „To zadanie już jest zatwierdzone, nie rób nic i zwróć sukces”.
  • Pewność wyniku: Funkcja isPostConditionSatisfied upewnia 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

  1. Testy przed zaufaniem: W inżynierii systemów agentowych deklaracje modelu są bezwartościowe. Prawdziwe zaufanie buduje się na twardych wynikach benchmarków.
  2. 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.
  3. 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.