Atvērtā pirmkoda specifikācija Codex orķestrēšanai: Symphony
Autori: Alex Kotliarskyi, Victor Zhu un Zach Brock
Pirms sešiem mēnešiem, strādājot pie iekšēja produktivitātes rīka, mūsu komanda pieņēma tobrīd pretrunīgi vērtētu lēmumu: mēs veidosim savu repozitoriju bez cilvēku rakstīta koda. Katrai mūsu projekta repozitorija rindai bija jābūt Codex ģenerētai.
Lai tas darbotos, mēs no pamatiem pārveidojām savu inženierijas darbplūsmu. Mēs izveidojām aģentiem draudzīgu repozitoriju, daudz ieguldījām automatizētos testos un aizsargmehānismos, un uztvērām Codex kā pilntiesīgu komandas biedru. Šo ceļu aprakstījām savā iepriekšējā emuāra ierakstā par "harness engineering".
Un tas darbojās, bet tad mēs nonācām pie nākamā pudeles kakla: konteksta pārslēgšanos.
Lai atrisinātu šo jauno problēmu, mēs izveidojām sistēmu ar nosaukumu Symphony. Symphony(atveras jaunā logā) ir aģentu orķestrēšanas rīks, kas projektu pārvaldības paneli, piemēram, Linear, pārvērš par vadības plakni kodēšanas aģentiem. Katrs atvērtais uzdevums saņem aģentu, aģenti darbojas nepārtraukti, bet cilvēki pārskata rezultātus.
Šajā rakstā ir paskaidrots, kā mēs izveidojām Symphony — kas dažās komandās nodrošināja 500% pieaugumu apstiprināto izmaiņu pieprasījumu skaitā — un kā to izmantot, lai pārvērstu savu uzdevumu izsekošanas rīku par pastāvīgi aktīvu aģentu orķestrēšanas rīku.
Interaktīvo kodēšanas aģentu maksimālais potenciāls
Pat kļūstot vieglāk lietojamiem, kodēšanas aģenti — neatkarīgi no tā, vai tiem piekļūst caur tīmekļa lietotnēm vai CLI — joprojām ir interaktīvi rīki.
Palielinoties aģentu darba apjomam OpenAI, mēs saskārāmies ar jauna veida slogu. Katrs inženieris atvēra dažas Codex sesijas, piešķīra uzdevumus, pārskatīja rezultātus, vadīja aģentu un atkārtoja. Praksē lielākā daļa cilvēku vienlaikus spēja ērti pārvaldīt trīs līdz piecas sesijas, pirms konteksta pārslēgšana kļuva apgrūtinoša. Pārsniedzot to, produktivitāte kritās. Mēs aizmirsām, kura sesija ko dara, lēkājām starp termināļiem, lai atgrieztu aģentus pie darba, un atkļūdojām ilgstošus uzdevumus, kas iestrēga pusceļā.
Aģenti bija ātri, taču mums bija sistēmisks pudeles kakls: cilvēku uzmanība. Mēs faktiski bijām izveidojuši ārkārtīgi spējīgu jaunāko inženieru komandu un tad norīkojuši savus cilvēkus tos sīki pārvaldīt. Šāda pieeja nebija mērogojama.
Perspektīvas maiņa
Mēs sapratām, ka optimizējam nepareizo lietu. Mēs bijām koncentrējuši savu sistēmu uz kodēšanas sesijām un iekļautiem PR, lai gan PR un sesijas patiesībā ir tikai līdzeklis mērķa sasniegšanai. Programmatūras darbu plūsmas lielākoties ir organizētas ap piegādājamiem rezultātiem: problēmām, uzdevumiem, pieteikumiem un atskaites punktiem.
Tāpēc mēs sev jautājām, kas notiktu, ja mēs pārstātu tieši uzraudzīt aģentus un tā vietā ļautu tiem paņemt darbu no mūsu uzdevumu pārvaldības rīka.
Šī ideja kļuva par Symphony — rakstītu specifikāciju, kas darbojas kā uzraugs aģentu veiktā darba orķestrēšanai.
Mūsu uzdevumu izsekošanas rīka pārvēršana par aģentu orķestrēšanas rīku
Symphony sākās ar vienkāršu koncepciju: jebkurš atvērts uzdevums aģentam ir jāpārņem un jāpabeidz. Tā vietā, lai pārvaldītu Codex sesijas vairākās cilnēs, mēs savu uzdevumu izsekošanas rīku padarījām par vadības plakni.
Šajā uzstàdìjumà katram atvērtajam Linear pieteikumam atbilst īpaša aģenta darbvieta. Symphony nepārtraukti uzrauga uzdevumu paneli un nodrošina, ka katram aktīvajam uzdevumam cilpà darbojas aģents, līdz tas ir pabeigts. Ja aģents avarē vai iestrēgst, Symphony to restartē.m Ja parādās jauns darbs, Symphony to paņem un sāk organizēt izpildi.
Mēs izveidojām savu darbplūsmu, balstoties uz pieteikumu statusiem, izmantojot uzdevumu pārvaldnieku Linear kā stāvokļu automātu.
Praksē Symphony atsaista darbu no sesijām un no apstiprināto izmaiņu pieprasījumiem. Dažas problēmas rada vairākus PR dažādos repozitorijos; citas ir tīra izpēte vai analīze, kas koda bāzei nepieskaras nemaz.
Kad darbs šādi tiek abstrahēts, pieteikumi var atspoguļot daudz lielākas darba vienības.
Mēs regulāri izmantojam Symphony, lai orķestrētu sarežģītas funkcijas un infrastruktūras migrācijas. Piemēram, mēs varam izveidot uzdevumu, lūdzot aģentu analizēt koda bāzi, Slack vai Notion un sagatavot ieviešanas plānu. Kad esam apmierināti ar plānu, aģents ģenerē uzdevumu koku, sadalot darbu posmos un definējot atkarības starp uzdevumiem.
Aģenti sāk strādāt tikai pie tiem uzdevumiem, kas nav bloķēti, tāpēc izpilde šajā DAG (izpildes soļu secībā) dabiski un optimāli notiek paralēli. Zemāk redzamajā piemērā mēs React jaunināšanu atzīmējām kā bloķētu, kamēr nav pabeigta migrācija uz Vite. Kā jau gaidīts, aģenti sāka React jaunināšanu tikai pēc tam, kad migrācija uz Vite bija pabeigta.
Aģenti var arī paši radīt darbu. Ieviešanas vai pārskatīšanas laikā tie bieži pamana uzlabojumus, kas neietilpst pašreizējā uzdevuma tvērumā: veiktspējas problēmu, pārstrukturēšanas iespēju vai labāku arhitektūru. Kad tas notiek, tie vienkārši izveido jaunu pieteikumu, ko vēlāk varam izvērtēt un ieplānot — daudzus no šiem turpmākajiem uzdevumiem arī paņem aģenti. Kamēr mēs šo procesu uzraugām, aģenti saglabā organizētību un virza darbu uz priekšu.
Šāds darba veids krasi samazina neskaidra darba uzsākšanas kognitīvās izmaksas. Ja aģents kaut ko izdara nepareizi, arī tā ir noderīga informācija, un izmaksas mums ir gandrīz nulles līmenī. Mēs varam ļoti lēti izveidot pieteikumus, lai aģents prototipētu un pētītu, un izmest jebkuras izpētes, kas mums nepatīk.
Tā kā orķestrators darbojas devbox vidēs un nekad neguļ, mēs varam pievienot uzdevumus no jebkuras vietas un zināt, ka aģents tos paņems. Piemēram, viens mūsu komandas inženieris no sava tālruņa Linear lietotnē veica trīs būtiskas izmaiņas, sēžot mājīgā namiņā ar nestabilu wifi.
Šāda darba veida radīts izpētes pieaugums
Novērojot darba ar Symphony ietekmi, visuzskatāmākā izmaiņa bija rezultātos. Dažās OpenAI komandās pirmajās trīs nedēļās mēs redzējām 6x pieaugumu integrēto PR skaitā. Ārpus OpenAI Linear dibinātājs Karri Saarinen, kad mēs izlaidām Symphony, izcēla darbvietu izveides pieaugumu(atveras jaunā logā). Taču dziļākā pārmaiņa ir tajā, kā komandas domā par darbu.
Kad mūsu inženieri vairs netērē laiku Codex sesiju uzraudzībai, koda izmaiņu ekonomika pilnībā mainās. Katras izmaiņas uztvertās izmaksas samazinās, jo mēs vairs neieguldām cilvēku pūles pašas ieviešanas virzīšanā.
Tas mainīja mūsu uzvedību. Tagad Symphony ir kļuvis pavisam vienkārši iedarbināt spekulatīvus uzdevumus. Izmēģiniet ideju, izpētiet pārstrukturēšanu, pārbaudiet hipotēzi un paturiet tikai tos rezultātus, kas šķiet daudzsološi.
Tas arī paplašina to cilvēku loku, kuri var ierosināt darbu. Mūsu produktu vadītājs un dizainers tagad var iesniegt funkciju pieprasījumus tieši Symphony. Viņiem nav jāizgūst repozitorijs vai jāpārvalda Codex sesija. Viņi apraksta funkciju un saņem pārskatīšanas paketi, kurā ir arī video demonstrācija, kā funkcija darbojas īstajā produktā.
Symphony izceļas arī lielos monorepozitorijos (piemēram, tādā, kāds mums ir OpenAI), kur pēdējais solis līdz PR integrēšanai ir lēns un trausls. Sistēma uzrauga CI, vajadzības gadījumā veic rebase, atrisina konfliktus, atkārto nestabilas pārbaudes un kopumā vada izmaiņu virzību caur konveijeru. Līdz brīdim, kad pieteikums sasniedz Merging, mums ir augsta pārliecība, ka izmaiņas nonāks galvenajā atzarā bez cilvēka iejaukšanās.
Pēc Symphony ieviešanas mēs deleģējam aģentiem vairāk darba un koncentrējamies uz grūtākiem, izpētes rakstura uzdevumiem.
Progress nes līdzi jaunas, atšķirīgas problēmas
Darbošanās šādā līmenī ietver zināmus kompromisus. Kad mēs pārgājām no operatīvas aģentu vadības uz darba piešķiri pieteikumu līmenī, mēs zaudējām iespēju tos pastāvīgi "pabīdīt" darba procesā un vajadzības gadījumā koriģēt kursu. Dažreiz aģents izveidoja kaut ko tādu, kas pilnībā netrāpīja mērķī. Tas bija noderīgi — šīs neveiksmes atklāja sistēmas nepilnības un palīdzēja mums to padarīt stabilāku.
Tā vietā, lai manuāli labotu rezultātu, mēs pievienojām aizsargmehānismus un prasmes, lai aģentiem izdotos nākamreiz. Laika gaitā tas mums ļāva papildināt savu ietvaru ar jaunām iespējām, piemēram, pilna cikla testu izpildi, lietotnes vadību caur Chrome DevTools un QA dūmu testu (smoke tests) pārvaldību. Mēs būtiski uzlabojām dokumentāciju un precizējām, kā izskatās labs rezultāts.
Ne katrs uzdevums atbilst Symphony darba stilam. Dažām problēmām joprojām nepieciešami inženieri, kas strādā tieši ar interaktīvām Codex sesijām, īpaši neskaidru problēmu vai darba gadījumos, kur vajadzīga pamatota spriestspēja un pieredze. Praksē tie parasti ir visinteresantākie un saistošākie uzdevumi, kuriem mūsu inženieri velta savu laiku.
Atšķirība ir tāda, ka Symphony var apstrādāt lielāko daļu rutīnas ieviešanas darba. Tas ļauj inženieriem koncentrēties uz vienu sarežģītu problēmu vienlaikus, nevis pastāvīgi mainīt kontekstu, pārslēdzoties starp mazākiem uzdevumiem.
Mēs arī sapratām, ka izturēšanās pret aģentiem kā pret stingriem mezgliem stāvokļu mašīnā nedarbojas labi. Modeļi kļūst gudrāki un spēj atrisināt lielākas problēmas, nekā paredz rāmji, kuros cenšamies tos iekļaut. Piemēram, agrīnajās versijās visas GitHub integrācijas bija daļa ārējā ietvara— piemēram, agrīnās versijas paredzēja, ka Codex veic tikai koda izmaiņas, bet pārējo procesu (izmaiņu iesniegšanu, testu palaišanu) noteica kodā. Mūsu pirmajās aģentu darba versijās mēs lūdzām Codex tikai izpildīt uzdevumu. Šī pieeja izrādījās pārāk ierobežojoša. Codex pilnībā spēj izveidot vairākus PR, kā arī lasīt pārskatīšanas atsauksmes un uz tām reaģēt. Tāpēc mēs tam iedevām rīkus— gh CLI, prasmes lasīt CI žurnālus utt. — un tagad varam lūgt Codex darīt vairāk, piemēram, aizvērt vecus PR vai sagatavot atskaites par pabeigto un pamesto darbu. Šāda veida uzdevumi ievērojami pārsniedz sākotnēji paredzēto funkciju apjomu.
Tāpēc mēs galu galā virzījāmies uz to, lai aģentiem izvirzītu mērķus, nevis noteiktu stingras pārejas — līdzīgi kā labs vadītājs uzdod mērķi savas komandas tiešajam padotajam. Modeļu spēks slēpjas to spējā spriest, tāpēc dodiet tiem rīkus un kontekstu un ļaujiet tiem darboties.
Symphony izmantošana Symphony izstrādei
Atverot Symphony repozitoriju, pirmais, ko pamanīsiet, ir tas, ka tehniski Symphony ir tikai SPEC.md fails — problēmas un iecerētā risinājuma definīcija. Tā vietā, lai izveidotu sarežģītu uzraudzības sistēmu, mēs definējām problēmu un vēlamos risinājumus, sniedzot aģentiem augsta līmeņa vadību.
Atsauces implementācija ir rakstīta Elixir valodā — jo, kad kods faktiski ir par brīvu, beidzot varat izvēlēties valodas pēc to stiprajām pusēm, piemēram, Elixir vienlaicīguma iespējām — taču pamatideju var izteikt vienkāršā Markdown dokumentā. Mēs aicinām norādīt savu iecienītāko kodēšanas aģentu uz specifikāciju un likt tam ieviest savu versiju.
Pirmā Symphony versija bija vienkārši Codex sesija, kas darbojās tmux, aptaujāja Linear un jauniem uzdevumiem palaida apakšaģentus. Tā darbojās, bet nebija īpaši uzticama. Otrā versija atradās mūsu galvenajā projekta repozitorijā, kas bija veidots, domājot par aģentiem. Mēs jau bijām izveidojuši aģentu ietvaru, lai dotu aģentiem prasmes un kontekstu augstas kvalitātes darbam šajā repozitorijā, tāpēc Symphony to visu vienkārši savieno.
Kad pamatfunkcionalitāte bija ieviesta, mēs izmantojām Symphony, lai veidotu Symphony.
Kad iekšēji prezentējām sistēmu, kas pārvaldīja uzdevumus un pievienoja sava darba apliecinājuma video, atsauksmes bija ārkārtīgi pozitīvas: mūsu Symphony projekta kanāls auga, un komandas visā organizācijā sāka to lietot organiski. Iekšējā produkta un tirgus atbilstība ir priekšnoteikums ārējai palaišanai OpenAI. Balstoties uz lietojumu, ko redzējām OpenAI, kļuva skaidrs, ka mums ir jādalās ar Symphony arī ārpus uzņēmuma ietvariem.
Tāpēc mēs izdalījām ideju atsevišķā SPEC.md un lūdzām Codex to ieviest. Paraugīstenošanai izvēlējāmies Elixir — salīdzinoši specifisku valodu ar izciliem pamatelementiem vienlaicīgu procesu orķestrēšanai un uzraudzībai. Codex izveidoja Elixir implementāciju vienā piegājienā, un pēc tam mēs turpinājām iterēt gan pie specifikācijas, gan implementācijas. Lai pilnveidotu specifikāciju, mēs pat lūdzām Codex to ieviest vairākās citās valodās — TypeScript, Go, Rust, Java, Python — un izmantot rezultātus, lai noteiktu neskaidrības un vienkāršotu sistēmu. Tas izdevās katrā valodā.
Codex veidošanas procesā mēs novērsām daudz sekundārās sarežģītības, piemēram, atkarības no konkrētiem repozitorijiem vai Linear MCP. Symphony vairs nav atkarīgs no mūsu iekšējiem repozitorijiem vai darbplūsmām. Pamatpieeja kļuva vienkārša:
Katram atvērtam uzdevumam garantēt, ka savā darbvietā darbojas aģents.
Papildus palīdzībai aktīvajā darbā izstrādes darbplūsma tagad ir kaut kas tāds, ko aģenti pārzina un ievēro. Izstrādes darbplūsma — darbs pie pieteikuma, repozitorija izgūšana, statusa maiņa uz "in progress, lai produktu vadītājs zinātu, ka pie tā strādā, PR pievienošana, pārvietošana uz statusu "Review", video pievienošana utt. — tagad ir fiksēta vienkāršā WORKFLOW.md failā. Tas viss ir process, kuru ievēroja cilvēki, taču tas nekad nebija dokumentēts. Tā vietā, lai paļautos uz šo netiešo soļu kopumu, mēs to tagad dokumentējam, un Symphony nodrošina, ka aģenti to ievēro. Tas ļauj mums veidot aģentus, kas strādā mums līdzās. Ja izlemsim, ka aģentiem pie pabeigta darba jāpievieno arī pašanalīze, mēs to pievienosim WORKFLOW.md, un Symphony vadīs aģentus šajā solī.
Mums bija iespēja izmantot arī Codex lietotņu servera režīmā(atveras jaunā logā) — iebūvētā "headless" režīmā priekš Codex. Šis režīms ļāva mums darbināt Codex un sazināties ar to programmatiski, izmantojot labi dokumentētu JSON-RPC API, tādām darbībām kā pavediena sākšana vai reaģēšana uz gājieniem. Tas ir daudz ērtāks un mērogojamāks veids nekā mēģināt mijiedarboties ar Codex caur CLI vai reāllaika tmux sesijām.
Codex App Server bija ideāli piemērots mūsu lietojumam: mēs izmantojam Codex sniegto ietvaru, vienlaikus kontroles mehānismus un saskarnes integrācijai. Piemēram, lai apakšaģentiem neatklātu Linear piekļuves pilnvaru, mēs izmantojam dinamiskus rīku izsaukumus(atveras jaunā logā), lai atklātu neapstrādāto linear_graphql funkciju, kas izpilda brīvi izvēlētus pieprasījumus pret Linear, nepaļaujoties uz MCP un neatklājot piekļuves pilnvaru konteineriem.
Kas tālāk
Symphony ir apzināti minimāls orķestrēšanas slānis. Mēs publicējam tā pirmkodu, lai parādītu Codex App Server jaudu, ja to savieno ar dažādiem darbplūsmas rīkiem, piemēram, Linear. Tāpēc mēs neplānojam uzturēt Symphony kā atsevišķu produktu. Uztveriet to kā paraugīstenošanu. Līdzīgi kā daudzi izstrādātāji izmantoja mūsu iepriekšējo rakstu par "harness engineering", lai veidotu savu repozitoriju struktūru, mēs ceram, ka jūs izmantosiet savu iecienītāko kodēšanas aģentu uz Symphony specifikāciju(atveras jaunā logā) un repozitoriju(atveras jaunā logā), lai izveidotu savas versijas, kas pielāgotas jūsu vidēm.
Spēks nāk no Codex un tā lietotņu servera. Symphony bija veids, kā savienot Codex ar Linear — divas lietas, ko jau izmantojām — lai atrisinātu darba pārvaldības problēmu. Kodēšanas aģentiem kļūstot labākiem spriest un ievērot norādījumus, mums šķiet, ka arī citos uzņēmumos šaurais pudeles kakls pārvietosies no koda rakstīšanas uz aģentu darba pārvaldību. Aizraujošākais ir tas, ka šķērslis eksperimentiem ar šādām kodēšanas aģentu sistēmām tagad ir pārsteidzoši zems. Jūs varat vienkārši būvēt lietas ar Codex.
Kopienas atzinības
Mēs esam sajūsmā redzēt, ka inženieru kopiena izmanto Symphony jau pirmajās nedēļās pēc izlaišanas, un uz 23. aprīli tas ir ieguvis vairāk nekā 15 tūkst. GitHub zvaigžņu(atveras jaunā logā).