Комментарии-остатки промпта.
Комментарии, которые являются артефактами генерационного диалога — пересказанные промпты, пошаговый нарратив, чат-ремарки и заглушки-эллипсисы вроде `// ... rest of the code here`, закоммиченные в исходники вместо настоящей документации.
##Signs and Symptoms
Ревьюер замечает комментарии-остатки промпта, когда комментарии документируют разговор, породивший код, а не сам код. Четыре признака, часто сопутствующих друг другу:
- Пересказ промпта — комментарий, дословно перефразирующий запрос (
// Function to add two numbers) над функцией, буквально названнойadd. - Нарратив шагов — построчный репортаж очевидных операций (
// Step 1: loop over the array,// increment i by 1надi++). - Чат-ремарки — реплики от второго лица в настоящем времени, адресованные вам, автору промпта (
// As requested, here is the updated handler,// Sure! Here's the fix,// Note: replace with your actual API key). - Эллипсис / остатки-заглушки —
// ... rest of the code here,// keep your existing logic,// your code here,// TODO: implement error handling, оставленные в закоммиченном исходнике.
// Function to add two numbers and return the result <- пересказывает промпт
function add(a: number, b: number): number {
// Step 1: add the two numbers <- проговаривает очевидное
const sum = a + b;
return sum; // return the sum
}
// As requested, here is the updated handler <- чат-ремарка для "вас"
export async function handler(req: Req, res: Res) {
// ... keep your existing validation logic here ... <- эллипсис: реальный код выброшен
// TODO: implement error handling <- заглушка отправлена как есть
const user = await db.users.find(req.params.id);
res.json(user);
}
Строка с эллипсисом — самая опасная: она читается как документация, но на деле является инструкцией человеку вставить код, который модель опустила — примените блок дословно, и существующая валидация молча исчезнет. OX Security обнаружила "комментарии повсюду" в 90–100% сгенерированного ИИ кода в своём исследовании 300+ репозиториев, описывая их как маркеры, которые "выглядят полезными, но в основном поддерживают сам ИИ, захламляя репозитории".
##Reasons for the Problem
Почему модели это выдают
- Подражание учебным корпусам на уровне следующего токена. Обучающая смесь насыщена постами блогов, ответами на StackOverflow и документацией, где каждая строка объясняется для новичка. Модель воспроизводит этот дидактический регистр — нарративность и пересказ намерения — потому что это статистически вероятное продолжение, а не потому что окружающий репозиторий в этом нуждается.
- Просачивание чат-регистра / подхалимство. RLHF настраивает ассистентов быть объясняющими и сговорчивыми в канале чата. Этот разговорный тон от второго лица протекает в канал кода, порождая ремарки вроде "Как и просили…" и "Примечание: вам следует…", которые теряют смысл, как только код отрывается от разговора.
- Рассуждение, проговорённое как комментарии. Модели выносят свой план ("Шаг 1… Шаг 2…") во встроенные комментарии — утечка цепочки рассуждений, замороженная в файле.
- Эллипсис — это удобство чата, применённое не к месту. В ответе чата
// ... rest unchanged ...— вежливый способ не перепечатывать файл. Когда такой ответ вставляется или автоматически применяется к реальному файлу, это удобство становится буквальным остатком — и буквальной потерей данных. - Нет контекста репозитория, поэтому она пересказывает промпт. Не имея тикета, домена и настоящего "почему", модели нечего сказать в комментарии по сути, поэтому она скатывается к перефразированию единственного, что у неё есть: вашего промпта. OX характеризует эти комментарии как "внутренние маркеры для навигации по ограничениям контекста… опору на краткосрочную память, а не на подлинное понимание".
Почему это вредит
- Нагрузка на ревью. Каждая строка нарратива — шум, который человек должен пробежать глазами. Формулировка OX: ИИ "кодит как джун" на машинной скорости, а человеческое ревью "не может масштабироваться под объём ИИ" — остаточные комментарии делают каждый дифф дороже для ревью именно тогда, когда диффов больше.
- Корректность / потеря данных. Заглушки-эллипсисы (
// ...existing code...) приводят к выбрасыванию реального кода, когда блоки применяются вслепую. - Гниение комментариев. Комментарии-пересказы промпта дублируют намерение кода прозой; проза расходится по мере изменения кода, оставляя активно вводящую в заблуждение документацию — классический запах Фаулера Comments (Комментарии) как дезодорант.
- Скрытая незавершённость.
// TODO: implement error handling— это сигнал модели о том, что она работала на пределе своей компетенции; отправленная как есть, это незаконченная логика, замаскированная под отслеживаемую задачу. - Сигналы безопасности.
// replace with your actual API keyобычно соседствует с захардкоженной учётной заглушкой — остаток помечает ровно ту строку, которая интересна сканеру (и злоумышленнику).
##Treatment
Тактики промптинга / генерации
- Ограничьте регистр: "Выведи файл целиком. Никогда не сокращай через
// ...,// rest of the codeили// existing code. Не проговаривай шаги — комментируй только неочевидное обоснование (почему). Никаких разговорных ремарок; это идёт прямо в репозиторий". - Просите унифицированный дифф вместо обёрнутого в прозу фрагмента, чтобы пропуски были явными и применимыми, а не отмахнуты комментарием-эллипсисом.
- Требуйте, чтобы модель запускала форматтер и ваш конфиг линтера (например,
no-warning-commentsс пользовательскими терминами) и сообщала результат — замыкание петли "проверь линтером" автоматически ловит остатки-заглушки/TODO. - Добавьте grep-барьер в pre-commit / CI на маркеры-остатки (
rest of the code,your code here,existing code,As requested,Step \d) и относитесь к маркерам-эллипсисам как к жёсткому блокеру, поскольку они часто означают, что код был молча выброшен.
Рефакторинг
Удаляйте чат-ремарки и нарратив без остатка. Там, где комментарий лишь пересказывает, что делает код, это сигнал сделать код самодокументируемым — примените Extract Function (Извлечение функции) и Rename (Переименование), чтобы имя несло намерение, затем оставьте только комментарии, объясняющие неочевидное почему (Фаулер: удаляйте комментарии, которые служат дезодорантом для плохих имён).
// до — остаток промпта
// Create a function that validates an email address using a regex
function validateEmail(input) {
// check if the input matches the email pattern
const re = /^[^@]+@[^@]+\.[^@]+$/;
// return true or false
return re.test(input);
}
// после — имя несёт намерение; единственный комментарий объясняет неочевидное почему
const EMAIL_RE = /^[^@]+@[^@]+\.[^@]+$/; // намеренно нестрогая: ловим только опечатки до отправки, а не RFC 5322
const isValidEmail = (input: string): boolean => EMAIL_RE.test(input);
Для остатка-эллипсиса никогда не применяйте блок как написано — сравните его с текущим файлом и восстановите то, что модель выбросила. Для // TODO: implement … либо доведите логику до конца, либо превратите её в отслеживаемую задачу и проваливайте сборку на термине-заглушке, чтобы она не могла попасть в продакшен как есть.
##Detected by
- ESLint no-warning-comments — Отмечает TODO/FIXME/XXX и пользовательские настраиваемые термины — задайте `terms`, чтобы ловить остатки-заглушки вроде "your code here" или "rest of the code"
- SonarQube / SonarSource S125 — Участки кода не должны быть закомментированы — отмечает урезанные/оставленные закомментированные блоки
- SonarQube / SonarSource S1135 — Отслеживает использование тегов "TODO" — выявляет остатки-заглушки TODO, попавшие в код
- SonarQube / SonarSource S1134 — Отслеживает использование тегов "FIXME"