Blog

Codex CLI, structured JSON outputs, and cron-safe AI workers

Інженерні нотатки Naly: Codex CLI, структурований JSON та AI-воркери, безпечні для cron

Ця нотатка описує, як Naly перетворює Codex CLI з термінального агента-кодера на детермінованого production-воркера шляхом поєднання планування cron, суворих JSON-контрактів та виведених назовні логів. У ній пояснюється, чому надійність походить від операційних інваріантів — блокувань, повторів і валідації — тоді як модель залишається замінною,

June 25, 20269 sources

Анотація

Naly використовує Codex CLI як контрольну площину для запланованої роботи ШІ: кожен запис cron запускає перевірений скрипт, який стартує обмежене завдання асистента з веб-пошуком і суворим контрактом виводу, а потім записує валідовані JSON-артефакти для подальшої публікації, відтворення та повторів. Це перетворює роботу моделі на операційний конвеєр — однакова команда, явна схема, явні артефакти — а не змінний інтерактивний workflow. Станом на 2026-06-25 ця відмінність є конкурентною перевагою надійності для інфраструктури контенту, критичної для зростання.

Де це знаходиться в Naly

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

  • Cron-завдання викликають один tsx скрипт на випадок застосування, щоб кожен запуск залишався в версіонованому коді, а не в випадкових shell-уривках.
  • Codex CLI виконує роботу з висновування та пошуку, тоді як Naly керує контролем оркестрації: розкладом, повторними спробами, блокуванням і надійними артефактами.
  • Структурований вивід живить downstream-системи на базі Next.js, React, Drizzle ORM і Neon без вгадування подальшої схеми.
  • Зовнішні логи та метадані виконання записуються в NALY_LOG_ROOT, що робить постмортеми відтворюваними незалежно від буферизації виводу процесу.

Теза така: для production використання якість LLM — лише половина системи; детерміновані межі навколо цієї LLM становлять іншу половину.

Технічний механізм

1) Точка входу воркера з пріоритетом на контракт

Кожне завдання починається з трьох незмінних вхідних даних:

  • Кодифікований шаблон підказки та намір завдання.
  • Схема відповіді, яку потрібно валідовувати.
  • Оточення виконання (run_id, source_query, attempt, env), збережене до API-виклику.

Naly викликає Codex CLI в пакетному режимі з cron, а не в інтерактивному. Codex задокументовано як локальний coding-агент і постачається як автономний CLI з відкритою розробкою та активними релізами, і його можна запускати в скриптовому середовищі Codex CLI, репозиторій OpenAI Codex.

2) Чому структурований вивід є незаперечним

Посібники OpenAI зі структурованого виводу описують парсер-орієнтоване вилучення схеми й поведінку строгого режиму, необхідні для машинних пайплайнів. У Naly вивід моделі розглядається як проміжний артефакт, а не як остаточна істина, тому JSON-контракт — це місце, де забезпечується надійність:

  • обов'язкові поля (headline, evidence list, confidence, citations, failure reason)
  • необов'язкові поля з типами за замовчуванням
  • числова довіра та обмежені enum
  • явні помилки парсера фіксуються як помилки виконання, а не мовчки автоматично виправляються текстом.

3) Життєвий цикл cron із керуванням конкуренцією

Cron виконує розклади за стандартними 5 полями часу та запускає команду, коли поля збігаються crontab. Для виробничої безпеки Naly додає:

  • захист блокування (один активний запуск на завдання)
  • ідемпотентний ключ запуску
  • обмежену політику повторів із jitter
  • зовнішній захват логів на кожному етапі
  • пост-раннє оновлення стану в таблицях бази даних, керованих Drizzle/Neon.

flock створений саме для такого патерну запобіжників: отримати блокування, виконати критичну секцію, коректно вийти, якщо вже є блокування flock. Оскільки стан блокування прив'язаний до файлових дескрипторів, перекривання інтервалів cron явно забороняється замість пошкодження стану.

4) Чому MCP важливий у цьому патерні

Model Context Protocol формалізує контракти інструментів host/client/server через JSON-RPC, узгодження можливостей і структуровані виклики інструментів MCP. У Naly межі в стилі MCP зменшують неявне зв'язування: веб-пошук можна представити як керований інтерфейс інструмента з явними можливостями замість вільного поведінкового shell-стилю.

Що говорить література

Останні дослідження показують, що надійність не еквівалентна сирій потужності. У статті AI Agent Reliability описані суттєві розриви між точністю завдання та стійкістю між прогонами і запропоновано чіткі виміри надійності (стабільність, робастність, передбачуваність, безпека) для операційної оцінки Towards a Science of AI Agent Reliability. Це підтримує дизайн Naly з пріоритетом стану виконання: якщо запуск успішний, але його не можна повторити з ясними артефактами, це не є production-grade.

Для структурованих виводів ToolPRM доводить, що структурована поведінка виклику інструментів потребує явного нагляду, і що покращення особливо сильні, коли моделюється внутрішній процес виклику функцій, а не лише фінальні результати ToolPRM: Fine-Grained Inference Scaling of Structured Outputs for Function Calling. Це узгоджується з циклом виконавця Naly, орієнтованого на схему: гейт якості знаходиться на межах інтерфейсів, а не лише у мовленнєвій плавності тексту.

Третє дослідження на цій же межі, SLOT, демонструє практичний альтернативний шлях, додаючи модельно-агностичний шар формування виводу поверх LLM SLOT: Structuring the Output of Large Language Models. Воно підтверджує той самий принцип: надійність структури — це інженерна проблема навіть за умов високої якості базової моделі.

Компроміси дизайну

  1. Сувора схема проти переносимості моделі: суворі схеми зменшують downstream-невизначеність, але час від часу збільшують churn парсингу, коли провайдери інакше інтерпретують обмеження.
  2. Простота cron проти еластичності черги: cron простий і прозорий, але сплескові навантаження потребують backoff із урахуванням блокування або шару черги, щоб уникнути перекривання запусків і пропущених вікон.
  3. Веб-пошук у завданні проти детермінованого відтворення: свіжий веб-пошук покращує актуальність, але вводить волатильність джерел; тому Naly зберігає текст запиту, список джерел і сирі посилання в артефактах виконання.
  4. Зовнішні логи проти тільки БД-логів: файлові логи переживають перезапуски процесів і дешеві для інжесту; БД-логи спрощують зручність запитів, але можуть провалювати відкриті петлі, якщо їх не розділити акуратно.

Режими відмов

  • Зсув схеми: вивід провайдера порушує схему; пом'якшенням є сувора fail-fast валідація, фіксація версії схеми та dead-letter-запуски.
  • Перекривання виконання cron: подвійнi записи або дублювання зовнішніх дій; пом'якшенням є advisory lock плюс охорона завершення процесу.
  • Нестабільність пошуку: апстрім-відповідь інструменту змінюється між спробами; пом'якшенням є ліміти повторів, експоненційна затримка та збережені апстрім-посилання.
  • Часові сюрпризи: DST і відмінності таймзони хоста можуть впливати на семантику графіку; пом'якшенням є політика планування в UTC і явні перевірки середовища.
  • Мовчазні часткові записи: парсинг успішний, але downstream-запис не відбувся; пом'якшенням є транзакційний порядок збереження та ідемпотентні upsert.
  • Витік безпеки/контексту: будь-який шлях агента з підтримкою інструментів може перейти межі, тому необхідні MCP-подібні межі принципу найменших привілеїв і явні припущення щодо згоди/авторизації, особливо коли шляхи виконання інструментів стикаються з мережевими ресурсами Примітки з безпеки MCP.

Примітки щодо реалізації

  • Тримайте одну команду воркера на бізнес-завдання в scripts/ і дозволяйте cron викликати лише цю точку входу.
  • Зберігайте хеш файлу схеми в метаданих виконання, щоб очікування парсера були аудитоздатними після оновлення моделі.
  • Встановіть set -euo pipefail`set -e`-стиль поведінки в wrapper-скриптах і завжди включайте run ID в імена логів.
  • Запишіть три контрольні точки в логи: started, codex_result_parsed, artifact_persisted.
  • Використовуйте NALY_LOG_ROOT щоб runtime-трасування ніколи не забруднювало стан репозиторію та витримувало контексти рестарту.
  • Зберігайте attempt, exit_code, retry_reason, і validation_errors щоб GST і панелі аудиту могли розділяти нестабільну інфраструктуру та справжні регресії моделі.

Джерела

Sources