У класичному програмному забезпеченні «дрібна зміна» в одному місці рідко ламає функцію на десятому екрані. У системах AI ламає, і часто. Змінюєш одне речення в промпті, щоб асистент був «більш лаконічним», а через тиждень виявляється, що він перестав надавати номери справ, бо скоротив і ці фрагменти. Ми ставимося до промпту та конфігурації моделі як до продакшн-коду: версіонуємо їх, тестуємо регресію перед кожним деплоєм і тримаємо шлях для відкату. Без цієї дисципліни зміни в AI — це рулетка, в якій виграш помічаєш одразу, а програш — лише за скаргами клієнтів.
Чому «дрібна зміна промпту» ламає продакшн
Промпт — це не конфігурація, це програма, написана природною мовою, а модель неінтуїтивно чутлива до цієї програми. Перенесення інструкції про формат з кінця на початок, додавання одного прикладу, заміна слова «опиши» на «перелічи» — кожна з цих дій може змістити поведінку моделі в цілій категорії запитів, а не лише в тому, яке ти тестував вручну. Перевірив три випадки, виглядають краще, задеплоїв — і не знаєш, що в четвертій категорії запитань якість впала.
Друга пастка — зміна, яку ти не вносив сам. Постачальник моделі оновлює версію під тією ж назвою, змінюється температура за замовчуванням, бібліотека інакше складає повідомлення. Система, яку ти не чіпав, починає відповідати інакше. Тому фіксація версії моделі та збережена конфігурація так само важливі, як версіонування промпту — контролюєш не лише свої зміни, а й чужі. Без golden set та регресійного тесту такий тихий дрифт виявляєш лише тоді, коли хтось порахує скарги.
Що саме версіонувати
Версіонування в AI не закінчується на тексті промпту. Відповідь моделі — це функція кількох речей одночасно, і кожна з них повинна мати збережене значення, інакше не відтвориш, чому вчора працювало, а сьогодні — ні. Ми розглядаємо весь цей набір як один артефакт з номером версії: зміна будь-якого поля — це нова версія і новий прогін тестів.
| Елемент | Що зберігати | Чому має значення |
|---|---|---|
| Системний промпт і шаблони | Повний текст, хеш, номер версії | Найчастіше джерело тихих регресій |
| Модель та її версія | Точний ідентифікатор, не назва «latest» | Постачальник змінює модель під тією ж назвою |
| Параметри генерації | Температура, top-p, ліміт токенів | Впливають на повторюваність і формат |
| Схема виходу | Визначення structured output | Зміна ламає код, який парсить відповідь |
| Контекст і інструменти | Версія бази знань, список доступних інструментів | Інший контекст — інша відповідь при тому ж промпті |
| Маршрутизація | Правила llm-router | Визначає, яка модель взагалі отримує запит |
Ключове — зв'язати всі ці поля в одну неподільну версію. Якщо версіонуєш промпт окремо від моделі, у разі збою не знатимеш, яку пару відкочувати. Ми присвоюємо всій конфігурації один номер і кожну відповідь у логах позначаємо цим номером — тоді з продакшену можна відтворити точно, що згенерувало даний результат. Той самий підхід ми детальніше описуємо в матеріалі про вибір моделі LLM для завдання.
Регресійні тести на golden set
#Golden set — це набір репрезентативних запитів з позначеним очікуваним результатом або критеріями прийнятності. Він є страхувальною сіткою, яка ловить регресію до того, як вона потрапить до клієнта. Правило просте: жодна зміна промпту чи моделі не йде в продакшн, доки не пройде регресійні тести на актуальному golden set, а результати не будуть порівняні з базовою лінією попередньої версії. Побудову такого набору та вибір метрик ми розкриваємо в тексті про те, як оцінювати систему RAG, а саму перевірку коректності виходів — у статті про валідацію виходів LLM.
Golden set починаємо з 50-100 реальних запитів з логів або звернень, а не з прикладів, вигаданих за столом — останні занадто регулярні й не відображають мову користувачів. Для кожного запиту визначаємо, як виглядає хороша відповідь: іноді це точний результат, частіше — набір фактів, які повинні бути присутніми, і формат, якого потрібно дотримуватися. Важливо, щоб у наборі були й складні та граничні випадки — саме вони регресують першими. Тест запускаємо при кожній зміні й порівнюємо відсоток пройдених запитів з попередньою версією; падіння навіть на кілька пунктів — сигнал зупинити деплой.
Кількості успішних виконань недостатньо без контексту, тому все це пов'язуємо з observability: кожен прогін має збережену версію, результат за категоріями запитів і приклади, які погіршилися. Тоді замість «якість впала» бачиш «категорія запитань про терміни оплати впала з 88 до 71 відсотка після зміни шаблону» — і знаєш, що відкочувати.
Безпечне оновлення моделі: shadow і A/B
#Регресійний тест офлайн ловить багато, але не все — реальний трафік має розподіли, які не відтвориш у golden set. Тому зміни моделі або великої версії промпту впроваджуємо поступово. Режим shadow — це запуск нової версії паралельно зі старою: клієнт бачить відповідь поточної версії, а нова генерує результат «в тіні», лише для порівняння. Нульовий ризик для користувача, а ти збираєш дані про те, як нова версія поводиться на реальному трафіку, перш ніж щось перемикати.
A/B йде на крок далі: спрямовуєш частину трафіку, наприклад 5-10 відсотків, на нову версію і порівнюєш метрики якості та бізнес-показники в обох групах. Це етап, на якому видно речі, невидимі офлайн — час відповіді, вартість, реакції користувачів. Шлюз переходу визначаємо заздалегідь: нова версія отримує весь трафік лише тоді, коли не погіршує ключові метрики порівняно зі старою. Ту саму логіку застосовуємо до маршрутизації звернень, де зміна порогу класифікатора теж може непомітно змістити поведінку.
| Етап впровадження | Що робить | Ризик для клієнта | Що виявляє |
|---|---|---|---|
| Регресійний тест офлайн | Golden set vs базова лінія | Нульовий | Падіння на відомих випадках |
| Shadow | Нова версія паралельно, без експозиції | Нульовий | Дрифт на реальному трафіку |
| A/B на частині трафіку | 5-10 відсотків на новій версії | Обмежений до вибірки | Метрики якості, вартість, час |
| Повне впровадження | Весь трафік на новій версії | Повний, з готовим rollback | — |
Чесний момент: shadow і A/B коштують, бо генеруєш відповіді подвійно або підтримуєш дві гілки. Для невеликих змін промпту зазвичай достатньо самого регресійного тесту офлайн; shadow і A/B залишаємо для змін моделі та перебудови промпту, де ризик реальний. Це компроміс між безпекою та вартістю, а не процедура на кожну описку.
Журнал змін і rollback
#Останній стовп — це слід і шлях повернення. Журнал змін відповідає на питання «що і коли змінилося»: номер версії, дата, автор, які поля торкнулися, результат регресійних тестів і рішення про деплой. Без цього діагностика збою починається з археології — хто, що і чому змінив три тижні тому. З журналом починаєш з одного питання: «яка версія вийшла перед тим, як метрики впали», і відповідь — під рукою.
Rollback має бути підготовлений до того, як він знадобиться. Оскільки вся конфігурація має один номер версії, відкат — це перемикання вказівника на попередню, перевірену версію — секунди, а не години переписування промпту по пам'яті. Тримаємо попередню версію готовою до запуску і визначаємо наперед, що запускає повернення: падіння метрики якості нижче порогу, стрибок вартості або зростання скарг. Те саме мислення застосовуємо в поточному моніторингу якості агента AI, де алерт пов'язується з готовим rollback. Мета одна: кожна зміна в системі AI має бути оборотною та задокументованою, щоб «дрібна зміна» ніколи не була дорогою в один бік.
FAQ
#Чи справді потрібно версіонувати промпти як код?
Так, і з тієї ж причини, що й код: промпт керує поведінкою продакшн-системи, а його зміна має реальні наслідки. Різниця лише в тому, що промпт більш чутливий — зміщення одного речення може змінити відповіді в цілій категорії запитів. Без номера версії та журналу не відтвориш, що і коли змінило поведінку, а діагностика збою перетворюється на вгадування.
Якого розміру має бути golden set?
#Зазвичай починаємо з 50-100 реальних запитів і розширюємо його в міру появи нових типів помилок з продакшену. Важливіша за кількість — репрезентативність: набір має покривати основні класи запитань плюс складні та граничні випадки, бо саме вони регресують першими. Кожен новий інцидент у продакшені — кандидат на додавання до golden set, щоб та сама помилка не повернулася непоміченою.
Навіщо shadow, якщо є регресійні тести офлайн?
#Тому що тест офлайн вимірює на наборі, який ти сам визначив, а реальний трафік має розподіли та формулювання, яких у ньому немає. Shadow запускає нову версію на реальному трафіку без експозиції клієнту, тому виявляє дрифт, невидимий у golden set, до того, як щось перемкнути. Це доповнення до регресійного тесту, а не його заміна — перший захищає від відомих помилок, другий — від невідомих.
Чи може оновлення моделі у постачальника зіпсувати систему без моєї зміни?
Так, і це одне з найпоширеніших джерел тихої регресії. Постачальник може змінити модель під тією ж назвою, а система, яку ти не чіпав, починає відповідати інакше. Тому фіксуємо точну версію моделі замість мітки «latest» і періодично запускаємо golden set, щоб виявити дрифт, на який не маємо прямого впливу.
Як швидко має працювати rollback?
#Повернення до попередньої версії має бути питанням секунд, а не годин — тому вся конфігурація має один номер версії, а попередня, перевірена версія зберігається готовою до запуску. Визначаємо заздалегідь, що запускає rollback: падіння метрики якості нижче порогу, стрибок вартості або зростання скарг. Чим раніше визначиш ці умови, тим менше рішень прийматимеш під тиском під час збою.