QASenior

Регресія промптів

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

Порівнюйте
Кейс за кейсом
Завжди закріплюйте
Промпт, модель, індекс
Блокуйте на
Тому, що проходило

Що означає регресія, коли відповідь оцінюють

У звичайному ПЗ регресія однозначна: тест, що проходив, тепер падає. Тут її треба визначити, бо кейс може дати 0,83 сьогодні й 0,79 завтра без жодних змін. Робоче визначення — покейсне й проти порога: кейс регресував, коли на базовій лінії він проходив власний критерій, а тепер не проходить, — і виміряно це на достатній кількості запусків, щоб семплінг не пояснював різницю.

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

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

Порівняння чесне, лише коли решта закріплена

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

Що треба закріпитиЩо станеться, якщо ні
Точний текст промпту, у системі контролю версійНіхто не скаже, що саме працювало, коли записали добрий результат, — тож його не відновити.
Версія моделі, ніколи не аліасВаша система оновлює себе в продакшні без диффу, рев’ю й відкату — схема, якої не терпів би жоден інший ваш компонент.
Параметри семплінгу — температура, top-p, seed, де єРозкид між запусками різний з обох боків порівняння, і виміряна вами різниця — це саме налаштування.
Індекс пошуку та його вмістПереіндексований корпус змінює те, що бачить модель. Промпт дістає хвалу або догану за документ, який приїхав у вівторок.
Схеми інструментів та їхні відповідіПерейменований аргумент тихо прибирає можливість, і симптом виглядає точно як гірший промпт.
Модель судді та її рубрикаВи змінили лінійку. Усі історичні числа стають незіставними — зазвичай так, що ніхто не помічає.

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

Як відрізнити справжню зміну від шуму семплінгу

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

  • Запускайте кожен кейс кілька разів — три як робочий мінімум, пʼять краще на малому наборі — і вважайте кейс пройденим, лише якщо він проходить стабільно, а не одного разу.
  • Виставляйте нульову температуру для оцінювальних запусків, де продукт це дозволяє. Детермінованим вивід від цього не стає, але розкид відчутно вужчає, і малі рухи стають читними.
  • Порахуйте розмір набору, перш ніж вірити дельті. На сорока кейсах один кейс — це два з половиною пункти, тож зсув на три пункти є одним кейсом, що передумав.
  • Звітуйте покейсний дифф як основний артефакт, а середнє — як примітку: дифф відповідає на питання, на яке середнє відповісти не може.

Ворота: що запускається, що блокує, скільки коштує

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

  • Що блокує

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

  • Що попереджає

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

  • Що записується

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

  • Скільки це коштує

    Девʼяносто кейсів по три запуски — це кілька хвилин і пара доларів на пулреквест. Закладайте це явно, інакше хтось тихо це вимкне.

Один сценарій варто відрепетирувати, а не імпровізувати: оновлення моделі. Провайдер оголошує нову версію й виводить стару з експлуатації в певну дату — і це найбільша регресійна подія в житті LLM-фічі. Прожену́вши повний набір проти нової версії, поки стара прив’язка ще працює, прочитайте покейсний дифф, полагодьте зламане й перемкніться в обраний вами день. Команди, що дізнаються про це в дату виведення, роблять ту саму роботу за пів дня, під поглядами користувачів.

Антипатерни, які варто назвати

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

Коли це застосовувати

Застосовуйте, коли

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

Уникайте, коли

  • Порівнювати лише за сукупною оцінкою: це статистика, що приховує зламані кейси.
  • Порівнянь з одного запуску на малому наборі, де один кейс, що передумав, виглядає як покращення на три пункти.
  • Експериментів, де індекс, схеми інструментів чи суддя змінилися одночасно з промптом.
  • Набору, що лише звітує: регресія, на яку ніхто не зобовʼязаний реагувати, — це регресія, що їде в реліз.

Було корисно?

Поділіться з тим, хто працює над тією ж задачею.