06 июл. 2024 г.·7 мин чтения

Проектная документация для сгенерированного кода с понятными заметками о намерении

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

Проектная документация для сгенерированного кода с понятными заметками о намерении

Почему этот код трудно проверять

Обычно проверяющие видят результат, а не выбор, который за ним стоит. Код работает, тесты проходят, а diff выглядит перегруженным, но ничего из этого не объясняет, зачем вообще было сделано изменение и какие части должны остаться неизменными.

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

Именно поэтому диффы сгенерированного кода часто кажутся тяжелее, чем написанные вручную. Разработчик просит «добавить сводки к заявкам в поддержку» и получает вместе с этим логику повторов, хелперы форматирования, обработку ошибок и флаги конфигурации. Что-то из этого полезно. Что-то — просто шум. Трудность в том, чтобы отличить одно от другого.

Скрытые правила еще сильнее замедляют проверку. То, что важно для людей, часто прячется в имени хелпера, строке промпта или значении по умолчанию внутри обертки. Если проверяющий пропустит одну такую деталь, он может по ошибке одобрить изменение продукта.

Поэтому проверяющие начинают читать в обратную сторону. Они просматривают diff, переходят в хелперы, ищут старое поведение и пытаются угадать, что автор хотел сохранить. Это отнимает время. И это же приводит к слабым комментариям, потому что люди спорят о форме кода вместо намерения.

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

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

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

Что должна отвечать ваша проектная документация

Сгенерированный код часто выглядит завершенным еще до того, как кто-то его понял. Проектная документация в первую очередь должна объяснять намерение. Проверяющим нужно узнать, какую проблему решает изменение, какие правила остаются неизменными и где заканчивается работа, еще до того, как они увидят длинный diff.

Начните с проблемы простыми словами. В первые несколько строк не используйте названия инструментов и внутренний жаргон. Опишите проблему пользователя или бизнеса так, как объяснили бы новому коллеге: сотрудники поддержки тратят время на одно и то же резюме, или задача по биллингу падает, когда входные данные приходят не по порядку. Если формулировка проблемы расплывчата, ревью тоже будет расплывчатым.

Затем отметьте части, которые нельзя менять. Это и есть ограничители. Возможно, формат ответа API должен остаться прежним, старые отчеты должны по-прежнему совпадать с прежними итогами, или любой текст для клиента должен утверждать человек. Проверяющим это нужно в самом начале, потому что так они понимают, не ушел ли сгенерированный код туда, куда ему нельзя.

Объясните, почему вы выбрали именно этот подход, а не другой. Коротко. Достаточно одной-двух конкретных причин: этот вариант использует текущую очередь, избегает изменения схемы или оставляет обработку ошибок в одном сервисе. Эссе не нужно. Нужна достаточная детализация, чтобы проверяющий мог сравнить код с планом.

Объем тоже должен иметь четкую границу. Скажите, где изменение заканчивается. Если новая логика покрывает только сводки заявок на английском языке и не меняет маршрутизацию, скажите это прямо. Заметки о границах экономят время, потому что проверяющие перестают искать работу, которой вообще не было в scope.

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

Если вы можете ответить на эти пункты на одной странице, ревью обычно становится быстрее и спокойнее. Люди тратят меньше времени на споры о стиле и больше — на решения, которые влияют на продукт.

Используйте записи о решениях для крупных выборов

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

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

Полезная запись может быть короткой:

  • Короткое название и дата, например «Использовать PostgreSQL для сводок заявок — 2026-04-13»
  • Вариант, который вы почти выбрали вместо этого
  • Почему вы выбрали именно этот путь сейчас
  • Что заставит вас изменить решение позже

Третий пункт должен быть конкретным. Не пишите «выбрали ради масштабируемости» и не останавливайтесь на этом. Напишите, что вы имеете в виду на самом деле: «Мы оставили сводки в PostgreSQL, потому что команда уже делает резервные копии, нагрузка на запросы невысокая, а добавление Redis принесло бы лишнюю настройку и мониторинг при небольшом выигрыше».

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

Последний пункт делает запись честной. Запись о решении — это не обещание навсегда. Это заметка о том, что имеет смысл при текущих условиях. Добавьте триггер вроде «перейти на очередь, если задачи по сводкам начнут задерживать обновления заявок» или «пересмотреть выбор модели, если стоимость за 1000 сводок удвоится».

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

Добавляйте граничные заметки на краях

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

Именно поэтому в проектной документации нужна короткая граничная заметка. Она показывает следующему проверяющему, где код начинается, где заканчивается и какие допущения заслуживают самого пристального внимания.

Запишите, каким входным данным код доверяет без дополнительных проверок, а каким — нет. Будьте прямыми. Если задача принимает текст заявки из вашей системы поддержки, скажите это. Если она игнорирует вложения, вставленный HTML или свободный текст от пользователей, тоже скажите об этом.

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

Числа полезнее предупреждений. «Считывает до 100 заявок, останавливается через 20 секунд и ограничивает стоимость модели $1 на пакет» — это уже можно проверить. «Использует OpenAI API и один файл промпта из репозитория» — намного лучше, чем заставлять людей искать это по сгенерированному коду.

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

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

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

Пишите документ до запроса на ревью

Сделайте процесс ревью строже
Используйте поддержку CTO на частичной занятости, чтобы сделать ИИ-изменения проще для оценки и безопаснее для слияния.

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

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

Начните с одного предложения о потребности пользователя или бизнеса. Сформулируйте конкретно. «Сотрудникам поддержки нужны сводки заявок, чтобы отвечать меньше чем за две минуты» работает намного лучше, чем «улучшить рабочий процесс».

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

Граничные заметки не менее важны. Сгенерированный код часто выглядит нормально в середине и становится рискованным на краях. Поместите заметки туда, где код касается данных клиентов, прав доступа, лимитов запросов, внешних API и путей сбоя. Если задача по сводкам может раскрыть приватный текст, повторить попытку дважды или завершиться с fail closed, скажите об этом прямо.

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

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

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

Простой пример: добавление ИИ-сводок в заявки в поддержку

Команде поддержки нужна короткая ИИ-сводка для каждой новой заявки, чтобы сотрудники могли быстро увидеть суть проблемы еще до того, как откроют весь тред. Звучит просто, но код может быстро расползтись по приему сообщений, сборке промпта, маскированию данных, вызовам модели, повторам, хранению и панели для сотрудников. Если часть этого кода сгенерирована, проверяющие могут застрять на одном хелпере за другим, так и не поняв, почему функция работает именно так.

Короткая проектная документация это проясняет. Запись о решении объясняет правила функции, а граничные заметки показывают, где система должна остановиться.

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

Граничные заметки должны были бы сказать это прямо:

  • Модель получает только текст заявки, тему и небольшое количество контекста по аккаунту.
  • У запроса есть жесткий лимит токенов, чтобы одна огромная заявка не раздула расходы.
  • Этап редактирования удаляет секреты аккаунта, ссылки для сброса, API-ключи и похожий чувствительный текст.
  • Система хранит сводку как внутреннюю заметку, а не как часть клиентского треда.
  • Сотрудник должен одобрить любой ответ, который использует сводку.

Это дает проверяющим что-то конкретное для оценки. Им не нужно читать каждый хелпер, чтобы понять, имеет ли дизайн смысл. Они могут задавать прямые вопросы: соблюдается ли лимит токенов, блокируются ли секреты до вызова модели и остается ли в потоке человеческое одобрение?

Вот почему проектная документация здесь так важна. Код может быть шумным, но намерение должно оставаться простым для проверки. Когда документ называет выборы и ограничения, ревью ИИ-кода становится намного быстрее и намного менее раздражающим.

Ошибки, которые тратят время ревью

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

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

Краткая заметка о дизайне должна сначала называть выбор. «Мы кэшируем сводки на 24 часа, чтобы страницы поддержки оставались быстрыми» — полезно. «Добавили слой кэша и обновили обработчики» — нет. Второе предложение сообщает, что изменилось, но не то, что вы пытались защитить.

Еще одна распространенная ошибка — скрывать вариант, от которого вы отказались. Если вы не укажете отброшенный вариант, компромисс исчезает, и ревью превращается в повторение старых споров. Одна строка может сэкономить десять комментариев: «Мы не делали сводку при каждой загрузке страницы, потому что стоимость API в тестах выросла в четыре раза». Это дает проверяющему что-то твердое для оценки.

Команды также прячут ограничения в комментариях к коду, которые почти никто не увидит во время ревью. Граничные заметки должны быть в документе рядом с самим решением. Если функция ломается для заявок длиннее 10 000 символов, скажите это заранее. Если задача работает только в одном регионе, тоже скажите. Проверяющим не нужно выяснять ограничения, открывая хелперы и разбирая условия.

Длинные эссе создают другую проблему. Их никто не обновляет. Через две или три итерации документ превращается в устаревшую выдумку, и проверяющие перестают ему доверять. Одностраничная заметка с несколькими записями о решениях обычно сохраняется намного лучше, чем пять страниц фона.

Размытые слова быстро тратят время. «Лучше», «чище» и «проще» сами по себе почти ничего не значат. Дайте причину, которую может проверить другой человек. Скажите, что новый поток сокращает повторные попытки с трех вызовов до одного, убирает нестабильную зависимость или позволяет откатиться меньше чем за пять минут.

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

Короткий чек-лист перед слиянием

Проверяйте ИИ-изменения быстрее
Получите помощь старшего специалиста с ограничениями по стоимости, повторам, промптам и вызовам моделей.

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

Используйте этот чек перед тем, как просить кого-то одобрить слияние:

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

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

Хорошо работает простой тест. Дайте документ человеку, который не делал эту функцию, и задайте три вопроса: какое решение мы приняли, какое правило должно остаться неизменным и где заканчивается это изменение? Если он колеблется, слияние может подождать.

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

Что дальше для вашей команды

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

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

Попросите проверяющих сначала читать намерение. Многие команды по-прежнему открывают diff и просматривают файлы один за другим. Сгенерированный код делает это медленным и раздражающим. Минутное чтение документа может сэкономить двадцать минут поисков по diff, потому что проверяющий уже знает, что код должен делать, чего он никогда не должен делать и какие компромиссы автор принял.

Держите записи о решениях рядом с кодом, а не в вики, которую люди забывают открыть. Если команда позже заменит очередь, изменит лимиты модели или уберет кэш, обновите заметку в том же pull request. Старые решения быстро устаревают, когда код продолжает меняться.

Достаточно простого командного ритуала:

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

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

Если вашей команде нужна помощь в настройке практичного процесса вокруг кода, сгенерированного ИИ, Oleg Sotnikov на oleg.is работает как CTO на частичной занятости и консультант для стартапов по разработке с приоритетом на ИИ и автоматизации. Для небольших команд внешняя структура ревью вроде этой может быть достаточной, чтобы превратить проектную документацию в обычную привычку, а не в лишнюю бумажную работу.

Часто задаваемые вопросы

Что должна отвечать проектная документация до начала ревью кода?

Начните с причины изменения простым языком. Затем укажите правила, которые не должны меняться, объем работы и любые рискованные границы, например данные клиентов, вызовы модели или повторы. Так проверяющим будет достаточно контекста еще до того, как они откроют большой дифф.

Почему диффы сгенерированного ИИ-кода сложнее проверять?

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

Когда мне нужна запись о решении?

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

Что делает запись о решении хорошей?

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

Что должно быть в граничных заметках?

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

Каким по длине должен быть документ?

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

Как показать, что результат ИИ должен оставаться внутренним?

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

Писать документ до кода или после?

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

Какие ошибки чаще всего тратят время ревью?

Команды теряют время, когда документы описывают файлы, а не решения, скрывают отброшенные варианты, прячут ограничения в комментариях или используют расплывчатые слова вроде «лучше» и «проще» без доказательств. Еще одна частая проблема — устаревшие документы, которые никто не обновляет после изменений в дизайне.

Как понять, что заметка достаточно ясна для слияния?

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