← Powrót do bloga

Małe, zweryfikowane kroki wygrywają z jednym gigantycznym promptem

Ilustracja zestawiająca jedno przeciążone gigantyczne zadanie z kilkoma małymi zweryfikowanymi krokami

Druga fundamentalna zasada pracy z agentami AI: rozbicie dużego żądania na mniejszą granulację, z weryfikacją po każdym kroku, daje lepsze wyniki niż jeden gigantyczny prompt.

Jeśli próbuje się zrealizować dużą nową funkcję, lepiej podzielić ją na mniejsze zadania, z kilku powodów.

Jedną z najważniejszych rzeczy wartych wspomnienia jest to, jak koszt tworzenia oprogramowania zachowuje się w czasie. W książce Code Complete znajduje się znany wykres pokazujący, o ile droższa staje się naprawa błędu w zależności od tego, w której fazie rozwoju zostanie wychwycony: podczas analizy koszt jest niemal zerowy, ale gdy oprogramowanie jest już produkcyjnie u klienta, koszt jest o rząd wielkości wyższy, a nawet większy. Przy tempie, w jakim AI generuje dziś kod, trzeba być jeszcze ostrożniejszym w projektowaniu architektury z góry — ponieważ refaktoryzacja to dokładnie ta rzecz, z którą AI radzi sobie niezbyt dobrze. Najlepszym podejściem jest trzymanie się standardów opisanych w książkach o czystym kodzie i stosowanie sprawdzonych wzorców dla struktury i logiki biznesowej — książki to jedno z najwyższej jakości źródeł, z których model AI uczył się poprawnych praktyk podczas treningu, więc rozumie je najlepiej. Dla AI ważne jest także utrzymanie kodu podzielonego na wyraźne warstwy, nawet w monolicie — agent znacznie łatwiej odnajduje się wtedy w kodzie.

Wróćmy do tego, jak faktycznie poprawnie dzielić zadania. Powiedzmy, że zadaniem jest zbudowanie nowego formularza satysfakcji klienta. Jakie fazy będą potrzebne?

  1. UI — formularz, jego pola i zdarzenie wysłania.
  2. Logika biznesowa — walidacja formularza, powiązanie zgłoszenia z kontem klienta, priorytet zgłoszenia.
  3. Struktura danych — jak dane wędrują do BE i z powrotem do FE.
  4. BE — ponownie walidacja i logika biznesowa, teraz po stronie backendu.
  5. Warstwa danych — mapowanie ze struktury danych na bazę danych.
  6. Utrwalanie danych oraz odpowiadająca im struktura wracająca z BE do FE.

Dla AI nie ma tak naprawdę znaczenia, od czego się zacznie — liczy się poprawny opis każdego kroku. Dla użytkownika najpraktyczniej jest zacząć albo od bazy danych, albo od frontendu.

To obejmuje wszystkie zadania. Pytanie brzmi teraz: jaka jest różnica między jednym dużym zadaniem a kilkoma mniejszymi?

W przypadku jednego zadania zaletą jest wspólny kontekst (cache) między krokami — agent nigdy nie musi niczego wyszukiwać ponownie. Ale przy większej liczbie tur ta zaleta się odwraca: im dłużej pozostaje się w jednym kontekście, tym więcej tokenów jest ponownie wysyłanych i przetwarzanych w każdej kolejnej turze, więc koszt tury stale rośnie wraz z rozmiarem kontekstu — przy długim zadaniu o wielu turach może to się złożyć na zauważalną kwotę.

Jeśli zamiast tego podzielimy zadania, AI zawsze wykonuje tylko swoją jedną konkretną część, którą na końcu można niezależnie przetestować — wychwytując błędy, zanim w ogóle rozpocznie się praca nad następną częścią. Zużywamy łącznie mniej tokenów, a możliwość niezależnej weryfikacji każdego kroku pozwala wychwycić halucynacje lub odstępstwa od wymagania znacznie wcześniej niż po zakończeniu jednego gigantycznego zadania. Mniejsze zadania nie wymagają też od modelu utrzymywania uwagi na każdym szczególe naraz.

Dlaczego jest to tak ważne dla modeli AI? Mają ograniczoną zdolność utrzymywania priorytetu przy dużej liczbie instrukcji naraz. Jeśli w jednym prompcie napisze się „dodaj nową funkcję, zrefaktoryzuj starą logikę i napraw trzy powiązane błędy", model układa własną kolejność priorytetów — która może nie zgadzać się z naszą. Rezultat: część zadania zostaje wykonana znakomicie, część po macoszemu, a nikt tego nie zauważa, dopóki coś się nie zepsuje na produkcji.

Właśnie dlatego AITM dzieli duże żądania na łańcuchy zadań zamiast pozwalać, by przebiegały jako jedno ciągłe przejście.

Jak to wygląda w praktyce: zwykły chat AI vs. AITM

Zwykły agent AI (chat/copilot w IDE): dostaje się jeden długi prompt, a agent pracuje w jednym ciągłym kontekście. Jeśli w 80% drogi pomyli się w szczególe, nie dowiemy się o tym, dopóki nie przejrzymy całego diffa — w międzyczasie praca nad kolejnymi punktami postępowała na zepsutym fundamencie.

AITM: to samo żądanie jest dzielone w chacie/brainstormingu na osobne, połączone w łańcuch wywołania zadań z zależnościami — zadanie B może wystartować dopiero wtedy, gdy zadanie A przeszło cały pipeline i zostało scalone. Jeśli zadanie A zawiedzie na review lub teście, zadanie B nie startuje na zepsutym fundamencie — czeka. Tymczasem watchdog sam ocenia niepowodzenie zadania A: jeśli potrafi przeanalizować błąd i zaproponować poprawkę, zadanie automatycznie startuje ponownie z promptem opisującym dokładnie ten błąd i proponowaną poprawkę; jeśli błąd jest niejasny lub nie da się go rozwiązać bez decyzji człowieka, zadanie zatrzymuje się i czeka, aż użytkownik zdecyduje, jak ma przebiegać dalej. Ponadto po scaleniu ostatniego zadania w łańcuchu uruchamiany jest krok chain-audit — deterministyczna (nie AI) kontrola końcowa, która ponownie waliduje kontrakty dotknięte przez cały łańcuch.

Różnica widoczna dla użytkownika: przy zwykłym agencie na końcu dostaje się jeden duży, nieprzejrzysty diff. W AITM dostaje się kilka mniejszych, nazwanych, niezależnie sprawdzonych zadań z własną historią — i wiadomo dokładnie, gdzie coś poszło nie tak, jeśli nie poszło zgodnie z planem.