Переход к основному контенту
OpenAI

4 февраля 2026 г.

Инженерия

Расширение возможностей Codex: как мы создали App Server

Автор: Силия Чен, член технического персонала

Загрузка…

Агент программирования Codex от OpenAI доступен на различных платформах: веб-приложение(открывается в новом окне), CLI(открывается в новом окне), расширение для IDE(открывается в новом окне) и новое приложение Codex для macOS. Все они работают на одном и том же ядре Codex — цикле агента и логике, лежащих в основе всех возможностей Codex. Что обеспечивает ключевую связь между ними? Codex App Server(открывается в новом окне) — удобный для клиентов двунаправленный API JSON-RPC1.

В этой публикации мы представим Codex App Server; мы поделимся нашими наработками о лучших способах интеграции возможностей Codex в ваш продукт, чтобы помочь вашим пользователям значительно улучшить их рабочие процессы. Мы рассмотрим архитектуру и протокол App Server и то, как он интегрируется с различными поверхностями Codex, а также дадим советы по использованию Codex, независимо от того, хотите ли вы превратить Codex в рецензента кода, агента SRE или помощника по программированию.

Как появился App Server

Прежде чем углубляться в архитектуру, немного о предыстории App Server. Изначально App Server был практичным способом повторного использования обвязки Codex в различных продуктах, которая постепенно эволюционировала в наш стандартный протокол.

Codex CLI начинался как TUI (терминальный пользовательский интерфейс), то есть доступ к Codex осуществляется через терминал. Когда мы создавали расширение для VS Code (более удобный для IDE способ взаимодействия с агентами Codex), нам нужен был способ использовать ту же обвязку, чтобы запускать тот же цикл агента из интерфейса IDE без повторной реализации. Это означало поддержку богатых паттернов взаимодействия, выходящих за рамки запроса/ответа, таких как исследование рабочей области, потоковая передача прогресса по мере того, как агент рассуждает, и выдача изменений. Сначала мы экспериментировали с тем, чтобы представить Codex как MCP-сервер(открывается в новом окне), но поддерживать семантику MCP в таком виде, чтобы это имело смысл для VS Code, оказалось сложно. Вместо этого мы внедрили протокол JSON-RPC, который отражал цикл TUI, что стало неофициальной первой версией(открывается в новом окне) App Server. В то время мы не ожидали, что другие клиенты будут зависеть от App Server, поэтому он не был спроектирован как стабильный API.

По мере того как внедрение Codex росло в течение следующих нескольких месяцев, внутренние команды и внешние партнёры хотели получить возможность встраивать тот же инструмент в свои собственные продукты, чтобы ускорить рабочие процессы разработки программного обеспечения у своих пользователей. Например, JetBrains и Xcode хотели обеспечить опыт работы с агентом уровня IDE, в то время как настольному приложению Codex требовалось координировать работу множества агентов Codex параллельно. Эти требования подтолкнули нас к разработке платформы, на которую со временем могли бы безопасно опираться как наши продукты, так и интеграции с партнёрами. Необходимо было обеспечить легкость интеграции и обратную совместимость, что означало возможность развивать протокол без нарушения работы существующих клиентов.

Далее мы расскажем, как мы разработали архитектуру и протокол, чтобы разные клиенты могли использовать один и тот же интерфейс.

Внутри структуры Codex

Сначала давайте подробнее рассмотрим, что находится внутри обвязки Codex и как App Server Codex предоставляет это клиентам. В нашей последней статье в блоге Codex мы подробно разобрали основной цикл агента, который координирует взаимодействие между пользователем, моделью и инструментами. Это основная логика системы Codex, но в полном взаимодействии с агентом есть и другие аспекты:

1. Жизненный цикл и сохранение потока. Поток — это разговор между пользователем и агентом Codex. Codex создаёт, возобновляет, создает форки и архивирует потоки, а также сохраняет историю событий, чтобы клиенты могли повторно подключаться и просматривать согласованную временную шкалу.

2. Конфигурация и аутентификация. Codex загружает конфигурацию, управляет значениями по умолчанию и запускает потоки аутентификации, такие как «Вход в систему через ChatGPT», включая состояние учетных данных.

3. Выполнение инструментов и расширения. Codex запускает инструменты оболочки (shell)/файловые инструменты в песочнице и подключает интеграции, такие как MCP-серверы и навыки, чтобы они могли участвовать в цикле агента в рамках единой модели политик.

Вся логика агента, о которой мы здесь упоминали, включая основной цикл агента, находится в части кодовой базы Codex CLI под названием «Ядро Codex(открывается в новом окне)». Ядро Codex — это своего рода библиотека, где хранится весь код агента, а также среда выполнения, которую можно запустить для выполнения цикла агента и управления сохранением одного потока Codex (разговора).

Чтобы быть полезной, система Codex должна быть доступна клиентам. Здесь и вступает в дело App Server.

Схема с заголовком «Процессный поток сервера приложений». Клиент отправляет сообщения JSON-RPC в stdio reader, который перенаправляет запросы в процессор сообщений Codex. Процессор взаимодействует с менеджером потоков и основным потоком через потоки поиска, дескрипторы потоков, отправленные запросы и события/обновления, а затем возвращает ответы клиенту.

App Server — это протокол JSON-RPC между клиентом и сервером, а также продолжительный процесс, который размещает основные потоки Codex. Как видно из приведенной выше схемы, процесс App Server имеет четыре основных компонента: stdio reader, процессор сообщений Codex, менеджер потоков и основные потоки. Менеджер потоков запускает одну основную сессию для каждого потока, а процессор сообщений Codex затем напрямую взаимодействует с каждой основной сессией для отправки клиентских запросов и получения обновлений.

Один запрос клиента может привести ко множеству обновлений событий, и именно эти подробные события позволяют нам создать богатый пользовательский интерфейс поверх App Server. Кроме того, stdio reader и процессор сообщений Codex служат слоем перевода между клиентом и основными потоками Codex. Они преобразуют клиентские JSON-RPC-запросы в основные операции Codex, прослушивают внутренний поток событий ядра Codex, а затем трансформируют эти низкоуровневые события в небольшой набор стабильных, готовых для пользовательского интерфейса JSON-RPC-уведомлений.

Протокол JSON-RPC между клиентом и App Server является полностью двунаправленным. Стандартный поток включает запрос клиента и множество уведомлений сервера. Кроме того, сервер может инициировать запросы, когда агенту требуется ввод, например, подтверждение, а затем приостановить ход до тех пор, пока от клиента не будет получен ответ.

Базовые компоненты разговора

Далее мы разберём базовые компоненты разговора, которые являются строительными блоками протокола App Server. Проектирование API для цикла агента — сложная задача, поскольку взаимодействие между пользователем и агентом не является простым диалогом «запрос/ответ». Один запрос пользователя может развернуться в структурированную последовательность действий, которую клиенту необходимо точно отразить: ввод пользователя, поэтапный прогресс агента, артефакты, создаваемые по ходу (например, диффы). Чтобы этот поток взаимодействий было легко интегрировать и чтобы он оставался устойчивым в разных пользовательских интерфейсах, мы выбрали три основных базовых компонента с чёткими границами и жизненными циклами:

1. Элемент: Элемент — это единица ввода/вывода в Codex. Элементы разделяются по типам (например, сообщение пользователя, сообщение агента, выполнение инструмента, запрос на утверждение, дифф), и у каждого из них есть четкий жизненный цикл:

  • item/started в начале элемента
  • необязательные события item/*/delta в качестве потоков содержимого (для потоковых типов элементов)
  • item/completed при завершении элемента с конечной полезной информацией

Этот жизненный цикл позволяет клиентам сразу начать рендеринг на started, передавать инкрементальные обновления на delta и завершать на completed.

2. Ход: Ход — это единица работы агента, инициируемая вводом пользователя. Процесс начинается, когда клиент отправляет входные данные (например, «запусти тесты и подведи итоги по ошибкам» / «run tests and summarize failures»), и заканчивается, когда агент завершает формирование выходных данных для этих данных. Ход содержит последовательность элементов, представляющих промежуточные шаги и результаты, полученные в процессе.

3. Поток: Поток — это надежный контейнер для текущей сессии Codex между пользователем и агентом. В нём несколько этапов. Потоки можно создавать, возобновлять, разветвлять (создавать ответвления) и архивировать. История потока сохраняется, чтобы клиенты могли подключиться повторно и просмотреть согласованную временную шкалу.

Рассмотрим упрощённый разговор между клиентом и агентом, где разговор представлен базовыми компонентами:

Схема с надписью «Поток сообщений протокола клиент-сервер: синхронизация для инициализации». Клиент отправляет на сервер запрос initialize с clientInfo. Сервер отвечает событием результата, содержащим строку userAgent «my_client/1.0».

В начале разговора клиент и сервер должны установить соединение — 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/start и turn/start на сервер. Сервер генерирует события — thread/started, turn/started, item/started и item/completed — показывая ход с сообщением пользователя: «запусти тесты и подведи итоги по ошибкам» («run tests and summarize failures»).

Когда клиент делает новый запрос, сначала создается поток, а затем ход. Сервер будет отправлять уведомления о ходе выполнения (thread/started и turn/started). Он также будет отправлять обратно входные данные, которые регистрируются как элементы, например, сообщение пользователя здесь.

Схема под названием «Поток сообщений протокола клиент-сервер: выполнение инструмента с необязательным утверждением». Во время вызова инструмента сервер отправляет item/started, затем item/commandExecution/requestApproval с указанием причины («run tests»). Клиент возвращает событие утверждения (allow/deny). Затем сервер отправляет item/completed, показывая выполнение команды («pnpm test»).

Вызовы инструментов также отправляются обратно клиенту в виде элементов. Кроме того, сервер может запросить одобрение клиента, прежде чем выполнить действие, отправив запрос на сервер. Подтверждение приостановит ход, пока клиент не ответит либо «разрешить», либо «отклонить». Вот как выглядит процесс утверждения в расширении VS Code:

Запрос в интерфейсе с темной темой с вопросом: «Хотите разрешить мне выполнить pnpm test для этой рабочей области?» Перечислены варианты: 1) Да, 2) Да и больше не спрашивать для команд, начинающихся с pnpm test, и 3) Нет, а внизу — кнопка «Отправить».
Схема с заголовком «Поток сообщений протокола клиент-сервер: поток сообщений агента потоковой передачи». Сервер передает сообщение ассистента по частям: item/started, два события agentMessage/delta («выполнено 3 теста», «все тесты пройдены»), затем item/completed. Ход заканчивается на turn/completed.

В конце сервер отправляет сообщение агента, а затем завершает ход с turn/completed. События дельты сообщений агента передают части сообщения обратно, пока сообщение не будет завершено с item/completed.

Сообщения на иллюстрации упрощены для удобства чтения. Если вы хотите увидеть полный ход в формате JSON, вы можете запустить тестовый клиент из репозитория Codex CLI:

Bash

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

Интеграция с клиентами

Теперь взглянем, как различные клиентские интерфейсы встраивают Codex через App Server. Мы рассмотрим три шаблона: локальные приложения и IDE, веб-версию Codex и TUI.

Схема под названием «Клиенты Codex, интегрированные с harness Codex через сервер приложений». Клиенты первой стороны (Codex Desktop App, TUI/CLI, Web Runtime) и сторонние интеграции (JetBrains IDEs, VS Code, Xcode) взаимодействуют с harness Codex через вызовы JSON-RPC.

Во всех трех случаях транспорт — JSON-RPC через stdio (JSONL). JSON-RPC упрощает создание клиентских привязок на выбранном вами языке. Codex и интеграции с партнерами реализовали клиентов App Server на таких языках, как Go, Python, TypeScript, Swift и Kotlin. Для TypeScript вы можете сгенерировать определения напрямую из протокола Rust, выполнив следующую команду:

Bash

1
codex app-server generate-ts

Для других языков вы можете сгенерировать пакет схемы JSON и передать его в предпочитаемый генератор кода, выполнив следующую команду:

Bash

1
codex app-server generate-json-schema
Локальные приложения и IDE
Скриншот VS Code с запущенным расширением Codex. Открыт тестовый файл Rust, и под ним панель Codex описывает запуск только fmt и cargo test -p codex-app-server, сообщая, что форматирование и тесты выполняются в ожидании окончательного результата (успех/сбой).

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

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

Веб-версия Codex
Снимок экрана веб-интерфейса Codex, на котором показано обновление под названием «Обновление сообщения об успешном входе в систему». Левая панель суммирует изменения, тесты и изменённые файлы, а правая панель отображает кодовые различия для login.rs с обновлённой формулировкой сообщения об успешном входе.

Codex Web использует harness Codex, но запускает его в контейнерной среде. Исполнимый модуль подготавливает контейнер с проверенной рабочей областью, запускает внутри него бинарный файл App Server и поддерживает длительное соединение JSON-RPC через канал stdio2. Веб-приложение (работающее во вкладке браузера пользователя) взаимодействует с бэкендом Codex по HTTP и SSE, который передает поток событий задач, создаваемых исполнимым модулем. Это позволяет сохранить легковесный интерфейс на стороне браузера, при этом обеспечивая единообразную среду выполнения как для настольных компьютеров, так и для веб-приложений.

Поскольку веб-сеансы недолговечны (вкладки закрываются, соединения пропадают), веб-приложение не может быть источником достоверной информации для длительных задач. Сохранение состояния и прогресса на сервере означает, что работа продолжается, даже если вкладка будет закрыта. Протокол потоковой передачи и сохранённые сеансы потоков упрощают повторное подключение нового сеанса, позволяя ему продолжиться с того места, где он был остановлен, и наверстать упущенное без необходимости восстанавливать состояние на стороне клиента.

TUI/Codex CLI
Скриншот терминала с запущенным Codex CLI. Показан баннер OpenAI Codex с моделью gpt-5.2-codex medium, команда пользователя «explain app server to me», и статус «Working». Ниже появляется подсказка: «write tests for @filename», с вариантами комбинаций клавиш.

Исторически TUI был «нативным» клиентом, который работал в том же процессе, что и цикл агента, и взаимодействовал напрямую с типами ядра Rust, а не с протоколом сервера приложений. Это ускорило ранние итерации, но также сделало TUI платформой для особых случаев.

Теперь, когда у нас есть App Server, мы планируем выполнить рефакторинг TUI(открывается в новом окне), чтобы использовать его таким образом, чтобы он вёл себя как любой другой клиент: запускал дочерний процесс App Server, общался по JSON-RPC через stdio и отображал те же потоковые события и подтверждения. Это разблокирует рабочие процессы, в которых TUI может подключаться к серверу Codex, работающему на удаленной машине, удерживая агента ближе к вычислительным ресурсам и позволяя продолжать работу, даже если ноутбук переходит в спящий режим или отключается, при этом по-прежнему предоставляя локально обновления в реальном времени и элементы управления.

Выбор подходящего протокола

Codex App Server станет основным методом интеграции, который мы будем поддерживать в дальнейшем, но также существуют и другие методы с более ограниченной функциональностью. По умолчанию мы рекомендуем клиентам использовать Codex App Server для интеграции с Codex, но советуем также рассмотреть различные методы интеграции, чтобы понять их преимущества и недостатки для вас. Ниже приведены наиболее распространенные способы использования Codex и случаи, когда каждый из них может быть подходящим.

Протоколы JSON-RPC

Codex в качестве MCP-сервера

Запустите codex mcp-server(открывается в новом окне) и подключитесь с любого MCP-клиента, поддерживающего stdio-серверы (например, OpenAI Agents SDK(открывается в новом окне)). Это хороший выбор, если у вас уже есть рабочий процесс на основе MCP и вы хотите использовать Codex как вызываемый инструмент. Недостаток заключается в том, что вы получаете только то, что предоставляет MCP, поэтому специфические для Codex взаимодействия, которые зависят от более богатой семантики сеанса (например, обновления diff), могут некорректно отображаться через конечные точки MCP.

Протоколы обвязки агента для разных провайдеров

Некоторые экосистемы предлагают переносимый интерфейс, который может работать с несколькими поставщиками моделей и средами выполнения. Это может быть хорошим выбором, если вы хотите одну абстракцию, которая координирует работу нескольких агентов. Компромисс заключается в том, что эти протоколы часто сходятся на общем подмножестве возможностей, что может затруднить представление более функциональных взаимодействий, особенно когда важны семантика инструментов и сессий, специфичная для провайдера. Эта область быстро развивается, и мы ожидаем, что по мере того, как мы будем определять лучшие примитивы для представления реальных рабочих процессов агентов, появятся более общие стандарты (skills(открывается в новом окне) — неплохой пример).

App Server Codex

Выберите App Server, если вам нужно, чтобы полный harness Codex был доступен как стабильный, удобный для пользовательского интерфейса поток событий. Вы получаете как полную функциональность цикла агента, так и другие вспомогательные функции, такие как вход через ChatGPT, обнаружение моделей и управление конфигурацией. Основная статья затрат — это работы по интеграции, поскольку вам нужно реализовать клиентскую JSON-RPC-привязку на вашем языке. На практике, однако, Codex может выполнять большую часть сложной работы, если предоставить ему схему JSON и документацию. Многие команды, с которыми мы работали, смогли быстро создать рабочую интеграцию с помощью Codex.

Другие способы встраивания Codex

Легковесный режим CLI с поддержкой скриптов для разовых задач и запусков CI. Это хорошо подходит для автоматизации и конвейеров, где вам нужна одна команда, которая выполняется до завершения в неинтерактивном режиме, передает структурированные ответы для журналов и завершает работу с четким сигналом об успехе или неудаче.

Библиотека TypeScript для программного управления локальными агентами Codex из вашего собственного приложения. Лучше всего подходит, если вам нужен нативный интерфейс библиотеки для серверных инструментов и рабочих процессов без создания отдельного JSON-RPC клиента. Поскольку он был выпущен раньше, чем App Server, в настоящее время поддерживается меньше языков и меньшая область охвата. При наличии интереса со стороны разработчиков мы можем добавить дополнительные SDK, которые оборачивают протокол App Server, чтобы команды могли охватить больше возможностей платформы без написания привязок JSON-RPC.

Что дальше

В этом посте мы поделились тем, как мы подходим к разработке нового стандарта взаимодействия с агентами и как превратить harness Codex в стабильный и удобный для клиентов протокол. Мы рассмотрели, как App Server предоставляет доступ к ядру Codex, позволяет клиентам управлять полным циклом агента и поддерживает работу широкого спектра интерфейсов, включая TUI, локальные интеграции с IDE и веб-среду выполнения.

Если это натолкнуло вас на идеи по интеграции Codex в ваши собственные рабочие процессы, стоит попробовать App Server. Весь исходный код находится в репозитории(открывается в новом окне) с открытым исходным кодом Codex CLI. Не стесняйтесь делиться своими отзывами и запросами на новые функции. Мы с нетерпением ждем вашего ответа и будем продолжать делать агентов более доступными для всех.

Автор

Celia Chen

Благодарности

Особая благодарность Майклу Болину, Оуэну Лину, Эрику Трауту и Расмусу Рюгаарду, которые внесли вклад в эту публикацию, а также всей команде Codex, работавшей над App Server.

Сноски

  1. 1

    Мы используем вариант «JSON‑RPC lite»: он сохраняет форму запроса/ответа/уведомления, но исключает заголовок "jsonrpc": "2.0" и оформлен как JSONL через stdio, а не как строгий JSON‑RPC 2.0.

  2. 2

     «stdio» — stdin/stdout сервера приложений внутри контейнера. В хостинговых конфигурациях эти потоки часто туннелируются через постоянное сетевое соединение (например, WebSocket-подобное) к среде выполнения контейнера — так что она ведёт себя как stdio, даже если это не буквальный локальный канал.