6 min čítania
Anatómia agentskej flotily
Najdrahšou lžou AI nástrojov je demo: dnu ide jeden prompt, von vyjde jedna dokonalá odpoveď. Skutočná produkčná práca takto nefunguje.
To, čo funguje, pripomína skôr malú firmu. Plánovač si prečíta úlohu a rozbije ju na zoznam práce. Builderi vlastnia každý svoj kúsok a nič viac. Revieweri posudzujú kód, ktorý nikdy nepísali. Testeri dostanú do kontextu špecifikáciu a diff, a ani slovo o tom, čo kto zamýšľal. Nikto z nich nie je múdrejší než model pod kapotou; všetci sú ten istý model. Rozdielne správanie z nich robí štruktúra, a práve štruktúra je tá vyinžinierovaná časť.
Prečo vôbec flotila
Jedna dlhá konverzácia s modelom degraduje predvídateľne. Kontext sa plní vlastným výstupom modelu a ten sa začne opierať o svoje skoršie odpovede namiesto kódu. Skoré chyby sa stávajú nosnými.
Rozdelenie práce kupuje to isté, čo kupuje v ľudskom tíme. Reviewer, ktorý nikdy nevidel builderove úvahy, nemôže zdediť jeho slepé miesta. Čerstvý kontext je pointa.
Takto vyzerá jedna slučka, ktorú púšťam. Pipeline na bugy, ktorá dotiahne tiket od spustenia až po skonvergovaný pull request bez ďalších promptov:
Každé rozvetvenie na tom obrázku je pomenovaná bariéra a brána, ktorá zlyhá, buď skúsi znova v rámci limitu, alebo zastaví beh s reportom. Nič neprejde mávnutím.
Harness
Agenti nemajú surový prístup k ničomu. Každé volanie nástroja prechádza cez hooky: malé deterministické skripty, ktoré bežia pred volaním aj po ňom a vedia ho zablokovať. Agent, ktorý chce spustiť shellový príkaz, podáva žiadosť, nevykonáva akciu. Databázová linka je najprísnejší príklad. Samotné pripojenie je read-only a hook navyše odmietne všetko, čo sa parsuje ako mutácia, v každom režime oprávnení; ani beh, ktorému je výslovne dovolené preskakovať potvrdenia, nedokáže zapisovať. Prompt je návrh. Hook je fakt.
Orchestrácia sa riadi tým istým pravidlom. Pipeline vyššie je kód. Model vypĺňa listy stromu:
assert(database.isReadOnly);
await isolateWorktree(`fix/${bug.id}`);
const prior = await memory.recall(bug);
const [brief, sites, history] = await parallel([
readTicket(bug),
locateCode(bug),
priorArt(bug),
]);
const repro = await reproduce(brief, sites);
if (!repro.ok) return report("NOT REPRODUCED");
const candidates = hypotheses(prior, brief, sites, history);
const verdicts = await parallel(candidates.map(selfDisprove));
const cause = pickSurvivor(verdicts);
if (!cause) return report("NO SURVIVING HYPOTHESIS");
const test = await writeFailingTest(repro);
assert(test.failsBeforeFix);
await parallel([fixFrontend(cause), fixBackend(cause), bootAppForSmoke()]);
const checks = await parallel([runScopedTests(cause), runSmoke(repro)]);
assert(checks.every((check) => check.green));
const commits = commitLogically();
const pr = await openPullRequest(push(commits));
await convergeReview(pr, { maxRounds: 3 });
return report({ cause, evidence: test, commits, pr });Riadenie toku je deterministické a stav behu žije v ledgeri, v súbore prepisovanom na každej hranici fázy. Beh na jednom bugu trvá aj hodinu, väčšinou čakaním na buildy, takže prežije sessiony. Keď session zomrie, beh pokračuje od poslednej brány, ktorou prešiel, pretože štruktúra nikdy nebola v kontextovom okne. Bola v kóde.
Desať aktívnych bugov znamená desať izolovaných worktree rozpracovaných paralelne. A keď sa pokus nepodarí, upratovanie znamená zmazať priečinok, nie vymotávať zlé commity zo zdieľaného checkoutu.
Čo vedia
Agenti sú presne takí bystrí, ako to, čo si vedia vyhľadať, takže recall je prvá a najlacnejšia fáza pipeline. Kódové bázy a dokumenty sú rozsekané do embeddingov a otázka „kde je tá vec, ktorá sa správa takto" sa stáva vyhľadaním namiesto grep safari. Rozhodnutia žijú v znalostnom grafe. Systémy, obmedzenia a trade-offy sú uzly; nahradené čím, závisí od, pokazilo sa lebo sú hrany. Embeddingy odpovedajú na to, kde veci sú. Graf na to, prečo sú také, aké sú.
Každý dokončený beh zapíše späť, čo sa naučil: príčinu, pascu, gotchu. To je rozdiel medzi flotilou, ktorá je s každým bugom múdrejšia, a flotilou, ktorá tú istú príčinu objavuje dvakrát.
Čo sa kazí
Ponechaná sama na seba flotila zlyháva sebavedomo. Zistenia, ktoré znejú vierohodne a sú nesprávne. Revieweri, ktorí odmávajú čokoľvek sformulované s autoritou. Riešením nikdy nebol lepší prompt. Je ním adverzariálna štruktúra: hypotézy s inštrukciou vyvrátiť samé seba, verifieri s inštrukciou vyvracať. Záver prežije len vtedy, keď ho skeptici nedokážu zabiť. Tento jeden vzor mi zabil viac falošných poplachov než akékoľvek znenie „buď opatrný a dôkladný".
A niektoré akcie flotila z princípu vykonať nemôže, nech je akokoľvek presvedčená: aplikovať databázovú migráciu, mutovať dáta, dokončiť pull request, zavrieť tiket. Všetko pripraví, reportuje a čaká. Nebezpečný posledný krok ostáva ľudský, pretože keď sa migrácia pokazí, zodpovedá za ňu človek. Flotila násobí úsudok, ktorý dostane, vrátane zlých rozhodnutí.
Každý nástroj pod touto pipeline raz niečo nahradí. Jej tvar (strážené akcie, deterministická štruktúra, adverzariálne review, pamäť, ktorá sa skladá) ostane. Presne túto zručnosť éra agentov odmeňuje: zaobchádzať s modelmi ako s inžinierskym materiálom.
Zdieľať článok