Раскрывая потенциал Codex: как мы создали App Server
Автор: Селия Чен (Celia Chen), технический специалист
ИИ-агент для написания кода от OpenAI, Codex, представлен на самых разных платформах: в веб-приложении, в интерфейсе командной строки (CLI), в виде расширения для IDE и в новом приложении Codex для macOS. «Под капотом» все они работают на базе единой среды Codex — цикла агента и логики, лежащих в основе всех интерфейсов Codex. Важнейшим связующим звеном между ними является сервер приложений Codex (Codex App Server) — удобный для клиента двунаправленный API на базе JSON-RPC
В этой статье мы представим Codex App Server и поделимся опытом интеграции возможностей Codex в ваш продукт, чтобы помочь пользователям оптимизировать их рабочие процессы. Мы рассмотрим архитектуру и протокол App Server, способы их интеграции с различными интерфейсами Codex, а также дадим советы по использованию Codex независимо от того, хотите ли вы превратить его в инструмент проверки кода, SRE-агента или ассистента по программированию.
Происхождение App Server
Прежде чем погружаться в архитектуру, полезно узнать предысторию App Server. Изначально App Server задумывался как практичный способ повторного использования среды Codex в разных продуктах, но со временем он перерос в наш стандартный протокол.
Codex CLI начинался как TUI (текстовый пользовательский интерфейс), что означает взаимодействие с Codex через терминал. Когда мы создали расширение для VS Code (более удобный для IDE способ взаимодействия с агентами Codex), нам потребовался способ использовать ту же среду для запуска того же цикла агента из интерфейса IDE без его повторной реализации. Это означало необходимость поддержки сложных паттернов взаимодействия, выходящих за рамки простого запроса/ответа: исследование рабочей области, потоковая передача прогресса по мере рассуждений агента и генерация различий (diff). Сначала мы экспериментировали с предоставлением Codex в качестве MCP-сервера, но поддерживать семантику MCP удобным для VS Code образом оказалось сложно. Вместо этого мы внедрили протокол JSON-RPC, дублирующий цикл TUI, который стал неофициальной первой версией App Server. В то время мы не ожидали, что другие клиенты будут зависеть от App Server, поэтому он не проектировался как стабильный API.
По мере роста популярности Codex в последующие месяцы внутренние команды и внешние партнеры выразили желание встраивать ту же среду в собственные продукты для ускорения рабочих процессов разработки ПО. Например, JetBrains и Xcode хотели получить возможности агента уровня IDE, а настольному приложению Codex требовалось параллельно координировать множество агентов Codex. Эти требования подтолкнули нас к созданию платформы, на которую наши собственные продукты и партнерские интеграции могли бы безопасно опираться в долгосрочной перспективе. Решение должно было быть простым в интеграции и обратной совместимости, что позволяло бы нам развивать протокол, не ломая существующие клиентские приложения.
Далее мы подробно рассмотрим, как мы спроектировали архитектуру и протокол, чтобы разные клиенты могли использовать единую среду.
Устройство среды Codex
Сначала давайте подробнее изучим внутреннее устройство среды Codex и то, как Codex App Server предоставляет к ней доступ клиентам. В нашей предыдущей статье блога о Codex мы подробно описали основной цикл агента, который координирует взаимодействие между пользователем, моделью и инструментами. Это ядро логики Codex, однако полноценная работа агента включает в себя и другие аспекты:
1. Жизненный цикл и персистентность потоков (threads). Поток — это диалог между пользователем и агентом в Codex. Codex создает, возобновляет, ветвит и архивирует потоки, а также сохраняет историю событий, чтобы клиенты могли восстанавливать соединение и отображать единую хронологию.
2. Конфигурация и авторизация. Codex загружает конфигурацию, управляет параметрами по умолчанию и выполняет процессы аутентификации, такие как «Войти с помощью ChatGPT», включая управление состоянием учетных данных.
3. Выполнение инструментов и расширения. Codex запускает инструменты оболочки и файлов в изолированной среде (песочнице), а также подключает интеграции, такие как MCP-серверы и навыки, позволяя им участвовать в цикле агента в рамках единой модели политик.
Вся описанная здесь логика агента, включая основной цикл работы, находится в части кодовой базы Codex CLI под названием Codex core. Codex core — это одновременно библиотека, где хранится весь код агента, и среда выполнения, которую можно запустить для выполнения цикла агента и управления сохранением состояния одного потока (диалога) Codex.
Чтобы среда Codex приносила пользу, к ней должен быть организован доступ для клиентов. Именно здесь на помощь приходит App Server.
App Server представляет собой одновременно протокол JSON-RPC для связи между клиентом и сервером, а также долгоживущий процесс, в котором размещаются потоки ядра Codex. Как видно из схемы выше, процесс App Server состоит из четырех основных компонентов: модуля чтения stdio, процессора сообщений Codex, менеджера потоков и самих потоков ядра. Менеджер потоков запускает по одному сеансу ядра для каждого потока, а процессор сообщений Codex напрямую взаимодействует с каждым сеансом ядра для отправки клиентских запросов и получения обновлений.
Один запрос клиента может приводить к множеству обновлений в виде событий, и именно эти детальные события позволяют нам создавать богатый пользовательский интерфейс поверх App Server. Кроме того, модуль чтения stdio и процессор сообщений Codex служат уровнем трансляции между клиентом и потоками ядра Codex. Они преобразуют JSON-RPC запросы клиента в операции ядра Codex, отслеживают поток внутренних событий ядра Codex, а затем трансформируют эти низкоуровневые события в небольшой набор стабильных JSON-RPC уведомлений, готовых для отображения в пользовательском интерфейсе.
Протокол JSON-RPC между клиентом и App Server является полностью двунаправленным. Типичный поток включает запрос клиента и множество уведомлений от сервера. Кроме того, сервер может инициировать запросы, когда агенту требуется ввод данных (например, подтверждение), а затем приостанавливать ход выполнения до ответа от клиента.
Примитивы диалога
Далее мы разберем примитивы диалога — строительные блоки протокола App Server. Проектирование API для цикла агента — сложная задача, поскольку взаимодействие пользователя и агента не сводится к простому запросу/ответу. Один запрос пользователя может разворачиваться в структурированную последовательность действий, которую клиент должен корректно отобразить: ввод пользователя, постепенный прогресс агента, артефакты, созданные по ходу работы (например, различия/diff). Чтобы сделать этот поток взаимодействия простым для интеграции и устойчивым в различных интерфейсах, мы остановились на трех основных примитивах с четкими границами и жизненными циклами:
1. Элемент (Item): Элемент — это атомарная единица ввода/вывода в Codex. Элементы имеют определенный тип (например, сообщение пользователя, сообщение агента, выполнение инструмента, запрос на подтверждение, diff) и каждый обладает четким жизненным циклом:
item/startedпри начале выполнения элемента- необязательные события
item/*/deltaпо мере поступления контента в режиме стриминга (для потоковых типов элементов) item/completedпри завершении элемента с его конечными данными (payload)
Такой жизненный цикл позволяет клиентам начинать отрисовку сразу по событию started, передавать инкрементальные обновления по событию delta и завершать процесс по событию completed.
2. Шаг (Turn): Шаг представляет собой единицу работы агента, инициируемую вводом пользователя. Он начинается, когда клиент отправляет запрос (например, «запустить тесты и обобщить информацию об ошибках») и заканчивается, когда агент завершает формирование результатов для этого ввода. Шаг содержит последовательность элементов, которые представляют промежуточные шаги и результаты, полученные в процессе работы.
3. Поток (Thread): Поток — это долговечный контейнер для продолжающегося сеанса связи с Codex между пользователем и агентом. Он содержит несколько шагов. Потоки можно создавать, возобновлять, ветвить и архивировать. История потоков сохраняется, чтобы клиенты могли восстанавливать соединение и отображать единую хронологию.
Теперь мы рассмотрим упрощенный диалог между клиентом и агентом, где разговор представлен в виде примитивов:
В начале диалога клиент и сервер должны установить рукопожатие initialize. Клиент должен отправить единственный запрос initialize перед выполнением любых других методов, а сервер подтверждает его ответом. Это дает серверу возможность заявить о своих возможностях и позволяет обеим сторонам согласовать версию протокола, флаги функций и значения по умолчанию до того, как наччнется реальная работа. Вот пример полезной нагрузки из расширения OpenAI для VS Code:
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}Вот что возвращает сервер:
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}Когда клиент делает новый запрос, он сначала создает поток (thread), а затем шаг (turn). Сервер отправляет обратно уведомления о ходе выполнения (thread/started и turn/started). Он также возвращает введенные данные, которые регистрирует как элементы, например сообщение пользователя в данном случае.
Вызовы инструментов также отправляются клиенту в виде элементов. Кроме того, сервер может запросить у клиента одобрение перед выполнением действия, отправив запрос сервера. Это одобрение приостановит выполнение шага до тех пор, пока клиент не ответит «разрешить» (allow) или «запретить» (deny). Вот как выглядит процесс одобрения в расширении VS Code:

В конце сервер отправляет сообщение агента и завершает шаг с помощью turn/completed. События дельты сообщения агента передают части сообщения до тех пор, пока сообщение не будет окончательно сформировано с помощью item/completed.
Сообщения на диаграмме упрощены для удобочитаемости. Если вы хотите посмотреть JSON для полного шага, вы можете запустить тестовый клиент из репозитория Codex CLI:
Bash
1codex debug app-server send-message-v2 "run tests and summarize failures"Интеграция с клиентами
Теперь давайте рассмотрим, как различные клиентские интерфейсы встраивают Codex через App Server. Мы рассмотрим три сценария: локальные приложения и IDE, веб-среду выполнения Codex и текстовый интерфейс (TUI).
Во всех трех случаях в качестве транспорта используется JSON-RPC поверх stdio (JSONL). JSON-RPC позволяет с легкостью создавать клиентские привязки на любом выбранном вами языке программирования. Интерфейсы Codex и партнерские интеграции реализовали клиенты App Server на таких языках, как Go, Python, TypeScript, Swift и Kotlin. Для TypeScript вы можете генерировать определения напрямую из протокола Rust, выполнив команду:
Bash
1codex app-server generate-tsДля других языков вы можете сгенерировать пакет JSON Schema и передать его предпочитаемому генератору кода, выполнив:
Bash
1codex app-server generate-json-schemaЛокальные приложения и IDE

Локальные клиенты обычно включают в себя или загружают платформо-зависимый бинарный файл App Server, запускают его как долгоживущий дочерний процесс и поддерживают открытым двунаправленный канал stdio для JSON-RPC. Например, в нашем расширении для VS Code и дексктопном приложении поставляемый артефакт содержит бинарный файл Codex для конкретной платформы и жестко привязан к проверенной версии, поэтому клиент всегда запускает именно те бинарные данные, которые мы протестировали.
Далеко не каждая интеграция может часто выпускать обновления клиента. Некоторые партнеры, такие как Xcode, разделяют циклы релиза, сохраняя клиент стабильным и позволяя ему при необходимости ссылаться на более свежий бинарный файл App Server. Таким образом они могут использовать улучшения на стороне сервера (например, более эффективное автосжатие в ядре Codex или недавно поддерживаемые ключи конфигурации) и внедрять исправления ошибок, не дожидаясь выпуска новой версии клиента. Интерфейс JSON-RPC в App Server разработан с учетом обратной совместимости, поэтому старые клиенты могут безопасно общаться с более новыми серверами.
Codex Web

Codex Web использует среду (harness) Codex, но запускает её в контейнеризированном окружении. Воркер подготавливает контейнер с зафиксированной рабочей средой (workspace), запускает внутри него бинарный файл App Server и поддерживает долгоживущий канал JSON-RPC поверх stdio
Поскольку веб-сессии эфемерны (вкладки закрываются, соединения прерываются), веб-приложение не может быть источником истинных данных (source of truth) для долго выполняющихся задач. Хранение состояния и прогресса на сервере означает, что работа продолжается, даже если вкладка исчезла. Протокол потоковой передачи и сохраненные сессии потоков позволяют новой сессии легко переподключиться, продолжить работу с того места, где она была остановлена, и наверстать упущенное без необходимости повторного создания состояния на стороне клиента.
TUI / Codex CLI

Исторически интерфейс TUI представлял собой «нативный» клиент, который выполнялся в том же процессе, что и цикл агента, и взаимодействовал напрямую с типами ядра Rust, а не с протоколом app-server. Это ускоряло первоначальную разработку, но также делало TUI интерфейсом-исключением.
Теперь, когда App Server существует, мы планируем рефакторить TUI, чтобы использовать его. Таким образом, он будет вести себя как любой другой клиент: запускать дочерний процесс App Server, общаться по протоколу JSON-RPC поверх stdio и отображать те же потоковые события и запросы на подтверждение. Это открывает возможности для рабочих процессов, в которых TUI может подключаться к серверу Codex, запущенному на удаленной машине, удерживая агента ближе к вычислительным ресурсам и продолжая работу, даже если ноутбук переходит в спящий режим или отключается от сети, и при этом предоставляя актуальные обновления и элементы управления локально.
Выбор правильного протокола
App Server для Codex будет основным методом интеграции, который мы будем поддерживать в дальнейшем, однако существуют и другие методы с более ограниченной функциональностью. По умолчанию мы рекомендуем клиентам использовать Codex App Server для интеграции с Codex, но стоит ознакомиться с различными методами интеграции и понять их плюсы и минусы. Ниже приведены наиболее распространенные способы управления Codex и случаи, когда каждый из них может оказаться наиболее подходящим.
Протоколы JSON-RPC
Codex в качестве MCP-сервера
Запустите codex mcp-server и подключитесь из любого MCP-клиента, поддерживающего stdio-серверы (например, OpenAI Agents SDK). Это отличный вариант, если у вас уже есть рабочий процесс на базе MCP и вы хотите вызывать Codex в качестве вызываемого инструмента. Обратной стороной является то, что вы получаете только то, что предоставляет MCP, поэтому специфичные для Codex взаимодействия, зависящие от более богатой семантики сеансов (например, обновления diff), могут некорректно маппироваться через эндпоинты MCP.
Кросс-провайдерные протоколы обвязки агентов
Некоторые экосистемы предлагают переносимый интерфейс, который может работать с несколькими провайдерами моделей и средами выполнения. Это может оказаться полезным, если вам нужна одна абстракция для координации работы нескольких агентов. Компромисс заключается в том, что такие протоколы часто сходятся на общем подмножестве возможностей, из-за чего более сложные взаимодействия бывает трудно представить, особенно когда важна семантика инструментов и сеансов конкретного провайдера. Эта сфера быстро развивается, и мы ожидаем появления новых стандартов по мере того, как мы определяем лучшие примитивы для представления реальных рабочих процессов агентов (skills — отличный пример этого).
Codex App Server
Выбирайте App Server, когда вам требуется полная обвязка Codex, представленная в виде стабильного потока событий, удобного для UI. Вы получаете как полную функциональность цикла агента, так и другие вспомогательные функции, такие как вход через ChatGPT (Sign in with ChatGPT), обнаружение моделей и управление конфигурацией. Основная сложность заключается в интеграции, так как вам потребуется создать клиентскую привязку JSON-RPC на вашем языке программирования. Однако на практике Codex способен взять на себя значительную часть тяжелой работы, если вы предоставите ему JSON-схему и документацию. Многим командам, с которыми мы работали, удалось быстро создать рабочую интеграцию с помощью Codex.
Другие способы внедрения Codex
Codex Exec
Легковесный скриптовый режим CLI для разовых задач и запусков CI. Он отлично подходит для автоматизации и пайплайнов, где требуется выполнить единственную команду до завершения в неинтерактивном режиме, транслировать структурированный вывод в логах и завершить работу с четким сигналом об успехе или ошибке.
Codex SDK
Библиотека TypeScript для программного управления локальными агентами Codex из вашего собственного приложения. Она лучше всего подходит, когда вам нужен нативный библиотечный интерфейс для серверных инструментов и рабочих процессов без создания отдельного JSON-RPC клиента. Поскольку она появилась раньше App Server, в настоящее время она поддерживает меньше языков и имеет меньшую поверхность API. Если появится интерес со стороны разработчиков, мы можем добавить дополнительные SDK, оборачивающие протокол App Server, чтобы команды могли задействовать больше возможностей обвязки без написания привязок JSON-RPC.
Дальнейшие шаги
В этой публикации мы рассказали о том, как мы подходим к проектированию нового стандарта взаимодействия с агентами и как превратить обвязку Codex в стабильный, дружественный к клиенту протокол. Мы рассмотрели, как App Server предоставляет ядро Codex, позволяет клиентам управлять полным циклом агента и обеспечивает работу широкого спектра интерфейсов, включая TUI, интеграции с локальными IDE и веб-среду выполнения.
Если это вдохновило вас на идеи по интеграции Codex в ваши собственные рабочие процессы, стоит попробовать App Server в деле. Весь исходный код находится в открытом репозитории Codex CLI. Не стесняйтесь делиться своими отзывами и запросами функций. Мы с нетерпением ждем ваших отзывов и продолжим делать агентов более доступными для каждого.
Автор
Благодарности
Особая благодарность Майклу Болину (Michael Bolin), Оуэну Лину (Owen Lin), Эрику Трауту (Eric Traut) и Расмусу Ригорду (Rasmus Rygaard), внесшим свой вклад в эту публикацию, а также всей команде Codex, работавшей над App Server.
Сноски
Полный текст статьи читайте на OpenAI
