Gå til hovedindhold
OpenAI

4. februar 2026

Ingeniørarbejde

Oplåsning af Codex-rammen: Sådan byggede vi app-serveren

Af Celia Chen, medarbejder hos det tekniske personale

Indlæser ...

OpenAI’s kodningsagent Codex findes på tværs af mange forskellige platforme: webappen(åbner i et nyt vindue), CLI'en(åbner i et nyt vindue), IDE-udvidelsen(åbner i et nyt vindue) og den nye Codex macOS-app. De drives dog alle af den samme Codex-ramme – agent-loop og logikken, der ligger til grund for alle Codex-oplevelser. Det afgørende bindeled mellem dem? Codex App Server(åbner i et nyt vindue), som er en brugervenlig, tovejs JSON-RPC1 API.

I dette indlæg introducerer vi Codex App Server. Vi deler vores erfaringer indtil videre om de bedste måder at integrere Codex’s funktioner i dit produkt for at hjælpe dine brugere med at optimere deres arbejdsgange. Vi vil dække App Server's arkitektur og protokol og hvordan den integreres med forskellige Codex-overflader, samt tips til at udnytte Codex, uanset om du vil gøre Codex til en kodeanmelder, en SRE-agent eller en kodningsassistent.

Baggrunden for App Server

Før vi ser nærmere på arkitekturen, er det nyttigt at kende App Serverens baggrundshistorie. Oprindeligt var App Server en praktisk måde at genbruge Codex-rammen på tværs af produkter, der gradvist udviklede sig til vores standardprotokol.

Codex CLI startede som en TUI (terminalbrugergrænseflade), hvilket betyder, at Codex tilgås gennem terminalen. Da vi byggede VS Code-udvidelsen (som er en mere IDE-venlig måde at interagere med Codex-agenter på), havde vi brug for en måde til at bruge den samme ramme, så vi kunne køre den samme agent-loop fra en IDE-UI uden at skulle genimplementere den. Det betød at understøtte rige interaktionsmønstre ud over anmodning/svar, såsom at udforske arbejdsområdet, streame fremskridt, mens agenten ræsonnerer og udsender forskelle. Vi eksperimenterede først med at eksponere Codex som en MCP-server(åbner i et nyt vindue), men det viste sig at være svært at vedligeholde MCP-semantik på en måde, der gav mening for VS Code. I stedet introducerede vi en JSON-RPC-protokol, der afspejlede TUI-loopet, hvilket blev den uofficielle første version(åbner i et nyt vindue) af App Server. På det tidspunkt forventede vi ikke, at andre klienter ville være afhængige af App Server, så den blev ikke designet som en stabil API.

Efterhånden som Codex blev mere udbredt i løbet af de næste par måneder, ønskede interne teams og eksterne partnere muligheden for at indlejre den samme ramme i deres egne produkter for at fremskynde deres brugeres softwareudviklingsprocesser. For eksempel ønskede JetBrains og Xcode en agentoplevelse af IDE-kvalitet, mens Codex-desktopappen havde brug for at håndtere mange Codex-agenter parallelt. Disse krav fik os til at designe en platformsoverflade, som både vores produkter og partnerintegrationer trygt kunne stole på over tid. Den skulle være nem at integrere og bagudkompatibel, hvilket betød, at vi kunne udvikle protokollen uden at påvirke eksisterende klienter.

Dernæst vil vi gennemgå, hvordan vi designede arkitekturen og protokollen, så forskellige klienter kan bruge den samme ramme.

Inde i Codex-rammen

Først lad os se nærmere på, hvad der er inde i Codex-rammen, og hvordan Codex App Server eksponerer den for klienter. I vores seneste Codex blog gennemgik vi det centrale agent-loop, der håndterer interaktionen mellem brugeren, modellen og værktøjerne. Dette er kernelogikken i Codex-rammen, men der er meget mere i den fulde agentoplevelse:

1. Trådens livscyklus og persistens. En tråd er en Codex-samtale mellem en bruger og en agent. Codex opretter, genoptager, forgrener og arkiverer tråde og gemmer hændelseshistorikken, så klienter kan genoprette forbindelsen og gengive en ensartet tidslinje.

2. Konfiguration og godkendelse. Codex indlæser konfiguration, administrerer standardindstillinger og kører godkendelsesflows såsom “Log ind med ChatGPT,” herunder status for legitimationsoplysninger.

3. Værktøjsudførelse og udvidelser. Codex udfører shell- og filværktøjer i en sandbox og forbinder integrationer såsom MCP-servere og færdigheder, så de kan deltage i agent-loopet under en ensartet politikmodel.

Al den agentlogik, som vi har nævnt her, inklusive det centrale agent-loop, findes i en del af Codex CLI-kodebasen kaldet for “Codex-kernen(åbner i et nyt vindue).” Codex-kernen er både et bibliotek, hvor alle agentkoder findes, og en runtime, der kan oprettes for at køre agent-loopet og administrere persistensen af én Codex-tråd (samtale).

For at være nyttig skal Codex-rammen være tilgængelig for klienter. Det er her App Server kommer ind.

Diagram med titlen “App Servers procesflow.” En klient sender JSON-RPC-meddelelser til en stdio-læser, der videresender anmodninger til en Codex-meddelelsesprocessor. Processoren interagerer med en trådadministrator og en kernetråd via opslagstråde, trådhåndtag, indsendte anmodninger og hændelser/opdateringer og returnerer derefter svar til klienten.

App Server er både JSON-RPC-protokollen mellem klienten og serveren og en langvarig proces, der hoster Codex-kerne-trådene. Som vi kan se fra diagrammet ovenfor, har en App Server-proces fire hovedkomponenter: stdio-læseren, Codex-meddelelsesprocessoren, trådadministratoren og kernetråde. Trådadministratoren opretter én kerne-session for hver tråd, og Codex-meddelelsesprocessoren kommunikerer derefter direkte med hver kerne-session for at indsende klientanmodninger og modtage opdateringer.

Én klientanmodning kan resultere i mange hændelsesopdateringer, og det er disse detaljerede hændelser, der giver os mulighed for at bygge en omfattende brugergrænseflade oven på App Server. Desuden fungerer stdio-læseren og Codex-meddelelsesprocessoren som oversættelseslaget mellem klienten og Codex-kerne-trådene. De oversætter klientens JSON-RPC-anmodninger til Codex-kerneoperationer, lytter til Codex-kernens interne hændelsesstrøm og omdanner derefter disse lavniveau-hændelser til et lille sæt stabile, UI-klare JSON-RPC-notifikationer.

JSON-RPC-protokollen mellem klienten og App Server er fuldt ud bidirektionel. En typisk tråd har en klientanmodning og mange servermeddelelser. Derudover kan serveren igangsætte anmodninger, når agenten har brug for input, som f.eks. en godkendelse, og derefter sætte dette turn på pause, indtil klienten svarer.

Samtaleprimitiverne

Dernæst vil vi nedbryde samtaleprimitiverne, som er byggeklodserne i App Server-protokollen. Det er vanskeligt at designe en API til et agent-loop, fordi bruger/agent-interaktionen ikke er en simpel anmodning/svar. En brugerforespørgsel kan udfolde sig til en struktureret sekvens af handlinger, som klienten skal repræsentere trofast: brugerens input, agentens trinvise fremskridt, artefakter, der produceres undervejs (f.eks. forskelle). For at gøre interaktionsstrømmen nem at integrere og robust på tværs af brugergrænseflader, brugte vi tre kerneprimitiver med klare grænser og livscyklusser:

1. Element: Et element er den atomare enhed for input/output i Codex. Elementer er kategoriserede (f.eks. brugermeddelelse, agentmeddelelse, værktøjsudførelse, godkendelsesanmodning, forskelle), som hver især har en eksplicit livscyklus:

  • element/startet når elementet begynder
  • valgfri element/*/delta-hændelser såsom indholdsstrømme (for streaming-elementtyper)
  • element/fuldført, når elementet afsluttes med sin endelige nyttelast

Denne livscyklus lader klienter begynde at gengive øjeblikkeligt ved startet, streame trinvise opdateringer ved delta og færdiggøre ved fuldført.

2. Turn: Et turn er en enhed af agentarbejde, der initieres af brugerinput. Det starter, når klienten indsender input (for eksempel "kør tests, og opsummer fejl"), og slutter, når agenten er færdig med at producere output for dette input. Et turn indeholder en sekvens af elementer, der repræsenterer de mellemliggende trin og output, der produceres undervejs.

3. Tråd: En tråd er en holdbar beholder til en igangværende Codex-session mellem en bruger og en agent. Den indeholder flere turns. Tråde kan oprettes, genoptages, forgrenes og arkiveres. Trådhistorik gemmes, så klienter kan genoprette forbindelse og gengive en ensartet tidslinje.

Vi vil nu se på en forenklet samtale mellem en klient og en agent, hvor samtalen er repræsenteret af primitiver:

Diagram med titlen “Meddelelsesflow for klient-/server-protokol: Initialiseringsanmodning.” En klient sender en initialiseringsanmodning med klientoplysninger til serveren. Serveren svarer med en resultathændelse, der indeholder userAgent-strengen “my_client/1.0.”

I begyndelsen af samtalen skal klienten og serveren etablere det indledende håndtryk. Klienten skal sende en enkelt indledende anmodning før nogen anden metode, og serveren bekræfter med et svar. Dette giver serveren mulighed for at reklamere for kapaciteter og lader begge parter blive enige om protokolversionering, funktionsflag og standardindstillinger, før det egentlige arbejde starter. Her er et eksempel på en nyttelast fra OpenAIs VS Code-udvidelse:

JSON

1
{
2
"method": "initialize",
3
"id": 0,
4
"params": {
5
"clientInfo": {
6
"name": "codex_vscode",
7
"title": "Codex VS Code Extension",
8
"version": "0.1.0"
9
}
10
}
11
}

Dette er, hvad serveren returnerer:

JSON

1
{
2
"id": 0,
3
"result": {
4
"userAgent": "codex_vscode/0.94.0-alpha.7 (Mac OS 26.2.0; arm64) vscode/2.4.22 (codex_vscode; 0.1.0)"
5
}
6
}
Diagram med titlen “Meddelelsesflow for klient-/server-protokol: E-mail-tråd- og turn-livscyklus.” Klienten sender tråd-/start- og turn-/start-anmodninger til serveren. Serveren sender hændelser – tråd/startet, turn/startet, element/startet og element/fuldført – der viser et turn, hvor brugermeddelelsen er "kør tests og opsummér fejl".

Når en klient laver en ny anmodning, vil den først oprette en tråd og derefter et turn. Serveren sender beskeder om fremskridt (tråd/startet og turn/startet). Den vil også sende input tilbage, som den registrerer som elementer, såsom denne brugermeddelelse.

Diagram med titlen “Meddelelsesflow for klient-/server-protokol: Værktøjsudførelse med valgfri godkendelse.” Under et værktøjskald udsender serveren element/startet og derefter item/commandExecution/requestApproval med en begrundelse (“kør tests”). Klienten returnerer en godkendelseshændelse (tillad/afvis). Serveren udsender derefter element/fuldført, der viser udførelsen af kommandoen ("pnpm test").

Værktøjsopkald sendes også tilbage til klienten som elementer. Derudover kan serveren bede om klientens godkendelse, før den kan udføre en handling ved at sende en serveranmodning. Godkendelsen sætter dette turn på pause, indtil klienten svarer med enten "tillad" eller "afvis". Sådan ser godkendelsesflowet ud i VS Code-udvidelsen:

Tilladelses-prompt på en grænseflade med et mørkt tema, der spørger: “Vil du give mig lov til at køre pnpm-test for dette arbejdsområde?” Den viser følgende muligheder: 1) Ja, 2) Ja, og spørg ikke igen for kommandoer, der starter med pnpm-test, og 3) Nej, med en Indsend-knap forneden.
Diagram med titlen “Meddelelsesflow for klient-/server-protokol: Streaming agent message flow.” Serveren streamer en assistentbesked i dele: element/startet, to agentMessage/delta-beskeder (“kørte 3 tests.”, “alle bestået”), derefter element/fuldført. Dette turn slutter med turn/fuldført.

Til sidst sender serveren en agentbesked og afslutter derefter dette turn med turn/fuldført. Agentmeddelelsens deltahændelser streamer dele af meddelelsen tilbage, indtil meddelelsen er færdiggjort med element/fuldført.

Beskederne i diagrammet er forenklede for at gøre dem lettere at læse. Hvis du vil se JSON for et fuldt turn, kan du køre testklienten fra Codex CLI-repoet:

Bash

1
codex debug app-server send-message-v2 "run tests and summarize failures"

Integration med klienter

Lad os nu se på, hvordan forskellige klientoverflader indlejrer Codex via App Server. Vi vil dække tre mønstre: lokale apps og IDE'er, Codex web-runtime og TUI'en.

Diagram med titlen “Codex-klienter integreret med Codex-ramme via app server.” Førstepartsklienter (Codex Desktop App, TUI/CLI, Web Runtime) og tredjepartsintegrationer (JetBrains IDEs, VS Code, Xcode) kommunikerer med Codex-rammen via JSON-RPC-kald.

På tværs af alle tre mønstre er transporten JSON-RPC over stdio (JSONL). JSON-RPC gør det enkelt at oprette klientbindinger i det sprog, du vælger. Codex-overflader og partnerintegrationer har implementeret App Server-klienter i programmeringssprog såsom Go, Python, TypeScript, Swift og Kotlin. For TypeScript kan du generere definitioner direkte fra Rust-protokollen ved at køre:

Bash

1
codex app-server generate-ts

For andre sprog kan du generere en JSON skema-bundle og indsætte den i din foretrukne kodegenerator ved at køre:

Bash

1
codex app-server generate-json-schema
Lokale apps og IDE'er
Skærmbillede af VS Code med Codex-udvidelsen kørende. En Rust-testfil er åben, og nedenunder beskriver Codex-panelet, at der kun køres fmt- og cargo-test -p codex-app-server, og rapporterer, at formatering og tests er i gang, mens der afventes et endeligt bestået/ikke bestået-resultat.

Lokale klienter pakker typisk en platformspecifik App Server-binær eller henter den, starter den som en langvarig underproces og holder en tovejs stdio-kanal åben til JSON-RPC. I vores VS Code-udvidelse og Desktop App inkluderer det leverede artefakt for eksempel den platformspecifikke Codex-binærfil og er fastlåst til en testet version, så klienten altid kører præcis de bits, som vi har valideret.

Ikke alle integrationer kan sende klientopdateringer ofte. Nogle partnere, såsom Xcode, adskiller udgivelsescyklusser ved at holde klienten stabil og lade den pege på en nyere App Server-binær, når det er nødvendigt. På den måde kan de tage server-side-forbedringer i brug (for eksempel bedre automatisk komprimering i Codex-kernen eller nyligt understøttede konfigurationsnøgler) og udrulle fejlrettelser uden at vente på en klientudgivelse. App Servers JSON-RPC-overflade er designet til at være bagudkompatibel, så ældre klienter kan kommunikere sikkert med nyere servere.

Codex Web
Skærmbillede af en Codex-webgrænseflade, der viser en opdatering med titlen "Meddelelse om vellykket login med opdatering". Det venstre panel opsummerer ændringer, tests og ændrede filer, mens det højre panel viser en kodediff for login.rs med opdateret formulering af beskeden om vellykket login.

Codex Web bruger Codex-rammen, men kører den i et container-miljø. En arbejder klargør en container med det udtjekkede arbejdsområde, starter App Server-binærfilen inde i den og vedligeholder en langvarig JSON-RPC over stdio2-kanal. Web-appen (der kører i brugerens browserfane) kommunikerer med Codex-backenden via HTTP og SSE, som streamer opgavehændelser, der produceres af arbejdstråden. Dette holder browserens UI let samtidig med, at der stadig oprettes en ensartet runtime på tværs af desktop og web.

Eftersom websessioner er flygtige (faner lukkes, netværk afbrydes), kan web-appen ikke være den pålidelige kilde til langvarige opgaver. Det er vigtigt at bevare status og fremskridt på serveren, så arbejdet kan fortsætte, også selvom fanen forsvinder. Streaming-protokollen og gemte trådsessioner gør det nemt for en ny session at genoprette forbindelsen, fortsætte der, hvor den slap, og indhente det forsømte uden at genopbygge tilstanden i klienten.

TUI/Codex CLI
Skærmbillede af en terminal, der kører Codex CLI. Den viser OpenAI Codex-banneret med modellen gpt-5.2-codex medium, en brugerkommando “forklar app serveren for mig,” og en “Arbejder”-status. Nedenfor vises et forslag: "skriv tests for @filnavn" med muligheder for genveje.

Historisk set var TUI en “native” klient, der kørte i samme proces som agent-loopet og kommunikerede direkte med Rust-kernetyper i stedet for app-server-protokollen. Det gjorde tidlige iterationer hurtige, men det gjorde også TUI'en til en overflade for særlige tilfælde.

Nu hvor App Server findes, planlægger vi at omstrukturere TUI'en(åbner i et nyt vindue) , så den opfører sig som enhver anden klient: starte en underordnet appserverproces, kommunikere JSON-RPC via stdio og gengive de samme streaminghændelser og godkendelser. Dette åbner op for arbejdsgange, hvor TUI'en kan oprette forbindelse til en Codex-server, der kører på en fjernmaskine, og holde agenten tæt på computeren og fortsætte arbejdet, også selvom den bærbare computer er i dvale-tilstand eller afbryder forbindelsen, samtidig med at den leverer liveopdateringer og kontroller lokalt.

Valg af den korrekte protokol

Codex App Server vil være den førsteklasses integrationsmetode, vi fastholder fremadrettet, men der vil også være andre metoder med mere begrænset funktionalitet. Som standard anbefaler vi, at kunderne bruger Codex App Server til at integrere med Codex, men det er værd at undersøge forskellige integrationsmetoder og forstå deres fordele og ulemper. Nedenfor er de mest almindelige måder at anvende Codex på, og hvornår hver af dem kan være et godt valg.

JSON-RPC-protokoller

Codex som en MCP-server

Kør codex mcp-server(åbner i et nyt vindue) og opret forbindelse fra en hvilken som helst MCP-klient, der understøtter stdio-servere (f.eks. OpenAI Agents SDK(åbner i et nyt vindue)). Dette er et godt valg, hvis du allerede har en MCP-baseret arbejdsgang og ønsker at anvende Codex som et kaldbart værktøj. Ulempen er, at du kun får det, som MCP eksponerer, så Codex-specifikke interaktioner, der er afhængige af rigere sessionssemantik (f.eks. diff-opdateringer), muligvis ikke kan kortlægges rent gennem MCP-endepunkter.

Protokoller til agent-rammen på tværs af udbydere

Nogle økosystemer tilbyder en portabel grænseflade, der kan målrettes mod flere modeludbydere og runtime-miljøer. Dette kan være et godt valg, hvis du ønsker én abstraktion, der koordinerer flere agenter. Afvejningen er, at disse protokoller ofte konvergerer mod den fælles delmængde af funktioner, hvilket kan gøre det sværere at repræsentere mere komplekse interaktioner, især når udbyderspecifikke værktøjs- og sessionssemantikker er vigtige. Dette område udvikler sig hurtigt, og vi forventer, at der vil opstå flere fælles standarder, efterhånden som vi finder de bedste primitiver til at repræsentere virkelige agent-arbejdsgange; (færdigheder(åbner i et nyt vindue) er et godt eksempel på dette).

Codex App Server

Vælg App Server, hvis hele Codex-rammen skal eksponeres som en stabil, brugervenlig hændelsesstrøm. Du får både den fulde funktionalitet af agent-loopet og andre understøttende funktioner såsom Log ind med ChatGPT, modelopdagelse og konfigurationsstyring. Den største omkostning er integrationsarbejdet, da du skal bygge JSON-RPC-bindingen på klientsiden i dit sprog. I praksis kan Codex dog klare en stor del af det hårde arbejde, hvis du bruger JSON-skemaet og dokumentationen. Mange af de teams, som vi arbejdede med, var i stand til hurtigt at implementere en fungerende integration ved hjælp af Codex.

Andre måder at indlejre Codex på

En let, scriptbar CLI-tilstand til engangsopgaver og CI-kørsler. Det er et godt valg til automatisering og pipelines, hvor du ønsker en enkelt kommando skal køre til ende uden interaktion, hvor struktureret output skal streames til logfiler og afslutte med et klart signal om vellykket eller fejl.

Et TypeScript-bibliotek til programmatisk styring af lokale Codex-agenter fra din egen applikation. Dette er det bedste valg, hvis du vil have en indbygget biblioteksgrænseflade til server-side værktøjer og arbejdsgange uden at skulle bygge en separat JSON-RPC-klient. Da den blev leveret tidligere end App Server, understøtter den i øjeblikket færre sprog og et mindre funktionsområde. Hvis der er interesse blandt udviklere, kan vi tilføje flere SDK'er, der indpakker App Server-protokollen, så teams kan dække mere af ramme-overfladen uden at skrive JSON-RPC-bindinger.

Kommende tiltag

I dette indlæg har vi set på, hvordan vi udvikler en ny standard for interaktion med agenter, og hvordan Codex-rammen kan gøres til en stabil, klientvenlig protokol. Vi beskrev, hvordan App Server eksponerer Codex-kernen, lader klienter styre det fulde agent-loop og driver en bred vifte af grænseflader, herunder TUI, lokale IDE-integrationer og web-runtime.

Hvis dette har givet dig idéer til, hvordan du kan integrere Codex i dine egne arbejdsgange, er det værd at prøve App Server. Alle kildekoder findes i Codex CLI open-source repo(åbner i et nyt vindue). Du er velkommen til at dele din feedback og dine forslag til funktioner. Vi ser frem til at høre fra dig og vi fortsætter arbejdet med at gøre agenter mere tilgængelige for alle.

Skrevet af

Celia Chen

Tak til

En særlig tak til Michael Bolin, Owen Lin, Eric Traut og Rasmus Rygaard, som bidrog til dette indlæg, og til hele Codex-teamet, der arbejdede på App Server.

Fodnoter

  1. 1

    Vi bruger en “JSON‑RPC lite”-variant: den bevarer formen for anmodning/svar/notifikation, men udelader "jsonrpc": "2.0" header og er indrammet som JSONL over stdio i stedet for streng JSON‑RPC 2.0.

  2. 2

     “stdio” henviser til app-serverens stdin/stdout inde i containeren. I hostede opsætninger bliver disse streams ofte tunneleret over en persistent netværksforbindelse (f.eks. WebSocket-lignende) til containerens runtime, så den opfører sig som stdio, selvom det ikke er en bogstavelig lokal pipe.