Handbooks
Руководства

Планирование изменения

Дайте планировщику запрос и handbook — получите байт-точный план правок и машиночитаемую декларацию того, чего он касается.

handbook plan --source <repo> --handbook <dir> --request "<text>" --out plan.md

Планировщик — агент только для чтения. Он просматривает каталоги, читает файлы и ищет по grep — у него вообще нет инструмента записи, даже отключённого, — а его результат — план, который выполнит кто-то другой.

Цикл

  1. Маршрутизация по handbook: какие файлы, функции и состояние в зоне охвата?
  2. Чтение реального исходника по каждому найденному адресу.
  3. Вывод блоков ### EDIT n с байт-точным текстом old и new.
  4. Завершение JSON-блоком деклараций.

Два артефакта, две роли

Handbooks — это индекс местоположений: он показывает разбросанные, неочевидные места, которые пропускает текстовый поиск, — зеркальные реализации, каждое чтение и каждую запись элемента состояния, точки соприкосновения подсистем. Реальный исходник — истина о том, что менять. Handbooks даёт адрес; код по этому адресу даёт байты.

Как написать хороший запрос

СлабоСильно
«Почини баг с загрузкой»«Загрузки, завершившиеся ошибкой 503, должны повторяться три раза с экспоненциальной выдержкой, прежде чем показывать ошибку»
«Добавь логирование»«Логировать id запроса и длительность на уровне INFO для каждого завершённого HTTP-запроса, используя существующий логгер»
«Сделай быстрее»«Кешировать результат resolveTenant на 60 секунд с ключом по id арендатора»

Формулируйте желаемое поведение, а не файл, в котором оно, по-вашему, находится. Название файла сужает поиск планировщика до места, о котором вы уже подумали, — а это обесценивает саму затею.

Чтение плана

### EDIT 1

- file: `src/upload.py`
- where: `Uploader.send (~88)` — wrap the request in the retry helper

```old
    response = self._client.put(url, data)
```

```new
    response = self._retry(lambda: self._client.put(url, data), attempts=3)
```

### EDIT 2

- file: `src/upload.py`
- where: `Uploader` — add the helper

```old
    def send(self, url, data):
```

```new
    def _retry(self, call, attempts):
        last = None
        for _ in range(attempts):
            try:
                return call()
            except TransientError as exc:
                last = exc
        raise last

    def send(self, url, data):
```

Both call sites now share one retry policy.

```json
{ "will_modify": ["Uploader.send"], "will_add": ["Uploader._retry"], "will_remove": [] }
```

Правила, которым подчиняется формат:

  • old должен быть байт-точным и встречаться в файле ровно один раз.
  • Пустой old означает «создать этот файл».
  • Правки нумеруются и идут по возрастанию, сверху вниз.
  • Завершающий блок json потребляется командой resync, чтобы уточнить охват обновления.

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

Когда он сдаётся

plan выходит с ненулевым кодом — он не пишет извинение в plan.md, чтобы скрипт скормил его apply.

abortedЧто случилосьЧто делать
fabricationОтвет трижды изобретал секции ## Tool result — модель рассуждала над воображаемым содержимым файловИспользуйте более сильную модель. Ничему из этого запуска нельзя доверять
turn-limitХоды закончились без единого блока EDITПовысьте --max-turns или сузьте запрос
no-planВызвал finish без чего-либо пригодногоОбычно запрос, не требующий изменений кода, или слишком расплывчатый для локализации

Почему фабрикация отклоняется целиком

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

Настройка

ФлагПо умолчаниюКогда менять
--max-turns <n>30Повышайте для большого репозитория или широкого изменения; понижайте, чтобы ограничить стоимость
--model <id>gpt-4o-miniЭто команда, которая больше всех выигрывает от более сильной модели
--handbook <dir>Передавайте всегда. Без него планировщик исследует вслепую
--out <file>(stdout)Опустите, чтобы перенаправлять вывод дальше

Без handbook

handbook plan --source ~/code/api --request "…"

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

Что разрешает песочница

list_dir(path)
read_file(path, start_line?, end_line?)
grep(pattern, path)
finish(plan)
  • Каждый путь разрешается внутри корня песочницы; побеги, в том числе через симлинки, отклоняются.
  • Handbooks смонтирован только для чтения в __handbook__/ — это отдельная песочница, не та, что для исходника.
  • Чтение ограничено 60 000 символами; grep ограничен 100 совпадениями и пропускает файлы больше 5 МБ.
  • Катастрофические регулярные выражения — неограниченный квантификатор над группой, которая сама его содержит, вроде (a+)+ или (.*)* — отклоняются аккуратной ошибкой инструмента, а не подвешивают запуск.

Дальше

На этой странице