Membuka kunci Codex: bagaimana kami membina pelayan aplikasi
Oleh Celia Chen, Ahli Kakitangan Teknikal
Ejen pengekodan OpenAI, Codex, wujud merentas banyak platform: aplikasi web(dibuka dalam tetingkap baru), CLI(dibuka dalam tetingkap baru), sambungan IDE(dibuka dalam tetingkap baru), dan aplikasi Codex macOS baharu. Di sebalik tabir, semuanya digerakkan oleh rangka Codex yang sama—gelung ejen dan logik yang mendasari semua pengalaman Codex. Apakah pautan kritikal antara mereka? Codex App Server(dibuka dalam tetingkap baru), API 1JSON-RPC dua hala yang mesra klien.
Dalam catatan ini, kami akan memperkenalkan Codex App Server; kami akan berkongsi pengetahuan kami setakat ini tentang cara terbaik untuk mengintegrasikan keupayaan Codex ke dalam produk anda bagi membantu pengguna anda mempercepatkan aliran kerja mereka. Kami akan membincangkan seni bina dan protokol App Server serta cara ia diintegrasikan dengan pelbagai permukaan Codex, serta petua untuk memanfaatkan Codex, sama ada anda mahu menjadikan Codex sebagai penilai kod, ejen SRE, atau pembantu pengekodan.
Sebelum mendalami seni bina, adalah berguna untuk mengetahui latar belakang pelayan aplikasi. Pada mulanya, App Server adalah cara yang praktikal untuk menggunakan semula harness Codex merentas produk yang secara beransur-ansur berkembang menjadi protokol standard kami.
Codex CLI bermula sebagai TUI (antara muka pengguna terminal), yang bermaksud Codex diakses melalui terminal. Apabila kami membina sambungan VS Code (cara yang lebih mesra IDE untuk berinteraksi dengan ejen Codex), kami memerlukan cara untuk menggunakan abah-abah yang sama supaya dapat memacu gelung ejen yang sama daripada antara muka pengguna IDE tanpa melaksanakannya semula. Ini bermaksud menyokong corak interaksi yang kaya melangkaui permintaan/tindak balas, seperti meneroka ruang kerja, menstrim kemajuan semasa ejen membuat penaakulan, dan mengeluarkan perbezaan. Kami mula-mula bereksperimen dengan mendedahkan Codex sebagai pelayan MCP(dibuka dalam tetingkap baru), tetapi mengekalkan semantik MCP dengan cara yang masuk akal untuk VS Code terbukti sukar. Sebaliknya, kami memperkenalkan protokol JSON-RPC yang mencerminkan gelung TUI, yang menjadi versi pertama tidak rasmi(dibuka dalam tetingkap baru) pelayan aplikasi. Pada masa itu, kami tidak menjangkakan klien lain akan bergantung pada App Server, jadi ia tidak direka bentuk sebagai API yang stabil.
Apabila penerimaan Codex meningkat sepanjang beberapa bulan berikutnya, pasukan dalaman dan rakan kongsi luaran mahukan keupayaan untuk membenamkan abah-abah yang sama ke dalam produk mereka sendiri bagi mempercepatkan aliran kerja pembangunan perisian pengguna mereka. Sebagai contoh, JetBrains dan Xcode mahukan pengalaman ejen bertaraf IDE, manakala aplikasi desktop Codex perlu menyelaraskan banyak ejen Codex secara serentak. Tuntutan tersebut mendorong kami untuk mereka bentuk permukaan platform yang boleh dipercayai oleh produk kami dan integrasi rakan kongsi dengan selamat dari semasa ke semasa. Ia perlu mudah untuk diintegrasikan dan serasi ke belakang, bermakna kami boleh mengembangkan protokol tanpa menjejaskan pelanggan sedia ada.
Seterusnya, kami akan menerangkan bagaimana kami mereka bentuk seni bina dan protokol supaya klien yang berbeza boleh menggunakan abah-abah yang sama.
Pertama, mari kita perincikan apa yang terdapat di dalam abah-abah Codex dan bagaimana Pelayan Aplikasi Codex mendedahkannya kepada klien. Dalam blog Codex terakhir kami, kami menghuraikan gelung ejen teras yang menyelaraskan interaksi antara pengguna, model, dan alat. Ini adalah logik teras bagi abah-abah Codex, tetapi terdapat lebih banyak lagi untuk pengalaman ejen sepenuhnya:
1. Kitaran hayat benang dan ketekalan. Satu thread ialah perbualan Codex antara seorang pengguna dan seorang ejen. Codex mencipta, menyambung semula, mencapah, dan mengarkibkan utas, serta mengekalkan sejarah acara supaya klien boleh menyambung semula dan memaparkan garis masa yang konsisten.
2. Konfigurasi dan Auth. Codex memuat konfigurasi, menguruskan tetapan lalai, dan menjalankan aliran pengesahan seperti “Log masuk dengan ChatGPT,” termasuk keadaan kelayakan.
3. Pelaksanaan alat dan sambungan. Codex melaksanakan alat shell/fail dalam kotak pasir dan menyambungkan integrasi seperti pelayan MCP dan kemahiran supaya ia boleh mengambil bahagian dalam gelung ejen di bawah model dasar yang konsisten.
Semua logik ejen yang kami sebutkan di sini, termasuk gelung ejen teras, berada dalam satu bahagian pangkalan kod Codex CLI yang dipanggil “Codex core(dibuka dalam tetingkap baru).” Teras Codex adalah kedua-duanya sebuah pustaka di mana semua kod ejen berada dan sebuah runtime yang boleh dimulakan untuk menjalankan gelung ejen serta menguruskan ketekalan satu thread Codex (perbualan).
Untuk berguna, abah-abah Codex perlu dapat diakses oleh klien. Di sinilah Pelayan Apl memainkan peranan.
Pelayan Aplikasi ialah kedua-dua protokol JSON-RPC antara klien dan pelayan serta proses jangka panjang yang mengehoskan thread teras Codex. Seperti yang dapat kita lihat daripada gambar rajah di atas, satu proses Pelayan Aplikasi mempunyai empat komponen utama: pembaca stdio, pemproses mesej Codex, pengurus thread, dan thread teras. Pengurus thread memulakan satu sesi teras bagi setiap thread, dan pemproses mesej Codex kemudian berkomunikasi dengan setiap sesi teras secara langsung untuk menghantar permintaan pelanggan dan menerima kemas kini.
Satu permintaan klien boleh menghasilkan banyak kemas kini acara, dan acara terperinci inilah yang membolehkan kami membina antara muka pengguna yang kaya di atas Pelayan Aplikasi. Selain itu, pembaca stdio dan pemproses mesej Codex berfungsi sebagai lapisan terjemahan antara klien dan bebenang teras Codex. Mereka menterjemahkan permintaan JSON-RPC klien kepada operasi teras Codex, mendengar aliran acara dalaman teras Codex, dan kemudian mengubah acara tahap rendah tersebut kepada satu set kecil pemberitahuan JSON-RPC yang stabil dan sedia untuk UI.
Protokol JSON-RPC antara klien dan Pelayan Aplikasi adalah sepenuhnya dua hala. Satu thread yang lazim mempunyai permintaan klien dan banyak notifikasi pelayan. Selain itu, pelayan boleh memulakan permintaan apabila ejen memerlukan input, seperti kelulusan, dan kemudian menjeda giliran sehingga klien memberikan respons.
Seterusnya, kami akan menghuraikan primitif perbualan, blok binaan protokol App Server. Mereka bentuk API untuk gelung ejen adalah mencabar kerana interaksi pengguna/ejen bukan sekadar permintaan/respons yang mudah. Satu permintaan pengguna boleh berkembang menjadi satu urutan tindakan berstruktur yang perlu diwakili dengan setia oleh klien: input pengguna, kemajuan beransur-ansur ejen, dan artifak yang dihasilkan sepanjang proses (contohnya, perbezaan). Untuk memudahkan integrasi dan ketahanan aliran interaksi merentasi UI, kami telah menetapkan tiga primitif teras dengan sempadan dan kitaran hayat yang jelas:
1. Item: Item ialah unit asas input/output dalam Codex. Item dikategorikan (contohnya, mesej pengguna, mesej ejen, pelaksanaan alat, permintaan kelulusan, perbezaan) dan setiap satu mempunyai kitaran hayat yang jelas:
item/startedapabila item bermula- acara
item/*/deltapilihan sebagai aliran kandungan masuk (untuk jenis item penstriman) item/completedapabila item dimuktamadkan dengan muatan terminalnya
Kitaran hayat ini membolehkan klien mula pemaparan serta-merta pada started, menstrim kemas kini berperingkat pada delta, dan memuktamadkan pada completed.
2. Giliran: Giliran adalah satu unit kerja ejen yang dimulakan oleh input pengguna. Ia bermula apabila klien menyerahkan input (contohnya, “jalankan ujian dan ringkaskan kegagalan”) dan berakhir apabila ejen selesai menghasilkan output untuk input tersebut. Satu giliran mengandungi satu jujukan item yang mewakili langkah-langkah pertengahan dan hasil yang dihasilkan sepanjang perjalanan.
3. Thread: Thread ialah bekas tahan lama untuk sesi Codex yang berterusan antara pengguna dan ejen. Ia mengandungi pelbagai giliran. Threads boleh dicipta, disambung semula, dicabang, dan diarkibkan. Sejarah perbualan disimpan supaya pelanggan boleh menyambung semula dan memaparkan garis masa yang konsisten.
Sekarang, kita akan melihat perbualan yang dipermudahkan antara seorang klien dan seorang ejen, di mana perbualan itu diwakili oleh primitif:
Pada permulaan perbualan, klien dan pelayan perlu mewujudkan jabat tangan initialize. Klien mesti menghantar satu permintaan initialize sebelum sebarang kaedah lain, dan pelayan mengesahkan dengan satu respons. Ini memberi pelayan peluang untuk mengiklankan keupayaan dan membolehkan kedua-dua pihak bersetuju mengenai penyusunan versi protokol, bendera ciri, dan tetapan lalai sebelum kerja sebenar bermula. Berikut ialah contoh muatan daripada sambungan VS Code OpenAI:
Ini adalah apa yang pelayan kembalikan:
Apabila pelanggan membuat permintaan thread, ia akan mula-mula mencipta benang dan kemudian pusingan. Pelayan akan menghantar kembali pemberitahuan untuk kemajuan (thread/started dan turn/started). Ia juga akan menghantar semula input yang didaftarkannya sebagai item, seperti mesej pengguna di sini.
Panggilan alat juga dihantar semula kepada klien sebagai item. Selain itu, pelayan mungkin meminta kelulusan klien sebelum ia boleh menjalankan tindakan dengan menghantar permintaan pelayan. Kelulusan akan menjeda giliran sehingga pelanggan membalas sama ada “benarkan” atau “tolak.” Inilah rupa aliran kelulusan dalam sambungan VS Code:

Akhirnya, pelayan menghantar mesej ejen dan kemudian menamatkan giliran dengan turn/completed. Peristiwa delta mesej ejen menstrimkan bahagian-bahagian mesej kembali sehingga mesej dimuktamadkan dengan item/completed.
Mesej dalam rajah dipermudahkan untuk memudahkan pembacaan. Jika anda ingin melihat JSON untuk satu giliran penuh, anda boleh menjalankan klien ujian daripada repositori Codex CLI:
Sekarang, mari kita lihat bagaimana permukaan klien yang berbeza membenamkan Codex melalui Pelayan Aplikasi. Kami akan membincangkan tiga corak: aplikasi tempatan dan IDE, runtime web Codex, dan TUI.
Merentasi ketiga-tiga, pengangkutan adalah JSON-RPC melalui stdio (JSONL). JSON-RPC memudahkan pembinaan pengikatan klien dalam bahasa pilihan anda. Permukaan Codex dan integrasi rakan kongsi telah melaksanakan klien App Server dalam bahasa termasuk Go, Python, TypeScript, Swift, dan Kotlin. Untuk TypeScript, anda boleh menjana definisi secara langsung daripada protokol Rust dengan menjalankan:
Untuk bahasa lain, anda boleh menjana satu bundel Skema JSON dan memasukkannya ke dalam penjana kod pilihan anda dengan menjalankan:

Pelanggan tempatan biasanya memberkas atau mendapatkan binari App Server khusus platform, melancarkannya sebagai proses anak yang berjalan lama, dan memastikan saluran stdio dua hala kekal terbuka untuk JSON-RPC. Dalam sambungan VS Code dan Aplikasi Desktop kami, sebagai contoh, artifak yang dihantar merangkumi binari Codex khusus platform dan dipasangkan kepada versi yang telah diuji supaya klien sentiasa menjalankan bit yang tepat yang kami sahkan.
Tidak semua integrasi boleh menghantar kemas kini klien dengan kerap. Sesetengah rakan kongsi seperti Xcode memisahkan kitaran keluaran dengan mengekalkan klien yang stabil dan membolehkannya menunjuk kepada binari Pelayan Aplikasi yang lebih baharu apabila diperlukan. Dengan cara itu, mereka boleh mengguna pakai penambahbaikan di sisi pelayan (contohnya, auto-pemadatan yang lebih baik dalam teras Codex atau kunci konfigurasi yang baru disokong) dan melancarkan pembaikan pepijat tanpa menunggu keluaran klien. Permukaan JSON-RPC Pelayan Apl direka bentuk untuk serasi ke belakang, jadi klien lama boleh berkomunikasi dengan pelayan baru dengan selamat.

Codex Web menggunakan abah-abah Codex, tetapi menjalankannya dalam persekitaran kontena. Seorang pekerja menyediakan kontena dengan ruang kerja yang telah diperiksa keluar, melancarkan binari pelayan aplikasi di dalamnya, dan mengekalkan saluran JSON-RPC jangka panjang melalui stdio2. Aplikasi web (berjalan dalam tab pelayar pengguna) berkomunikasi dengan backend Codex melalui HTTP dan SSE, yang menstrim acara tugas yang dihasilkan oleh pekerja. Ini memastikan UI di sisi pelayar kekal ringan sambil masih memberikan kami masa jalan yang konsisten di seluruh desktop dan web.
Oleh kerana sesi web bersifat sementara (tab ditutup, rangkaian terputus), aplikasi web tidak boleh menjadi sumber kebenaran untuk tugas yang memerlukan masa yang lama. Mengekalkan keadaan dan kemajuan pada pelayan bermaksud kerja akan diteruskan walaupun tab hilang. Protokol penstriman dan sesi thread yang disimpan memudahkan sesi baharu untuk menyambung semula, meneruskan dari tempat ia berhenti, dan mengejar ketertinggalan tanpa perlu membina semula keadaan dalam klien.

Secara sejarah, TUI adalah klien “native” yang berjalan dalam proses yang sama seperti gelung ejen dan berkomunikasi terus dengan jenis teras Rust dan bukannya protokol pelayan aplikasi. Itu menjadikan iterasi awal pantas, tetapi ia juga menjadikan TUI sebagai permukaan kes istimewa.
Sekarang bahawa Pelayan Aplikasi sudah wujud, kami merancang untuk memfaktorkan semula TUI(dibuka dalam tetingkap baru) untuk menggunakannya supaya ia berfungsi seperti klien lain: melancarkan proses anak Pelayan Aplikasi, berkomunikasi menggunakan JSON-RPC melalui stdio dan memaparkan acara penstriman dan kelulusan yang sama. Ini membuka aliran kerja di mana TUI boleh menyambung kepada pelayan Codex yang berjalan pada mesin jauh, memastikan ejen dekat dengan pengiraan dan meneruskan kerja walaupun komputer riba tidur atau terputus sambungan, sambil masih menyampaikan kemas kini langsung dan kawalan secara tempatan.
Codex App Server akan menjadi kaedah integrasi kelas pertama yang kami kekalkan pada masa akan datang, tetapi terdapat juga kaedah lain dengan fungsi yang lebih terhad. Secara lalai, kami mengesyorkan agar klien menggunakan Codex App Server untuk berintegrasi dengan Codex, tetapi adalah berbaloi untuk meneliti kaedah integrasi yang berbeza dan memahami kelebihan serta kekurangannya. Berikut adalah cara yang paling biasa untuk menggerakkan Codex dan bila setiap satu mungkin sesuai.
Jalankan codex mcp-server(dibuka dalam tetingkap baru) dan sambungkan dari mana-mana klien MCP yang menyokong pelayan stdio (contohnya, OpenAI Agents SDK(dibuka dalam tetingkap baru)). Ini adalah pilihan yang baik jika anda sudah mempunyai aliran kerja berasaskan MCP dan ingin menggunakan Codex sebagai alat yang boleh dipanggil. Kelemahannya ialah anda hanya mendapat apa yang didedahkan oleh MCP, jadi interaksi khusus Codex yang bergantung pada semantik sesi yang lebih kaya (contohnya, kemas kini perbezaan) mungkin tidak dipetakan dengan kemas melalui titik akhir MCP.
Sesetengah ekosistem menawarkan antara muka mudah alih yang boleh menyasarkan berbilang penyedia model dan persekitaran masa jalan. Ini boleh menjadi padanan yang baik jika anda mahukan satu abstraksi yang menyelaraskan pelbagai ejen. Komprominya ialah protokol ini sering menumpu pada subset keupayaan yang sama, yang boleh menjadikan interaksi yang lebih kaya lebih sukar untuk diwakili, terutamanya apabila semantik alat dan sesi khusus penyedia adalah penting. Ruang ini berkembang dengan cepat dan kami menjangkakan bahawa lebih banyak piawaian umum akan muncul apabila kami mengenal pasti primitif terbaik untuk mewakili aliran kerja ejen dunia sebenar (kemahiran(dibuka dalam tetingkap baru) adalah contoh yang baik untuk ini).
Pilih App Server apabila anda ingin abah-abah Codex penuh didedahkan sebagai aliran acara yang stabil dan mesra UI. Anda mendapat kedua-dua fungsi penuh gelung ejen dan ciri sokongan lain seperti Log masuk dengan ChatGPT, penemuan model, dan pengurusan konfigurasi. Kos utama adalah kerja integrasi, kerana anda perlu membina pengikatan JSON-RPC di bahagian klien dalam bahasa anda. Dalam amalan, walau bagaimanapun, Codex mampu melakukan banyak kerja berat jika anda memberikan skema JSON dan dokumentasi kepadanya. Banyak pasukan yang kami bekerjasama dapat membuat integrasi yang berfungsi dengan cepat menggunakan Codex.
Mod CLI yang ringan dan boleh diskripkan untuk tugas sekali-sekala dan larian CI. Ia sesuai untuk automasi dan saluran paip di mana anda mahukan satu arahan untuk dijalankan hingga selesai secara tidak interaktif, menstrim output berstruktur untuk log, dan keluar dengan isyarat kejayaan atau kegagalan yang jelas.
Pustaka TypeScript untuk mengawal ejen Codex tempatan secara programatik dari dalam aplikasi anda sendiri. Ia paling sesuai apabila anda mahukan antara muka perpustakaan asli untuk alat dan aliran kerja sisi pelayan tanpa membina klien JSON-RPC yang berasingan. Memandangkan ia dihantar lebih awal daripada App Server, pada masa ini ia menyokong lebih sedikit bahasa dan kawasan yang lebih kecil. Jika terdapat minat daripada pembangun, kami mungkin akan menambah SDK tambahan yang membungkus protokol Pelayan Aplikasi supaya pasukan boleh meliputi lebih banyak permukaan abah-abah tanpa menulis pengikatan JSON-RPC.
Dalam siaran ini, kami berkongsi cara kami mendekati mereka bentuk standard baharu untuk berinteraksi dengan ejen dan cara menukar rangka Codex menjadi protokol yang stabil dan mesra klien. Kami telah membincangkan bagaimana Pelayan Aplikasi mendedahkan teras Codex, membolehkan klien memacu gelung ejen penuh, dan menggerakkan pelbagai permukaan termasuk TUI, integrasi IDE tempatan, dan masa jalan web.
Jika ini mencetuskan idea untuk mengintegrasikan Codex ke dalam aliran kerja anda sendiri, adalah berbaloi untuk mencuba App Server. Semua kod sumber terletak dalam repositori sumber terbuka Codex CLI repo(dibuka dalam tetingkap baru). Sila jangan segan untuk berkongsi maklum balas dan permintaan ciri anda. Kami teruja untuk mendengar daripada anda dan untuk terus menjadikan ejen lebih mudah diakses oleh semua orang.
Penulis
Pengakuan
Ucapan terima kasih khas kepada Michael Bolin, Owen Lin, Eric Traut, dan Rasmus Rygaard, yang menyumbang kepada siaran ini, serta kepada seluruh pasukan Codex yang bekerja pada Pelayan Aplikasi.
Nota kaki
- 1
Kami menggunakan varian “JSON‑RPC lite”: ia mengekalkan bentuk permintaan/tindak balas/pemberitahuan, tetapi mengabaikan
"jsonrpc": "2.0"pengepala dan dirangka sebagai JSONL melalui stdio dan bukannya JSON‑RPC 2.0 yang ketat. - 2
“stdio” merujuk kepada stdin/stdout pelayan-apl di dalam kontena. Dalam persediaan yang dihoskan, aliran tersebut sering kali disalurkan melalui sambungan rangkaian berterusan (contohnya, seperti WebSocket) ke masa jalan kontena—jadi ia berfungsi seperti stdio walaupun ia bukan paip tempatan yang sebenar.


