OpenAI Codex у CI/CD: коди повернення, потік JSONL і ціна прогону

37 хв. читання
BINANCE · СПОТ І ДЕРИВАТИВИ
Крипта з нуля
Комісія 0,1%, торги 24/7, старт з $10
Відкрити рахунок

Коротко (TL;DR)

  • codex exec — це той самий агент Codex, лише без інтерфейсу: завдання приходить аргументом або через stdin, поступ вирушає у stderr, а в stdout лишається фінальна відповідь. Офіційний опис режиму — на сторінці неінтерактивного режиму Codex.
  • Конвеєру потрібні дві речі: --json і код повернення. За заміром на версії 0.147.0 (13 серпня 2026) провал ходу дає код 1 і подію turn.failed у потоці, а помилка у прапорцях — код 2 ще до звернення до мережі.
  • Перша пастка не в правах, а в stdin. Якщо потік введення відкритий, codex exec "завдання" пише «Reading additional input from stdin…» і чекає нескінченно. Лікується додаванням < /dev/null.
  • У CI ключ передають на одну команду, а не на весь job — змінною CODEX_API_KEY. Для GitHub є офіційний екшен, який ховає ключ за проксі та знімає sudo з раннера.
  • Один прогін коштує центи, і це обчислюється точно. Звірка тарифної сітки кредитів із цінами API дає курс 1 кредит = $0,04, а типовий нічний прогін на GPT-5.6 Terra виходить близько $0,18.
  • Дані актуальні на 13 серпня 2026 і перевірені на Codex CLI 0.147.0 (реліз 7 серпня 2026). Версії тут старіють швидко: три офіційні рецепти вже розійшлися з бінарником — розбір у кінці.

Що робить codex exec і чим відрізняється від Codex у терміналі

codex exec — це запуск Codex без текстового інтерфейсу: команда отримує завдання, виконує його до кінця і завершується, повертаючи процесу код виходу. У довідці версії 0.147.0 вона описана буквально як «Run Codex non-interactively» і має короткий псевдонім codex e.

Різниця з інтерактивним циклом у терміналі не в силі агента, а в тому, хто ухвалює рішення. В інтерактиві ви бачите план, підтверджуєте команди й правите курс. У exec підтверджувати нікому: агент відпрацює рівно з тими правами й за тими правилами, які ви задали до запуску.

Завдання можна передати трьома способами, і вони не взаємозамінні:

# 1. Промпт аргументом — звичайний випадок для CI
codex exec "перевір міграції на зворотну сумісність"

# 2. Промпт зі stdin: сентинел «-» каже «читай завдання цілком звідси»
cat prompt.txt | codex exec -

# 3. Промпт аргументом + дані через трубу: stdin приїде як блок <stdin>
npm test 2>&1 | codex exec "підсумуй тести, що впали, і запропонуй мінімальну правку"

Третій спосіб — найбільш недооцінений. Він перетворює агента на звичайний елемент конвеєра: ліворуч команда, що виробляє дані, праворуч — інструмент, який їх розбирає. Саме так пишуть зведення за логами, розбори збірок, що впали, і чернетки коментарів до pull request.

BINANCE COPY TRADINGКопітрейдинг на BinanceВідкрита статистика трейдерів, старт з $10, вимкнення одним кліком.Обрати трейдера

Потоки розведено навмисно: поступ друкується у stderr, а в stdout потрапляє лише фінальне повідомлення. Тому codex exec "..." > result.md дає чистий файл без службового шуму, а не перемішаний лог.

Три шляхи запустити Codex без людини: exec, SDK і GitHub Action

Поверхонь три, і обирати між ними треба свідомо. Неочевидне тут те, що всі три ведуть в один і той самий бінарник: TypeScript SDK, за його власним README, запускає процес codex й обмінюється з ним подіями JSONL через stdin і stdout, а офіційний екшен просто ставить CLI і викликає codex exec. Змінюється обв’язка, а не рушій.

ПоверхняЩо цеКоли братиЧим платить
codex execкоманда CLIjob уже живе в shell-скрипті; потрібен мінімум залежностейсамі розбираєте JSONL і коди повернення
Codex SDKбібліотека для TypeScript або PythonCodex — рушій усередині вашого продукту чи оркестраторапотрібен рантайм Node 18+ або Python 3.10+
openai/codex-actionготовий екшен GitHubконвеєр живе в GitHub Actionsменше контролю, зате ключ захищено з коробки
codex cloud execнадсилання завдання у хмаруробота довга, раннер тримати не хочетьсяпозначена експериментальною, потрібен ID середовища

Четвертий рядок часто випадає з оглядів. Команда codex cloud exec --env <ENV_ID> "завдання" надсилає роботу у хмарні задачі Codex просто зі скрипта, підтримує --branch і --attempts (кілька спроб із вибором найкращої). За довідкою 0.147.0 уся гілка codex cloud позначена як експериментальна — у критичний конвеєр її ставити рано, але для фонових задач вона знімає питання «де тримати раннер».

Прапорці codex exec, від яких залежить доля прогону в CI

Довідка codex exec --help на версії 0.147.0 довга, але для автоматизації значення має короткий перелік. Нижче — те, що справді змінює поведінку прогону.

ПрапорецьЩо робитьЧому важливий у CI
--jsonпереводить stdout у потік JSON Linesєдиний спосіб читати хід роботи програмно
-o, --output-last-message <файл>пише фінальну відповідь у файлфайл лишається артефактом job; у stdout відповідь теж прийде
--output-schema <файл>змушує фінальну відповідь відповідати JSON Schemaнаступний крок конвеєра отримує стабільні поля, а не прозу
--sandbox <режим>read-only, workspace-write, danger-full-accessза замовчуванням агент не може писати на диск
--ephemeralне зберігати файли сесії на дискна спільному раннері не лишає слідів роботи
--ignore-user-configне читати config.toml із CODEX_HOMEпрогін перестає залежати від налаштувань чужої машини
--ignore-rulesпропустити файли .rules користувача і проєктуте саме для правил запуску команд
--skip-git-repo-checkдозволити запуск поза git-репозиторіємпотрібен рідко і свідомо, див. нижче
-C, --cd <каталог>робочий корінь агентау монорепозиторії обмежує ділянку роботи
--add-dir <каталог>додатковий каталог на записколи правки потрібні поза основним робочим каталогом

Окремо стоїть -c (або --config): він перевизначає будь-яке значення конфігурації за крапковим шляхом, наприклад -c model="gpt-5.6-terra". Саме через нього офіційний cookbook видає агентові право на запис, не чіпаючи --sandbox.

Машиночитний вивід: потік JSONL, схема відповіді та коди повернення

Без --json конвеєр бачить лише фінальний текст. З ним stdout перетворюється на потік подій, де кожен рядок — самостійний об’єкт JSON. Типи подій: thread.started, turn.started, turn.completed, turn.failed, родина item.* та error. Усередині item приїздять повідомлення агента, міркування, запуски команд, правки файлів, виклики інструментів і оновлення плану.

Практична цінність у тому, що витрата токенів приходить просто в потоці: подія turn.completed несе поле usage з лічильниками input_tokens, cached_input_tokens, output_tokens і reasoning_output_tokens. Це готовий вхід для обліку вартості, про який нижче.

BINANCEДосі дивишся збоку?Ринок працює без вихідних. Рахунок на Binance відкривається за 2 хвилини.Почати зараз

Що відбувається при провалі, огляди зазвичай не показують — а для CI це важливіше за успішний випадок. Ось справжній хвіст потоку з прогону без чинних облікових даних (13 серпня 2026, версія 0.147.0):

{"type":"thread.started","thread_id":"019ffaa2-1de8-76d3-896a-5352ae4e9447"}
{"type":"turn.started"}
{"type":"error","message":"Reconnecting... 2/5 (unexpected status 401 Unauthorized...)"}
{"type":"item.completed","item":{"id":"item_0","type":"error","message":"Falling back from WebSockets to HTTPS transport..."}}
{"type":"turn.failed","error":{"message":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header..."}}

Звідси два висновки. Перший: події error йдуть у stdout упереміш із корисними, тому «взяти останній рядок» — робоча стратегія лише тоді, коли ви справді чекаєте turn.failed або turn.completed. Другий: причина відмови лежить у потоці текстом, і її не треба виколупувати з логів.

Коди повернення в документації не описані, тому я заміряв їх на версії 0.147.0:

КодЩо сталосяЩо робити конвеєру
0хід завершеночитати фінальне повідомлення або файл -o
1агент дійшов до моделі, але хід провалився; у потоці turn.failedпоказати причину з потоку, вирішити — повторювати чи падати
2Codex до роботи не дійшов: невідомий прапорець, помилка командного рядкалагодити сам виклик, повтор марний

Двійку перевірено контрольним дослідом: завідомо неіснуючий прапорець --no-such-flag-xyz дає рівно той самий код і ту саму форму повідомлення, що й застарілий прапорець. Тобто 2 означає «неправильна команда», а не «конкретно ця опція застаріла».

Якщо наступному кроку потрібні поля, а не текст, задайте схему. Файл schema.json описує форму відповіді, а прогін має такий вигляд:

codex exec "збери метадані проєкту" \
  --output-schema ./schema.json \
  -o ./project-metadata.json < /dev/null

Чому codex exec зависає в раннері й лікується одним /dev/null

Це найдорожча пастка неінтерактивного запуску, і в матеріалах топу її немає. Симптом: job висить до таймауту, у лозі один рядок — «Reading additional input from stdin…». Завдання при цьому передано аргументом, і логічно читати більше нічого.

Механіка проста. Codex підтримує передавання даних через трубу: якщо stdin запайплено, його вміст додається до промпту як блок <stdin>. Відрізнити «труба порожня» від «дані ще не прийшли» неможливо, поки трубу не закрито. В інтерактивному терміналі це непомітно, а в раннері, cron-задачі чи при запуску з батьківського процесу потік введення часто лишається відкритим — і агент чекає на дані, яких не буде.

Замір 13 серпня 2026 на версії 0.147.0, два прогони з однаковим завданням:

Умова запускуПоведінкаПідсумок
stdin відкритий (тримаємо трубу)друкує «Reading additional input from stdin…»висить нескінченно, знято сторожем через 30 с
stdin закритий: < /dev/nullпрацює штатнозавершився за 22 с з кодом 1 (немає облікових даних)

Лікування — одна конструкція в кінці команди:

codex exec --json "прожени тести і полагодь падіння" < /dev/null

Офіційний cookbook для GitLab обходить ту саму проблему інакше — загортає виклик у script -q -c, тобто видає процесу псевдотермінал. Спосіб робочий, але < /dev/null простіший і не тягне за собою зайву утиліту.

Поруч живе друга причина миттєвої зупинки: Codex відмовляється працювати поза git-репозиторієм. Повідомлення при цьому каже не про git, а про довіру — «Not inside a trusted directory and –skip-git-repo-check was not specified», код повернення 1. За текстом помилки в документації шукати марно, тож запам’ятайте формулювання: воно означає «поклади завдання в репозиторій або свідомо додай --skip-git-repo-check».

Автентифікація автоматичного прогону: ключ, а не акаунт

Розвилка «акаунт ChatGPT чи API-ключ» в автоматичному прогоні вирішується інакше, ніж на своїй машині. Рекомендований шлях — ключ: його простіше видати, відкликати й ротувати.

Змінна називається CODEX_API_KEY, і в неї є особливість, яку легко проминути: вона підтримується лише в codex exec. Ставити її належить на одну команду, а не на весь job:

CODEX_API_KEY=$MY_KEY codex exec --json "розбери тести, що впали" < /dev/null

Вимога не косметична. Документація прямо забороняє оголошувати OPENAI_API_KEY або CODEX_API_KEY змінною рівня job у конвеєрі, який викачує чи запускає код із репозиторію: скрипти збірки, тести, хуки встановлення залежностей і скомпрометований сторонній екшен у тому самому job прочитають цю змінну без жодного зламу.

Ганяти CI під акаунтом ChatGPT теж можна, але шлях рівно один і він незручний за будовою, а не через недогляд. Треба створити auth.json командою codex login на довіреній машині, покласти файл на раннер і дозволити Codex оновлювати його самому: клієнт освіжає пачку токенів, якщо останнє оновлення старше приблизно за 8 діб, і записує нові значення назад у той самий файл. Звідси три правила, які ламають наївну схему:

  • Не перезаписуйте файл початковим секретом на кожному рейсі — зітрете токени, які Codex щойно оновив.
  • Один auth.json на один раннер або на строго послідовний потік задач; два паралельні job розсинхронізують сесію.
  • Для публічних і open-source репозиторіїв цей шлях заборонено просто в документації: файл містить чинні токени доступу.

З решти змінних в автоматичному прогоні знадобляться CODEX_HOME (корінь стану, каталог мусить існувати заздалегідь), RUST_LOG для докладних логів під час розбору інциденту і CODEX_NON_INTERACTIVE=1 для тихого встановлення офіційним скриптом.

Codex GitHub Action: проксі для ключа і зняття sudo з раннера

Для GitHub Actions є офіційний екшен openai/codex-action@v1. Він ставить CLI, піднімає проксі Responses API, якщо ви передали ключ, і запускає codex exec із заданими правами. Фінальне повідомлення агента віддається виходом final-message — його можна передати в наступний job.

- name: Run Codex
  id: run_codex
  uses: openai/codex-action@v1
  with:
    openai-api-key: ${{ secrets.OPENAI_API_KEY }}
    prompt-file: .github/codex/prompts/review.md
    output-file: codex-output.md

Найцікавіше в екшені — не входи, а те, як він поводиться з ключем. Розбір його action.yml показує три прийоми поспіль: ключ передається проксі через stdin і вичищається з середовища процесу, файл із відомостями про проксі отримує права лише на читання і власника root, а потім із користувача раннера незворотно знімається sudo — і екшен тут же перевіряє, що sudo справді перестав працювати, інакше падає.

Навіщо такі складнощі, пояснюють самі автори в розборі загроз екшена: на раннерах GitHub за замовчуванням доступний sudo без пароля, а отже через procfs можна прочитати пам’ять чужого процесу і дістати звідти ключ. Комбінація «пісочниця лише для читання плюс вимкнена мережа», яка багатьом здається достатньою, ключ не захищає.

Звідси практичний висновок: safety-strategy за замовчуванням (drop-sudo) міняти не треба, а значення unsafe на спільному раннері ставити не можна. Виняток один — Windows, де інших варіантів наразі немає і екшен сам це перевіряє першим кроком.

Ще одна деталь для тих, хто читає лише сторінку документації: в action.yml оголошено входи, яких там немає. Це permission-profile (сучасна заміна входу sandbox; в описі входу вони прямо названі взаємовиключними), output-schema (текст схеми просто у workflow) і output-schema-file (шлях до файлу схеми в репозиторії), responses-api-endpoint (свій ендпоїнт, наприклад в Azure) та allow-bot-users (поіменний перелік довірених ботів).

За замовчуванням запустити такий workflow може лише той, хто має право запису в репозиторій, — це окремий крок перевірки всередині екшена. Розширювати перелік входами allow-users і allow-bots варто обережно: якщо відкрити запуск усім, чужі люди почнуть витрачати квоту вашого ключа.

Codex у GitLab CI та будь-якому іншому раннері: рецепт на голому CLI

Екшен зручний, але він не обов’язковий: codex exec — звичайна консольна команда, і вона однаково працює в GitLab CI, Jenkins, Buildkite або в cron на своїй машині. В OpenAI є офіційний cookbook саме для GitLab, а сам GitLab описує зв’язку у своєму блозі, тож тема раннерів давно не зводиться до GitHub.

Мінімальна job для GitLab CI має такий вигляд:

codex_review:
  stage: codex
  image: node:24
  rules:
    - if: '$CI_MERGE_REQUEST_ID && $OPENAI_API_KEY'
  script:
    - npm -g i @openai/codex@0.147.0
    - codex --version
    - |
      CODEX_API_KEY="$OPENAI_API_KEY" codex exec --json \
        --sandbox read-only \
        -o codex-report.md \
        "Розбери зміни гілки проти $CI_MERGE_REQUEST_TARGET_BRANCH_NAME і опиши ризики" \
        < /dev/null > codex-events.jsonl
      echo "codex rc=$?"
  artifacts:
    when: always
    paths: [codex-report.md, codex-events.jsonl]

Тут зібрані всі правила, розібрані вище: версію CLI закріплено, ключ живе у змінній CI/CD і підставляється на одну команду, потік введення закрито, права мінімальні, а артефакти зберігаються when: always — інакше при падінні job ви не побачите ні звіту, ні потоку подій. Правило rules пропускає job, якщо ключа немає: на merge request із форку секрети не віддаються, і без такої перевірки job падатиме без користі.

Офіційний cookbook робить ще один крок, корисний у GitLab: перетворює вивід агента на формат CodeClimate, і тоді зауваження видно просто у віджеті merge request, поруч із лінтером і тестами.

Права і мережа автономного прогону: пісочниця та профілі доступу

За замовчуванням агент працює в режимі лише для читання: він бачить репозиторій, але записати нічого не може. Це правильний типовий стан для CI, і саме тому рецепт автовиправлення змушений явно видавати право на запис.

Три режими пісочниці та їхній сенс в автоматичному прогоні:

  • read-only — аналіз, рев’ю, зведення, генерація звітів. Годиться для більшості задач у конвеєрі.
  • workspace-write — правки файлів у робочому каталозі: автовиправлення, міграції, оновлення документації.
  • danger-full-access — знімає обмеження; документація допускає його лише в ізольованому середовищі на кшталт одноразового контейнера.

Прапорець --ask-for-approval в автоматичному прогоні майже завжди позбавлений сенсу: питати нікого. Значення never описане як «execution failures are immediately returned to the model» — тобто агент не зупиниться, а спробує розв’язати проблему сам. Межу йому ставить пісочниця, а не політика схвалень; докладний розбір самих режимів схвалення і пісочниці — в окремому уроці.

Два прапорці ізоляції варто ставити в CI за замовчуванням. --ignore-user-config відв’язує прогін від config.toml у домашньому каталозі (автентифікація при цьому все одно береться з CODEX_HOME), а --ignore-rules — від користувацьких і проєктних файлів .rules. Разом вони дають відтворюваність: результат перестає залежати від того, що лежало на конкретній машині.

Скільки коштує один прогін: курс кредита і розрахунок за токенами

Вартість автоматизації — те місце, де огляди уриваються на фразі «залежить від моделі». Рахувати можна точніше, і для цього досить двох офіційних таблиць.

Витрата за підпискою ChatGPT вимірюється кредитами, витрата за ключем — доларами. Величини пов’язані жорстко: якщо зіставити обидві таблиці на одну дату, множник виявляється однаковим для всіх моделей і всіх трьох класів токенів.

МодельКредити за 1 млн (вхід / кеш / вихід)Долари за 1 млн (вхід / кеш / вихід)
GPT-5.6 Sol125 / 12,5 / 750$5 / $0,50 / $30
GPT-5.6 Terra50 / 5 / 300$2 / $0,20 / $12
GPT-5.6 Luna5 / 0,5 / 30$0,20 / $0,02 / $1,20
GPT-5.462,5 / 6,25 / 375$2,50 / $0,25 / $15

Поділіть будь-яку пару — вийде $0,04 за кредит, тобто 25 кредитів на долар. Збіг тримається на 14 звірках із 15 (п’ять моделей на три класи токенів); єдине відхилення — вихід GPT-5.4 mini, де в кредитній таблиці стоїть округлене 113 замість точного 112,5. Величину ніде не оголошено вендором як «курс» — це висновок із зіставлення офіційного прайсу API з тарифною сіткою кредитів на 13 серпня 2026.

Тепер прогін. Візьмемо типове нічне завдання: агент читає частину репозиторію, ганяє тести, править файл і пише звіт. Припущення (це модель, а не рахунок з особистого кабінету): 150 тисяч вхідних токенів сумарно за ходами, з них 120 тисяч кешованих, і 8 тисяч токенів на виході.

МодельВартість прогону30 прогонів на місяць
GPT-5.6 Luna~$0,018~$0,54
GPT-5.6 Terra~$0,18~$5,40
GPT-5.6 Sol~$0,45~$13,50

У кредитах той самий прогін на Terra коштує 4,5 кредита — і $0,18 за курсом вище. Цифри скромні, але масштаб вирішує: рев’ю на кожен pull request при сотні PR на місяць дає вже $18 на Terra і $45 на Sol.

Два важелі впливають на рахунок сильніше за вибір моделі. Перший — кеш: повторний контекст коштує вдесятеро дешевше за свіжий, тому довгий ланцюжок ходів по одному репозиторію обходиться не так дорого, як здається. Другий — обсяг виходу: це найдорожчий клас токенів, і прохання «покажи лише diff і три рядки пояснення» заощаджує більше, ніж зміна моделі. Якщо прогони йдуть за підпискою, корисно розуміти й будову лімітів плану — кредити починають витрачатися після того, як включений обсяг вичерпано.

Відмови, повтори і таймаути: що Codex робить сам, а що має CI

Codex обороняється від мережевих збоїв сам, і знати глибину цієї оборони корисно: вона прямо впливає на тривалість job. Заміряна поведінка за недоступної моделі (13 серпня 2026, версія 0.147.0): п’ять спроб підключення через WebSocket, чесне повідомлення «Falling back from WebSockets to HTTPS transport», ще п’ять спроб через HTTPS і вихід із кодом 1. На порожній відмові весь цикл зайняв 21–22 секунди.

Замір збігається з задокументованими значеннями за замовчуванням: stream_max_retries дорівнює 5, request_max_retries — 4. Тобто на справжній мережевій гикавці прогін не впаде з першої спроби, і додавати свій цикл повторів згори зазвичай не потрібно.

А от чого в команди немає — так це власної стелі часу. Прапорця загального таймауту в довідці 0.147.0 не існує; параметр stream_idle_timeout_ms зі значенням 300 000 мс — це вікно тиші потоку, а не межа тривалості прогону. Висновок практичний: обмеження зобов’язаний ставити конвеєр.

# стеля у 15 хвилин засобами системи
timeout 900 codex exec --json "завдання" < /dev/null
echo "rc=$?"   # 124 — спрацював таймаут

У GitHub Actions ту саму роль відіграє timeout-minutes у кроку чи job, у GitLab CI — властивість timeout. Ставити його треба завжди: навіть без пастки stdin агент може піти в довге завдання, а раннер коштує грошей.

СимптомЙмовірна причинаЩо перевірити
Job висить, у лозі «Reading additional input from stdin…»відкритий stdinдодати < /dev/null
Миттєвий вихід із кодом 2невідомий прапорець або помилка в командіcodex exec --help на своїй версії
Код 1 і «Not inside a trusted directory»запуск поза git-репозиторіємпокласти роботу в репозиторій або --skip-git-repo-check
Код 1, у потоці turn.failed з 401ключ не доїхав до командиключ ставиться на сам виклик, а не на job
Прогін падає, хоча раніше працювавоновився CLI, прапорець зникзакріпити версію, звірити довідку
Порожній stdout за непорожнього stderrдивитеся не той потікфінальна відповідь у stdout, поступ у stderr

Застарілі рецепти: –full-auto та імена входів Codex Action

Ця тема старіє швидше, ніж пишуться статті про неї, — включно з офіційними. Три розбіжності, знайдені 13 серпня 2026 на версії 0.147.0.

Прапорця --full-auto більше немає. Перевірено трьома шляхами: codex exec --full-auto відповідає «error: unexpected argument ‘–full-auto’ found» і кодом 2; codex --full-auto дає те саме; пошук рядків самим бінарником знаходить нуль входжень. Метод при цьому перевірено на контрольній групі — тим самим пошуком знайдено дев’ять інших імен прапорців і змінних (CODEX_HOME — 60 входжень, ephemeral — 36, skip-git-repo-check — 2 і так далі). Тобто нуль означає відсутність, а не зламаний пошук.

При цьому сторінка неінтерактивного режиму на ту саму дату стверджує, що прапорець збережено як застарілий заради сумісності й він друкує попередження, а офіційний cookbook для GitLab ставить codex exec --full-auto у робочий приклад — поруч із командою npm -g i @openai/codex@latest, тобто рецепт встановлює свіжу версію і тут же викликає те, чого в ній немає.

Імена входів екшена розходяться між двома офіційними сторінками. Cookbook з автовиправлення використовує openai_api_key і codex_args через підкреслення, тоді як action.yml оголошує openai-api-key і codex-args через дефіс. GitHub Actions зіставляє входи за точним іменем, тому скопійований рецепт дає рівно той симптом, який описано в розділі усунення несправностей офіційної документації: проксі не стартує, бо ключ до нього не доїхав.

Що написано в джереліЩо в артефакті на 13.08.2026Як писати
codex exec --full-auto (cookbook GitLab)прапорця немає, код повернення 2--sandbox workspace-write
«--full-auto збережено як deprecated» (документація)у бінарнику 0 входженьвважати прапорець видаленим
openai_api_key, codex_args (cookbook автовиправлення)openai-api-key, codex-args в action.ymlчерез дефіс
openai/codex-action@main (cookbook)тег @v1 у документаціїзакріплювати версію

Звідси правило, дорожче за будь-який із цих трьох фактів: закріплюйте версію CLI і тег екшена. npm -g i @openai/codex@latest у job означає, що одного ранку конвеєр поїде на новій версії, про яку ви не знали. В екшена для цього є вхід codex-version.

Три рецепти: автовиправлення тестів, changelog і правка по репозиторію

Автовиправлення падіння CI. Офіційний шаблон побудовано навколо розділення прав, і це головне в ньому. Job із Codex отримує лише contents: read і persist-credentials: false, агент лагодить тести, а результат зберігається патчем-артефактом. Другий job із правами на запис застосовує патч і відкриває pull request — ключа OpenAI він при цьому не бачить узагалі. Людина лишається в контурі: вона дивиться PR, а не довіряє автоматиці коміт у головну гілку.

Зауважте, що друге офіційне джерело — cookbook з автовиправлення — робить інакше: комітить і відкриває PR у тому самому job. Схема простіша, але права ширші, і на публічному репозиторії я б обрав варіант із двома job.

Чернетка changelog. Тут агент узагалі не має нічого змінювати, тому режим лише для читання і труба:

git log --oneline v1.4.0..HEAD \
  | codex exec --sandbox read-only \
      "Згрупуй коміти за змістом і напиши changelog для користувачів, без внутрішніх деталей" \
  > CHANGELOG.draft.md

Масова правка по репозиторію. Завдання на кшталт «перейменуй застарілий виклик в усіх сервісах» розв’язується не одним прогоном, а циклом із перевіркою. Тут знадобляться --output-schema (щоб отримати машиночитний звіт про те, що змінено) і двокрокова робота через codex exec resume --last "тепер прожени тести і полагодь, що зламав" — друга команда продовжує ту саму сесію, а не починає з нуля. Файли інструкцій проєкту агент читає і в неінтерактивному режимі, тому правила стилю краще тримати в AGENTS.md, а не переписувати в промпт щоразу.

Codex SDK на TypeScript і Python: коли код кращий за exec

Якщо Codex стає частиною вашого продукту, а не кроком конвеєра, розбирати JSONL руками ні до чого — є офіційні SDK.

import { Codex } from "@openai/codex-sdk";

const codex = new Codex();
const thread = codex.startThread();
const turn = await thread.run("Знайди причину падіння тестів і запропонуй правку");

console.log(turn.finalResponse);

TypeScript-версія потребує Node.js 18 і новіше, вміє продовжувати тред повторним run(), відновлювати його за ідентифікатором через resumeThread() і віддавати події в міру надходження через runStreamed(). Схему відповіді можна задати на кожен хід, зокрема згенерувавши її з Zod.

Python-версія ставиться як pip install openai-codex, потребує Python 3.10 і новіше та влаштована інакше: вона керує локальним app-server через JSON-RPC, а не ганяє CLI. Пресети пісочниці там задано явно — Sandbox.read_only, Sandbox.workspace_write, Sandbox.full_access — і режим можна міняти між ходами одного треда.

Ключова відмінність SDK від прямого виклику команди — не можливості, а форма. Під капотом TypeScript SDK, за його README, запускає той самий CLI і читає той самий потік JSONL, а CODEX_API_KEY підкладає в середовище процесу сам. Тому вибір простий: якщо завдання вміщається в shell-скрипт — беріть exec і не тягніть рантайм у раннер; якщо навколо агента потрібна логіка (черга задач, свій інтерфейс, розбір проміжних подій) — беріть SDK і отримаєте типи замість ручного розбору рядків.

Ризики автономного прогону: витік ключа і чужий текст у завданні

Автономність тут означає, що помилок ніхто не помітить у момент їх скоєння. Звідси чесний перелік того, де ця схема ламається.

  • Ключ витікає через права, а не через мережу. Поки в процесу є sudo без пароля, вміст пам’яті сусідніх процесів доступний на читання — і режим «лише читання з диска» ключ не рятує. Тому в GitHub Actions працює drop-sudo, а у своєму раннері ключ варто тримати в окремому кроці й не пускати в job недовірений код.
  • Недовірений текст приїздить разом із завданням. Тіло pull request може містити інструкції в HTML-коментарі, невидимому для людини; туди ж належать повідомлення окремих комітів, скриншоти і файли інструкцій репозиторію, якщо робота йде над вмістом чужого PR. Промпт, зібраний із таких даних, треба чистити — і не давати агентові прав на запис у цьому сценарії.
  • Стан раннера після агента не гарантовано. Автори екшена радять ставити його останнім кроком job: агент міг лишити запущені процеси, переписати файли інших екшенів на хості або дописати щось у .git/hooks із розрахунку на привілейовані кроки, які підуть далі.
  • Тихий провал дорожчий за гучний. Прогін без стелі часу і без перевірки коду повернення виглядає як успішний: job зелений, артефакт порожній. Перевіряйте $? і зберігайте артефакти when: always.
  • Рецепти старіють. Три розбіжності офіційних джерел із бінарником, розібрані вище, — не поодинокий випадок, а властивість продукту, що швидко змінюється. Незакріплена версія перетворює цю властивість на поломку конвеєра.

Що в цій схемі працює на вашу користь: права за замовчуванням вузькі (лише читання), запуск поза репозиторієм заборонено, провал машиночитний, а офіційний шаблон із патчем-артефактом дозволяє лишити людину в контурі, не сповільнюючи конвеєр.

Що застаріє першим. Склад прапорців і наявність окремих опцій — перевіряйте командою codex exec --help на своїй версії. Далі — тарифна сітка і ціни API (курс кредита доведеться перерахувати), потім набір входів екшена: звіряйте з action.yml того тега, який закріпили. Статус експериментальних команд на кшталт codex cloud exec теж змінюється.

Часті запитання

Який код повернення дає codex exec, якщо агент не впорався? За заміром на версії 0.147.0 — 1. Той самий код приходить при запуску поза git-репозиторієм. Код 2 означає інше: Codex до роботи не брався, бо не розібрав командний рядок (невідомий прапорець, помилка). Перевіряти $? обов’язково: без цього прогін, що впав, має в конвеєрі вигляд успішного, а артефакт лишається порожнім.

Чому codex exec завис і нічого не виводить? Найімовірніше, відкрито потік введення. Codex підтримує передавання даних через трубу і додає вміст stdin до промпту, тому чекає, поки трубу закриють, навіть якщо завдання вже передано аргументом. У лозі при цьому один рядок — «Reading additional input from stdin…». Лікується додаванням < /dev/null до команди.

Чи можна запускати codex exec за розкладом через cron? Так, це звичайна консольна команда. Три речі обов’язкові: закрити stdin, поставити зовнішню стелю часу через timeout і передавати ключ на сам виклик, а не експортувати в середовище. Корисно додати --ephemeral, щоб прогін не лишав файлів сесії, і писати потік --json у файл — інакше розбирати нічний інцидент буде нічим.

Потрібен для CI ключ API чи вистачить підписки ChatGPT? Офіційно рекомендовано ключ: його простіше видавати, відкликати й ротувати. Роботу під акаунтом ChatGPT підтримано, але вона потребує возити між рейсами файл auth.json і дотримуватися трьох правил: не перезаписувати його початковим секретом, не ділити між паралельними задачами і не застосовувати цю схему в публічних репозиторіях.

Чи працює codex exec поза git-репозиторієм? За замовчуванням ні: прогін завершується з кодом 1 і повідомленням «Not inside a trusted directory and –skip-git-repo-check was not specified». Обмеження захищає від руйнівних правок там, де не можна відкотитися. Обійти можна прапорцем --skip-git-repo-check, але робити це варто свідомо — наприклад, в одноразовому контейнері, де втрачати нічого.

Чим Codex SDK відрізняється від виклику codex exec зі свого коду? Можливості ті самі: TypeScript-версія запускає той самий CLI і читає той самий потік JSONL. Відрізняється форма роботи — ви отримуєте треди, типізовані події, структурований вивід і керування середовищем замість ручного розбору рядків. Якщо завдання вміщається в shell-скрипт, SDK не потрібен; якщо навколо агента росте своя логіка, він заощаджує багато коду.

Курс «OpenAI Codex: агентний кодинг» · модуль «PRO: автономність і якість». Повна програма і два маршрути навчання — на сторінці курсу.

Попередній урок: Безпека й пісочниця: мережа, секрети

BINANCE SIMPLE EARN
Крипта лежить?
Simple Earn: відсоток нараховується щодня
Відкрити Earn
Поділитися
Зв'язатися:
Крипто- та data-аналітик, інженер-програміст (факультет комп'ютерних наук ХНУРЕ). В IT з 2008 року: адміністрував корпоративний моніторинг у «Vodafone Україна», сім років розробляв і просував веб-проєкти, п'ять років керував маркетингом на метриках — конверсія, CTR, ROI, LTV.Криптовалютними ринками займаюся з 2021 року: ончейн-метрики, токеноміка, макроекономічні індикатори. Розробив власну data-driven модель аналізу ринку на 30+ метрик. Стек — Python (pandas, NumPy, SciPy, matplotlib), математична статистика та EDA; збір і звірку даних автоматизую AI-агентами.Принцип — «Don't trust, verify»: кожна цифра перевірена за першоджерелом, ключові — щонайменше за двома незалежними; прогнози — лише сценарії з умовами. Теза без даних не публікується.