Pag-unlock sa Codex harness: paano namin binuo ang App Server
Ni Celia Chen, Miyembro ng Technical Staff
Ang coding agent ng OpenAI na Codex ay umiiral sa maraming iba’t ibang platform: ang web app(magbubukas sa bagong window), ang CLI(magbubukas sa bagong window), ang IDE extension(magbubukas sa bagong window), at ang bagong Codex macOS app. Sa likod ng eksena, lahat sila ay pinapagana ng iisang Codex harness—ang agent loop at lohika na nagsisilbing pundasyon ng lahat ng karanasan sa Codex. Ang kritikal na ugnayan sa pagitan nila? Ang Codex App Server(magbubukas sa bagong window), isang madaling gamitin at bidirectional na JSON-RPC1 API.
Sa post na ito, ipakikilala namin ang Codex App Server; ibabahagi namin ang aming mga natutunan hanggang ngayon tungkol sa pinakamahuhusay na paraan para madala ang mga kakayahan ng Codex sa iyong produkto, upang matulungan ang iyong mga user na mas mapahusay ang kanilang mga workflow. Tatalakayin namin ang arkitektura at protokol ng App Server at kung paano ito naisasama sa iba’t ibang surface ng Codex, pati na rin ang mga tip kung paano mas mapapakinabangan ang Codex, kung gusto mong gawing tagasuri ng code ang Codex, SRE agent, o coding assistant.
Bago sumabak sa arkitektura, makabubuting malaman ang kasaysayan ng App Server. Noong una, ang App Server ay praktikal na paraan lang upang magamit muli ang Codex harness sa iba't ibang produkto, na unti-unting umunlad at naging aming pamantayang protokol.
Nagsimula ang Codex CLI bilang isang TUI (terminal user interface), na nangangahulugang ina-access ang Codex sa pamamagitan ng terminal. Nang binuo namin ang VS Code extension (isang mas IDE-friendly na paraan para makipag-ugnayan sa mga Codex agent), kinailangan naming gumamit ng parehong harness upang mapatakbo ang parehong agent loop mula sa isang IDE UI nang hindi ito muling iniimplementa. Ang ibig sabihin noon ay ang pagsuporta sa komplikadong mga pattern ng interaksyon na higit pa kaysa sa kahilingan/pagtugon, tulad ng paggalugad sa workspace, pag-usad ng streaming habang nag-iisip ang agent, at pag-aabiso ng mga diff. Una naming sinubukang ilantad ang Codex bilang isang MCP server(magbubukas sa bagong window), ngunit napatunayang mahirap panatilihin ang may-katuturang semantika ng MCP para sa VS Code. Sa halip, ipinakilala namin ang JSON-RPC na protokol na sumasalamin sa TUI loop, na naging di-opisyal na unang bersyon(magbubukas sa bagong window) ng App Server. Noong panahong iyon, hindi namin inasahan na aasa ang ibang mga client sa App Server, kaya hindi ito dinisenyo bilang matatag na API.
Habang lumalago ang paggamit ng Codex sa mga sumunod na buwan, ginusto ng mga panloob na team at panlabas na katuwang ang kakayahang i-embed ang parehong harness sa kanilang sariling mga produkto upang mapabilis ang mga daloy ng trabaho ng kanilang mga user sa pag-develop ng software. Halimbawa, ginusto ng JetBrains at Xcode ng karanasan sa agent na kasing-husay ng IDE, habang kinakailangan ng Codex desktop app na magpagana ng maraming Codex agent nang sabay-sabay. Itinulak kami ng mga kahilingang iyon na magdisenyo ng platform surface na maaaring ligtas na maasahan ng aming mga produkto gayundin ng mga kasamang katuwang sa paglipas ng panahon. Kinailangang maging madaling isama ito at backward compatible, ibig sabihin ay maaari naming paunlarin ang protokol nang hindi sinisira ang mga kasalukuyang client.
Susunod, tatalakayin natin kung paano namin dinisenyo ang arkitektura at protokol upang magamit ng iba't ibang client ang parehong harness.
Una, mag-zoom in tayo sa kung ano ang nasa loob ng Codex harness at kung paano ito inilalantad ng Codex App Server sa mga client. Sa aming huling Codex blog, tinalakay namin ang pangunahing agent loop na nagsasaayos ng interaksyon sa pagitan ng user, ng modelo, at ng mga tool. Ito ang pangunahing lohika ng Codex harness, ngunit may higit pa sa kumpletong karanasan ng agent:
1. Siklo ng buhay at pagpapanatili ng thread. Ang thread ay pag-uusap sa Codex sa pagitan ng user at agent. Gumagawa, nagpapatuloy, nagfo-fork, at nag-a-archive ang Codex ng mga thread, at pinananatili ang kasaysayan ng mga kaganapan upang makakonekta muli ang mga kliyente at makapag-render ng pare-parehong timeline.
2. Config at awtentikasyon. Naglo-load ang Codex ng configuration, pinamamahalaan ang mga default, at nagpapatakbo ng mga daloy ng pag-authenticate tulad ng “Mag-sign in gamit ang ChatGPT,” pati na ang estado ng kredensyal.
3. Pagpapatupad ng tool at mga extension. Ang Codex ay nagpapatakbo ng mga shell/file tool sa sandbox at nagse-set up ng mga integrasyon tulad ng mga server at kasanayang MCP upang makalahok ang mga ito sa agent loop sa ilalim ng pare-parehong modelo ng patakaran.
Lahat ng lohika ng agent na binanggit natin dito, kabilang ang pangunahing loop ng agent, ay nasa isang bahagi ng codebase ng Codex CLI na tinatawag na “Codex core(magbubukas sa bagong window).” Ang Codex core ay kapwa library kung saan matatagpuan ang lahat ng agent code at runtime na maaaring ilunsad upang patakbuhin ang agent loop at pamahalaan ang persistence ng isang Codex thread (usapan).
Para maging kapaki-pakinabang, kailangang maging accessible sa mga client ang Codex harness. Diyan pumapasok ang App Server.
Ang App Server ay kapwa ang JSON-RPC na protokol sa pagitan ng client at ng server at ang pangmatagalang proseso na nagho-host ng mga pangunahing thread ng Codex. Gaya ng makikita natin sa diagram sa itaas, ang isang proseso ng App Server ay may apat na pangunahing bahagi: ang stdio reader, ang tagaproseso ng mensahe ng Codex, ang tagapamahal ng thread, at mga core thread. Ang tagapamahala ng thread ay naglulunsad ng isang core session para sa bawat thread, at pagkatapos ay direktang nakikipag-ugnayan ang tagaprosesol ng mensahe ng Codex sa bawat core session upang magsumite ng mga kahilingan ng client at tumanggap ng mga update.
Ang isang kahilingan ng client ay maaaring magresulta sa maraming pag-update ng kaganapan, at ang mga detalyadong kaganapang ito ang nagbibigay-daan sa amin na bumuo ng detalyadong UI sa ibabaw ng App Server. Bukod pa rito, ang stdio reader at ang tagaproseso ng mensahe ng Codex ay nagsisilbing tagapagsalin sa pagitan ng client at ng mga pangunahing thread ng Codex. Isinasalin nila ang mga JSON-RPC na kahilinga ng client sa mga pangunahing operasyon ng Codex, nakikinig sa panloob na daloy ng mga kaganapan ng Codex core, at pagkatapos ay binabago ang mga mababang antas na kaganapan sa isang maliit na hanay ng mga matatag, handa sa UI na JSON-RPC na mga abiso.
Ang JSON-RPC na protokol sa pagitan ng client at ng App Server ay ganap na bidirectional. Ang isang karaniwang thread ay may kahilingan mula sa client at maraming abiso mula sa server. Bukod dito, maaaring magpasimula ang server ng mga kahilingan kapag kailangan ng agent ng input, tulad ng pag-apruba, at pagkatapos ay ihinto ang turn hanggang sa tumugon ang client.
Susunod, iisa-isahin namin ang mga pangunahing bahagi ng pag-uusap, ang mga pundasyon ng protokol ng App Server. Mahirap magdisenyo ng API para sa isang agent loop dahil ang interaksyon ng user/agent ay hindi lang simpleng kahilingan/tugon. Ang kahilingan ng user ay maaaring magbukas sa nakabalangkas na pagkakasunod-sunod ng mga aksyon na kailangang katawanin ng kliyente nang tapat: ang input ng user, ang unti-unting pag-usad ng agent, at mga artifact na nalilikha sa proseso (hal., mga diff). Upang gawing madali ang pagsasama at matatag sa iba't ibang UI ang daloy ng interaksyon na iyon, napagpasyahan namin ang tatlong pangunahing batayan na may malinaw na mga hangganan at mga yugto ng siklo:
1. Item: Ang item ay ang pangunahing yunit ng input/output sa Codex. Ang mga item ay may mga uri (hal., mensahe ng user, mensahe ng agent, pagpapatupad ng tool, kahilingan sa pag-apruba, diff) at bawat isa ay may malinaw na lifecycle:
item/startedkapag nagsisimula ang item- opsyonal na
item/*/deltana mga kaganapan bilang mga daloy ng nilalaman sa (para sa mga uri ng item na pang-streaming) item/completedkapag natatapos ang item kasama ang huling payload nito
Pinapahintulutan ng lifecycle na ito ang mga client na magsimulang mag-render kaagad sa started, mag-stream ng mga karagdagang update sa delta, at magtapos sa completed.
2. Ikot: Ang ikot ay isang yunit ng trabaho ng agent na sinisimulan ng input ng user. Nagsisimula ito kapag nagsumite ang client ng input (halimbawa, “patakbuhin ang mga pagsusuri at ibuod ang mga pagkabigo”) at nagtatapos kapag natapos na ng agent ang paggawa ng mga output para sa input na iyon. Ang isang turn ay naglalaman ng sunod-sunod na mga item na kumakatawan sa mga hakbang at output na nalilikha sa proseso.
3. Thread: Ang thread ay ang matibay na container para sa tuloyt-tuloy na sesyon ng Codex sa pagitan ng isang user at agent. Naglalaman ito ng maraming ikot. Maaaring likhain, ipagpatuloy, i-fork, at i-archive ang mga thread. Ang kasaysayan ng thread ay pinananatili upang makakonekta muli ang mga client at makapag-render ng pare-parehong timeline.
Ngayon, titingnan natin ang isang pinasimpleng pag-uusap sa pagitan ng isang client at agent, kung saan ang pag-uusap ay kinakatawan ng mga pangunahing bahagi:
Sa simula ng pag-uusap, kailangang maitatag ng client at ng server ang pagpapasimulang pagkamay. Dapat magpadala ang client ng isang initialize na kahilingan bago ang anumang ibang pamamaraan, at kinikilala ito ng server sa pamamagitan ng isang tugon. Binibigyan nito ang server ng pagkakataong ipakilala ang mga kakayahan at hinahayaan ang magkabilang panig na magkasundo sa bersyon ng protokol, mga flag ng tampok, at mga default bago magsimula ang tunay na trabaho. Narito ang isang halimbawa ng payload mula sa extension ng VS Code ng OpenAI:
Ito ang ibinabalik ng server:
Kapag gumawa ang client ng bagong kahilingan, una itong lilikha ng thread at pagkatapos ay turn. Magpapadala pabalik ang server ng mga abiso para sa progreso (thread/started at turn/started). Ipapadala rin nito pabalik ang mga input na naitala nito bilang mga item, tulad ng mensahe ng user dito.
Ang mga tawag sa tool ay ibinabalik din sa client bilang mga item. Bukod rito, maaaring humingi ang server ng pag-apruba mula sa client bago ito makapagpatakbo ng aksyon sa pamamagitan ng pagpapadala ng kahilingan sa server. Ihihinto ng pag-apruba ang ikot hanggang sa sumagot ang client ng alinman sa “payagan” o “tanggihan.” Ganito ang hitsura ng daloy ng pag-apruba sa VS Code extension:

Sa huli, nagpapadala ang server ng mensahe ng agent at pagkatapos ay tinatapos ang turn gamit ang turn/completed. Ibinabalik ng mga delta event ng mensahe ng agent ang mga bahagi ng mensahe hanggang sa ito ay matapos gamit ang item/completed.
Ang mga mensahe sa diagram ay pinasimple para sa mas madaling pagbabasa. Kung gusto mong makita ang JSON para sa isang buong ikot, maaari mong patakbuhin ang test client mula sa Codex CLI repo:
Ngayon, tingnan natin kung paano ini-embed ng iba’t ibang client surface ang Codex sa pamamagitan ng App Server. Tatalakayin natin ang tatlong pattern: mga lokal na app at IDE, Codex web runtime, at ang TUI.
Sa tatlong ito, ang transport ay JSON-RPC sa ibabaw ng stdio (JSONL). Pinadadali ng JSON-RPC ang pagbuo ng mga client binding sa wika na gusto mo. Ang mga surface ng Codex at mga integrasyon ng katuwang ay nagpatupad ng mga client ng App Server sa mga wikang kasama ang Go, Python, TypeScript, Swift, at Kotlin. Para sa TypeScript, maaari kang bumuo ng mga depinisyon nang direkta mula sa Rust na protokol sa pamamagitan ng pagpapatakbo ng:
Para sa iba pang wika, maaari kang bumuo ng JSON Schema bundle at ipasok ito sa iyong gustong code generator sa pamamagitan ng pagpapatakbo ng:

Karaniwang binu-bundle o kinukuha ng mga lokal na kliyente ang App Server binary na partikular sa platform, inilulunsad ito bilang pangmatagalang child process, at pinananatiling bukas ang isang bidirectional stdio channel para sa JSON-RPC. Sa aming VS Code extension at Desktop App, halimbawa, kasama sa ipinadalang artifact ang platform-specific na Codex binary at ito ay naka-pin sa isang nasubok na bersyon upang palaging patakbuhin ng kliyente ang eksaktong mga bahagi na aming na-validate.
Hindi lahat ng integrasyon ay kayang magpadala ng mga update sa client nang madalas. Ang ilang mga katuwang na tulad ng Xcode ay naghihiwalay ng mga siklo ng paglabas sa pamamagitan ng pagpapanatiling matatag ng client at pinapayagan itong ituro sa mas bagong App Server binary kapag kinakailangan. Sa ganitong paraan, maaari nilang gamitin ang mga pagpapabuti sa server-side (halimbawa, mas mahusay na auto-compaction sa Codex core o mga bagong sinusuportahang config key) at ilunsad ang mga pag-aayos ng bug nang hindi naghihintay ng paglabas ng client. Ang JSON-RPC surface ng App Server ay dinisenyo upang maging backward compatible, kaya't ligtas na makikipag-usap ang mas lumang mga client sa mas bagong mga server.

Ginagamit ng Codex Web ang Codex harness, ngunit pinapatakbo ito sa isang container environment. Nagpo-provision ang isang manggagawa ng container gamit ang na-check-out na workspace, inilulunsad ang App Server binary sa loob nito, at nagpapanatili ng pangmatagalang JSON-RPC sa stdio2 channel. Ang web app (na tumatakbo sa tab ng browser ng user) ay nakikipag-ugnayan sa backend ng Codex sa pamamagitan ng HTTP at SSE, na nag-i-stream ng mga kaganapan sa gawain na ginawa ng manggagawa. Pinananatiling magaan nito ang UI ng browser habang nagbibigay pa rin sa amin ng pare-parehong runtime sa desktop at web.
Dahil panandalian ang mga web session (nagsasara ang mga tab, napuputol ang network), hindi maaaring maging pinagmumulan ng katotohanan ang web app para sa mga gawain na tumatagal ng mahabang panahon. Ang pagpapanatili ng estado at progreso sa server ay nangangahulugang magpapatuloy ang trabaho kahit mawala ang tab. Pinapadali ng streaming na protokol at mga naka-save na session ng thread ang muling pagkonekta ng isang bagong session, ipagpatuloy kung saan ito tumigil, at makahabol nang hindi muling binubuo ang estado sa client.

Noon, ang TUI ay isang “native” na client na tumatakbo sa parehong proseso gaya ng agent loop at direktang nakikipag-usap sa mga pangunahing uri ng Rust sa halip na sa app-server na protoko. Pinabilis nito ang maagang pag-uulit, ngunit ginawa rin nitong isang espesyal na kaso ang TUI.
Ngayong umiiral na ang App Server, plano naming i-refactor ang TUI(magbubukas sa bagong window) upang magamit ito at kumilos na parang ibang client: maglunsad ng child process ng App Server, makipag-usap gamit ang JSON-RPC sa stdio, at i-render ang parehong streaming event at pag-apruba. Binubuksan nito ang mga daloy ng trabaho kung saan maaaring kumonekta ang TUI sa isang Codex server na tumatakbo sa remote na makina, pinapanatiling malapit ang agent sa compute at ipinagpapatuloy ang trabaho kahit matulog o madiskonekta ang laptop, habang naghahatid pa rin ng mga live na update at kontrol nang lokal.
Ang Codex App Server ang magiging pangunahing paraan ng integrasyon na aming pananatilihin sa hinaharap, ngunit may iba pang mga paraan na may mas limitadong kakayahan. Bilang default, inirerekomenda naming gamitin ng mga client ang Codex App Server para makapag-integrate sa Codex, ngunit mahalaga ring suriin ang iba’t ibang paraan ng integrasyon at unawain ang mga kalamangan at kahinaan ng mga ito. Nasa ibaba ang mga pinakakaraniwang paraan para patakbuhin ang Codex at kung kailan maaaring angkop ang bawat isa.
Patakbuhin ang codex mcp-server(magbubukas sa bagong window) at kumonekta mula sa anumang MCP client na sumusuporta sa mga stdio server (hal., Mga OpenAI Agent SDK(magbubukas sa bagong window)). Eksakto ito kung mayroon ka nang daloy ng trabaho na batay sa MCP at gusto mong tawagin ang Codex bilang isang maaring tawaging kasangkapan. Pero ang kakulangan ay makukuha mo lang ay kung ano ang inilalantad ng MCP, kaya ang mga interaksyon na partikular sa Codex na umaasa sa mas detalyadong semantika ng sesyon (hal., mga pag-update ng pagkakaiba) ay maaaring hindi maayos na maipasa sa pamamagitan ng mga endpoint ng MCP.
Nag-aalok ang ilang ecosystem ng portable na interface na maaaring mag-target ng maraming provider ng modelo at mga runtime. Maaari itong maging angkop kung gusto mo ng abstraction na nagko-coordinate ng maraming ahente. Ang kapalit ay madalas na nagko-converge ang mga protokol na ito sa karaniwang subset ng mga kakayahan, na maaaring magpahirap sa pagrepresenta ng mas detalyadong interaksyon, lalo na kapag mahalaga ang mga semantika ng tool at session na partikular sa provider. Mabilis na umuunlad ang larangang ito, at inaasahan naming lilitaw ang mas karaniwang mga pamantayan habang inaalam natin ang pinakamahusay na mga pangunahing sangkap upang katawanin ang mga daloy ng trabaho ng mga agent sa totoong mundo (skills(magbubukas sa bagong window) ay isang magandang halimbawa nito).
Piliin ang App Server kapag gusto mong maipakita ang buong Codex harness bilang matatag at UI-friendly na event stream. Makukuha mo ang parehong buong kakayahan ng agent loop at iba pang sumusuportang tampok tulad ng Mag-sign in gamit ang ChatGPT, pagtuklas ng modelo, at pamamahala ng configuration. Ang pangunahing gastos ay ang pagsisikap sa integrasyon, dahil kailangan mong buuin ang client-side JSON-RPC binding sa iyong wika. Sa praktika, gayunpaman, kayang gawin ng Codex ang maraming mabibigat na trabaho kung ibibigay mo rito ang JSON schema at dokumentasyon. Maraming mga koponan na nakatrabaho namin ang nakagawa ng gumaganang integrasyon nang mabilis gamit ang Codex.
Isang magaan, nasusulat sa script na CLI mode para sa mga minsanang gawain at mga CI run. Eksakto ito sa automation at mga pipeline kung saan gusto mo ng iisang utos na tatakbo hanggang matapos nang hindi kinakailangan ng interaksyon, mag-stream ng mga naka-structure na output para sa mga log, at mag-exit na may malinaw na senyales ng tagumpay o pagkabigo.
Isang TypeScript library para sa programatikong pagkontrol sa mga lokal na Codex agent mula sa loob ng sarili mong application. Pinakamainam ito kapag gusto mong magkaroon ng native na interface ng library para sa mga tool at daloy ng trabaho sa server-side nang hindi kinakailangang bumuo ng hiwalay na JSON-RPC client. Dahil naipadala ito nang mas maaga kaysa sa App Server, kasalukuyan itong sumusuporta sa mas kaunting wika at mas maliit na saklaw. Kung may interes ang mga developer, maaari kaming magdagdag ng karagdagang mga SDK na bumabalot sa App Server na protokol upang masaklaw ng mga koponan ang mas malaking bahagi ng harness surface nang hindi kinakailangang magsulat ng mga JSON-RPC bindings.
Sa post na ito, ibinahagi namin kung ano ang diskrate namin sa pagdidisenyo ng bagong pamantayan para sa pakikipag-ugnayan sa mga agent at kung paano gawing matatag at madaling gamitin na protokol ng kliyente ang Codex harness. Tinalakay namin kung paano inilalantad ng App Server ang Codex core, hinahayaan ang mga client na patakbuhin ang buong agent loop, at pinapagana ang malawak na hanay ng mga interface kabilang ang TUI, mga lokal na IDE integration, at ang web runtime.
Kung nagbigay ito ng mga ideya para sa pag-integrate ng Codex sa sarili mong mga daloy ng trabaho, sulit subukan ang App Server. Nasa Codex CLI open-source repo(magbubukas sa bagong window) ang lahat ng source code. Huwag mag-atubiling ibahagi ang iyong feedback at mga kahilingan sa tampok. Nasasabik kaming makarinig mula sa iyo at patuloy na gawing mas naa-access ang mga agent para sa lahat.
May-akda
Mga Pagkilala
Espesyal na pasasalamat kina Michael Bolin, Owen Lin, Eric Traut, at Rasmus Rygaard, na nag-ambag sa post na ito, at sa buong Codex team na nagtrabaho sa App Server.
Mga Footnote
- 1
Gumagamit kami ng variant na “JSON‑RPC lite”: pinapanatili nito ang anyo ng request/response/notification, ngunit inaalis ang
"jsonrpc": "2.0"header at naka-frame bilang JSONL sa ibabaw ng stdio sa halip na mahigpit na JSON‑RPC 2.0. - 2
Ang “stdio” ay tumutukoy sa stdin/stdout ng app-server sa loob ng container. Sa mga naka-host na setup, ang mga stream na iyon ay madalas na itinatunnel sa isang tuloy-tuloy na koneksyon sa network (hal., gaya ng sa WebSocket) papunta sa container runtime—kaya't kumikilos ito na parang stdio kahit hindi ito literal na local pipe.


