Sebuah spesifikasi sumber terbuka untuk orkestrasi Codex: Symphony
Oleh Alex Kotliarskyi, Victor Zhu, dan Zach Brock
Enam bulan lalu, saat mengerjakan alat produktivitas internal, tim kami membuat keputusan yang kontroversial (saat itu): kami akan membangun repo kami tanpa kode yang ditulis manusia. Setiap baris di repositori proyek kami harus dihasilkan oleh Codex.
Untuk mewujudkannya, kami mendesain ulang alur kerja rekayasa kami dari nol. Kami membangun repositori yang ramah agen, berinvestasi besar pada pengujian otomatis dan batasan pengamanan, serta memperlakukan Codex sebagai rekan tim seutuhnya. Kami mendokumentasikan perjalanan itu dalam post blog kami sebelumnya tentang harness rekayasa.
Dan itu berhasil, tetapi kemudian kami menghadapi hambatan berikutnya: peralihan konteks.
Untuk menyelesaikan masalah baru ini, kami membangun sistem bernama Symphony. Symphony(terbuka di jendela baru) adalah orkestrator agen yang mengubah papan manajemen proyek seperti Linear menjadi bidang kendali untuk agen pengodean. Setiap tugas terbuka mendapatkan agen, agen berjalan terus-menerus, dan manusia meninjau hasilnya.
Post ini menjelaskan bagaimana kami membuat Symphony—yang menghasilkan peningkatan 500% dalam pull request yang berhasil masuk di beberapa tim—dan cara menggunakannya untuk mengubah pelacak isu Anda sendiri menjadi orkestrator agen yang selalu aktif.
Batas atas agen pengodean interaktif
Bahkan ketika semakin mudah digunakan, agen pengodean—baik diakses melalui aplikasi web maupun CLI—masih merupakan alat interaktif.
Seiring dengan meningkatnya skala pekerjaan agentik di OpenAI, kami menemukan jenis beban baru. Setiap insinyur akan membuka beberapa sesi Codex, menetapkan tugas, meninjau output, mengarahkan agen, lalu mengulanginya. Dalam praktiknya, kebanyakan orang hanya bisa dengan nyaman mengelola tiga sampai lima sesi sekaligus sebelum peralihan konteks menjadi menyakitkan. Lebih dari itu, produktivitas menurun. Kita mungkin akan lupa sesi mana yang sedang mengerjakan apa, berpindah antar terminal untuk mendorong agen kembali ke jalur yang benar, dan melakukan debugging tugas berdurasi panjang yang macet di tengah jalan.
Agen-agen itu cepat, tetapi kami memiliki hambatan sistem: perhatian manusia. Kami secara efektif telah membangun tim berisi insinyur junior yang sangat mumpuni, lalu menugaskan insinyur manusia kami untuk mengatur mereka dengan detail secara berlebihan. Itu tidak akan bisa diskalakan.
Perubahan perspektif
Kami menyadari bahwa kami mengoptimalkan hal yang salah. Kami mengarahkan sistem kami pada sesi pengodean dan PR yang telah digabungkan, padahal PR dan sesi sebenarnya hanyalah sarana menuju tujuan akhir. Alur kerja perangkat lunak sebagian besar diatur berdasarkan hasil kerja: isu, tugas, tiket, milestone.
Jadi kami bertanya pada diri sendiri apa yang akan terjadi jika kami berhenti mengawasi agen secara langsung dan malah membiarkan mereka menarik pekerjaan dari pelacak tugas kami.
Ide itu menjadi Symphony, sebuah spesifikasi tertulis yang berfungsi sebagai supervisor untuk mengorkestrasi pekerjaan agentik.
Mengubah pelacak isu kami menjadi orkestrator agen
Symphony dimulai dari konsep sederhana: setiap tugas terbuka harus diambil dan diselesaikan oleh agen. Alih-alih mengelola sesi Codex di banyak tab, kami menjadikan pelacak isu kami sebagai bidang kendali.
Dalam pengaturan ini, setiap isu Linear yang terbuka dipetakan ke workspace agen khusus. Symphony terus memantau papan tugas dan memastikan bahwa setiap tugas aktif memiliki agen yang berjalan dalam siklus sampai selesai. Jika agen crash atau macet, Symphony akan memulainya ulang. Jika ada pekerjaan baru muncul, Symphony akan mengambilnya dan mulai mengatur pekerjaan tersebut.
Kami membangun alur kerja kami berdasarkan status tiket, menggunakan manajer tugas Linear sebagai mesin state.
Dalam praktiknya, Symphony memisahkan pekerjaan dari sesi dan dari pull request. Beberapa isu menghasilkan beberapa PR di berbagai repositori; yang lain murni investigasi atau analisis yang tidak pernah menyentuh basis kode.
Begitu pekerjaan diabstraksikan dengan cara ini, tiket dapat merepresentasikan unit pekerjaan yang jauh lebih besar.
Kami rutin menggunakan Symphony untuk mengorkestrasi fitur kompleks dan migrasi infrastruktur. Misalnya, kami dapat membuat tugas yang meminta agen menganalisis basis kode, Slack, atau Notion dan menghasilkan rencana implementasi. Setelah kami puas dengan rencananya, agen menghasilkan bagan pohon tugas, memecah pekerjaan menjadi beberapa tahap dan mendefinisikan dependensi antar tugas.
Agen hanya mulai mengerjakan tugas yang tidak terblokir, sehingga eksekusi berjalan secara alami dan optimal secara paralel untuk DAG ini (urutan langkah eksekusi). Dalam contoh di bawah, kami menandai peningkatan React sebagai terblokir pada migrasi ke Vite. Sesuai dugaan, agen baru mulai melakukan peningkatan React hanya setelah migrasi ke Vite selesai.
Agen juga dapat membuat pekerjaan sendiri. Selama implementasi atau peninjauan, mereka sering menemukan perbaikan yang berada di luar cakupan tugas saat ini: masalah performa, peluang refactoring, atau arsitektur yang lebih baik. Ketika itu terjadi, mereka cukup membuat isu baru yang bisa kami evaluasi dan jadwalkan nanti—banyak dari tugas lanjutan ini juga diambil oleh agen. Sementara kami mengawasi proses ini, agen tetap terorganisasi dan memastikan pekerjaan terus bergerak maju.
Cara kerja ini secara dramatis mengurangi biaya kognitif untuk memulai pekerjaan yang ambigu. Jika agen melakukan sesuatu dengan salah, itu tetap informasi yang berguna, dan biayanya bagi kami nyaris nol. Kami bisa dengan sangat murah membuat tiket agar agen membuat prototipe dan bereksplorasi, lalu membuang eksplorasi apa pun yang tidak kami sukai.
Karena orkestrator berjalan di devbox dan tidak pernah tidur, kami bisa menambahkan tugas dari mana saja dan tahu agen akan mengambilnya. Misalnya, seorang engineer di tim kami membuat tiga perubahan signifikan dari aplikasi Linear di ponselnya dari kabin nyaman dengan wifi yang buruk.
Peningkatan eksplorasi dari bekerja dengan cara ini
Saat mengamati dampak bekerja dengan Symphony, perubahan yang paling jelas adalah output. Di beberapa tim di OpenAI, kami melihat jumlah PR yang berhasil masuk meningkat 6X dalam tiga minggu pertama. Di luar OpenAI, pendiri Linear Karri Saarinen menyoroti lonjakan workspace yang dibuat(terbuka di jendela baru) saat kami merilis Symphony. Namun, perubahan yang lebih dalam adalah bagaimana tim memikirkan pekerjaan.
Ketika insinyur kami tidak lagi menghabiskan waktu untuk mengawasi sesi Codex, aspek ekonomi kode berubah sepenuhnya. Biaya yang dirasakan untuk setiap perubahan turun karena kami tidak lagi menginvestasikan upaya manusia untuk menggerakan implementasi itu sendiri.
Hal tersebut mengubah perilaku kami. Kini, memulai tugas-tugas spekulatif di Symphony menjadi hal yang sangat mudah. Coba sebuah ide, jajaki kemungkinan refactoring, uji sebuah hipotesis, dan pertahankan hanya hasil-hasil yang tampak menjanjikan.
Ini juga memperluas siapa yang dapat memulai pekerjaan. Manajer produk dan desainer kami kini dapat langsung mengajukan permintaan fitur ke Symphony. Mereka tidak perlu checkout repo atau mengelola sesi Codex. Mereka cukup mendeskripsikan fitur tersebut, dan sebagai balasannya, mereka akan menerima paket tinjauan yang mencakup video panduan yang memperlihatkan fitur tersebut berjalan di dalam produk yang sebenarnya.
Symphony juga unggul di monorepo besar (seperti yang kami miliki di OpenAI) di mana tahap akhir untuk memasukkan PR berjalan lambat dan rapuh. Sistem memantau CI, melakukan rebase saat diperlukan, menyelesaikan konflik, mencoba ulang pemeriksaan yang tidak stabil, dan secara umum mengawal perubahan melalui pipeline. Pada saat tiket mencapai Merging, kami sangat yakin perubahan tersebut akan masuk ke cabang utama tanpa perlu pengawasan manual dari manusia.
Kemajuan membawa masalah-masalah baru yang berbeda.
Beroperasi pada tingkat ini membawa konsekuensi. Ketika kami beralih dari memandu agen secara interaktif menjadi sekadar menugaskan pekerjaan pada tingkat tiket, kami kehilangan kemampuan untuk terus-menerus memberikan arahan di tengah proses kerja serta melakukan koreksi arah saat diperlukan. Terkadang, hasil kerja agen justru meleset sepenuhnya dari sasaran. Itu berguna—kegagalan tersebut mengungkap celah dalam sistem dan membantu kami membuatnya lebih tangguh.
Alih-alih menambal hasilnya secara manual, kami menambahkan batasan pengamanan dan kemampuan agar agen bisa berhasil di kesempatan berikutnya. Seiring waktu, ini membuat kami menambahkan kemampuan baru ke harness kami, seperti menjalankan pengujian menyeluruh, mengendalikan aplikasi melalui Chrome DevTools, dan mengelola pengujian smoke QA. Kami meningkatkan kualitas dokumentasi kami secara signifikan dan memperjelas seperti apa standar yang baik itu.
Tidak setiap tugas cocok dengan gaya kerja Symphony. Beberapa masalah tetap memerlukan insinyur yang bekerja langsung dengan sesi Codex interaktif, terutama masalah yang ambigu atau pekerjaan yang membutuhkan penilaian dan keahlian yang kuat. Pada praktiknya, ini biasanya merupakan tugas-tugas yang paling menarik dan menyenangkan bagi para insinyur kami untuk dikerjakan.
Perbedaannya adalah Symphony dapat menangani sebagian besar pekerjaan implementasi rutin. Itu memungkinkan insinyur fokus pada satu masalah sulit pada satu waktu alih-alih terus-menerus melakukan peralihan konteks di antara tugas yang lebih kecil.
Kami juga belajar bahwa memperlakukan agen sebagai node kaku dalam mesin state tidak bekerja dengan baik. Model menjadi lebih pintar dan mampu memecahkan masalah yang lebih besar daripada batasan kaku yang coba kami paksakan padanya. Misalnya, versi awal memiliki semua integrasi GitHub sebagai bagian dari harness luar—contohnya, versi-versi awal mengharapkan Codex hanya membuat perubahan kode, dengan sisa proses (mengirimkan perubahan, menjalankan pengujian) ditentukan dalam kode. Versi awal pekerjaan agentik kami hanya meminta Codex mengimplementasikan tugas. Pendekatan itu terbukti terlalu membatasi. Codex sepenuhnya mampu membuat beberapa PR sekaligus membaca masukan peninjauan dan menanganinya. Jadi kami memberinya alat CLI —gh, skill untuk membaca log CI, dan sebagainya—dan sekarang kami dapat meminta Codex melakukan lebih banyak hal, seperti menutup PR lama atau menarik laporan tentang pekerjaan yang selesai vs. yang ditinggalkan. Jenis-jenis tugas seperti ini berada jauh di luar cakupan awal implementasi fitur yang telah kami tetapkan sebelumnya.
Jadi pada akhirnya kami beralih dengan memberi agen tujuan alih-alih transisi yang dibatasi secara ketat, mirip seperti manajer yang baik akan menetapkan sasaran kepada laporan langsung di timnya. Kekuatan model berasal dari kemampuannya untuk bernalar, jadi beri mereka alat dan konteks lalu biarkan mereka bekerja.
Menggunakan Symphony untuk membangun Symphony
Saat Anda membuka repositori Symphony, hal pertama yang akan Anda perhatikan adalah bahwa Symphony secara teknis hanyalah sebuah file SPEC.md—definisi masalah dan solusi yang dimaksudkan. Alih-alih membangun sistem supervisi yang kompleks, kami mendefinisikan masalah dan solusi yang dimaksud, memberi agen arahan tingkat tinggi.
Implementasi referensinya ditulis dalam Elixir—karena ketika kode pada dasarnya gratis, Anda akhirnya bisa memilih bahasa berdasarkan keunggulannya, seperti konkurensi Elixir—tetapi ide intinya bisa dijelaskan dalam dokumen Markdown sederhana. Kami mendorong Anda untuk mengarahkan agen pengodean favorit Anda ke spesifikasi tersebut dan memintanya mengimplementasikan versinya sendiri.
Versi pertama Symphony hanyalah sesi Codex yang berjalan di tmux, melakukan polling ke Linear dan memunculkan sub-agen untuk menangani tugas baru. Itu berfungsi, tetapi tidak terlalu andal. Versi kedua berada di dalam repositori proyek utama kami, yang memang dirancang dengan mempertimbangkan keberadaan agen. Kami sudah membangun harness agen untuk memberi agen kemampuan dan konteks agar dapat menghasilkan pekerjaan berkualitas tinggi di repo ini, jadi Symphony tinggal menghubungkan semuanya.
Begitu fungsionalitas dasarnya ada, kami menggunakan Symphony untuk membangun Symphony.
Saat kami mendemonstrasikan secara internal sistem yang mengelola tugas dan melampirkan video bukti kerjanya, reaksinya sangat positif: saluran proyek Symphony kami berkembang, dan tim di seluruh organisasi mulai menggunakannya secara organik. Product-market fit internal adalah prasyarat untuk peluncuran eksternal di OpenAI. Berdasarkan penggunaan yang kami amati di OpenAI, menjadi jelas bagi kami bahwa Symphony sudah saatnya dibagikan hingga ke luar lingkup perusahaan.
Jadi kami mewujudkan idenya menjadi SPEC.md mandiri dan meminta Codex untuk mengimplementasikannya. Untuk implementasi referensi, kami memilih Elixir, bahasa yang tergolong niche dengan primitive yang sangat baik untuk mengorkestrasi dan mengawasi proses konkuren. Codex membangun implementasi Elixir tersebut dalam satu kali pengerjaan, dan sejak saat itu kami terus melakukan iterasi, baik pada spesifikasi maupun implementasinya. Untuk menyempurnakan spesifikasi tersebut, kami bahkan meminta Codex untuk mengimplementasikannya dalam beberapa bahasa lain—TypeScript, Go, Rust, Java, Python—dan menggunakan hasilnya untuk mengidentifikasi ambiguitas serta menyederhanakan sistem. Codex berhasil di setiap bahasa.
Melalui proses membangun Codex, kami menghapus banyak kompleksitas insidental, seperti ketergantungan pada repositori tertentu atau Linear MCP. Symphony tidak lagi bergantung pada repositori atau alur kerja internal kami. Pendekatan intinya menjadi sederhana:
Untuk setiap tugas terbuka, pastikan ada agen yang berjalan di workspace-nya sendiri.
Selain membantu pekerjaan yang sedang aktif, alur kerja pengembangan kini menjadi sesuatu yang diketahui dan diikuti agen. Alur kerja pengembangan—mengerjakan sebuah isu, checkout repo, menandainya "dalam progress" agar PM tahu itu sedang dikerjakan, menambahkan PR, memindahkannya ke status Peninjauan, melampirkan video, dan seterusnya—kini termuat dalam file alur kerja.md yang sederhana. Semua ini adalah proses yang diikuti manusia, tetapi tidak pernah didokumentasikan. Daripada mengandalkan sekumpulan langkah implisit ini, sekarang kami mendokumentasikannya, dan Symphony memastikan agen mengikutinya. Ini memungkinkan kami membangun agen yang bekerja bersama kami. Jika kami memutuskan bahwa agen juga harus melampirkan refleksi diri ke pekerjaan yang sudah selesai, kami akan menambahkannya ke alur kerja.md, dan Symphony akan membimbing agen ke langkah tersebut.
Kami juga sempat menggunakan Codex dalam mode app server(terbuka di jendela baru), mode headless bawaan untuk Codex. Mode ini memungkinkan kami menjalankan Codex dan berbicara dengannya secara terprogram melalui API JSON-RPC yang terdokumentasi dengan baik untuk hal-hal seperti memulai thread atau merespons giliran. Mode ini jauh lebih nyaman dan dapat diskalakan daripada mencoba berinteraksi dengan Codex melalui CLI atau sesi tmux langsung.
Codex App Server sangat cocok untuk kasus penggunaan kami: kami memanfaatkan harness yang disediakan Codex dengan tetap memiliki knob dan hook untuk disambungkan. Misalnya, untuk menghindari mengekspos akses token Linear ke subagen, kami menggunakan dynamic tool calls(terbuka di jendela baru) untuk mengekspos fungsi mentah linear_graphql yang mengeksekusi permintaan arbitrer terhadap Linear, tanpa bergantung pada MCP atau mengekspos akses token ke container.
Apa berikutnya
Symphony adalah lapisan orkestrasi minimal yang memang disengaja. Kami menjadikannya sumber terbuka untuk mendemonstrasikan kekuatan Codex App Server saat dipasangkan dengan berbagai alat alur kerja, seperti Linear. Karena itu, kami tidak berencana mempertahankan Symphony sebagai produk mandiri. Anggap saja ini sebagai implementasi referensi. Mirip dengan bagaimana banyak pengembang yang mengarahkan agen pengodean mereka ke post harness insinyur untuk menyusun repositori mereka, kami berharap Anda mengarahkan agen pengodean favorit Anda ke spesifikasi(terbuka di jendela baru) dan repositori(terbuka di jendela baru) Symphony untuk membangun versi Anda sendiri yang disesuaikan dengan lingkungan Anda.
Kekuatannya berasal dari Codex dan app server-nya. Symphony adalah cara untuk menghubungkan Codex ke Linear, dua hal yang sudah kami gunakan, untuk menyelesaikan masalah manajemen pekerjaan. Seiring agen pengodean menjadi lebih baik dalam bernalar dan mengikuti instruksi, kami menduga hambatan di perusahaan lain juga akan berubah dari menulis kode menjadi mengelola pekerjaan agentik. Bagian yang menarik adalah hambatan untuk bereksperimen dengan sistem agen pengodean ini sekarang ternyata sangat rendah. Anda bisa langsung membangun sesuatu dengan Codex.
Apresiasi untuk komunitas
Kami sangat senang melihat komunitas rekayasa menggunakan Symphony dalam beberapa minggu sejak peluncurannya, meraih lebih dari 15 ribu bintang GitHub(terbuka di jendela baru) per 23 April.