Hurtigere agentbaserede arbejdsgange med WebSockets i Responses API
Af Brian Yu og Ashwin Nathan, medlemmer af det tekniske personale
Når du beder Codex om at rette en fejl, scanner den din kodebase for relevante filer, læser dem for at opbygge kontekst, foretager ændringer og udfører tests for at bekræfte, at rettelsen fungerede. I praksis betyder det snesevis af frem- og tilbagegående anmodninger til Responses API: fastlægge modellens næste handling, køre et værktøj på din computer, sende værktøjets output tilbage til API'et og gentage processen.
Alle disse forespørgsler kan tilsammen løbe op i minutter, som brugerne bruger på at vente på, at Codex fuldfører komplekse opgaver. Set ud fra et latenstidssynspunkt bruger Codex-agentens løkke det meste af tiden på tre hovedfaser: arbejde i API-tjenesterne (til validering og behandling af anmodninger), modelinferens og tid på klientsiden (kørsel af værktøjer og opbygning af modelkontekst). Modelinferens er den fase, hvor modellen kører på GPU’er for at generere nye token. Tidligere var udførelsen af LLM-inferens på GPU'er den langsomste del af den agentiske løkke, så API-tjenestens overhead var let at skjule. Efterhånden som inferensen bliver hurtigere, bliver den samlede API-overhead fra en agentisk rollout langt mere mærkbar.
I dette indlæg forklarer vi, hvordan vi gjorde agent-loops ved hjælp af API’et 40 % hurtigere fra start til slut, så brugerne kunne opleve springet i inferenshastighed fra 65 til næsten 1.000 token i sekundet. Vi greb dette an gennem caching, eliminering af unødvendige netværkshop, forbedring af vores sikkerhedsstak til hurtigt at markere problemer og – vigtigst af alt – udvikling af en metode til at oprette en vedvarende forbindelse til Responses API'en i stedet for at skulle foretage en række synkrone API-kald.

I Responses API'en kørte tidligere flagskibsmodeller som GPT‑5 og GPT‑5.2 med cirka 65 token pr. sekund (TPS). Ved lanceringen af GPT‑5.3‑Codex‑Spark, en hurtig kodningsmodel, var vores mål at være en størrelsesorden hurtigere: over 1.000 TPS, muliggjort af specialiseret Cerebras-hardware, der er optimeret til LLM-inferens. For at sikre, at brugerne kunne opleve den reelle hastighed i denne nye model, var vi nødt til at reducere API-overhead.
Omkring november 2025 lancerede vi en intensiv indsats for at forbedre ydeevnen på Responses API, hvor vi gennemførte mange optimeringer af ventetiden på den kritiske sti for en enkelt forespørgsel:
- Cachelagring af gengivne tokens og modelkonfiguration i hukommelsen for at springe dyre tokeniseringer og netværkskald over ved multi-turn-svar
- Reduktion af netværksforsinkelsen ved at undgå anvendelse af mellemliggende tjenester (f.eks. billedbehandlingsopløsning) og i stedet direkte at benytte selve inferenstjenesten
- Vi forbedrer vores sikkerhedssystem, så vi kan køre visse klassifikatorer og hurtigere markere samtaler
Med disse forbedringer oplevede vi en forbedring på næsten 45 % i tiden til det første token (TTFT), hvilket afspejler, hvor responsiv API'en føles – men disse forbedringer var stadig ikke hurtige nok til GPT‑5.3‑Codex‑Spark. Selv med disse forbedringer var overhead i Responses API’en for stor i forhold til modellens hastighed. Det betød, at brugerne måtte vente på de CPU’er, der kørte vores API, før de kunne bruge de GPU’er, der servicerede modellen.
Det dybereliggende problem var strukturelt: Vi behandlede hver Codex-anmodning som uafhængig og inkluderede samtaletilstand og anden genanvendelig kontekst i hver efterfølgende anmodning. Selv når det meste af samtalen ikke havde ændret sig, betalte vi stadig for arbejde, der var forbundet med hele historikken. Efterhånden som samtalerne blev længere, blev den gentagne behandling mere omkostningstung.
For at stramme designet op har vi genovervejet transportprotokollen: Kunne vi opretholde en vedvarende forbindelse og gemme tilstanden i cachen i stedet for at oprette en ny forbindelse via HTTP og sende hele samtalehistorikken ved hver opfølgende anmodning? Tanken var kun at sende nye oplysninger, der krævede validering og behandling, og at gemme genanvendelige tilstande i hukommelsen, så længe forbindelsen var aktiv. Dette ville mindske omkostningerne ved overflødigt arbejde.
Vi overvejede et par forskellige tilgange, herunder WebSockets og gRPC tovejsstreaming. Vi valgte WebSockets, fordi det som en simpel protokol til meddelelsestransport ikke krævede, at brugerne ændrede deres input- og outputstrukturer i Responses API. Det var udviklervenligt og passede godt ind i vores eksisterende arkitektur med minimale forstyrrelser.
Det første WebSocket-prototype ændrede vores opfattelse af, hvad der var muligt for Responses API-latens. En ingeniør på Codex-teamet med dyb ekspertise på tværs af API-stakken fik stablet en prototype på benene ved at køre en Codex-agent natten over.
I den pågældende prototype blev agentbaserede rollouts modelleret som en enkelt, langvarig respons. Ved hjælp af asyncio-funktionerne ville Responses API'et asynkront gå i ventetilstand i samplingsløkken, efter at et værktøjsopkald var blevet samplet, og Responses API'et ville sende en response.done-begivenhed tilbage til klienten. Når værktøjsopkaldet var udført, ville klienter sende en response.append-hændelse tilbage med værktøjsresultatet, hvilket fjernede blokeringen af samplingsløkken og lod modellen fortsætte.
En analogi her er at behandle det lokale værktøjsopkald som et hostet værktøjsopkald. Når modellen udfører en websøgning, afbryder inferensløkken, kalder en websøgetjeneste og placerer tjenestens svar i modelkonteksten. I vores design gjorde vi det samme; men i stedet for at kalde en fjernservice sendte vi modellens værktøjsopkald tilbage til klienten via WebSocket-forbindelsen. Da klienten svarede, lagde vi svaret på klientens værktøjsopkald ind i konteksten og fortsatte med at sample.
Dette design var ekstremt effektivt, fordi det eliminerede gentaget API-arbejde på tværs af en udrulning af en agent. Vi kunne udføre arbejdet før inferensen én gang, holde en pause, mens værktøjet kører, og til sidst udføre arbejdet efter inferensen én gang.
Desværre skete dette på bekostning af en mindre velkendt og mere kompliceret API-struktur. Vi ønskede, at udviklere skulle kunne integrere WebSocket-understøttelse uden at skulle omskrive deres API-integration til en ny interaktionsform.
I den version, vi har lanceret, er vi vendt tilbage til en velkendt fremgangsmåde: Vi bruger fortsat response.create med samme indhold og anvender previous_response_id for at fortsætte samtalekonteksten fra det forrige svar.
Ved en WebSocket-forbindelse opbevarer serveren en cache i hukommelsen, der er begrænset til den aktuelle forbindelse, med oplysninger om tidligere svar. Når en efterfølgende response.create omfatter previous_response_id, henter vi den tilstand fra cachen i stedet for at genopbygge hele samtalen fra bunden.
Den cachelagrede tilstand omfatter:
- Det forrige
response-objekt - Tidligere input- og outputelementer
- Værktøjsdefinitioner og navneområder
- Genanvendelige prøveobjekter, såsom tidligere genererede tokens

Ved at genbruge den tidligere svartilstand i hukommelsen kunne vi opnå flere større optimeringer:
- At få nogle af vores sikkerhedsklassificerings- og anmodningsvalideringssystemer til kun at behandle nye indtastninger og ikke hele historikken hver gang
- Bevarer en cache i hukommelsen af renderede token, som vi føjer til, så vi kan springe unødvendig tokenisering over
- Genbrug af vores velafprøvede modelopløsnings- og ruteføringslogik på tværs af anmodninger
- Overlappende, ikke-blokerende opgaver efter databehandlingen, såsom fakturering, med efterfølgende anmodninger
Målet var at komme så tæt som muligt på prototypen med minimal overhead, men med en API-udformning, som udviklere allerede forstod og byggede ud fra.
Efter to måneders intensiv udvikling af WebSocket-funktionen lancerede vi en alfa-version sammen med en række førende startups inden for kodningsteknologi, så de kunne integrere den i deres infrastruktur og gradvist øge trafikken på en sikker måde. Alfabrugerne var meget begejstrede og rapporterede forbedringer på op til 40 %(åbner i et nyt vindue) i deres agentbaserede arbejdsgange. I lyset af den positive alfa-feedback var vi klar til at gå i luften.
Resultaterne af lanceringen var øjeblikkelige. Codex skiftede hurtigt størstedelen af trafikken på deres Responses API over til WebSocket-tilstand, hvilket medførte markante forbedringer i ventetiden. Med GPT‑5.3‑Codex‑Spark nåede vi vores mål på 1.000 TPS og oplevede spidsbelastninger på op til 4.000 TPS, hvilket viser, at Responses API kan følge med den langt hurtigere inferens i reel produktionstrafik. Effekten viste sig hurtigt i udviklerfællesskabet også:
- Codex lagde hurtigt størstedelen af deres trafik over på WebSockets. Codex-brugere, der kører de nyeste model såsom GPT‑5.3‑Codex(åbner i et nyt vindue), GPT‑5.4(åbner i et nyt vindue) nyere får alle glæde af den øgede hastighed i WebSocket-tilstand.
- Vercel integrerede WebSocket-tilstand i AI SDK og oplevede, at latenstiden faldt med op til 40 %(åbner i et nyt vindue).
- Clines arbejdsgange med flere filer er 39 % hurtigere(åbner i et nyt vindue).
- OpenAI-modeller i Cursor blev op til 30 % hurtigere(åbner i et nyt vindue).
WebSocket-tilstand er en af de vigtigste nye funktioner i Responses API siden lanceringen i marts 2025. På blot nogle få uger gik vi fra idé til drift i produktion gennem et tæt samarbejde mellem OpenAI's API- og Codex-teams. Det forbedrer ikke blot agenternes implementeringstid markant, men imødekommer også et stigende behov hos udviklere: I takt med at modelinferensen bliver hurtigere, skal de tjenester og systemer, der omgiver inferensen, også blive hurtigere, så disse fordele kan komme brugerne til gode.
Forfattere
Brian Yu og Ashwin Nathan
Tak til
En særlig tak til Responses API- og Codex-holdene, som har arbejdet på at udvikle WebSocket-tilstanden.


