Amiga
Оглавление курса · урок 4 из 14

Модуль 1 · Codex без человека в цикле · урок 4 из 14

Продолжение и ветвление сессий в скриптах

Одна задача — один вызов codex exec: так работает большинство автоматизаций. Но иногда шаги связаны: сначала разобрать проблему, потом исправить, потом проверить. Повторять анализ в каждом вызове дорого, а терять контекст — обидно. Для этого у codex exec есть resume и fork. Разберём, как ими пользоваться в скриптах и где они вредят.

Сессия и её идентификатор

Каждый запуск codex exec создаёт сессию (в событиях и SDK она называется thread). Если вы не указали --ephemeral, сессия сохраняется на диск, и к ней можно вернуться. Идентификатор приходит первым событием потока --json:

bash
codex exec --json "найди причину падения теста OrderTest::testRefund" > step1.jsonl
THREAD_ID=$(jq -r 'select(.type=="thread.started") | .thread_id' step1.jsonl | head -n1)
echo "$THREAD_ID"

Для интерактивных сессий то же самое делается командами /resume и /fork — см. урок «Сессии». В скриптах работают подкоманды codex exec.

resume: продолжить с того же места

bash
codex exec resume "$THREAD_ID" "исправь причину, которую ты нашёл; тесты в tests/ не меняй"

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

Есть и короткая форма codex exec resume --last: продолжить самую свежую сессию из текущего каталога. Флаг --all расширяет поиск на сессии из любых каталогов. В скриптах --last удобен, но опасен: если на машине параллельно идут два запуска в одном каталоге, «последней» может оказаться чужая сессия. В CI и в любых конкурентных сценариях передавайте идентификатор явно. Вместо UUID подкоманды принимают и имя сессии.

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

bash
codex exec "проверь изменения на гонки данных"
codex exec resume --last "исправь гонки, которые ты нашёл"

fork: ответвить и попробовать иначе

codex exec fork копирует сохранённую сессию в новую. Исходная остаётся нетронутой, а копия продолжает работу с другим промптом:

bash
codex exec fork "$THREAD_ID" "попробуй исправить через изменение запроса, а не через кэш"

Если промпт не указан, fork просто создаёт копию без нового хода. Промпт обязателен, если вы передаёте картинки, --output-schema, --output-last-message или --ephemeral.

Локально fork хорошо сочетается с флагом --worktree: Codex создаст отдельный управляемый Git worktree, и альтернативное решение не смешается с первым.

bash
codex exec fork "$THREAD_ID" --worktree "попробуй альтернативный подход"

--worktree работает только при локальном запуске и не совмещается с resume, review, --ephemeral и --ignore-user-config. О работе с worktree в целом — урок «Несколько задач параллельно».

Когда продолжать, а когда начинать заново

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

Ситуация Что делать
Анализ, затем исправление того же resume: агенту нужны выводы анализа
Два альтернативных решения одной проблемы fork от общего анализа
Ревью того, что сделал агент новая сессия: ревьюер не должен видеть рассуждения автора
Предыдущий шаг ушёл в тупик новая сессия с уточнённым промптом
Независимые задачи в одном пайплайне новые сессии, лучше с --ephemeral

Третий пункт важен. Если тот же агент, который писал исправление, его же и проверяет, он склонен соглашаться со своими решениями. Для проверки запускайте отдельную сессию, например codex review --uncommitted — неинтерактивное ревью незакоммиченных изменений.

Сценарий целиком

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

bash
#!/usr/bin/env bash
set -euo pipefail

# 1. Анализ: только чтение, ответ по схеме
codex exec --json \
  --output-schema .codex/schemas/diagnosis.json -o diagnosis.json \
  "Тест $1 падает. Найди причину, ничего не меняй." > step1.jsonl
THREAD_ID=$(jq -r 'select(.type=="thread.started") | .thread_id' step1.jsonl | head -n1)

if [ "$(jq -r .confidence diagnosis.json)" = "low" ]; then
  echo "Причина не ясна, нужен человек"; exit 1
fi

# 2. Исправление в той же сессии, с правом записи
codex exec --sandbox workspace-write resume "$THREAD_ID" \
  "Исправь найденную причину минимальным изменением. Тесты не меняй. Запусти тест снова." \
  > fix-report.md

# 3. Независимое ревью — новая сессия
codex review --uncommitted > review.md

Схема diagnosis.json здесь — объект с полями cause, files и confidence (enum: low, medium, high). Как её составить — в предыдущем уроке.

Обратите внимание на права и порядок флагов. Первый шаг идёт в read-only по умолчанию. Второму нужна запись, поэтому --sandbox workspace-write стоит перед подкомандой resume: это флаг самой codex exec. Флаги вывода — --json, -o, --output-schema, --ephemeral — в исходниках CLI объявлены глобальными и работают и с подкомандами. Проверьте, как ваша версия применяет права к продолженной сессии: codex exec resume --help и пробный запуск на тестовой ветке.

Где хранятся сессии и почему это важно в CI

Сессии лежат внутри CODEX_HOME (по умолчанию ~/.codex; в README TypeScript SDK указан каталог ~/.codex/sessions). Отсюда два следствия для CI.

Между job сессия не переживёт. Каждый job GitLab CI стартует в чистом контейнере. Многошаговый сценарий проще всего держать внутри одного job. Переносить CODEX_HOME артефактом между job технически можно, но это хрупко и проверяется только экспериментом на вашей версии.

В CODEX_HOME может лежать авторизация. При входе через ChatGPT там хранится auth.json с токенами. Никогда не сохраняйте CODEX_HOME целиком в артефакты или кэш пайплайна: артефакты скачивает любой, у кого есть доступ к проекту.

Если сессия не нужна после запуска, ставьте --ephemeral: файлы не пишутся на диск, а значит, нечему утечь. Но помните, что продолжить такую сессию уже нельзя.

Попробуйте сами

10–15 мин на рабочем месте
  1. Запустите анализ с --json, достаньте thread_id и продолжите сессию через codex exec resume <id> вопросом «какие файлы ты читал на прошлом шаге?». Убедитесь, что контекст сохранился.
  2. Сделайте codex exec fork от той же сессии с другим промптом и сравните ответы.
  3. Проверьте codex exec resume --help в своей версии CLI и выпишите, какие флаги доступны при продолжении.

Коротко

  • Идентификатор сессии приходит в событии thread.started потока --json.
  • codex exec resume <id> продолжает сессию, codex exec fork <id> копирует её в новую.
  • В скриптах передавайте идентификатор явно: --last может подхватить чужую сессию.
  • Ревью сделанного агентом — всегда в новой сессии.
  • CODEX_HOME не кладите в артефакты: там могут быть токены.
Отметка хранится только в вашем браузере
Хотите связаться с владельцем
компании напрямую?
Дмитрий Тарасов
Дмитрий Тарасов
СЕО

НАПИСАТЬ

Написать в MAX