Një specifikim open-source për orkestrimin e Codex: Symphony
Nga Alex Kotliarskyi, Victor Zhu dhe Zach Brock
Gjashtë muaj më parë, teksa punonim mbi një mjet të brendshëm produktiviteti, ekipi ynë mori një vendim të diskutueshëm (në atë kohë): do ta ndërtonim depon tonë pa asnjë kod të shkruar nga njeriu. Çdo rresht në depon e projektit tonë duhej të gjenerohej nga Codex.
Për ta bërë këtë të funksiononte, ne ridizenjuam rrjedhën tonë të inxhinierisë nga themeli. Ndërtuam një depo miqësore për agjentët, investuam shumë në teste të automatizuara dhe gardhë sigurie, dhe e trajtuam Codex si një bashkëpunëtor të plotë. E dokumentuam atë udhëtim në postimin tonë të mëparshëm në blog mbi harness engineering.
Dhe funksionoi, por më pas hasëm pengesën tjetër: ndërrimin e kontekstit.
Për ta zgjidhur këtë problem të ri, ndërtuam një sistem të quajtur Symphony. Symphony(hapet në një dritare të re) është një orkestrues agjentësh që e kthen një tabelë menaxhimi projekti si Linear në një plan kontrolli për agjentë kodimi. Çdo detyrë e hapur merr një agjent, agjentët ekzekutohen vazhdimisht dhe njerëzit rishikojnë rezultatet.
Ky postim shpjegon se si e krijuam Symphony—duke sjellë një rritje 500% të kërkesave pull të integruara në disa ekipe—dhe si ta përdorni për ta kthyer gjurmuesin tuaj të issue-ve në një orkestrues agjentësh gjithmonë aktiv.
Tavani i agjentëve interaktivë të kodimit
Edhe pse po bëhen më të lehtë për t’u përdorur, agjentët e kodimit—qofshin përmes aplikacioneve web apo CLI—janë ende mjete interaktive.
Ndërsa shkalla e punës agjentike u rrit në OpenAI, ne gjetëm një lloj të ri barre. Çdo inxhinier hapte disa sesione Codex, caktonte detyra, rishikonte rezultatin, drejtonte agjentin dhe e përsëriste procesin. Në praktikë, shumica e njerëzve mund të menaxhonin rehat tre deri në pesë sesione njëherësh para se ndërrimi i kontekstit të bëhej i dhimbshëm. Përtej kësaj, produktiviteti binte. Harronim cili sesion po bënte çfarë, hidheshim midis terminaleve për t’i shtyrë agjentët sërish në drejtimin e duhur dhe korrigjonim detyra afatgjata që ngecnin në gjysmë.
Agjentët ishin të shpejtë, por ne kishim një pengesë sistemi: vëmendjen njerëzore. Në thelb kishim ndërtuar një ekip inxhinierësh juniorë jashtëzakonisht të aftë, dhe më pas u kishim caktuar inxhinierëve tanë njerëzorë t’i mikromenaxhonin. Kjo nuk do të shkallëzohej.
Një ndryshim perspektive
Kuam se po optimizonim gjënë e gabuar. Po e orientonim sistemin tonë rreth sesioneve të kodimit dhe PR-ve të bashkuara, ndërsa PR-të dhe sesionet janë në të vërtetë një mjet drejt një qëllimi. Rrjedhat e punës në softuer organizohen kryesisht rreth dorëzimeve: issue, detyra, tiketa, pika historike.
Kështu që pyetëm veten se çfarë do të ndodhte nëse ndalonim së mbikëqyruri agjentët drejtpërdrejt dhe në vend të kësaj i linim të tërhiqnin punë nga gjurmuesi ynë i detyrave.
Ajo ide u bë Symphony, një specifikim i shkruar që funksionon si mbikëqyrës për të orkestruar punën agjentike.
Ta kthesh gjurmuesin e issue-ve në një orkestrues agjentësh
Symphony filloi me një koncept të thjeshtë: çdo detyrë e hapur duhet të merret dhe të përfundohet nga një agjent. Në vend që të menaxhonim sesione Codex në shumë skeda, ne e bëmë gjurmuesin tonë të issue-ve planin e kontrollit.
Në këtë konfigurim, çdo issue e hapur në Linear korrespondon me një hapësirë pune të dedikuar për agjentin. Symphony vëzhgon vazhdimisht tabelën e detyrave dhe siguron që çdo detyrë aktive të ketë një agjent që ekzekutohet në qark derisa të përfundojë. Nëse një agjent rrëzohet ose ngec, Symphony e rinis. Nëse shfaqet punë e re, Symphony e merr dhe fillon të organizojë punën.
Ne e ndërtuam rrjedhën tonë të punës bazuar në statuset e tiketave, duke përdorur menaxherin e detyrave Linear si një makinë gjendjesh.
Në praktikë, Symphony e shkëput punën nga sesionet dhe nga kërkesat pull. Disa issue prodhojnë disa PR nëpër depo; të tjerat janë hetime ose analiza të pastra që nuk prekin kurrë bazën e kodit.
Pasi puna abstragohet në këtë mënyrë, tiketat mund të përfaqësojnë njësi shumë më të mëdha pune.
Ne e përdorim rregullisht Symphony për të orkestruar veçori komplekse dhe migrime infrastrukture. Për shembull, mund të hapim një detyrë ku i kërkojmë agjentit të analizojë bazën e kodit, Slack ose Notion dhe të prodhojë një plan zbatimi. Pasi të jemi të kënaqur me planin, agjenti gjeneron një pemë detyrash, duke e ndarë punën në faza dhe duke përcaktuar varësitë midis detyrave.
Agjentët nisin punën vetëm mbi detyrat që nuk janë të bllokuara, ndaj ekzekutimi shpaloset natyrshëm dhe në mënyrë optimale paralelisht për këtë DAG (një sekuencë hapash ekzekutimi). Në shembullin më poshtë, e shënuam përditësimin e React si të bllokuar nga një migrim te Vite. Siç pritej, agjentët nisën përditësimin e React vetëm pasi migrimi te Vite përfundoi.
Agjentët mund të krijojnë punë edhe vetë. Gjatë zbatimit ose rishikimit, ata shpesh vërejnë përmirësime që bien jashtë fushës së detyrës aktuale: një problem performance, një mundësi refaktorimi ose një arkitekturë më të mirë. Kur kjo ndodh, ata thjesht hapin një issue të re që ne mund ta vlerësojmë dhe planifikojmë më vonë—shumë prej këtyre detyrave pasuese merren gjithashtu nga agjentët. Ndërsa ne e mbikëqyrim këtë proces, agjentët qëndrojnë të organizuar dhe e mbajnë punën duke ecur përpara.
Kjo mënyrë pune ul në mënyrë dramatike koston njohëse të nisjes së punës së paqartë. Nëse agjenti gabon diçka, kjo është sërish informacion i dobishëm dhe kostoja për ne është pothuajse zero. Mund të hapim shumë lirë tiketa që agjenti të prototipojë dhe eksplorojë, dhe të hedhim poshtë çdo eksplorim që nuk na pëlqen.
Për shkak se orkestruesi ekzekutohet në devboxes dhe nuk fle kurrë, ne mund të shtojmë detyra nga kudo dhe të dimë se një agjent do ta marrë. Për shembull, një inxhinier në ekipin tonë bëri tre ndryshime të rëndësishme nga aplikacioni Linear në telefonin e tij nga një kabinë e rehatshme me wifi të dobët.
Një rritje e eksplorimit nga kjo mënyrë pune
Kur vëzhguam efektet e punës me Symphony, ndryshimi më i dukshëm ishte rezultati. Në disa ekipe në OpenAI, pamë që numri i PR-ve të integruara u rrit 6 herë në tre javët e para. Jashtë OpenAI, themeluesi i Linear Karri Saarinen theksoi një rritje të mprehtë të hapësirave të punës të krijuara(hapet në një dritare të re) teksa lançuam Symphony. Megjithatë, ndryshimi më i thellë është mënyra si ekipet mendojnë për punën.
Kur inxhinierët tanë nuk shpenzojnë më kohë duke mbikëqyrur sesionet Codex, ekonomia e ndryshimeve në kod ndryshon plotësisht. Kostoja e perceptuar e çdo ndryshimi bie sepse ne nuk po investojmë më përpjekje njerëzore në drejtimin e vetë zbatimit.
Kjo e ndryshoi sjelljen tonë. Është bërë triviale të nisim detyra spekulative në Symphony. Provo një ide, eksploro një refaktorim, testo një hipotezë dhe mbaj vetëm rezultatet që duken premtuese.
Kjo zgjeron gjithashtu se kush mund ta nisë punën. Menaxheri ynë i produktit dhe dizenjuesi tani mund të hapin kërkesa për veçori drejtpërdrejt në Symphony. Ata nuk kanë nevojë të klonojnë depon ose të menaxhojnë një sesion Codex. Ata e përshkruajnë veçorinë dhe marrin një paketë rishikimi që përfshin një video demonstrimi të veçorisë duke funksionuar brenda produktit real.
Symphony shkëlqen gjithashtu në monorepo të mëdha (si ajo që kemi në OpenAI) ku metri i fundit i integrimit të një PR-je është i ngadaltë dhe i brishtë. Sistemi vëzhgon CI, bën rebase kur nevojitet, zgjidh konfliktet, riprovon kontrollet e paqëndrueshme dhe përgjithësisht i shoqëron ndryshimet nëpër pipeline. Deri kur një tiketë arrin te Merging, kemi besim të lartë se ndryshimi do të hyjë në degën kryesore pa mbikëqyrje njerëzore.
Përparimi sjell probleme të reja, të ndryshme
Të operosh në këtë nivel vjen me kompromise. Kur kaluam nga drejtimi interaktiv i agjentëve te caktimi i punës në nivel tikete, humbëm aftësinë për t’i shtyrë vazhdimisht gjatë rrugës dhe për të korrigjuar kursin kur nevojitej. Ndonjëherë agjenti prodhonte diçka që nuk qëllonte fare në shenjë. Kjo ishte e dobishme—ato dështime zbuluan boshllëqe në sistem dhe na ndihmuan ta bënim më të qëndrueshëm.
Në vend që ta arnonim rezultatin manualisht, shtuam gardhë sigurie dhe aftësi që agjentët të kishin sukses herën tjetër. Me kalimin e kohës, kjo na çoi të shtonim aftësi të reja në harness-in tonë, si ekzekutimi i testeve end-to-end, kontrolli i aplikacionit përmes Chrome DevTools dhe menaxhimi i testeve smoke të QA. Përmirësuam ndjeshëm dokumentacionin tonë dhe sqaruam se si duket puna e mirë.
Jo çdo detyrë i përshtatet stilit të punës së Symphony. Disa probleme ende kërkojnë inxhinierë që punojnë drejtpërdrejt me sesione interaktive Codex, veçanërisht probleme të paqarta ose punë që kërkon gjykim dhe ekspertizë të fortë. Në praktikë, këto zakonisht janë detyrat më interesante dhe më të këndshme ku inxhinierët tanë kalojnë kohën.
Dallimi është se Symphony mund të përballojë pjesën më të madhe të punës rutinë të zbatimit. Kjo i lejon inxhinierët të përqendrohen në një problem të vetëm të vështirë në të njëjtën kohë, në vend që të ndërrojnë vazhdimisht kontekst midis detyrave më të vogla.
Mësuam gjithashtu se trajtimi i agjentëve si nyje të ngurta në një makinë gjendjesh nuk funksionon mirë. Modelet bëhen më të zgjuara dhe mund të zgjidhin probleme më të mëdha sesa kutia ku përpiqemi t’i fusim. Për shembull, versionet e hershme i kishin të gjitha integrimet GitHub si pjesë të harness-it të jashtëm—për shembull, versionet e hershme prisnin që Codex vetëm të bënte ndryshime kodi, duke specifikuar pjesën tjetër të procesit (dorëzimin e ndryshimeve, ekzekutimin e testeve) në kod. Versionet tona të hershme të punës agjentike vetëm i kërkonin Codex të zbatonte detyrën. Kjo qasje doli tepër kufizuese. Codex është plotësisht i aftë të krijojë disa PR, si edhe të lexojë komentet e rishikimit dhe t’u përgjigjet atyre. Kështu që i dhamë mjete—CLI gh, aftësi për të lexuar log-et e CI, etj.—dhe tani mund t’i kërkojmë Codex të bëjë më shumë, si mbyllja e PR-ve të vjetra ose tërheqja e raporteve mbi punën e përfunduar kundrejt asaj të braktisur. Këto lloj detyrash binin shumë jashtë kutisë fillestare të zbatimit të veçorive.
Prandaj, përfundimisht kaluam drejt dhënies së objektivave për agjentët në vend të tranzicioneve të rrepta, ngjashëm me mënyrën si një menaxher i mirë do t’i caktonte një qëllim një raportuesi të drejtpërdrejtë në ekipin e tij. Fuqia e modeleve vjen nga aftësia e tyre për arsyetim, ndaj jepuni mjete dhe kontekst dhe lërini të punojnë.
Përdorimi i Symphony për të ndërtuar Symphony
Kur hapni depon e Symphony, gjëja e parë që do të vini re është se Symphony teknikisht është vetëm një skedar SPEC.md—një përkufizim i problemit dhe i zgjidhjes së synuar. Në vend që të ndërtonim një sistem kompleks mbikëqyrjeje, ne përcaktuam problemin dhe zgjidhjet e synuara, duke u dhënë agjentëve drejtim të nivelit të lartë.
Zbatimi referencë është shkruar në Elixir—sepse kur kodi është praktikisht falas, më në fund mund të zgjedhësh gjuhët për pikat e tyre të forta, si konkurrenca e Elixir—por ideja thelbësore mund të shprehet në një dokument të thjeshtë Markdown. Ju inkurajojmë ta drejtoni agjentin tuaj të preferuar të kodimit te specifikimi dhe ta bëni të zbatojë versionin e vet.
Versioni i parë i Symphony ishte thjesht një sesion Codex që ekzekutohej në tmux, duke pyetur periodikisht Linear dhe duke nisur nën-agjentë për detyra të reja. Funksiononte, por nuk ishte veçanërisht i besueshëm. Versioni i dytë jetonte brenda depos sonë kryesore të projektit, e cila ishte ndërtuar duke pasur parasysh agjentët. Ne kishim ndërtuar tashmë infrastrukturën e agjentit për t’u dhënë agjentëve aftësitë dhe kontekstin për të bërë punë me cilësi të lartë në këtë depo, kështu që Symphony thjesht i lidh të gjitha.
Pasi funksionaliteti bazë ekzistonte, ne përdorëm Symphony për të ndërtuar Symphony.
Kur e demonstruam brenda kompanisë sistemin që menaxhonte detyrat dhe bashkëngjiste videon e tij të provës së punës, reagimi ishte jashtëzakonisht pozitiv: kanali i projektit tonë Symphony u rrit dhe ekipet në të gjithë organizatën nisën ta përdornin në mënyrë organike. Përputhja produkt-treg e brendshme është një parakusht për lançim të jashtëm në OpenAI. Bazuar në përdorimin që pamë në OpenAI, u bë e qartë se duhej ta ndanim Symphony përtej mureve të kompanisë.
Kështu e nxorëm idenë në një SPEC.md të pavarur dhe i kërkuam Codex ta zbatonte. Për zbatimin referencë, zgjodhëm Elixir, një gjuhë relativisht e veçantë me primitive të shkëlqyera për orkestrimin dhe mbikëqyrjen e proceseve konkurruese. Codex ndërtoi zbatimin në Elixir me një të rënë dhe prej andej vazhduam të iteronim si mbi specifikimin ashtu edhe mbi zbatimin. Për të lëmuar specifikimin, madje i kërkuam Codex ta zbatonte në disa gjuhë të tjera—TypeScript, Go, Rust, Java, Python—dhe t’i përdorte rezultatet për të identifikuar paqartësitë dhe për të thjeshtuar sistemin. Ia doli në çdo gjuhë.
Përmes procesit të ndërtimit të Codex, hoqëm shumë kompleksitet rastësor, si varësitë nga depo specifike ose Linear MCP. Symphony nuk varet më nga depot apo rrjedhat tona të brendshme të punës. Qasja thelbësore u bë e thjeshtë:
Për çdo detyrë të hapur, garantoni që një agjent po ekzekutohet në hapësirën e vet të punës.
Përveçse ndihmon me punën aktive, rrjedha e zhvillimit tani është diçka që agjentët e njohin dhe e ndjekin. Rrjedha e zhvillimit—puno mbi një issue, klono një depo, vendose në progres që PM ta dijë se po punohet, shto PR-në, kaloje në statusin Review, bashkëngjit video, etj.—tani është kapur në një skedar të thjeshtë WORKFLOW.md. E gjithë kjo ishte një proces që njerëzit e ndiqnin, por nuk ishte dokumentuar kurrë. Në vend që të mbështetemi te ky grup hapash i nënkuptuar, tani e dokumentojmë, dhe Symphony siguron që agjentët ta ndjekin. Kjo na lejon të ndërtojmë agjentë që punojnë krah nesh. Nëse vendosim që agjentët duhet të bashkëngjisin edhe vetë-reflektim te puna e përfunduar, do ta shtojmë këtë te WORKFLOW.md, dhe Symphony do t’i udhëzojë agjentët drejt atij hapi.
Ne arritëm gjithashtu ta përdornim Codex në modalitetin app server(hapet në një dritare të re), një modalitet headless i integruar për Codex. Ky modalitet na lejoi të ekzekutonim Codex dhe të komunikonim me të në mënyrë programatike përmes një API-je JSON-RPC të dokumentuar mirë për gjëra si nisja e një thread ose reagimi ndaj turneve. Është një mënyrë shumë më e përshtatshme dhe e shkallëzueshme sesa përpjekja për të bashkëvepruar me Codex përmes CLI ose sesioneve live tmux.
Codex App Server ishte përshtatje perfekte për rastin tonë të përdorimit: ne përfitojmë nga harness-i që ofron Codex duke pasur njëkohësisht kontrollues dhe hook-e ku të lidhemi. Për shembull, për të shmangur ekspozimin e token-it të aksesit Linear te nën-agjentët, ne përdorim dynamic tool calls(hapet në një dritare të re) për të ekspozuar funksionin e papërpunuar linear_graphql që ekzekuton kërkesa arbitrare kundër Linear, pa u mbështetur te MCP ose pa ekspozuar token-in e aksesit te kontejnerët.
Çfarë vjen më pas
Symphony është një shtresë orkestrimi qëllimisht minimale. Po e bëjmë open source për të demonstruar fuqinë e Codex App Server kur çiftohet me mjete të ndryshme të rrjedhës së punës, si Linear. Si e tillë, nuk planifikojmë ta mirëmbajmë Symphony si produkt më vete. Mendoni për të si një zbatim referencë. Ngjashëm me mënyrën si shumë zhvillues i drejtuan agjentët e tyre të kodimit te postimi mbi harness engineering për të krijuar depo të tyre, shpresojmë që edhe ju ta drejtoni agjentin tuaj të preferuar të kodimit te specifikimi(hapet në një dritare të re) dhe depoja(hapet në një dritare të re) e Symphony për të ndërtuar versionet tuaja të përshtatura për mjediset tuaja.
Fuqia vjen nga Codex dhe app serveri i tij. Symphony ishte një mënyrë për të lidhur Codex me Linear, dy gjëra që tashmë i përdornim, për të zgjidhur problemin e menaxhimit të punës. Ndërsa agjentët e kodimit përmirësohen në arsyetim dhe ndjekjen e udhëzimeve, dyshojmë se pengesa në kompani të tjera do të zhvendoset gjithashtu nga shkrimi i kodit drejt menaxhimit të punës agjentike. Pjesa emocionuese është se barriera për të eksperimentuar me këto sisteme agjentësh kodimi tani është çuditërisht e ulët. Thjesht mund të ndërtosh gjëra me Codex.
Përmendje për komunitetin
Jemi të entuziazmuar të shohim komunitetin e inxhinierisë duke përdorur Symphony në javët që prej publikimit, duke grumbulluar mbi 15 mijë yje në GitHub(hapet në një dritare të re) deri më 23 prill.