Розширення можливостей 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 був практичним способом повторного використання обв'язки 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 і як App Server Codex надає це клієнтам. У нашій останній статті у блозі Codex ми детально розібрали основний цикл агента, який координує взаємодію між користувачем, моделлю та інструментами. Це основна логіка системи Codex, але у повній взаємодії з агентом є інші аспекти:
1. Життєвий цикл та збереження потоку. Потік — це розмова між користувачем та агентом Codex. Codex створює, відновлює, створює форки та архівує потоки, а також зберігає історію подій, щоб клієнти могли повторно підключатися та переглядати узгоджену часову шкалу.
2. Конфігурація та автентифікація. Codex завантажує конфігурацію, керує значеннями за промовчанням і запускає потоки автентифікації, такі як «Вхід у систему через ChatGPT», включаючи стан облікових даних.
3. Виконання інструментів та розширення Codex запускає інструменти оболонки (shell)/файлові інструменти в пісочниці та включає інтеграції, такі як MCP-сервери та навички, щоб вони могли брати участь у циклі агента в рамках єдиної моделі політик.
Уся логіка агента, про яку ми згадували, включаючи основний цикл агента, знаходиться в частині кодової бази Codex CLI під назвою «Ядро Codex(відкривається у новому вікні)». Ядро Codex — це свого роду бібліотека, де зберігається весь код агента, а також середовище виконання, яке можна запустити для виконання циклу агента та управління збереженням одного потоку Codex (розмови).
Щоб бути корисною, система Codex має бути доступна клієнтам. Тут і вступає у справу App Server.
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. Елементи мають тип (наприклад, повідомлення користувача, повідомлення агента, виконання інструменту, запит на затвердження, diff), і кожен з них має явний життєвий цикл.
item/startedна початку елемента- необов'язкові події
item/*/deltaяк потоки вмісту (для потокових типів елементів) item/completedпри завершенні елемента з кінцевою корисною інформацією
Цей життєвий цикл дозволяє клієнтам одразу розпочати рендеринг на started, передавати інкрементальні оновлення на delta та завершувати на completed.
2. Хід: Хід — це одиниця роботи агента, що починається з введення користувача. Процес починається, коли клієнт відправляє вхідні дані (наприклад, «запусти тести і підведи підсумки помилок» / «run tests and summarize failures»), і закінчується, коли агент завершує формування вихідних даних для цих даних. Хід містить послідовність елементів, що становлять проміжні кроки та результати, отримані в процесі.
3. Потік: Потік — це надійний контейнер для поточної сесії Codex між користувачем та агентом. У ньому міститься кілька етапів. Потоки можна створювати, відновлювати, розгалужувати (створювати форки) та архівувати. Історія потоку зберігається, щоб клієнти могли підключитися повторно та переглянути узгоджену тимчасову шкалу.
Розглянемо спрощену розмову між клієнтом та агентом, де розмова представлена базовими компонентами:
На початку розмови клієнт та сервер повинні встановити з'єднання — initialize. Клієнт повинен надіслати єдиний запит initialize перед будь-яким іншим методом, і сервер підтверджує з'єднання відповіддю. Це дозволяє серверу оголосити про свої можливості та дозволяє обом сторонам узгодити версію протоколу, прапори функцій та значення за замовчуванням до того, як розпочнеться робота. Ось приклад даних із розширення OpenAI для VS Code:
Ось що повертає сервер:
Коли клієнт робить новий запит, спочатку створюється потік, потім хід. Сервер надсилатиме сповіщення про прогрес (thread/started і turn/started). Він також буде відправляти вхідні дані, які реєструються як елементи, наприклад, повідомлення користувача тут.
Виклики інструментів також надсилаються клієнту у вигляді елементів. Крім того, сервер може запитати підтвердження клієнта, перш ніж зможе виконати дію, надіславши запит на сервер. Підтвердження призупинить хід, поки клієнт не відповість або allow, або deny. Ось як виглядає процес підтвердження у розширенні VS Code:

Наприкінці сервер відправляє повідомлення агента, а потім завершує хід із turn/completed. Події дельти повідомлень агента передають частини повідомлення назад, доки повідомлення не буде завершено з item/completed.
Повідомлення на ілюстрації спрощені для зручності читання. Якщо ви хочете побачити повний хід у JSON, ви можете запустити тестовий клієнт з репозиторію Codex CLI:
Тепер погляньмо, як різноманітні клієнтські інтерфейси вбудовують Codex через App Server. Ми розглянемо три шаблони: локальні програми та IDE, веб-версію Codex та TUI.
У всіх трьох випадках транспорт — JSON-RPC через stdio (JSONL). JSON-RPC спрощує створення клієнтських прив'язок обраною вами мовою. Codex та інтеграції з партнерами реалізували клієнтів App Server такими мовами, як Go, Python, TypeScript, Swift та Kotlin. Для TypeScript можна згенерувати визначення безпосередньо з протоколу Rust, виконавши таку команду:
Для інших мов ви можете згенерувати пакет схеми JSON і передати його в потрібний генератор коду, виконавши наступну команду:

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

Codex Web використовує harness Codex, але запускає його у контейнерному середовищі. Модуль підготовляє контейнер з перевіреною робочою областю, запускає всередині нього бінарний файл App Server і підтримує тривале з'єднання JSON-RPC через канал stdio2. Веб-застосунок (що працює у вкладці браузера користувача) взаємодіє з бекенд Codex по HTTP і SSE, який передає потік подій завдань, створюваних модулем. Це дозволяє зберегти простоту інтерфейсу на стороні браузера, забезпечуючи однакове середовище виконання як для настільних комп'ютерів, так і для веб-застосунків.
Оскільки веб-сеанси недовговічні (вкладки закриваються, з'єднання зникають), веб-застосунок не може бути джерелом достовірної інформації для тривалих завдань. Збереження стану та прогресу на сервері означає, що робота продовжується, навіть якщо вкладка буде закрита. Протокол потокової передачі та збережені сеанси потоків спрощують повторне підключення нового сеансу, дозволяючи йому продовжитися з місця, де його було зупинено, і надолужити втрачене без необхідності відновлювати стан на стороні клієнта.

Історично TUI був «нативним» клієнтом, який працював у тому процесі, як і цикл агента, і взаємодіяв безпосередньо з типами ядра Rust, а чи не з протоколом сервера додатків. Це прискорило ранні ітерації, але зробило TUI платформою для особливих випадків.
Тепер, коли у нас є App Server, ми плануємо виконати рефакторинг TUI(відкривається у новому вікні), щоб використовувати його таким чином, щоб він поводився як будь-який інший клієнт: запускав дочірній процес App Server, спілкувався JSON-RPC через stdio і відображав ті ж потокові події та підтвердження. Це розблокує робочі процеси, в яких TUI може підключатися до сервера Codex, що працює на віддаленій машині, утримуючи агента ближче до обчислювальних ресурсів і дозволяючи продовжувати роботу, навіть якщо ноутбук переходить у сплячий режим або відключається, при цьому, як і раніше, локально надаючи оновлення в реальному часі та елементи керування.
Codex App Server стане основним методом інтеграції, який ми підтримуватимемо надалі, але також існують інші методи з більш обмеженою функціональністю. За замовчуванням ми рекомендуємо клієнтам використовувати Codex App Server для інтеграції з Codex, але радимо також розглянути різні методи інтеграції, щоб зрозуміти їх переваги та недоліки для вас. Нижче наведені найпоширеніші способи використання Codex та випадки, коли кожен із них може бути доречним.
Запустіть codex mcp-server(відкривається у новому вікні) і підключіться з будь-якого клієнта MCP, що підтримує stdio-сервери (наприклад, OpenAI Agents SDK(відкривається у новому вікні)). Це хороший вибір, якщо у вас вже є робочий процес на основі MCP і ви хочете використовувати Codex як інструмент, який можна викликати. Недолік полягає в тому, що ви отримуєте тільки те, що надає MCP, тому специфічні для Codex взаємодії, які залежать від більшої семантики сеансу (наприклад, оновлення diff), можуть некоректно відображатися через кінцеві точки MCP.
Деякі екосистеми пропонують переносний інтерфейс, який може працювати з кількома постачальниками моделей та середовищами виконання. Це може бути хорошим вибором, якщо ви хочете одну абстракцію, яка координує роботу кількох агентів. Компроміс полягає в тому, що ці протоколи часто сходяться на загальному підмножині можливостей, що може утруднити уявлення більш функціональних взаємодій, особливо коли важлива семантика інструментів та сесій, специфічна для провайдера. Ця область швидко розвивається, і ми очікуємо, що в міру того, як ми визначатимемо найкращі примітиви для представлення реальних робочих процесів агентів, з'являться загальніші стандарти (skills(відкривається у новому вікні) — непоганий приклад).
Виберіть App Server, якщо вам потрібно, щоб повний harness Codex був доступний як стабільний, зручний для інтерфейсу користувача потік подій. Ви отримуєте як повну функціональність циклу агента, так і інші допоміжні функції, такі як вхід через ChatGPT, виявлення моделей та керування конфігурацією. Основна стаття витрат — це роботи з інтеграції, оскільки вам потрібно реалізувати клієнтську JSON-RPC-прив'язку вашою мовою. Насправді, Codex може виконувати більшу частину складної роботи, якщо надати йому схему JSON і документацію. Багато команд, з якими ми працювали, змогли швидко створити робочу інтеграцію за допомогою 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. Не соромтеся ділитися своїми відгуками та запитами на нові функції. Ми з нетерпінням чекаємо на вашу відповідь і будемо продовжувати робити агентів більш доступними для всіх.
Автор
Подяки
Особлива подяка Майклу Боліну, Оуену Ліну, Еріку Трауту та Расмусу Рюгаарду, які зробили внесок у цю публікацію, а також всій команді Codex, яка працювала над App Server.
Виноски
- 1
Ми використовуємо варіант JSON-RPC lite: він зберігає форму запиту/відповіді/повідомлення, але виключає заголовок
"jsonrpc": "2.0"і оформлений як JSONL через stdio, а не як чіткий JSON‑RPC 2.0. - 2
«stdio» — stdin/stdout сервера додатків усередині контейнера. У хостингових конфігураціях ці потоки часто тунелюються через постійне мережне з'єднання (наприклад, WebSocket-подібне) до середовища виконання контейнера, так що воно поводиться як stdio, навіть якщо це не буквальний локальний канал.


