Упс! Не вдала спроба:(
Будь ласка, спробуйте ще раз.

Чому одного промпта недостатньо: як зробити AI-розробку надійнішою

Роман Бланяр
Роман Бланяр Full-Stack Developer IdeaSoft
Підписатися на нас
0
8 хвилин читання
Чому одного промпта недостатньо: як зробити AI-розробку надійнішою зображення 1

«Не порушуй зворотну сумісність». «Врахуй усі крайні випадки». «Напиши надійний код». «Будь обережним — це стосується грошей».

Такі інструкції регулярно з’являються у промптах для AI-асистентів, які допомагають розробникам писати код. Вони звучать як чіткі правила. Проблема в тому, що технічно правилами вони не є.

Є простий спосіб це перевірити: запитайте, що станеться, якщо AI проігнорує таку інструкцію. У більшості випадків — нічого.

Тест не впаде. CI-пайплайн не стане червоним. Розробник не отримає автоматичного попередження. Код може виглядати цілком коректно, пройти код-рев’ю і потрапити в production. Саме тут проходить важлива межа між промптом і контрактом.

Промпт описує те, що ми хочемо отримати. Контракт створює умови, за яких порушення правила неможливо залишити непоміченим.

Чому навіть детального промпта недостатньо

Проблема не в тому, що розробники погано формулюють промпти. Навіть дуже детальна інструкція залишається текстом природною мовою, а природна мова допускає інтерпретації. Візьмемо простий приклад: «Не порушуй зворотну сумісність».

Для людини це звучить однозначно. Але що саме вважати порушенням?

Наприклад, AI може перейменувати поле API-відповіді, вирішивши, що нова назва зрозуміліша. З погляду моделі це може бути цілком логічним покращенням. Але клієнтський застосунок, який очікує стару назву поля, просто перестане працювати. І проблема може проявитися не одразу, а через кілька тижнів уже в production.

Друга причина глибша: у промпта немає перевіряльника. Типи перевіряє компілятор. Тести запускає test runner. Вхідні дані можна перевіряти за допомогою runtime validation — перевірки даних під час виконання. А хто перевіряє, чи виконав AI фразу із системного промпта? Часто — ніхто. Тому порушення інструкції може пройти через весь процес розробки абсолютно безшумно.

До того ж промпти змінюються. Їх скорочують, об’єднують, переносять між файлами та переписують. Під час чергового рефакторингу важливе правило можна випадково видалити — і команда навіть не помітить цього.

Підписуйтеся на наші соцмережі

Від побажань до реальних перевірок

Вихід полягає не в тому, щоб писати ще довші та детальніші промпти. Критичні вимоги потрібно переносити туди, де їх можна автоматично перевірити. Умовно це можна описати як чотири рівні: типи, runtime validation, тести та acceptance criteria.

Типи — найдешевший рівень захисту. Вони визначають структуру даних, сигнатури функцій та певні архітектурні межі. Це швидкий спосіб відловити велику кількість простих помилок.

Наступний рівень — runtime validation. Тут система перевіряє вже реальні дані: те, що прийшло з API, бази даних, JSON-запиту або безпосередньо від користувача.

Далі йдуть тести. Вони дозволяють перевіряти не лише структуру, а й поведінку системи: порядок операцій, побічні ефекти, повторні запити або ситуації, коли кілька процесів одночасно працюють з одними даними.

Нарешті, є acceptance criteria — критерії приймання, сформульовані мовою бізнесу. Наприклад: «Переказ понад встановлений ліміт не може бути виконаний лише з одним погодженням». Це вже не абстрактне «будь обережним із грошима». Це конкретна умова, виконання якої можна перевірити перед тим, як зміна потрапить у production.

Рівні впорядковані від дешевих до дорогих: типи швидкі й широкі, але поверхові; acceptance criteria — найповільніші й найвужчі, зате єдині, що говорять мовою бізнесу. І тут криється найпоширеніша помилка — зупинитися на першому рівні й вважати, що контракт готовий. Типи — це те, з чого контракт починається, а не те, чим він закінчується.

Як перетворити промпт на контракт

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

«Не порушуй зворотну сумісність» перетворюється на contract test, який порівнює нову реалізацію зі схемою попереднього релізу. Додали нове поле — тест проходить. Перейменували старе — CI падає.

«Врахуй усі крайні випадки» перетворюється на конкретний список сценаріїв, які справді важливі для продукту, з окремим тестом для кожного. Адже «всі крайні випадки» неможливо перевірити. А сім конкретно визначених сценаріїв — можна.

«Напиши надійний код» перетворюється на валідацію вхідних даних плюс визначену поведінку системи при повторному запиті. Ідемпотентність операції можна перевірити тестом. Надійність узагалі — ні.

«Будь обережним — це стосується грошей» перетворюється на конкретний acceptance criterion, який перевіряє фінансовий інваріант. Для критичних операцій із грошима або авторизацією принцип може бути максимально простим: немає названого критерію — немає merge.

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

Іноді найкращий контракт — це кілька рядків коду

Показовий приклад — правило, за яким frontend API client повинен автоматично генеруватися зі схеми backend і ніколи не писатися вручну. Команда знала це правило. Воно було записане у внутрішній документації. Його додали й до системного промпта AI-асистента. І все одно його порушували.

Не через недбалість. Розробник працює над функціональністю, бачить, що згенерований метод не зовсім підходить, і вирішує, що швидше написати один API-виклик вручну. AI робить рівно те саме і рівно з тієї ж причини.

Але достатньо було додати просту CI-перевірку, яка завершується помилкою, якщо в певній директорії з’являється написаний вручну API-виклик. Тридцять секунд роботи — і жодного порушення відтоді.

Саме правило при цьому не стало зрозумілішим. Воно стало обов’язковим до виконання.

І це важлива деталь у контексті AI-розробки. Хороший контракт не повинен залежати від того, хто написав код — людина чи модель. Якщо правило застосовується лише до AI, це, швидше за все, не контракт. Це побажання.

Чи означає це, що промпти не потрібні?

Ні. Промптинг залишається важливою частиною роботи з AI, особливо в розробці. Просто промпти добре вирішують інший клас завдань. Вони можуть задавати напрямок, пояснювати контекст, описувати бажаний стиль коду, допомагати AI обирати між кількома допустимими рішеннями або визначати рівень деталізації відповіді.

Тобто промпт чудово підходить для того, щоб спрямовувати модель. Але критичні вимоги — безпека, гроші, авторизація, сумісність, структура даних або ключова бізнес-логіка — потребують механізмів, які можуть автоматично сигналізувати про порушення. Інакше команда фактично покладається на те, що модель правильно зрозуміє текстову інструкцію і вирішить її виконати. У міру того як AI пише дедалі більшу частину production-коду, ця різниця стає особливо важливою.

Тому замість нескінченного розширення системних промптів варто поставити простіше запитання: які з наших інструкцій насправді є критичними правилами — і що станеться, якщо AI їх порушить?

Якщо відповідь — «нічого», це ще не контракт. Промпт — це побажання. Контракт — це те, що може впасти. Саме тому найнадійніші правила для AI часто варто писати не природною мовою, а мовою типів, валідації, тестів і CI.

Роман Бланяр, Full-Stack Developer IdeaSoft

Якщо ви хочете поділитися з читачами SPEKA власним досвідом, розповісти свою історію чи опублікувати колонку на важливу для вас тему, долучайтеся. Відтепер ви можете зареєструватися на сайті SPEKA і самостійно опублікувати свій пост.
0
Icon 0

Підписуйтеся на наші соцмережі