Перейти к содержимому
Оригинал
Juejin · ИИ-программирование· 小蠢驴打代码·· 6 часов назадИзбранное редакциейОценка ИИ71

Добавляем в режим Codex Plan журнал решений codex-plan-ledger: фиксируем выбор и проверяем отклонения от плана

Краткий обзор ИИ

codex-plan-ledger записывает решения, принятые в режиме Codex Plan (/plan), в файл docs/plans/<id>/decisions.json. Этот файл попадает в тот же PR, что и код, его можно диффить и ревьюить, а команда plan-ledger check --base main сопоставляет изменённые файлы с планом и показывает, что вышло за рамки плана и какие запланированные файлы остались нетронутыми.

Почему это важно

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

Полный текст · Перевод ИИ

Когда пишешь код в режиме Plan в Codex (/plan), самое ценное — зачастую не сам план, а те несколько решений, которые были приняты по ходу его составления: повторять ли попытку при сбое, задавать конфигурацию через параметры или через переменные окружения, какие файлы трогать нельзя. Эти решения обычно остаются только в переписке. Посмотришь на PR через две недели — ревьюер видит код, но не видит, «почему тогда выбрали именно так»; и сверить, не вышло ли код за изначально оговорённые рамки, тоже не с чем.

codex-plan-ledger делает ровно две вещи:

  1. Журнал решений. Записывает решения из режима Plan в docs/plans/<id>/decisions.json в репозитории: вопросы, которые Codex задал вам, и ваши ответы, ещё не определённые варианты из плана, явно указанные в плане значения по умолчанию — всё там. Он лежит в одном PR с кодом, его можно диффить и ревьюить.
  2. Проверка выхода за рамки. Когда код написан, plan-ledger check --base main сверяет изменённые файлы с планом: файлы, изменённые вне плана, и файлы, перечисленные в решениях, но так и не тронутые, — всё это выводится в отчёт.

Image 1: 10 секунд: Codex /plan задаёт вопросы и отвечает → ответы записываются в decisions.json → при написании кода изменён лишний файл вне плана → plan-ledger check выводит этот файл

Как это работает

Image 2: UML-диаграмма последовательности: разработчик, Codex /plan, Stop hook, decisions.json, Codex пишет код, plan-ledger check, ревью PR — в хронологическом порядке отмечено, что записывается и что читается на каждом шаге.

Как пользоваться

npm i -g github:miniLV/codex-plan-ledger
plan-ledger init --write   # 写入 Codex hooks 配置

Дальше как обычно /plan в Codex, и на вопросы Codex отвечаете там же, как обычно. Когда план готов, Stop hook делает три вещи: разбирает план, пишет журнал, генерирует одностраничный офлайн-HTML. В терминале появляется лишняя строка, например:

plan-ledger: nothing to answer; 2 answered in Codex → file://…/plan.html

На этой странице можно проверить все решения: то, на что уже ответили в Codex, помечается «отвечено в Codex»; явно указанные в плане значения по умолчанию помечаются «по умолчанию, можно проверить» и не считаются пунктами, ожидающими ответа; нерешённые пункты выбираются все сразу, по кнопке генерируется JSON для отправки, который вставляется в следующее сообщение. Невыбранные пункты записываются как «без ответа, сохраняется значение по умолчанию», это не считается согласием.

Когда код написан:

plan-ledger check --base main          # 可读报告
plan-ledger check --base main --strict # 有偏离时 exit 1,可以放进 CI

Несколько ограничений по дизайну:

  • Рендеринг целиком на чистых шаблонах, без дополнительных вызовов модели, без зависимостей, один HTML-файл, без сети.
  • hook никогда не блокирует этот раунд и не ждёт вас. Если формат плана не распознан, пропускает как есть, добавляя лишь одну подсказку.
  • Ответы на странице хранятся только как данные и не исполняются.

Как выглядит журнал

{
  "id": "n-selection",
  "title": "Selection",
  "question": "How should users select the greeting language?",
  "source": "codex-native",        // Codex 自己问的,你在 Codex 里答的
  "options": [
    { "id": "a", "label": "Named flag", "recommended": true },
    { "id": "b", "label": "Second positional argument", "recommended": false },
    { "id": "c", "label": "Environment variable", "recommended": false }
  ],
  "chosen": "a",
  "status": "answered"
}

Этот фрагмент — из реальной сессии режима Plan (codex-cli 0.156.0): Codex задал 2 вопроса через request_user_input, реальный Stop hook вычитал вопросы и ответы из записи сессии и записал их в журнал. Вся эта сессия — около 43000 токенов. Нужно оговориться: в этот раз в промпте явно требовалось, чтобы Codex сначала задавал вопросы, — это проверка функциональности, а не измерение эффекта.

На практике: честно говоря, число раундов не уменьшилось

Изначально задумывалось, что «ответить на все решения на одной странице за раз удобнее, чем когда Codex спрашивает раунд за раундом». Я провёл парный эксперимент на vercel/[email protected]: одна и та же задача, одна и та же модель и настройки, нативный режим Plan и режим с plan-ledger прогоняются по разу, на вопросы отвечает скрипт по скрытому эталонному ответу. Всего два раунда, 2 задачи, n = 3 пары, это можно считать лишь ориентировочными данными:

Раунд / задача Раундов до финального варианта (нативный / plan-ledger) Всего токенов (нативный / plan-ledger) Приёмка
1 / strict-option 1 / 2 717,487 / 586,971 все прошли
2 / strict-option 1 / 2 180,208 / 205,644 все прошли
2 / month-unit 1 / 1 179,053 / 140,020 все прошли
  • Число раундов не улучшилось: из 3 пар проиграл в 2, ничья в 1. По токенам где больше, где меньше, единого направления нет (в двух раундах конфигурации запуска разные, токены можно сравнивать только внутри одного раунда).
  • Выход за рамки пойман в 3/3: после реализации в копию подложили новые файлы вне плана и вернули файлы из плана в исходное состояние — во всех 3 прогонах это было выведено в отчёт; на чистом варианте в 3/3 ложных срабатываний не было.
  • Изменения внутри файла, противоречащие решениям, пойманы в 0/3: если внутри файла из плана написать код, противоположный выбранному варианту, проверка этого не обнаружит. Она смотрит только «какие файлы изменены», но не читает содержимое кода — это известное ограничение.

Поэтому позиционирование проекта сместилось с «ответить на одной странице и сэкономить раунды» на нынешнее «журнал решений + проверка выхода за рамки». Эксперимент вскрыл ещё два момента, которые уже исправлены: режим Plan в Codex, даже когда его просят перечислить решения, сначала задаёт вопросы через встроенный request_user_input, поэтому теперь эти вопросы и ответы сразу записываются в журнал и повторно не задаются; «Chosen defaults» в конце плана раньше считались пунктами, ожидающими ответа, а теперь записываются как значения по умолчанию, доступные для проверки, и не считаются ожидающими ответа. После этих изменений замеры ещё не повторялись.

Полные данные и скрипты лежат в репозитории: раунд 1, раунд 2, план замеров.

Текущее состояние и что дальше

Ранний прототип v0.1, с покрытием тестами. Экспериментальные части: UserPromptSubmit hook и чтение нативных вопросов и ответов из записи сессии (формат записи сессии — не публичный контракт, если прочитать не удаётся, шаг пропускается). Windows не тестировался.

Дальше:

  • Сверять решения по содержимому (то есть тот самый 0/3 выше).
  • Больше задач, минимум 3 повторов на группу, измерить, насколько журнал покрывает решения в одной сессии и как работает обнаружение отклонений.

Пробуйте, заводите issue: github.com/miniLV/code… · главная страница и онлайн-демо: minilv.github.io/codex-plan-…

Идейно вдохновлялся html-plan и answer-me-with-html, код не переиспользовал.

Источник: Juejin · ИИ-программирование · juejin.cn