Привет, Хабр! Возможно, вы знаете меня по дайджестам проекта far2l, но сегодня хочу поделиться кое-чем другим. Это небольшая и очень полезная утилита и формат файлов для неё, которые родились из моей повседневной работы с AI-ассистентами (в том числе в процессе работы над тем же фаром). Штука получилась настолько удобной, что я решил поделиться ей с сообществом. Поехали!

Боль и страдания ручного копипаста

Думаю, многим здесь знаком этот цикл:

  1. Вы: «Перепиши вот эту функцию, чтобы она обрабатывала ещё и такой-то случай».

  2. AI: «Конечно! Вот обновлённый код…» (выдаёт красивый блок кода).

  3. Вы: Вручную выделяете этот блок, переключаетесь в IDE, находите нужный файл и нужную функцию, аккуратно заменяете старый код на новый, поправляете отступы, которые почти всегда едут. Запускаете, видите ошибку, возвращаетесь к AI и повторяете всё заново.

Ручной копипаст — самое узкое место во всём процессе. Он отнимает время, утомляет и провоцирует ошибки. Да, есть платные плагины для IDE, позволяющие AI менять код самостоятельно, но они стоят денег, некоторые недоступны в РФ, а ещё мне удобнее самому решать, какие части кода проекта экспонировать нейронке, это сильно влияет на качество результата.

Конечно, все мы пробовали предлагать ИИ сразу генерировать patch-файлы, и, конечно, знаем, что файлы получаются битыми. Происходит это от того, что на входе сетка «видит» не байты, а токены, и сгенерировать верный с точностью до байта патч она не в состоянии.

Размышляя о том, как можно было бы упростить процесс, я вспомнил про систему обновлений форума Simple Machines. Там использовался семантический подход: вместо строгих инструкций «замени строку 4 на вот такую», файлы с обновлениями содержали семантические инструкции «найди вот этот блок кода, и допиши после него вот это». Интуиция подсказывала: такой патч ИИ сочинить будет куда проще!

Из этой идеи родился формат файлов .ap (AI-friendly Patch), который уже некоторое время существенно облегчает мою жизнь и экономит время.

Как устроен .ap?

Это простой, человекочитаемый YAML-файл. Формат использует несколько ключевых понятий:

  • действие, action: Что мы делаем? (REPLACE, INSERT_AFTER, INSERT_BEFORE, DELETE).

  • цель, target: Где мы это делаем?

  • фрагмент, snippet: Уникальный фрагмент кода, который нужно найти. Поиск «умный» — он игнорирует отступы и пустые строки

  • якорь, anchor (необязательно): Если snippet встречается в файле несколько раз (например, return result), можно указать «якорь» — более крупный и точно уникальный блок кода (скажем, сигнатура функции), внутри которого нужно искать snippet

На примере из README

Представим, что у нас есть простой файл greeter.py:

# greeter.py
def say_hello():
    # Эту строку мы хотим изменить
    print("Hello, world!")

Мы просим AI изменить приветствие (не забыв «скормить» ему спеку на .ap формат и инструкцию генерировать ответ именно в нём). Вместо нового блока кода он выдаёт нам вот такой файл (назовём его afix.ap — я обычно использую это имя, чтоб легко было найти патч вверху списка файлов в папке):

# afix.ap
version: "1.0"
changes:
  - file_path: "greeter.py"
    modifications:
      - action: REPLACE
        target:
          snippet: 'print("Hello, world!")'
        content: 'print("Hello, AI-powered Habr!")'

Запускаем патчер из командной строки:

python3 ap.py --patch afix.ap

И наш greeter.py автоматически обновляется:

# greeter.py
def say_hello():
    # Эту строку мы хотим изменить
    print("Hello, AI-powered Habr!")

И, разумеется, формат позволяет пропатчить (или создать с нуля) целую серию файлов. Больше никакого ручного поиска и копипаста! Вся рутина автоматизирована.

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

Всё необходимое — в репозитории:

  1. Сам скрипт-патчер ap.py (в папке implementation)

  2. Файл со спецификацией формата ap.md

Общаясь с AI, прикладываем к промпту содержимое ap.md и ставим задачу: «сгенерируй ответ в формате ap». Как минимум, Gemini 2.5 Pro отлично с этим справляются. Полученный .ap файл сохраняем себе и применяем скриптом ap.py.

Приглашаю обсуждать и тестировать!

Вот такая штука получилась. Я уже активно использую её в своих проектах, и она экономит мне кучу времени и нервов. Возможно, это только начало: наверняка и формат и утилиту можно улучшить.

Поэтому и делюсь этим с вами. Пробуйте, тестируйте, ломайте! Что если snippet будет слишком коротким? А что если он найдётся 10 раз? Как поведёт себя патчер с разными окончаниями строк (спойлер: я постарался это учесть)?

Буду рад любому фидбеку, идеям и, конечно, тикетам в багтрекере. Давайте вместе сделаем взаимодействие с AI-помощниками ещё чуточку удобнее!

Комментарии (2)


  1. nidalee
    12.10.2025 03:40

    Я думал, все уже перешли на агентов, которые либо сами правят файлы, либо пишут пулл реквесты.


    1. Rive
      12.10.2025 03:40

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