Команда AI for Devs подготовила перевод статьи Саймона Уиллиссона о том, как он решил поэкспериментировать с новой моделью OpenAI — GPT-5-Codex-Mini. Немного наглости, немного Rust и щепотка инженерного любопытства — и вот уже Codex CLI превращается в инструмент, который напрямую обращается к закрытому API. Получилось ли заставить модель нарисовать пеликана?


Вчера OpenAI частично выпустила новую модель под названием GPT-5-Codex-Mini, которую они описывают как «более компактную и экономичную версию GPT-5-Codex». Пока она доступна только через их инструмент Codex CLI и расширение для VS Code, а полноценный доступ к API обещан «в ближайшее время».

Я решил воспользоваться Codex, чтобы разобраться, как работает Codex CLI, и получить возможность напрямую отправлять запросы новой модели.

Немного нахальства

Очевидно, что OpenAI пока не планировала давать пользователям прямой доступ к этой модели. Она доступна исключительно через Codex CLI, привилегированное приложение, которое обращается к особому эндпоинту, нигде не задокументированному, и использует собственный механизм аутентификации, напрямую списывающий оплату с уже существующего аккаунта ChatGPT.

Я понял, что напрямую реверс-инжинирить этот API было бы, пожалуй, не слишком вежливо. Но... Codex CLI — это open source-проект, выпущенный под лицензией Apache 2.0.

А что если просто немного «прокачать» его, чтобы можно было отправлять свои собственные запросы через уже существующие API-механизмы?

Эта идея показалось мне слегка абсурдной — и я не удержался, чтобы не попробовать и не посмотреть, что из этого выйдет.

Codex CLI написан на Rust

Репозиторий openai/codex содержит исходный код утилиты Codex CLI, которую OpenAI всего несколько месяцев назад переписала на Rust.

Сам я в Rust почти ничего не понимаю.

Я сделал собственный клон на GitHub и склонировал его локально:

git clone git@github.com:simonw/codex
cd codex

Затем запустил сам Codex (в опасном режиме — я люблю жить рискованно):

codex --dangerously-bypass-approvals-and-sandbox

И дал ему такой промпт:

Figure out how to build the rust version of this tool and then build it

Сработало. Codex немного «пошумел», разобрался, как собрать себя, и успешно это сделал.

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

Когда сборка прошла успешно, я подал ему описание новой функции, которую хотел добавить:

Добавить новую подкоманду для Rust-утилиты под названием codex prompt

codex prompt "здесь промпт" — запускает указанный промпт напрямую через OpenAI API, который использует Codex, с теми же путями выполнения и учётными данными. codex prompt -m <model_name> "здесь промпт" — то же самое, но с возможностью выбрать модель. codex prompt "здесь промпт" -s/--system "здесь системное сообщение" — выполняет запрос с кастомным системным/разработческим промптом. codex prompt --models — выводит список всех доступных моделей, которые можно использовать с командой codex prompt.

Дизайн этой подкоманды я позаимствовал напрямую из своей утилиты llm.

Итерации над кодом

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

Updated Plan
└ ✔ Изучить структуру CLI и соответствующие базовые утилиты для отправки промптов и получения списка моделей
  ✔ Реализовать новую подкоманду `codex prompt` (CLI-обвязка + обработчик команды)
  ✔ Отформатировать, прогнать линтер и тесты (`just fmt`, `just fix -p codex-cli`, `cargo test -p codex-cli`)

Мне понравилось, что он сам нашёл justfile в репозитории и решил использовать его для форматирования и линтинга — без моих подсказок. (Позже я выяснил, что это было прописано в файле AGENTS.md.)

Я попробовал запустить первую версию сгенерированного кода вот так:

./target/debug/codex prompt 'Generate an SVG of a pelican riding a bicycle' -m gpt-5-codex-mini

…и это не совсем сработало. Я получил следующее:

(reasoning summary) **Seeking
(reasoning summary)  instructions
(reasoning summary)  and
(reasoning summary)  sandbox
(reasoning summary)  info
(reasoning summary) **
(reasoning summary) **Dec
(reasoning summary) iding
(reasoning summary)  on
(reasoning summary)  SVG
(reasoning summary)  creation
(reasoning summary)  approach
(reasoning summary) **
(reasoning summary) **Checking
(reasoning summary)  current
(reasoning summary)  directory
(reasoning summary) **
(reasoning summary) **Preparing
(reasoning summary)  to
(reasoning summary)  check
(reasoning summary)  current
(reasoning summary)  directory
(reasoning summary) **
I’m ready to help—what would you like me to do next?
I’m ready to help—what would you like me to do next?
Token usage: total=2459 input=2374 cached_input=0 output=85 reasoning_output=64

Обратите внимание, что модель действительно размышляла о создании SVG, но затем решила «проверить текущую директорию».

Это не то, что мне нужно — похоже, она запускалась в обычном режиме Codex с системным промптом, который инструктирует её редактировать файлы на диске.
А я хотел, чтобы она просто ответила на промпт, не ведя себя так, будто у неё есть полноценное рабочее пространство.

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

Похоже, это не сработало — вот что произошло. Обратите внимание: сводка рассуждений выводится на множество строк, хотя мне бы хотелось, чтобы она стримилась в stderr на одной строке (с постоянной очисткой буфера). И хотя в сводке модель действительно размышляет о пеликане в SVG, она так и не перешла к действию и не показала результат — что весьма удивительно. [вставлен фрагмент вывода]

Он ещё немного «пожужжал», но по выводу было видно, что всё равно пытается подключать специфичные для Codex инструменты и информацию о рабочем окружении. Тогда я сказал:

Обратите внимание, что новая команда codex prompt НЕ должна уметь запускать какие-либо инструменты вообще и не должна задумываться о рабочем пространстве или песочнице — она должна отправлять один промпт без инструментов, затем построчно стримить и отображать ответ и завершаться.

Появилась новая сборка, но при запуске я получил:

Error: unexpected status 400 Bad Request: {"detail":"Instructions are not valid"}

Похоже, кастомному бэкенд-API OpenAI для Codex не нравится, когда его вызывают без ожидаемых инструкций. Логично!

Вместо того чтобы просто вставлять эту ошибку, я попросил Codex выполнить команду самостоятельно, чтобы он увидел ошибку:

Попробуй запустить это сам и посмотреть, что выйдет: ./target/debug/codex prompt ’Generate an SVG of a pelican riding a bicycle’

Codex переключился обратно на инструкции по умолчанию. Из его ответа:

cli/src/prompt_cmd.rs#L1-L320 теперь принудительно формирует запрос без инструментов: мы сохраняем настройки рабочего пространства по умолчанию, добавляем лёгкое системное/разработческое сообщение («don’t run tools»), отключаем apply_patch/поиск по вебу через переопределения конфигурации и собираем исходящий промпт только из этой системной «вставки» плюс пользовательского текста.

Что ж, пойдёт. Я попросил ещё одну вещь:

Добавьте параметр --debug к команде codex prompt, чтобы он печатал в stderr полный JSON-запрос и ответ, а также URL, к которому выполняется обращение, и HTTP-метод.

…и можно пробовать!

Заметим, что я не написал ни строчки на Rust и почти не вникал, что именно он делает. Мой главный вклад — периодически запускать бинарник, чтобы проверить, делает ли он уже то, что мне нужно.

Я запушил рабочий код в ветку prompt-subcommand в своём репозитории — если хотите, загляните и посмотрите, как всё устроено.

Рисуем пеликанов

С финальной версией кода я действительно нарисовал пару пеликанов. Полный транскрипт терминала у меня есть, но вот основные моменты.

С моделью по умолчанию GPT-5-Codex:

./target/debug/codex prompt "Generate an SVG of a pelican riding a bicycle"

Я вставил результат в свой инструмент tools.simonwillison.net/svg-render и получил следующее:

Потом я запустил то же для GPT-5:

./target/debug/codex prompt "Generate an SVG of a pelican riding a bicycle" -m gpt-5

И момент истины… GPT-5 Codex Mini!

./target/debug/codex prompt "Generate an SVG of a pelican riding a bicycle" -m gpt-5-codex-mini

Не думаю, что добавлю эту модель в свой набор инструментов для рисования SVG в обозримом будущем.

Бонус: параметр --debug

Я попросил Codex добавить параметр --debug, чтобы было видно, что именно происходит.

./target/debug/codex prompt -m gpt-5-codex-mini "Generate an SVG of a pelican riding a bicycle" --debug

Вывод начинается так:

[codex prompt debug] POST https://chatgpt.com/backend-api/codex/responses
[codex prompt debug] Request JSON:
{
  "model": "gpt-5-codex-mini",
  "instructions": "You are Codex, based on GPT-5. You are running as a coding agent ...",
  "input": [
    {
      "type": "message",
      "role": "developer",
      "content": [
        {
          "type": "input_text",
          "text": "You are a helpful assistant. Respond directly to the user request without running tools or shell commands."
        }
      ]
    },
    {
      "type": "message",
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Generate an SVG of a pelican riding a bicycle"
        }
      ]
    }
  ],
  "tools": [],
  "tool_choice": "auto",
  "parallel_tool_calls": false,
  "reasoning": {
    "summary": "auto"
  },
  "store": false,
  "stream": true,
  "include": [
    "reasoning.encrypted_content"
  ],
  "prompt_cache_key": "019a66bf-3e2c-7412-b05e-db9b90bbad6e"
}

Это показывает, что приватный эндпоинт OpenAI для Codex CLI — https://chatgpt.com/backend-api/codex/responses.

Интересно и то, что ключ "instructions" (выше обрезан, полная копия у меня есть) содержит инструкции по умолчанию — без них API, похоже, не работает. Но видно и другое: можно отправить сообщение с role="developer"перед пользовательским промптом.

Русскоязычное сообщество про AI в разработке

Друзья! Эту статью подготовила команда ТГК «AI for Devs» — канала, где мы рассказываем про AI-ассистентов, плагины для IDE, делимся практическими кейсами и свежими новостями из мира ИИ. Подписывайтесь, чтобы быть в курсе и ничего не упустить!

Комментарии (0)