Коротка відповідь. Код від AI перевіряється так само, як pull request джуна: уважно, за списком і без довіри до впевненого тону. Різниця в акцентах – моделі роблять специфічні помилки: пропускають edge cases, вигадують API, тягнуть застарілі патерни й повторюють небезпечні приклади зі свого навчання. Нижче – чекліст із поясненнями і готовий markdown-варіант для копіювання у свій процес.
Чому це не паранойя
Згенерований код має підступну властивість: він завжди виглядає завершеним. Акуратні назви, коментарі, впевнена структура. Людський недописаний код видно одразу; недописаний AI-код виглядає як готовий. Тому перевірка за списком тут важливіша, ніж для власного коду, де ти хоча б пам'ятаєш, що зрізав кути.
1. Коректність: edge cases, які моделі люблять пропускати
Happy path майже завжди правильний. Перевіряй краї:
- Порожні значення:
[],'',null,undefined,0. Класика:
// Згенеровано: працює, поки items не порожній
function averagePrice(items: Product[]): number {
const total = items.reduce((sum, item) => sum + item.price, 0);
return total / items.length; // [] → 0/0 → NaN, тихо попливе далі по коду
} NaN не кидає помилку – він мандрує обчисленнями і випливає десь в UI як «₴NaN». Модель цей випадок пропускає стабільно.
- Межі діапазонів: перший/останній елемент, off-by-one в індексах і слайсах.
- Асинхронні краї: що буде, якщо запит впаде? Якщо два запити завершаться не в тому порядку? Якщо компонент розмонтується до відповіді?
- Дублікати й повтори: повторний клік, повторний виклик, той самий id двічі.
Прийом: спитай модель «які edge cases цей код не обробляє?» – вона часто чесно перелічить власні пропуски. Потім перевір сам, бо перелік теж буває неповний.
2. Безпека: модель вчилась і на поганих прикладах
- Ін'єкції. Конкатенація рядків у SQL,
dangerouslySetInnerHTMLз даними користувача,eval. Якщо дані користувача склеюються з кодом чи запитом без параметризації/екранування – стоп. - Секрети в коді. Ключі й токени, вписані literal-ом «для прикладу». Всі секрети – лише зі змінних середовища.
- Вигадані залежності. Модель може імпортувати пакет, якого не існує, або з назвою, схожою на популярний (а зловмисники реєструють такі назви – це називається typosquatting). Правило: кожен новий пакет із згенерованого коду перевіряй руками на npm – хто автор, скільки завантажень, коли оновлювався.
- Надмірні права й довіра до вводу. Валідація на клієнті без валідації на сервері, відсутність перевірки власника ресурсу.
3. Відповідність кодовій базі
Модель без контексту пише «середньостатистичний» код, а не твій:
- Дублювання утиліт. Згенерований
formatDateпри живомуlib/dates.ts– класика. Перед комітом: чи не існує вже функція/компонент для цього? - Стиль і конвенції. Іменування, структура папок, підхід до стилів. Чужорідний шматок ускладнить життя всім наступним читачам.
- Патерни актуальної версії. Класові компоненти замість хуків, застарілі API бібліотек. Звіряй із документацією поточної версії, а не з упевненістю моделі.
Агентні інструменти, які бачать репозиторій, помиляються тут рідше – про це в розборі агентного workflow.
4. Тести як контракт
Найнадійніший спосіб перевірити згенерований код – тест, який ти написав або хоча б уважно прочитав сам:
- тест фіксує очікувану поведінку до того, як ти повірив реалізації;
- згенеровані тести читай прискіпливіше, ніж код: модель схильна писати тести, які проходять, а не тести, які перевіряють;
- один тест на головний edge case (порожній ввід, помилка запиту) цінніший за п'ять тестів happy path.
5. Приватні дані й ліцензії в промптах
Перевірка працює в обидва боки – дивись не лише на те, що виходить, а й на те, що ти відправляєш:
- не встав в промпт секрети, персональні дані користувачів, приватний код, який заборонено виносити (NDA);
- для робочих проєктів з'ясуй політику компанії щодо AI-інструментів до того, як вставив туди половину репозиторію.
Приклад: та сама помилка до і після перевірки
Ін'єкція – найдорожча з типових помилок, тому окремо. Згенерований варіант, який «працює»:
// ❌ Дані користувача склеєні із запитом – SQL-ін'єкція
async function findUser(email: string) {
return db.query(`SELECT * FROM users WHERE email = '${email}'`);
}Введи в поле ' OR '1'='1 – і запит поверне всіх користувачів. Виправлення завжди одне – параметризація:
// ✅ Дані передаються окремо від коду запиту
async function findUser(email: string) {
return db.query('SELECT * FROM users WHERE email = $1', [email]);
}Модель знає правильний варіант і згенерує його, якщо попросити. Проблема в тому, що вона згенерує і неправильний – із тією ж упевненістю. Тому пункт чекліста, а не сподівання.
Як вбудувати чекліст у процес
Чекліст, який лежить у нотатках, не працює. Що працює:
- PR-темплейт. Додай пункти в шаблон pull request – тоді перевірка відбувається там, де ти й так дивишся diff.
- Питання моделі наприкінці генерації. Стандартне завершальне повідомлення: «пройдись по цьому коду за чеклістом: edge cases, безпека, дублювання з кодовою базою». Модель – непоганий перший фільтр власних помилок; ти – другий і вирішальний.
- Правило двох читань. Перше читання – «що цей код робить», друге – «як його зламати». Друге читання і є рев'ю; без нього перше – просто ознайомлення.
Готовий чекліст для копіювання
## AI-код: перевірка перед комітом
- [ ] Порожні значення: [], '', null, undefined, 0 – поведінка визначена
- [ ] Межі: перший/останній елемент, off-by-one
- [ ] Асинхронність: помилка запиту, гонки, розмонтування
- [ ] Немає конкатенації даних користувача в SQL/HTML/команди
- [ ] Немає секретів у коді – лише env
- [ ] Кожен новий пакет перевірено на npm (автор, завантаження, свіжість)
- [ ] Не дублює наявні утиліти/компоненти проєкту
- [ ] Відповідає конвенціям кодової бази
- [ ] API звірено з документацією поточної версії
- [ ] Є тест на головний edge case, і я його прочитав
- [ ] У промпт не потрапили секрети/приватні дані
- [ ] Я можу пояснити кожен рядок цього кодуОстанній пункт – найважливіший
«Можу пояснити кожен рядок» – це фільтр, який ловить усе, що пропустили попередні. Якщо рядок незрозумілий, у тебе два чесні варіанти: розібратися або викинути. Третього – «закомітити і сподіватися» – у професійній роботі немає. Ширший контекст, де AI допомагає, а де заважає, – у базовій статті AI для програміста; а системно ставити навичку читання чужого коду найшвидше через регулярні code review з ментором.