Hashline или replace: имеет ли значение формат правок?

Машинный перевод Оригинал статьи.


содержание

В статье Проблема обвязки Джан Бёлюк показал, что правки в стиле hashline (с привязкой к номерам строк, как в 4#WB) превосходят традиционные правки в режиме replace (сопоставление old_string/new_string) в работе агентов для программирования. Я экспериментирую с разработкой собственной обвязки (tau), и мне захотелось проверить этот результат и понять, стоит ли использовать в ней hashline как стратегию редактирования по умолчанию. Поэтому я создал edit-bench, чтобы самостоятельно проверить это на нескольких языках и моделях.

Условия эксперимента

edit-bench генерирует тесты на основе мутаций, используя существующие кодовые базы. Вы указываете скрипту каталог, и он создаёт мутации: удаляет инструкцию, инвертирует логическое значение, меняет аргументы местами и т. д.

  • Языки: Python (из hive), TypeScript (из oh-my-pi), Rust (из irradiate)
  • Модели: gpt-4.1-mini, google/gemini-3-flash-preview, qwen/qwen3.5-397b-a17b
  • Режимы редактирования: replace (old_string/new_string) и hashline (привязка к номерам строк)
  • 20 задач на язык, по одному запуску с единственной попыткой
  • Я также недавно добавил нечёткое сопоставление в tau (каскадная обрезка пробельных символов: trim_end → trim_both → unicode normalization) и хотел посмотреть, поможет ли это

Результаты

Режим replace:

Модель Python TypeScript Rust
gemini-3-flash 95% 80% 95%
qwen3.5-397b 90% 85% 85%
gpt-4.1-mini 65% 75% 45%

Режим hashline (из предыдущих запусков):

Модель Python TypeScript Rust
gemini-3-flash 70% 85% 90%
qwen3.5-397b 85% 85% 90%
gpt-4.1-mini 50% 70% 55%

Hashline заметно ухудшает результаты на Python и, по-видимому, почти не влияет на TypeScript и Rust. Эта зависимость от языка интересна — значимые пробельные символы в Python могут повышать вероятность ошибок при правках с привязкой к строкам.

Помогает ли нечёткое сопоставление?

По-видимому, нет.

Я добавил сбор трассировок, чтобы проверить, срабатывает ли вообще в tau каскад обрезки пробельных символов для нечёткого сопоставления при запусках в режиме replace. Для 114 успешных правок и 20 неудачных правок (3 модели × 3 языка) нечёткое сопоставление сработало ноль раз.

Из 20 неудачных правок:

  • 1 содержала пробельные символы в конце строк (теоретически исправимо)
  • ~8 включали номера строк в old_string (ошибка модели)
  • ~11 содержали полностью выдуманный текст

Когда модели правильно воспроизводят old_string, они правильно воспроизводят и пробельные символы. Когда же они ошибаются, то очень сильно — каскадная обрезка пробельных символов не помогает.

(Подробности анализа трассировок)

Выводы

  1. В сравнении hashline и replace нет однозначного победителя. Эффект зависит от языка и модели. На Python hashline ухудшает результаты; на TypeScript разницы нет; на Rust всё неоднозначно.

  2. Результаты Джана трудно обобщить. react-edit-benchmark работает только с JavaScript и использует LSP для получения обратной связи при проверке. В наших условиях (без LSP, несколько языков) картина получается другой. В частности, цикл обратной связи через LSP, вероятно, затрудняет интерпретацию результатов. Возможность повторить попытку, получив сообщения об ошибках типов, заметно помогает модели, причём этот эффект зависит от формата правок.

  3. Для современных моделей проблема, которую решает нечёткое сопоставление, неактуальна. LLM либо в точности воспроизводят исходный текст, либо выдумывают что-то совершенно другое. Случаи почти точного совпадения с различиями лишь в пробельных символах, на которые рассчитано нечёткое сопоставление, на практике почти не встречаются.

  4. Для моделей текущего поколения в современных обвязках формат правок — не узкое место. Разрыв между моделями (90%+ у gemini-3-flash против 55–65% у gpt-4.1-mini) намного больше разрыва между форматами правок. Вложите усилия в выбор модели и промпт-инжиниринг, прежде чем беспокоиться о формате правок.

Обязательная оговорка: маленькая выборка, статистическая строгость отсутствует, так что воспринимайте результаты с учётом этого.

Все данные: nwyin/edit-bench, задачи #13 и #14.