Open-source specifikacija za orkestraciju Codexa: Symphony
Autori: Alex Kotliarskyi, Victor Zhu i Zach Brock
Prije šest mjeseci, dok je naš tim radio na internom alatu za produktivnost, donijeli smo, za to vrijeme, kontroverznu odluku: izgradit ćemo naš repozitorij bez ijednog retka koda koji je napisao čovjek. Svaki redak u našem projektnom repozitoriju morao je generirati Codex.
Kako bi to uspjelo, iz temelja smo redizajnirali naš inženjerski radni proces.Izgradili smo repozitorij prilagođen agentima, znatno uložili u automatizirane testove i zaštitne mehanizme te Codex tretirali kao punopravnog člana tima. To smo putovanje dokumentirali u prethodnoj objavi na blogu o razvoju operativnog okvira za agente.
I uspjelo je, ali tad smo naišli na sljedeće usko grlo: promjenu konteksta.
Kako bismo riješili taj novi problem, izgradili smo sustav koji smo nazvali Symphony. Symphony(otvara se u novom prozoru) je orkestrator agenata koji ploču za upravljanje projektima poput Lineara pretvara u upravljački centar za agente za programiranje.Svaki otvoreni zadatak dobiva agenta, agenti rade kontinuirano, a ljudi pregledavaju rezultate.
Ova objava objašnjava kako smo stvorili Symphony – što je u nekim timovima rezultiralo povećanjem broja spojenih pull requestova za 500 % – i kako ga upotrijebiti da vlastiti alat za praćenje zadataka pretvorite u stalno aktivan orkestrator agenata.
Ograničenja interaktivnih agenata za kodiranje
Iako ih je sve lakše upotrebljavati, agenti za kodiranje – bilo da im se pristupa putem web-aplikacija ili CLI-ja – i dalje su interaktivni alati.
Kako se opseg rada agenata u OpenAI-ju povećavao, naišli smo na novu vrstu opterećenja. Svaki bi inženjer otvorio nekoliko Codex sesija, dodijelio zadatke, pregledao rezultate, usmjeravao agenta i ponavljao postupak. U praksi je većina ljudi mogla upravljati s tri do pet sesija istodobno prije nego što bi stalno prebacivanje između zadataka postalo naporno. Nakon toga produktivnost je padala. Zaboravljali bismo koja sesija radi na čemu, skakali između terminala kako bismo agente vratili na pravi put i otklanjali probleme dugotrajnih zadataka koji su zapeli na pola puta.
Agenti su bili brzi, ali imali smo usko grlo u sustavu: ljudsku pažnju.U praksi smo izgradili tim iznimno sposobnih mlađih inženjera, a zatim ljudskim inženjerima zadali da njima mikroupravljaju. To nije bilo održivo u većem opsegu.
Promjena perspektive
Shvatili smo da optimiziramo pogrešnu stvar. Naš sustav organizirali smo oko sesija programiranja i spojenih PR-ova, iako su PR-ovi i sesije zapravo samo sredstvo do cilja. Softverski radni procesi uglavnom su organizirani oko isporučivih rezultata: zadataka, aktivnosti, tiketa i etapa.
Zato smo se zapitali što bi se dogodilo kad bismo prestali izravno nadzirati agente i umjesto toga im dopustili da sami preuzimaju posao iz našeg praćenja zadataka.
Ta je ideja postala Symphony, pisana specifikacija koja funkcionira kao nadzornik za orkestraciju agentskog rada.
Pretvaranje našeg alata za praćenje zadataka u orkestratora agenata
Symphony je započeo jednostavnim konceptom: svaki otvoreni zadatak agent treba preuzeti i dovršiti. Umjesto upravljanja Codex sesijama u više kartica, naš alat za praćenje zadataka pretvorili smo u upravljačko središte.
U ovom postavu svaki otvoreni Linear zadatak povezan je s namjenskim radnim prostorom agenta. Symphony neprestano prati ploču zadataka i osigurava da svaki aktivni zadatak ima agenta koji radi sve dok ne bude dovršen. Ako se agent sruši ili zaglavi, Symphony ga ponovno pokreće. Ako se pojavi novi zadatak, Symphony ga preuzima i počinje organizirati rad.
Naš radni proces temeljili smo na statusima zadataka, pri čemu je Linear služio kao sustav za upravljanje stanjima.
U praksi Symphony odvaja rad od sesija i pull requestova. Neki zadaci rezultiraju s više PR-ova u različitim repozitorijima, dok su drugi isključivo istraga ili analiza koja nikada ne dotiče bazu koda.
Kad se rad apstrahira na ovaj način, tiketi mogu predstavljati mnogo veće jedinice rada.
Symphony redovito upotrebljavamo za orkestraciju složenih značajki i migracija infrastrukture. Primjerice, možemo otvoriti zadatak kojim tražimo od agenta da analizira bazu koda, Slack ili Notion i izradi plan implementacije. Kad smo zadovoljni planom, agent generira stablo zadataka, razlažući rad u faze i definirajući ovisnosti među zadacima.
Agenti počinju raditi samo na zadacima koji nisu blokirani, pa se izvođenje za ovaj DAG (slijed koraka izvršavanja) odvija prirodno i optimalno paralelno. U primjeru u nastavku označili smo React nadogradnju kao blokiranu migracijom na Vite. Očekivano, agenti su počeli nadograđivati React tek nakon što je migracija na Vite bila dovršena.
Agenti također mogu sami otvarati nove zadatke. Tijekom implementacije ili pregleda često primijete poboljšanja koja izlaze iz okvira trenutačnog zadatka: problem s performansama, priliku za refaktoriranje ili bolju arhitekturu. Kad se to dogodi, jednostavno otvore novi issue koji kasnije možemo procijeniti i rasporediti – mnoge od tih naknadnih zadataka također preuzmu agenti. Dok nadgledamo taj proces, agenti ostaju organizirani i održavaju radni zamah.
Ovakav način rada dramatično smanjuje kognitivni trošak pokretanja nejasno definiranog rada. Ako agent nešto pogrešno napravi, to je i dalje korisna informacija, a naš je trošak gotovo nula. Vrlo jednostavno možemo otvoriti tikete kako bi agent izrađivao prototipe i istraživao te odbaciti sva rješenja koja nam se ne sviđaju.
Budući da orkestrator radi na devboxovima i nikad ne spava, zadatke možemo dodavati s bilo kojeg mjesta i znati da će ih agent preuzeti. Primjerice, jedan inženjer u našem timu napravio je tri značajne promjene putem aplikacije Linear na svom telefonu, iz udobne kolibe s lošim Wi-Fijem.
Povećano istraživanje zahvaljujući ovakvom načinu rada
Kada smo promatrali učinke rada sa Symphonyjem, najočitija promjena bila je količina rezultata. U nekim timovima u OpenAI-ju vidjeli smo da se broj spojenih PR-ova povećao 6 puta u prva tri tjedna. Izvan OpenAI-ja, osnivač Lineara Karri Saarinen istaknuo je porast broja stvorenih radnih prostora(otvara se u novom prozoru) nakon što smo objavili Symphony. Međutim, dublja promjena leži u tome kako timovi razmišljaju o radu.
Kad naši inženjeri više ne troše vrijeme na nadzor Codex sesija, ekonomika promjena koda potpuno se mijenja. Percipirani trošak svake promjene pada jer više ne ulažemo ljudski trud u samo provođenje implementacije.
To je promijenilo naše ponašanje. Postalo je jednostavno pokretati spekulativne zadatke u Symphonyju. Isprobajte ideju, istražite refaktoriranje, testirajte hipotezu i zadržite samo rezultate koji izgledaju obećavajuće.
To također proširuje krug ljudi koji mogu pokretati rad. Naš produktni menadžer i dizajner sada mogu izravno otvarati zahtjeve za značajke u Symphonyju. Ne moraju preuzimati repozitorij niti upravljati Codex sesijom. Opišu značajku i dobiju paket za pregled koji uključuje video prikaz značajke u radu unutar stvarnog proizvoda..
Symphony se također ističe u velikim monorepozitorijima (poput onog koji imamo u OpenAI-ju) gdje je završni korak spajanja PR-a spor i osjetljiv. Sustav prati CI, po potrebi radi rebase, rješava konflikte, ponovno pokreće nestabilne provjere i općenito provodi promjene kroz cijeli proces. Kad tiket dosegne Merging, imamo veliko povjerenje da će promjena ući u glavnu granu bez ljudskog nadzora.
Napredak donosi nove, drukčije probleme
Rad na ovoj razini uključuje kompromise. Kada smo s interaktivnog usmjeravanja agenata prešli na dodjeljivanje rada na razini tiketa, izgubili smo mogućnost da ih stalno usmjeravamo tijekom rada i po potrebi korigiramo smjer. Ponekad bi agent proizveo nešto što je potpuno promašilo cilj. To je bilo korisno – ti su neuspjesi otkrili praznine u sustavu i pomogli nam da ga učinimo robusnijim.
Umjesto da ručno krpamo rezultat, dodali smo zaštitne mehanizme i vještine kako bi agenti sljedeći put uspjeli. S vremenom nas je to navelo da našem operativnom okviru dodamo nove mogućnosti, poput pokretanja end-to-end testova, upravljanja aplikacijom putem Chrome DevToolsa i provođenja QA smoke testova. Znatno smo unaprijedili dokumentaciju i pojasnili kako izgleda dobar rezultat.
Ne odgovara svaki zadatak stilu rada Symphonyja. Neki problemi i dalje zahtijevaju inženjere koji rade izravno s interaktivnim Codex sesijama, posebno nejasni problemi ili rad koji zahtijeva snažnu prosudbu i stručnost. U praksi su to obično najzanimljiviji i najugodniji zadaci na koje naši inženjeri troše vrijeme.
Razlika je u tome što Symphony može preuzeti glavninu rutinskog implementacijskog rada. To inženjerima omogućuje da se usredotoče na jedan težak problem odjednom umjesto da se stalno prebacuju između manjih zadataka
Također smo naučili da tretiranje agenata kao krutih čvorova u sustavu stanja ne funkcionira dobro. Modeli postaju pametniji i mogu rješavati veće probleme od okvira u koji ih pokušavamo smjestiti. Primjerice, rane verzije imale su sve GitHub integracije kao dio vanjskog operativnog okvira – primjerice, očekivalo se da Codex radi samo izmjene koda, dok je ostatak procesa (slanje promjena, pokretanje testova) bio definiran u kodu. U ranim verzijama agentskog rada od Codexa smo tražili samo da implementira zadatak. Taj se pristup pokazao previše ograničavajućim. Codex je potpuno sposoban izraditi više PR-ova, kao i pročitati povratne informacije iz pregleda i postupiti prema njima. Zato smo mu dali alate –gh CLI, vještine za čitanje CI logova itd. – i sad možemo tražiti od Codexa da radi i više, poput zatvaranja starih PR-ova ili izrade izvješća o dovršenom naspram napuštenog rada. Takve su vrste zadataka bile daleko izvan početnog okvira implementacije značajke.
Zato smo s vremenom prešli na davanje ciljeva agentima umjesto strogih prijelaza, slično kao što dobar menadžer dodjeljuje cilj svom izravno podređenom članu tima. Moć modela proizlazi iz njihove sposobnosti rasuđivanja, stoga im dajte alate i kontekst i pustite ih da odrade svoje.
Korištenje Symphonyja za izgradnju Symphonyja
Kada otvorite repozitorij Symphony, prvo što ćete primijetiti jest da je Symphony tehnički samo datoteka SPEC.md – definicija problema i predviđenog rješenja. Umjesto izgradnje složenog sustava nadzora, definirali smo problem i predviđena rješenja te agentima dali smjernice na visokoj razini.
Referentna implementacija napisana je u Elixiru – jer kad je kȏd praktički besplatan, napokon možete birati jezike prema njihovim prednostima, poput Elixirove istodobne obrade – ali temeljna ideja može se izraziti u jednostavnom Markdown dokumentu.Potičemo vas da svog omiljenog agenta za programiranje usmjerite na specifikaciju i navedete ga da implementira vlastitu verziju.
Prva verzija Symphonyja bila je samo Codex sesija koja se izvršavala u tmux-u, periodično provjeravala Linear i pokretala podagente za nove zadatke. Radilo je, ali nije bilo osobito pouzdano.Druga verzija nalazila se unutar našeg glavnog projektnog repozitorija, koji je bio izrađen imajući agente na umu. Već smo izgradili okvir za agente kako bismo agentima dali vještine i kontekst za kvalitetan rad u ovom repozitoriju, pa Symphony to jednostavno povezuje.
Kad je postojala osnovna funkcionalnost, koristili smo Symphony za izgradnju Symphonyja.
Kada smo interno demonstrirali sustav koji upravlja zadacima i prilaže video kao dokaz rada, reakcija je bila izrazito pozitivna: naš projektni kanal Symphony rastao je, a timovi diljem organizacije počeli su ga organski koristiti.Interna potvrda da proizvod odgovara potrebama tržišta preduvjet je za lansiranje izvan OpenAI-ja. Na temelju upotrebe koju smo vidjeli u OpenAI-ju, postalo je jasno da Symphony trebamo podijeliti i izvan tvrtke.
Zato smo ideju izdvojili u samostalni SPEC.md i zatražili od Codexa da ga implementira.Za referentnu implementaciju odabrali smo Elixir, relativno nišni jezik s izvrsnim mogućnostima za orkestraciju i nadzor istodobnih procesa. Codex je izradio implementaciju u Elixiru iz prvog pokušaja, a mi smo otad nastavili dorađivati i specifikaciju i implementaciju. Kako bismo doradili specifikaciju, čak smo zamolili Codex da je implementira u nekoliko drugih jezika – TypeScriptu, Gou, Rustu, Javi i Pythonu – te iskoristi rezultate za prepoznavanje nejasnoća i pojednostavljenje sustava. Uspio je u svakom jeziku..
Tijekom razvoja Codexa uklonili smo mnogo sporedne složenosti, poput ovisnosti o određenim repozitorijima ili Linear MCP-u.Symphony više ne ovisi o našim internim repozitorijima ni radnim procesima.Temeljni pristup postao je jednostavan:
Za svaki otvoreni zadatak osigurajte da agent radi u vlastitom radnom prostoru.
Osim što pomaže u aktivnom radu, razvojni radni proces sada je nešto što agenti poznaju i slijede. Razvojni radni proces – rad na zadatku, preuzimanje repozitorija, postavljanje statusa u tijeku kako bi PM znao da se na tome radi, dodavanje PR-a, premještanje u status pregled, prilaganje videozapisa itd. – sad je zabilježen u jednostavnoj datoteci WORKFLOW.md. Sve je to proces koji su ljudi slijedili, ali nikad nije bio dokumentiran. Umjesto oslanjanja na taj implicitni skup koraka, sada ga dokumentiramo, a Symphony osigurava da ga agenti slijede. To nam omogućuje izgradnju agenata koji rade uz nas. Ako odlučimo da agenti dovršenom radu trebaju priložiti i samorefleksiju, dodat ćemo to u WORKFLOW.md, a Symphony će usmjeriti agente prema tom koraku.
Također smo koristili Codex u načinu rada App Server(otvara se u novom prozoru), ugrađenom neinteraktivnom načinu rada za Codex. Taj nam je način omogućio da pokrećemo Codex i programski komuniciramo s njim putem dobro dokumentiranog JSON-RPC API-ja za stvari poput pokretanja threada ili reagiranja na promjene. To je mnogo praktičniji i skalabilniji pristup od pokušaja interakcije s Codexom putem CLI-ja ili aktivnih tmux sesija.
Codex App Server savršeno je odgovarao našem slučaju upotrebe: iskorištavamo operativni okvir koji Codex pruža, a pritom imamo kontrole i priključne točke za integraciju. Primjerice, kako ne bismo izložili Linear access token podagentima, upotrebljavamo dinamičke pozive alata(otvara se u novom prozoru) kako bismo izložili sirovu funkciju linear_graphql koja izvršava proizvoljne zahtjeve prema Linearu, bez oslanjanja na MCP i bez izlaganja access tokena kontejnerima.
Što slijedi
Symphony je namjerno minimalan orkestracijski sloj. Objavljujemo ga kao open source kako bismo pokazali snagu Codex App Servera kada se upari s različitim alatima za radni proces, poput Lineara. Kao takav, ne planiramo održavati Symphony kao samostalan proizvod. Promatrajte ga kao referentnu implementaciju. Slično kao što su mnogi razvojni inženjeri usmjerili svoje agente za programiranje na objavu o razvoju operativnog okvira za agente kako bi postavili temelj svojih repozitorija, nadamo se da ćete svoj omiljeni agent za programiranje usmjeriti na Symphony specifikaciju(otvara se u novom prozoru) i repozitorij(otvara se u novom prozoru) kako biste izgradili vlastite verzije prilagođene svojim okruženjima.
Snaga dolazi od Codexa i njegova App Servera. Symphony je bio način da povežemo Codex i Linear, dvije stvari koje smo već upotrebljavali, kako bismo riješili problem upravljanja radom. Kako agenti za programiranje budu postajali bolji u rasuđivanju i praćenju uputa, pretpostavljamo da će se usko grlo i u drugim tvrtkama pomaknuti s pisanja koda prema upravljanju radom agenata. Uzbudljivo je to što je prepreka za eksperimentiranje s ovim sustavima agenata za programiranje sada iznenađujuće niska. Možete jednostavno graditi stvari s Codexom.
Pohvale zajednici
Oduševljeni smo što vidimo da inženjerska zajednica koristi Symphony u tjednima nakon objave, prikupivši više od 15 tisuća zvjezdica na GitHubu(otvara se u novom prozoru) zaključno s 23. travnja.