Spesifikasi sumber terbuka untuk pengorkestraan Codex: Symphony
Oleh Alex Kotliarskyi, Victor Zhu dan Zach Brock
Enam bulan lalu, ketika mengusahakan alat produktiviti dalaman, pasukan kami membuat keputusan yang kontroversi (pada masa itu): kami akan membina repo kami tanpa kod yang ditulis manusia. Setiap baris dalam repositori projek kami mesti dijana oleh Codex.
Bagi menjayakannya, kami mereka bentuk semula aliran kerja kejuruteraan kami dari asasnya. Kami membina repositori yang mesra ejen, melabur besar-besaran dalam ujian automatik dan kawalan keselamatan, dan menganggap Codex sebagai rakan sepasukan sepenuhnya. Kami mendokumentasikan perjalanan itu dalam catatan blog kami sebelum ini tentang kejuruteraan harness.
Dan ia berjaya, tetapi kemudian kami menemui kekangan seterusnya: pertukaran konteks.
Untuk menyelesaikan masalah baharu ini, kami membina sebuah sistem yang dipanggil Symphony. Symphony(dibuka dalam tetingkap baru) ialah pengatur ejen yang menukarkan papan pengurusan projek seperti Linear kepada satah kawalan untuk ejen pengaturcaraan. Setiap tugasan terbuka diberikan ejen, ejen berjalan secara berterusan dan manusia menyemak hasilnya.
Siaran ini menerangkan cara kami mencipta Symphony—yang menghasilkan peningkatan 500% dalam pull request yang berjaya digabungkan pada beberapa pasukan—dan cara menggunakannya untuk menukar penjejak isu anda sendiri menjadi penyelaras ejen yang sentiasa hidup.
Had atas ejen pengekodan interaktif
Walaupun ia semakin mudah digunakan, ejen pengekodan—sama ada diakses melalui aplikasi web atau CLI—masih merupakan alat interaktif.
Apabila skala kerja agentic meningkat di OpenAI, kami menemui beban baharu. Setiap jurutera akan membuka beberapa sesi Codex, menetapkan tugasan, menyemak output, membimbing ejen dan mengulang. Dalam amalan, kebanyakan orang boleh mengurus tiga hingga lima sesi pada satu masa dengan selesa sebelum pertukaran konteks menjadi sukar. Lebih daripada itu, produktiviti menurun. Kami akan terlupa sesi mana yang melakukan apa, melompat antara terminal untuk mengembalikan ejen ke landasan dan menyahpepijat tugasan berjalan lama yang tersekat di pertengahan jalan.
Ejen-ejen itu pantas, tetapi kami menghadapi kekangan sistem: tumpuan manusia. Kami pada dasarnya telah membina pasukan jurutera junior yang sangat berkebolehan, kemudian menugaskan jurutera kami untuk mengawasi mereka dengan teliti. Itu tidak akan dapat dikembangkan.
Peralihan perspektif
Kami sedar kami sedang mengoptimumkan perkara yang salah. Kami mengorientasikan sistem kami di sekitar sesi pengekodan dan PR yang digabungkan, sedangkan PR dan sesi sebenarnya hanyalah cara untuk mencapai tujuan. Aliran kerja perisian sebahagian besarnya diatur di sekitar hasil kerja: isu, tugasan, tiket, pencapaian.
Jadi kami bertanya kepada diri sendiri apa yang akan berlaku jika kami berhenti menyelia ejen secara langsung dan sebaliknya membiarkan mereka menarik kerja daripada penjejak tugasan kami.
Idea itu menjadi Symphony, spesifikasi bertulis yang berfungsi sebagai penyelia untuk menyelaras kerja agentic.
Menukar penjejak isu kami menjadi penyelaras ejen
Symphony bermula dengan konsep mudah: mana-mana tugas terbuka patut diambil dan diselesaikan oleh ejen. Daripada mengurus sesi Codex dalam berbilang tab, kami menjadikan penjejak isu kami sebagai satah kawalan.
Dalam persediaan ini, setiap isu Linear terbuka dipetakan kepada ruang kerja ejen khusus. Symphony memerhati papan tugasan secara berterusan dan memastikan setiap tugas aktif mempunyai ejen yang berjalan dalam gelung sehingga ia selesai. Jika ejen ranap atau tersekat, Symphony memulakannya semula. Jika kerja baharu muncul, Symphony akan mengambilnya dan mula mengatur kerja.
Kami membina aliran kerja kami berdasarkan status tiket, menggunakan pengurus tugasan Linear sebagai mesin keadaan.
Dalam amalan, Symphony memisahkan kerja daripada sesi dan daripada pull request. Sesetengah isu menghasilkan berbilang PR merentas repo; yang lain ialah penyiasatan atau analisis semata-mata yang tidak pernah menyentuh pangkalan kod.
Sebaik sahaja kerja diabstrakkan dengan cara ini, tiket boleh mewakili unit kerja yang jauh lebih besar.
Kami kerap menggunakan Symphony untuk menyelaraskan ciri yang kompleks dan migrasi infrastruktur. Contohnya, kami mungkin memfailkan tugasan yang meminta ejen menganalisis pangkalan kod, Slack atau Notion dan menghasilkan pelan pelaksanaan. Setelah kami berpuas hati dengan pelan itu, ejen menjana pokok tugasan, memecahkan kerja kepada beberapa peringkat dan mentakrifkan pergantungan antara tugasan.
Ejen hanya mula mengerjakan tugasan yang tidak tersekat, jadi pelaksanaan berjalan secara semula jadi dan optimum secara selari untuk DAG ini (satu urutan langkah pelaksanaan). Sebagai contoh, kami menandakan naik taraf React sebagai terhalang sementara menunggu migrasi ke Vite. Seperti yang dijangkakan, agen mula menaik taraf React hanya selepas migrasi kepada Vite selesai.
Ejen juga boleh mencipta kerja sendiri. Semasa pelaksanaan atau semakan, mereka sering menyedari penambahbaikan yang berada di luar skop tugasan semasa: isu prestasi, peluang pemfaktoran semula, atau seni bina yang lebih baik. Apabila itu berlaku, mereka hanya mencipta isu baharu yang boleh kami nilai dan jadualkan kemudian—banyak tugasan susulan ini juga diambil oleh ejen. Sementara kami memantau proses ini, ejen kekal teratur dan memastikan kerja terus bergerak ke hadapan.
Cara bekerja ini mengurangkan dengan ketara kos kognitif untuk memulakan kerja yang samar. Jika ejen tersilap, itu masih maklumat yang berguna dan kos kepada kami hampir sifar. Kami boleh memfailkan tiket dengan sangat murah untuk ejen membuat prototaip dan meneroka, serta membuang mana-mana penerokaan yang kami tidak suka.
Oleh sebab penyelaras berjalan pada devbox dan tidak pernah tidur, kami boleh menambah tugasan dari mana-mana sahaja dan tahu ejen akan mengambilnya. Sebagai contoh, seorang jurutera dalam pasukan kami membuat tiga perubahan penting daripada aplikasi Linear pada telefonnya dari sebuah kabin yang selesa dengan wifi yang teruk.
Peningkatan penerokaan daripada cara bekerja ini
Apabila memerhatikan kesan menggunakan Symphony, perubahan yang paling ketara ialah hasil. Dalam kalangan beberapa pasukan di OpenAI, kami melihat bilangan PR yang diterima meningkat sebanyak 500% dalam tiga minggu pertama. Di luar OpenAI, pengasas Linear, Karri Saarinen, mengetengahkan lonjakan dalam ruang kerja yang dicipta(dibuka dalam tetingkap baru) semasa kami melancarkan Symphony. Namun, perubahan yang lebih mendalam ialah cara pasukan berfikir tentang kerja.
Apabila jurutera kami tidak lagi meluangkan masa menyelia sesi Codex, ekonomi perubahan kod berubah sepenuhnya. Kos yang dirasakan bagi setiap perubahan menurun kerana kami tidak lagi melaburkan usaha manusia untuk memacu pelaksanaan itu sendiri.
Itu mengubah tingkah laku kami. Kini menjadi remeh untuk memulakan tugasan spekulatif dalam Symphony. Cuba idea, teroka pemfaktoran semula, uji hipotesis, dan hanya menyimpan hasil yang kelihatan menjanjikan.
Ia juga meluaskan siapa yang boleh memulakan kerja. Pengurus produk dan pereka kami kini boleh memfailkan permintaan ciri terus ke dalam Symphony. Mereka tidak perlu menyemak repo atau mengurus sesi Codex. Mereka menerangkan ciri itu dan mendapat kembali pakej semakan yang termasuk panduan video tentang ciri yang berfungsi dalam produk sebenar.
Symphony juga menyerlah dalam monorepo berskala besar (seperti yang kami miliki di OpenAI), apabila peringkat akhir untuk menggabungkan PR menjadi lambat dan mudah gagal. Sistem memantau CI, melakukan rebase apabila diperlukan, menyelesaikan konflik, mencuba semula semakan yang tidak stabil, dan secara umumnya membimbing perubahan melalui saluran pembangunan. Apabila tiket mencapai status Penggabungan, kami amat yakin bahawa perubahan tersebut akan berjaya digabungkan ke dalam cabang utama tanpa perlu pemantauan berterusan oleh manusia.
Selepas melaksanakan Symphony, kami menyerahkan lebih banyak kerja kepada ejen dan menumpukan pada tugasan yang lebih sukar dan lebih bersifat penerokaan.
Selepas melaksanakan Symphony, kami menyerahkan lebih banyak kerja kepada ejen dan menumpukan pada tugasan yang lebih sukar dan lebih bersifat penerokaan.
Kemajuan datang dengan masalah baharu yang berbeza
Beroperasi pada tahap ini datang dengan pertukaran. Apabila kami beralih daripada membimbing ejen secara interaktif kepada memberi mereka kerja pada peringkat tiket, kami kehilangan keupayaan untuk sentiasa menolak mereka di pertengahan jalan dan membetulkan haluan apabila perlu. Kadangkala ejen menghasilkan sesuatu yang langsung tersasar. Itu berguna—kegagalan tersebut mendedahkan jurang dalam sistem dan membantu kami menjadikannya lebih teguh.
Daripada menampal hasilnya secara manual, kami menambah pagar pelindung dan kemahiran supaya ejen boleh berjaya pada kali seterusnya. Dari masa ke masa, ini membawa kami menambah keupayaan baharu pada harness kami, seperti menjalankan ujian hujung ke hujung, mengendalikan aplikasi melalui Chrome DevTools dan mengurus ujian asap QA. Kami meningkatkan dokumentasi kami dengan ketara dan menjelaskan rupa hasil yang baik.
Bukan setiap tugasan sesuai dengan gaya kerja Symphony. Sesetengah masalah masih memerlukan jurutera bekerja terus dengan sesi Codex interaktif, terutamanya masalah yang samar atau kerja yang memerlukan pertimbangan dan kepakaran yang kukuh. Dalam amalan, ini biasanya ialah tugasan yang paling menarik dan menyeronokkan untuk diluangkan masa oleh jurutera kami.
Bezanya ialah Symphony boleh mengendalikan sebahagian besar kerja pelaksanaan rutin. Itu membolehkan jurutera menumpukan pada satu masalah sukar pada satu masa dan bukannya sentiasa bertukar konteks antara tugasan yang lebih kecil.
Kami juga mendapati bahawa menganggap ejen sebagai nod tegar dalam mesin keadaan tidak berfungsi dengan baik. Model-model menjadi semakin pintar dan mampu menyelesaikan masalah yang lebih besar daripada kerangka yang cuba kita tetapkan untuknya. Versi awal kerja agentik kami hanya meminta Codex melaksanakan tugas tersebut. Pendekatan itu terbukti terlalu terhad. Codex berupaya sepenuhnya untuk mencipta berbilang PR serta membaca maklum balas semakan dan menanganinya. Jadi kami memberikannya alat—gh CLI, keupayaan untuk membaca log CI, dan sebagainya—dan kini kami boleh meminta Codex melakukan lebih banyak perkara, seperti menutup PR lama atau mendapatkan laporan tentang kerja yang telah disiapkan berbanding yang ditinggalkan. Jenis tugasan ini jauh di luar skop pelaksanaan ciri awal.
Jadi akhirnya kami bergerak ke arah memberi ejen objektif dan bukannya peralihan ketat, sama seperti pengurus yang baik akan memberikan matlamat kepada laporan langsung dalam pasukannya. Kekuatan model-model datang daripada keupayaan mereka untuk menaakul, jadi berikan model-model tersebut alat dan konteks, lalu biarkan model-model tersebut menghasilkan yang terbaik.
Menggunakan Symphony untuk membina Symphony
Apabila anda membuka repositori Symphony,(dibuka dalam tetingkap baru) perkara pertama yang anda akan perasan ialah Symphony secara teknikal hanyalah fail SPEC.md —takrifan masalah dan penyelesaian yang dimaksudkan. Daripada membina sistem penyeliaan yang kompleks, kami mentakrifkan masalah dan penyelesaian yang dirancang, sekali gus memberikan hala tuju peringkat tinggi kepada ejen.
Pelaksanaan rujukan ditulis dalam Elixir—kerana apabila kod pada bebas secara berkesan, anda akhirnya boleh memilih bahasa berdasarkan kekuatannya, seperti keserentakan Elixir—tetapi idea terasnya boleh dinyatakan dalam dokumen Markdown yang ringkas. Kami menggalakkan anda menghalakan ejen pengekodan kegemaran anda kepada spesifikasi itu dan memintanya untuk melaksanakan versinya sendiri.
Versi pertama Symphony hanyalah sesi Codex yang berjalan dalam tmux, meninjau Linear secara berkala dan melancarkan sub-ejen untuk tugasan baharu. Ia berfungsi, tetapi tidak begitu boleh dipercayai. Versi kedua berada dalam repositori projek utama kami, yang dibina dengan mengambil kira ejen. Kami telah pun membina rangka kerja ejen untuk memberikan ejen kemahiran dan konteks bagi melakukan kerja berkualiti tinggi dalam repo ini, jadi Symphony hanya menghubungkan semuanya.
Setelah fungsi asas wujud, kami menggunakan Symphony untuk membina Symphony.
Apabila kami menunjukkan secara dalaman sistem yang mengurus tugasan dan melampirkan video bukti kerja, reaksinya amat positif: saluran projek Symphony kami berkembang dan pasukan di seluruh organisasi mula menggunakannya secara organik. Kesesuaian pasaran produk dalaman ialah prasyarat untuk pelancaran luaran di OpenAI. Berdasarkan penggunaan yang kami lihat di OpenAI, menjadi jelas bahawa kami patut berkongsi Symphony melangkaui tembok syarikat.
Jadi, kami mengekstrak idea itu ke dalam SPEC.md kendiri dan meminta Codex melaksanakannya. Untuk implementasi rujukan, kami memilih Elixir, bahasa yang agak khusus dengan primitif yang sangat baik untuk menyelaras dan menyelia proses serentak. Codex membina implementasi Elixir dalam satu percubaan dan dari situ kami terus membuat iterasi pada kedua-dua spesifikasi dan implementasi. Untuk memperkemas spesifikasi tersebut, kami malah meminta Codex melaksanakannya dalam beberapa bahasa lain—TypeScript, Go, Rust, Java, Python—dan menggunakan hasilnya untuk mengenal pasti kekaburan serta mempermudah sistem. Ia berjaya dalam setiap bahasa.
Melalui proses membina Symphony, kami membuang banyak kerumitan sampingan, seperti kebergantungan pada repositori tertentu atau Linear MCP. Symphony tidak lagi bergantung pada repositori atau aliran kerja dalaman kami. Pendekatan teras menjadi mudah:
Bagi setiap tugas terbuka, pastikan ejen berjalan dalam ruang kerjanya sendiri.
Selain membantu dengan kerja yang sedang dijalankan, aliran kerja pembangunan kini juga merupakan sesuatu yang diketahui dan diikuti oleh agen. Aliran kerja pembangunan—bekerja pada isu, periksa repositori, menetapkannya sebagai sedang dijalankan supaya PM tahu ia sedang diusahakan, menambahkan permintaan tarik (PR), mengalihkannya kepada status Semak, melampirkan video, dan sebagainya—kini didokumentasikan dalam fail WORKFLOW.md yang ringkas. Semua ini ialah proses yang diikuti oleh manusia, tetapi tidak pernah didokumentasikan. Daripada bergantung pada set langkah tersirat ini, kami kini mendokumentasikannya dan Symphony memastikan ejen mengikutinya. Ini membolehkan kita membina ejen yang bekerja bersama-sama kita. Jika kami memutuskan bahawa ejen juga perlu melampirkan refleksi kendiri pada kerja yang telah disiapkan, kami akan menambahkannya pada WORKFLOW.md, dan Symphony akan membimbing ejen ke langkah tersebut.
Kami juga berpeluang menggunakan Codex dalam mod pelayan aplikasi(dibuka dalam tetingkap baru), iaitu mod tanpa antara muka pengguna terbina dalam untuk Codex. Mod ini membolehkan kami menjalankan Codex dan berinteraksi dengannya secara programatik melalui API JSON-RPC yang didokumentasikan dengan baik bagi perkara seperti memulakan utas atau memberi reaksi terhadap giliran. Ini lebih mudah dan boleh diskala berbanding cuba berinteraksi dengan Codex melalui CLI atau sesi tmux secara langsung.
Codex App Server amat sesuai untuk kes penggunaan kami: kami memanfaatkan platform yang disediakan oleh Codex sambil mempunyai penyesuaian dan hook untuk disambungkan. Sebagai contoh, untuk mengelakkan pendedahan token akses Linear kepada subejen, kami menggunakan panggilan alat dinamik(dibuka dalam tetingkap baru) untuk mendedahkan fungsi mentah linear_graphql yang melaksanakan permintaan arbitrari terhadap Linear, tanpa bergantung pada MCP atau mendedahkan token akses kepada kontena.
Apa seterusnya
Symphony ialah lapisan penyelaras yang direka dengan sengaja agar minimal. Kami menjadikannya sumber terbuka untuk menunjukkan keupayaan Codex App Server apabila digandingkan dengan pelbagai alat aliran kerja, seperti Linear. Oleh itu, kami tidak merancang untuk mengekalkan Symphony sebagai produk kendiri. Anggaplah ini sebagai pelaksanaan rujukan. Sama seperti ramai pembangun mengarahkan ejen pengaturcaraan mereka kepada 'harness engineering post' untuk membina kerangka repositori mereka, kami berharap anda mengarahkan ejen pengaturcaraan kegemaran anda kepada spesifikasi(dibuka dalam tetingkap baru) dan repositori(dibuka dalam tetingkap baru) Symphony untuk membina versi anda sendiri yang disesuaikan dengan persekitaran anda.
Kuasa itu datang daripada Codex dan pelayan aplikasinya. Symphony ialah cara untuk menghubungkan Codex kepada Linear, dua perkara yang telah kami gunakan, bagi menyelesaikan masalah pengurusan kerja. Apabila ejen pengekodan menjadi lebih baik dalam penaakulan dan mengikuti arahan, kami mengesyaki kekangan di syarikat lain juga akan beralih daripada menulis kod kepada mengurus kerja agentic. Bahagian yang menarik ialah halangan untuk melakukan eksperimen dengan sistem ejen pengekodan ini kini sangat rendah. Anda hanya boleh membina sesuatu dengan Codex.
Seruan komuniti
Kami sangat gembira melihat komuniti kejuruteraan menggunakan Symphony dalam beberapa minggu sejak pelancarannya, dengan memperoleh lebih daripada 15K bintang GitHub(dibuka dalam tetingkap baru) setakat 23 April.