Desbloquear o potencial do Codex: como criámos o App Server
Por Celia Chen, membro da Equipa Técnica
O agente de programação Codex da OpenAI está disponível em várias plataformas: aplicação web(abre numa nova janela), CLI(abre numa nova janela), extensão IDE(abre numa nova janela) e a nova aplicação Codex para macOS. Nos bastidores, todos são alimentados pelo mesmo sistema Codex—o ciclo do agente e a lógica que sustenta todas as experiências do Codex. Qual é o elo crucial entre eles? O Codex App Server(abre numa nova janela), uma API JSON-RPC1 bidirecional e fácil de utilizar para o cliente.
Neste post, vamos apresentar o Codex App Server; vamos partilhar o que aprendemos até agora sobre as melhores formas de integrar as capacidades do Codex no teu produto para ajudar os teus utilizadores a otimizar os seus fluxos de trabalho. Vamos abordar a arquitetura e o protocolo do App Server (servidor de aplicações, em português) e como ele se integra com diferentes superfícies do Codex, além de dicas sobre como tirar partido do Codex, quer queiras transformá-lo num revisor de código, num agente de SRE ou num assistente de programação.
Antes de mergulharmos na arquitetura, é útil conheceres a história do App Server. Inicialmente, o App Server era uma forma prática de reutilizar a estrutura do Codex em diversos produtos, que gradualmente evoluiu para o nosso protocolo padrão.
A CLI do Codex começou como uma TUI (interface de utilizador do terminal), o que significa que o Codex é acedido através do terminal. Quando criámos a extensão do VS Code (uma forma mais compatível com IDE para interagir com agentes Codex), precisávamos de uma forma de utilizar a mesma estrutura para controlar o mesmo ciclo do agente a partir da interface do utilizador de IDE sem ter de o voltar a implementar. Isto significava suportar padrões de interação complexos que iam para além do pedido/resposta, como explorar o espaço de trabalho, transmitir o progresso à medida que o agente raciocina e emitir diferenças. Primeiro, experimentámos expor Codex como um servidor MCP(abre numa nova janela), mas manter a semântica do MCP de uma forma que fizesse sentido para o VS Code revelou-se difícil. Em vez disso, introduzimos um protocolo JSON-RPC que espelhava o ciclo da TUI, tornando-se a primeira versão não oficial(abre numa nova janela) do App Server. Na altura, não esperávamos que outros clientes dependessem do App Server, por isso não foi concebido como uma API estável.
À medida que a adoção do Codex cresceu nos meses seguintes, as equipas internas e os parceiros externos quiseram integrar a mesma estrutura nos seus próprios produtos para acelerar os fluxos de trabalho de desenvolvimento de software dos seus utilizadores. Por exemplo, a JetBrains e o Xcode queriam uma experiência de agente ao nível de um IDE, enquanto a aplicação de desktop Codex precisava de orquestrar muitos agentes do Codex em paralelo. Essas exigências levaram-nos a criar uma superfície de plataforma na qual tanto os nossos produtos como as integrações de parceiros pudessem confiar de forma segura ao longo do tempo. Tinha de ser fácil de integrar e compatível com versões anteriores, o que significava que podíamos evoluir o protocolo sem afetar os clientes existentes.
De seguida, vamos explicar como concebemos a arquitetura e o protocolo para que diferentes clientes possam utilizar a mesma estrutura.
Em primeiro lugar, vamos analisar em detalhe o que está dentro da estrutura do Codex e como o App Server do Codex a expõe aos clientes. Na nossa última publicação no blogue Codex, detalhámos o ciclo principal do agente que orquestra a interação entre o utilizador, o modelo e as ferramentas. Esta é a lógica central da estrutura do Codex, mas a experiência completa do agente vai muito além disso:
1. Ciclo de vida e persistência do thread. Uma thread é uma conversa do Codex entre um utilizador e um agente. O Codex cria, retoma, bifurca e arquiva threads, e mantém o histórico de eventos para que os clientes se possam voltar a ligar e apresentar uma linha temporal consistente.
2. Configuração e autenticação. O Codex carrega a configuração, gere predefinições e executa fluxos de autenticação como "Iniciar sessão com o ChatGPT", incluindo o estado das credenciais.
3. Execução de ferramentas e extensões. O Codex executa ferramentas de shell/ficheiro num ambiente isolado (sandbox) e integra recursos como servidores e competências MCP para que possam participar no ciclo do agente sob um modelo de política consistente.
Toda a lógica do agente que aqui mencionamos, incluindo o ciclo principal do agente, encontra-se numa parte da base de código da Codex CLI denominada "núcleo do Codex(abre numa nova janela)" (Codex core). O núcleo do Codex é simultaneamente uma biblioteca onde reside todo o código do agente e um ambiente de execução que pode ser iniciado para executar o ciclo do agente e gerir a persistência de uma thread (conversa) do Codex.
Para ser útil, a estrutura do Codex precisa de ser acessível aos clientes. É aí que entra o App Server.
O servidor de aplicações funciona tanto como protocolo JSON-RPC entre o cliente e o servidor, como um processo de longa duração que aloja as threads do núcleo do Codex. Como podemos ver no diagrama acima, um processo do App Server tem quatro componentes principais: o leitor de stdio, o processador de mensagens do Codex, o gestor de threads e as threads principais. O gestor de threads inicia uma sessão principal para cada thread, e o processador de mensagens do Codex comunica diretamente com cada sessão principal para enviar pedidos do cliente e receber atualizações.
Um pedido do cliente pode resultar em muitas atualizações de eventos, e são estes eventos detalhados que nos permitem construir uma interface de utilizador rica sobre o App Server. Além disso, o leitor stdio e o processador de mensagens do Codex funcionam como a camada de tradução entre o cliente e as threads de núcleo do Codex. Traduzem os pedidos JSON-RPC do cliente em operações do núcleo do Codex, monitorizam o fluxo de eventos interno do núcleo do Codex e, em seguida, transformam esses eventos de baixo nível num pequeno conjunto de notificações JSON-RPC estáveis e prontas para a interface do utilizador.
O protocolo JSON-RPC entre o cliente e o App Server é totalmente bidirecional. Uma thread típica tem um pedido do cliente e várias notificações do servidor. Além disso, o servidor pode iniciar pedidos quando o agente precisa de uma informação, como uma aprovação, e depois pausar a interação até que o cliente responda.
A seguir, vamos analisar os princípios básicos da conversação, os componentes fundamentais do protocolo do App Server. Conceber uma API para um ciclo de agente é complicado porque a interação entre o utilizador e o agente não é um simples pedido/resposta. Um pedido de utilizador pode desdobrar-se numa sequência estruturada de ações que o cliente precisa de representar fielmente: a entrada do utilizador, o progresso incremental do agente e os artefactos produzidos ao longo do caminho (por exemplo, diffs). Para facilitar a integração e garantir a resiliência deste fluxo de interação em diferentes interfaces de utilizador, definimos três elementos básicos com limites e ciclos de vida bem definidos:
1. Item: um item é a unidade atómica de entrada/saída no Codex. Os itens são tipificados (por exemplo, mensagem do utilizador, mensagem do agente, execução de ferramenta, pedido de aprovação, diff) e cada um tem um ciclo de vida explícito:
item/startedquando o item inicia- eventos opcionais
item/*/deltacomo fluxos de conteúdo (para tipos de item de streaming) item/completedquando o item é concluído com a sua carga útil final
Este ciclo de vida permite que os clientes comecem a renderizar imediatamente em started, transmitam atualizações incrementais em delta e finalizem em completed.
2. Interação: Uma interação é uma unidade de trabalho do agente iniciada pela entrada do utilizador. Começa quando o cliente submete uma entrada (por exemplo, "executa testes e resume falhas") e termina quando o agente termina de produzir resultados para essa entrada. Uma interação contém uma sequência de itens que representam os passos intermédios e os resultados produzidos ao longo do processo.
3. Thread: Uma thread é o recipiente duradouro para uma sessão Codex em curso entre um utilizador e um agente. Contém várias interações. É possível criar, retomar, bifurcar e arquivar threads. O histórico do thread é mantido para que os clientes se possam voltar a ligar e apresentar uma linha do tempo consistente.
Agora, vamos analisar uma conversa simplificada entre um cliente e um agente, onde a conversa é representada por elementos básicos:
No início da conversa, o cliente e o servidor precisam estabelecer o aperto de mão de inicialização. O cliente deve enviar um único pedido de inicialização antes de qualquer outro método, e o servidor confirma com uma resposta. Isto dá ao servidor a oportunidade de anunciar capacidades e permite que ambas as partes concordem sobre a versão do protocolo, os sinalizadores de funcionalidade e as predefinições antes de o verdadeiro trabalho começar. Eis um exemplo de payload da extensão do VS Code da OpenAI:
Isto é o que o servidor devolve:
Quando um cliente faz um novo pedido, primeiro cria uma thread e depois uma interação. O servidor enviará notificações de progresso (thread/started e turn/started). Também enviará de volta as entradas que regista como itens, como a mensagem do utilizador aqui.
As chamadas de ferramentas também são enviadas de volta ao cliente como itens. Além disso, o servidor pode solicitar a aprovação do cliente antes de poder executar uma ação, enviando um pedido ao servidor. A aprovação interromperá o processamento até que o cliente responda com "permitir" ou "negar". Este é o aspeto do fluxo de aprovação na extensão do VS Code:

No final, o servidor envia uma mensagem de um agente e depois termina a interação com turn/completed. Os eventos delta da mensagem do agente transmitem partes da mensagem de volta até que esta seja finalizada com item/completed.
As mensagens no diagrama foram simplificadas para facilitar a leitura. Se quiseres ver o JSON de uma interação completa, podes executar o cliente de teste a partir do repositório Codex CLI:
Agora, vamos ver como diferentes interfaces de cliente integram o Codex através do App Server. Vamos abordar três padrões: aplicações e IDEs locais, Codex web runtime e a TUI.
Nos três casos, o transporte é JSON-RPC sobre stdio (JSONL). O JSON-RPC facilita a criação de interfaces de cliente na linguagem da sua preferência. As plataformas Codex e as integrações com parceiros implementaram clientes do App Server em linguagens como Go, Python, TypeScript, Swift e Kotlin. Para TypeScript, podes gerar definições diretamente a partir do protocolo Rust ao executar:
Para outras linguagens, podes gerar um pacote JSON Schema e introduzi-lo no teu gerador de código preferido executando:

Os clientes locais normalmente agrupam ou obtêm um binário específico da plataforma do App Server, iniciam-no como um processo long-running child e mantêm um canal bidirecional stdio aberto para JSON-RPC. Na nossa extensão do VS Code e na aplicação de ambiente de trabalho, por exemplo, o artefacto distribuído inclui o binário do Codex específico da plataforma e está fixado a uma versão testada, para que o cliente execute sempre exatamente os mesmos bits que validámos.
Nem todas as integrações conseguem enviar atualizações ao cliente com frequência. Alguns parceiros, como o Xcode, separam os ciclos de lançamento ao manter o cliente estável e permitir que este aponte para um binário mais recente do App Server quando necessário. Dessa forma, podem adotar melhorias do lado do servidor (por exemplo, melhor compressão automática no núcleo do Codex ou novas chaves de configuração suportadas) e lançar correções de bugs sem esperar pelo lançamento de uma versão do cliente. A interface JSON-RPC do App Server foi concebida para ser compatível com versões anteriores, permitindo que os clientes mais antigos comuniquem com os servidores mais recentes sem problemas.

O Codex Web utiliza a estrutura do Codex, mas executa-a num ambiente contentor. Um trabalhador aprovisiona um contentor com o espaço de trabalho, inicia o binário do App Server no seu interior e mantém um canal JSON-RPC de longa duração sobre stdio2. A aplicação web (executada no separador do browser do utilizador) comunica com o backend do Codex via HTTP e SSE, que transmite os eventos de tarefas produzidos pelo trabalhador. Isto mantém a IU do lado do navegador leve, ao mesmo tempo que nos proporciona um desempenho consistente em desktops e na web.
Como as sessões web são efémeras (os separadores fecham, as ligações caem), a aplicação web não pode ser a fonte de verdade para tarefas de longa duração. Manter o estado e o progresso no servidor significa que o trabalho continua mesmo que o separador desapareça. O protocolo de streaming e as sessões de thread guardadas facilitam a reconexão de uma nova sessão, permitindo retomar exatamente de onde foi interrompida e recuperar o atraso sem reconstruir o estado no cliente.

Historicamente, a TUI era um cliente "nativo" que corria no mesmo processo que o ciclo do agente e comunicava diretamente com os tipos centrais de Rust em vez do protocolo do servidor de aplicações. Isso tornou a iteração inicial rápida, mas também fez da TUI uma plataforma de caso especial.
Agora que o App Server existe, planeamos refatorizar a TUI(abre numa nova janela) para a utilizar, de modo a que se comporte como qualquer outro cliente: lançar um child process do App Server, comunicar via JSON-RPC sobre stdio e renderizar os mesmos eventos de streaming e aprovações. Isto possibilita fluxos de trabalho em que a TUI se pode ligar a um servidor Codex em execução numa máquina remota, mantendo o agente perto da computação e permitindo a continuidade do trabalho mesmo que o portátil entre em modo de suspensão ou se desligue, enquanto ainda fornece atualizações e controlos em tempo real localmente.
O Codex App Server continuará a ser o método de integração principal que iremos manter daqui para a frente, mas também existem outros métodos com funcionalidades mais limitadas. Por predefinição, recomendamos que os clientes utilizem o Codex App Server para integrar com o Codex, mas vale a pena analisar diferentes métodos de integração e compreender os seus prós e contras. De seguida, apresentamos as formas mais comuns de utilizar o Codex e quando cada uma delas pode ser uma boa opção.
Executa codex mcp-server(abre numa nova janela) e liga-te a partir de qualquer cliente MCP que suporte servidores stdio (por exemplo, OpenAI Agents SDK(abre numa nova janela)). Isto é uma boa opção se já tiveres um fluxo de trabalho baseado em MCP e quiseres usar o Codex como uma ferramenta invocável. A desvantagem é que só obténs o que o MCP expõe, por isso as interações específicas do Codex que dependem de uma semântica de sessão mais rica (por exemplo, atualizações de diferenças) podem não se mapear de forma clara através dos endpoints do MCP.
Alguns ecossistemas oferecem uma interface portátil que pode direcionar-se a vários fornecedores de modelos e tempos de execução. Isto pode ser uma boa opção se quiseres uma abstração que coordene vários agentes. A desvantagem é que estes protocolos convergem frequentemente para um subconjunto comum de funcionalidades, o que pode dificultar a representação de interações mais complexas, especialmente quando a semântica específica da ferramenta e da sessão do fornecedor é importante. Este espaço está a evoluir rapidamente, e esperamos que surjam padrões mais comuns à medida que descobrimos os melhores elementos básicos para representar fluxos de trabalho de agentes no mundo real (skills(abre numa nova janela) é um bom exemplo disso).
Escolhe o App Server quando quiseres que a estrutura completa do Codex seja exposta como um fluxo de eventos estável e fácil de utilizar na interface. Tens acesso tanto à funcionalidade completa do ciclo do agente como a outras funcionalidades de suporte, como o login com o ChatGPT, a descoberta de modelos e a gestão de configuração. O principal custo é o trabalho de integração, uma vez que é necessário criar a ligação JSON-RPC do lado do cliente na sua linguagem. Na prática, no entanto, o Codex consegue fazer grande parte do trabalho pesado se lhe forneceres o JSON schema e a documentação. Muitas equipas com quem trabalhamos conseguiram implementar uma integração funcional rapidamente utilizando o Codex.
Um modo CLI leve e programável para tarefas pontuais e execuções de CI. É uma boa opção para automatização e pipelines onde se pretende que um único comando seja executado até à conclusão de forma não interativa, transmita uma saída estruturada para os registos e termine com um sinal claro de sucesso ou falha.
Uma biblioteca TypeScript para controlar programaticamente agentes Codex locais a partir da tua própria aplicação. É melhor quando desejas uma interface de biblioteca nativa para ferramentas e fluxos de trabalho do lado do servidor sem ter de criar um cliente JSON-RPC separado. Como foi lançado antes do App Server, atualmente suporta menos linguagens e tem uma área de cobertura menor. Se houver interesse dos programadores, podemos adicionar SDKs adicionais que encapsulem o protocolo do App Server, permitindo que as equipas explorem uma área maior da estrutura sem escrever ligações JSON-RPC.
Nesta publicação, partilhámos como abordamos a criação de um novo padrão para interagir com agentes e como transformar a estrutura do Codex num protocolo estável e fácil de utilizar para o cliente. Abordámos como o App Server expõe o núcleo do Codex, permite que os clientes controlem o ciclo completo do agente e suporta uma vasta gama de interfaces, incluindo a TUI, integrações locais com IDE e o runtime web.
Se isto te inspirou a integrar o Codex nos teus próprios fluxos de trabalho, vale a pena experimentar o App Server. Todo o código-fonte está no repositório(abre numa nova janela) open source da CLI do Codex. Sente-te à vontade para partilhar o teu feedback e sugestões de funcionalidades. Estamos ansiosos por ouvir a tua opinião e continuar a tornar os agentes mais acessíveis a todos.
Autor
Agradecimentos
Um agradecimento especial a Michael Bolin, Owen Lin, Eric Traut e Rasmus Rygaard, que contribuíram para esta publicação, e a toda a equipa do Codex que trabalhou no App Server.
Notas de rodapé
- 1
Utilizamos uma variante "JSON‑RPC lite": mantém a forma de pedido/resposta/notificação, mas omite o
"jsonrpc": "2.0"cabeçalho e está estruturado como JSONL sobre stdio em vez de JSON‑RPC 2.0 estrito. - 2
"stdio" refere-se ao stdin/stdout do servidor de aplicações dentro do contentor. Nas configurações alojadas, estes fluxos são frequentemente tunelados através de uma ligação de rede persistente (por exemplo, semelhante ao WebSocket) para o tempo de execução do contentor — portanto, comporta-se como stdio, mesmo que não seja um pipe local literal.


