Продакшен-фіча на AI, якою я володію, працювала вчора. Сьогодні ламається на кожному четвертому виклику. Код не правили. Промпт не чіпали. Модель не перемикали. Retrieval-індекс не перебудовували. Ніщо в системі, за будь-яким читанням діфу, не зрушило. І все ж чверть відповідей неправильні — тихо впевнено неправильні, так, що жоден користувач не зарепортить баг. Вони просто помітять, що продукт став дурнішим, ніж тиждень тому, і підуть.
Так виглядає життя без evals. І причина, з якої більшість команд, що відвантажують AI у 2026, досі без evals, у тому, що дисципліна складніша, ніж здається, дорожча, ніж виглядає, і не дає задовільної зеленої галочки. Це також єдина інженерна практика, що відділяє команди, які відвантажують AI-продукти, від команд, які відвантажують AI-демо.
Це третя опора трилогії. Контекст-інжиніринг — це те, що рантайм збирає в момент виклику моделі. Spec-driven development — це те, що пише команда, з чого рантайм потім збирає. Evals — це те, як ви дізнаєтеся, що хоч щось із цього працює. Без третьої опори перші дві складаються — специфікація стає вірою, контекст — театром, а ваша «AI-фіча» — штукою, яка тричі відпрацювала на демо.
Теза жорсткіша, ніж людям зручно. Якщо ви відвантажуєте AI-фічі без evals, у вас не продукт. У вас демо з користувачами.
Чому традиційне тестування не працює
У кожного інженера, який це читає, тридцять років інтуїції тестування побудовані на одній несучій передумові: тестована система детермінована. На одному й тому самому вході вона дає той самий вихід. Юніт-тест — це пара (вхід, очікуваний вихід), яку можна прикріпити до коміту і ганяти вічно.
Ця передумова тепер невірна для значущого шматка вашої кодової бази.
Виклик моделі — це не функція. Це розподіл імовірностей по виходах, з якого береться вибірка. Два ідентичні виклики дають різні рядки, обидва потенційно валідні. Виклик, який дав правильну відповідь у березні, у квітні може дати іншу правильну відповідь — або неправильну, — бо Anthropic, або OpenAI, або ваш retrieval-індекс, або ваш системний промпт, або описи інструментів, або версія моделі, або max_tokens, або температура зсунулися на волосину. Уся модель піраміди тестування — юніт, інтеграція, e2e, все зелене, відвантажуємо — стояла на передумові, яка тепер тільки частково вірна. Шар юніт-тестів на дні піраміди працює для всього нижче межі моделі. Вище неї піраміда перевертається і поводиться дивно.
Спокуса — відмахнутися. «Поставимо температуру в нуль і напишемо асерти». Це купує приблизно три тижні хибної впевненості. temperature=0 — це не детермінізм, це низька дисперсія. Порядок tool-викликів усе одно плаває. Retrieval може повернути різні чанки на той самий запит, бо в індексі з’явився новий документ. Модель за API-ендпоінтом може оновитися без попередження. Ілюзія детермінізму — це те, що робить баг, коли він приходить, нерозслідуваним.
Evals — це дисципліна навмисного тестування недетермінованої системи правильними інструментами. Це не юніт-тести з зайвими кроками. Це інша форма.
Що таке eval насправді
Eval — це трійка (вхід, твердження про поведінку, рубрика оцінки), яка проганяє усю систему — виклик моделі, інструменти, retrieval, історію, все, — і оцінює вихід проти рубрики, толерантної до природної дисперсії системи, але водночас ловить реальні регресії.
У зрілих кодових базах трапляються чотири форми, і вони лежать на спектрі від «дешево і крихко» до «дорого і чесно».
| Форма | Що робить | Коли використовувати | Вартість | Що ловить |
|---|---|---|---|---|
| Рядкове / regex-співпадіння | Перевіряє наявність або відсутність літеральних патернів у виході | Відмови з високою ставкою, формати фіксованої форми, наявність структурних полів | Безкоштовно | Катастрофічні промахи, поломки формату |
| Структурна перевірка полів | Парсить вихід як JSON/XML і ассертить конкретні поля | Форма tool-викликів, schema-bound виходи, лейбли класифікації | Дешево | Дрейф схеми, переворот лейблів, криві відповіді |
| LLM-as-judge | Друга (зазвичай сильніша, від іншого вендора) модель оцінює вихід за рубрикою | Відкриті виходи, тон, корисність, багатокритеріальна якість | Середньо ($) | Регресії якості, тонкий дрейф, поломки персони |
| Рев’ю людиною | Реальна людина оцінює вибірку | Калібрування еталону, калібрування моделі-судді, нові моди відмови | Дорого ($$$) | Усе інше; підлога, відносно якої ви калібруєте інші форми |
Помилка — вибрати одне і вважати достатнім. Рядкові співпадіння майже безкоштовні, але майже нічого не кажуть про те, чи добрий вихід — лише про те, що він не катастрофічно зламаний. LLM-as-judge ловить нюанси, але успадковує упередження і моди відмови своєї моделі. Рев’ю людиною — єдина чесна відповідь на «це взагалі добре?», але не масштабується до CI. Зрілі eval-сьюти шарують усі чотири: дешеві перевірки гейтять кожен прогон, LLM-судді семплують відсоток, люди калібрують суддю проти відкладеного золотого набору з квартальною періодичністю.
Чотири шари evals
Пастка, у яку я спостерігаю команду за командою, — думати, що eval — це одна річ. Це щонайменше чотири, і кожен шар ламається по-своєму, якщо його пропустити. Фрейм паралелить п’ять шарів контексту навмисно — читачі, які засвоїли той фрейм, можуть користуватися ним і тут.
Capability evals. Чи робить сама модель потрібне взагалі, в ізоляції? Це ті evals, які ганяють Anthropic і OpenAI, щоб вирішити, чи може нова модель замінити попередню. Ви їх не пишете. Ви їх споживаєте — і звертаєте увагу, коли model card публікує оцінки, які матеріально зсунулися на бенчмарку, близькому до вашого випадку. Capability evals — це нульовий поверх. Якщо модель не може задачу сама, ніякий контекст-інжиніринг не врятує.
Behavior evals. Враховуючи ваш промпт і ваш контекст, чи видає модель потрібну форму? Це шар, на якому зупиняється більшість команд, і він найдешевший. Behavior evals ловлять «у JSON правильні поля», «відмова спрацьовує, коли має», «модель обирає інструмент A, а не B». Якщо ганяєте лише один шар — ганяйте цей. Але behavior evals недостатньо — вони верифікують форму, не суть.
System evals. Чи дає увесь пайплайн — retrieval, планування, tool-виклики, історія, сумаризація, відмова, все, — правильний end-to-end результат на реалістичному вході? System evals — там, де живе більшість реальних багів. Retrieval повернув не той чанк. Сумарізатор історії викинув обмеження. Планувальник викликав потрібний інструмент із невірними аргументами. Behavior eval на кожному компоненті пройшов; end-to-end поведінка впала. Більшість команд ніколи не ганяли system eval. Це видно.
Regression evals. Коли щось змінюється — правка системного промпту, новий інструмент, бамп версії моделі, ребілд retrieval-індексу, твік Claude.md — які раніше прохідні приклади тепер падають? Regression evals — це шар, що ловить «відвантажили правку промпту у вівторок і тихо зламали 12% клієнтських флоу». Без regression evals ви не знаєте, що зламали ваші зміни. Дізнаєтеся від користувачів. Потім дізнаєтеся, що зміна, яку ви звинувачуєте, — не та, що зламала, бо за тиждень відвантажили три зміни. Regression evals — єдиний найвищорукоятний шар, щоб додати, якщо його немає.
Патерн: більшість команд роблять часткові behavior evals, ніяких system evals і ад-хок regression. Команди, які відвантажують надійні AI-фічі, роблять усі чотири, з чіткою історією володіння кожним.
Чотири складні проблеми eval-інжинірингу
Навмисне віддзеркалюючи фрейм контекст-інжинірингу: дисципліна зводиться до чотирьох проблем, що випливають на кожній нетривіальній AI-фічі. Жодна не вирішується додаванням eval-кейсів. Усі чотири — системно-інженерні.
Покриття: як ви знаєте, що ваш eval-набір представляє те, що реально роблять користувачі?
Eval-набір, який ви написали на перший день, заснований на входах, які ви уявили, що користувачі слатимуть. Реальні входи відрізняються способами, яких ви не передбачили — інша довжина, інші мови, інша ввічливість, інші спроби зламати систему, інші домени, про які ви не думали. Eval-набір, що не відображає продакшен-трафік, — це декорація.
Команди, які це вирішують, ставляться до курування eval-набору як до продовжуваної data-pipeline задачі. Санітизовані продакшен-промпти безперервно семплюються в набір. Крайові випадки, що одного разу зламалися, закріплюються. Набір росте; старі кейси прунять, коли вони перестають бути репрезентативними; покриття міряється проти реального розподілу трафіку. Команди, які так не роблять, пишуть двадцять кейсів на перший день, відвантажують і дивуються, коли система ламається на двадцять першому.
Стабільність: як відрізнити реальну регресію від шуму?
Недетермінована система дає різні відповіді на кожному прогоні. Ваш eval-скор плаватиме навіть без змін під капотом. Частина цієї флуктуації — безглузда дисперсія; частина — передній фронт реальної регресії, яку треба ловити. Розділяти ці дві речі важче, ніж здається.
Відповідь статистична, не алгоритмічна. Проженіть кожен eval-кейс N разів (5–20 залежно від вартості), агрегуйте і беріть pass-rate (не pass/fail) як метрику. Ставте пороги, тримаючи в умі дисперсію: перехід з 95% на 92% за один прогон — шум; стійкий перехід з 95% на 85% за три прогони — регресія. Це ближче до дисципліни A/B-тестів, ніж до дисципліни юніт-тестів. Інженери, які раніше не робили experiment design, знаходять цей шматок найнезручнішим.
Вартість: як ганяти тисячу evals і не розоритися?
Кожен eval-прогон — це один або більше виклик моделі. Серйозний eval-сьют — скажімо, триста кейсів, п’ять семплів на кожен, LLM-as-judge зверху — це півтори тисячі викликів моделі за прогон, плюс по два на кейс (тестована система плюс суддя), разом три тисячі викликів. За реалістичними цінами 2026 це нетривіальний рахунок за CI-білд. Ганяйте на кожному PR — і до кінця кварталу отримаєте питання від фінансів.
Зрілі команди тіерять сьют: маленький smoke-набір ганяється на кожному PR, повний сьют — уночі на main, найбільший LLM-суддя семпл — щотижня. Критичні шляхи отримують більше семплів; long-tail кейси — менше. Вартість — це бюджет, яким явно керують так само, як хвилинами CI. Команди, які не тіерять, або не ганяють нічого, або безглуздо палять гроші.
Дрейф: що відбувається, коли ваші золоті відповіді застарівають?
Відповідь, вірна у лютому, може бути невірна у травні, бо продукт змінився, дані змінилися, політика змінилася або світ змінився. «Податкова ставка минулого року» більше не правильна відповідь. «CEO компанії X» оновлюється без попередження. Ваш eval-набір гниє, якщо його не підтримувати. І гниль невидима, поки прохідний eval насправді не тестує невірну поведінку.
Дисципліна двоєдина: де можливо — пиньте золоті відповіді до дати і джерела, і рев’юйте eval-набір за розкладом. Останнє звучить нудно; так і є. Це також єдиний спосіб тримати набір чесним. Вважайте підтримку eval-набору повторюваною інженерною статтею бюджету, а не разовою інвестицією.
П’ять правил, вивчених у продакшені
Пронумеровані, бо зароблені, а не виведені.
1. Реальні промпти, ніколи не синтезовані. Найчастіша помилка, яку я бачу, — команди наповнюють eval-набір промптами, які написали самі, у голосі, яким, як вони уявляють, говорять користувачі. Реальні користувачі так не говорять. Вони друкарські помилки роблять. Вставляють markdown. Включають нерелевантний контекст. Обривають речення на півслові. Eval-набір, побудований з уявних входів, розповідає про уявну систему, не про вашу реальну. Завжди засівайте набір санітизованим продакшен-трафіком. Завжди.
2. LLM-as-judge потрібна інша модель. Спокуса — оцінювати вихід Claude за допомогою Claude. Дешевше і промпт знайомий. Це також зворотний зв’язок, який лестить вашій системі. Використовуйте іншу модель, ідеально від іншого вендора, для судді — а на evals з високими ставками використовуйте модель сильнішу за ту, яку оцінюєте. Та сама родина, що оцінює себе, ловить форму, не суть. Крос-вендорне оцінювання ловить речі, у яких родина колективно слабка.
3. Вважайте eval-дрейф багом, а не шумом. Коли раніше прохідний eval починає падати без зміни коду, лінива реакція — повторити, побачити, що пройшов, і пройти повз. Доросла реакція — розслідувати. Щось зрушило — модель за API, ваш retrieval-індекс, апстрім-залежність. «Наступного разу пройшов» — не закритий тікет. Тихо деградуючі продакшен AI-фічі майже завжди спершу виглядають як тихий eval-дрейф; команда, що навчилася ганятися за дрейфом, ловить інциденти на три тижні раніше команди, що ні.
4. Ганяйте regression evals на змінах промпту і контексту, а не лише при свопі моделі. Більшість команд із хоч якоюсь регресійною дисципліною ганяють її лише при зміні версії моделі. Правка системного промпту в два слова може уронити тридцять evals — і уронить. Новий інструмент у тулбоксі може зламати tool-routing на входах, що не мають до нього жодного стосунку. Реорганізований AGENTS.md може змінити, як модель інтерпретує кожен промпт. Вважайте кожну зміну в контекстному пайплайні кандидатом на регресію і гейтьте її eval-сьютом так само, як гейтите код тестами.
5. Evals належать CI. Якщо вони не блокують, вони декорація. Нічний eval-звіт, який ніхто не читає, — не eval-сьют. Дашборд із червоними квадратами, що все одно відвантажується, — не eval-сьют. Увесь сенс evals у тому, що вони запобігають потраплянню регресій у продакшен — а отже, мають блокувати. Так, це важко. Так, дисперсія робить це важчим. Так, питання вартості реальне. Вирішуйте ці проблеми замість проблеми «прибрати гейт». Команда, яка не гейтить, робить eval-театр, не eval-інжиніринг.
Де це все-таки ламається
Я б продавав щось, залишивши лише це. Evals необхідні; вони недостатні; і є реальні випадки, де дисципліна не застосовується чисто.
- По-справжньому відкриті виходи. «Напиши вірш про втрату». Рубрики немає. LLM-as-judge може оцінити тон і дотримання обмежень, але не може оцінити хороший вірш. Для таких поверхонь evals ловлять підлогу (безпека, формат, довжина), а стелю володіють люди. Удавати інакше — це evals, які оцінюють середнє і карають виняткове.
- Багатоходові root-cause задачі. Семиходовий агентський ран падає на ході сьомому. Причина — помилка стану на ході другому. Eval флагить падіння на сьомому, але діф між прохідним і падаючим трейсом захований на п’ять ходів углиб. Потрібні trace-level evals — що оцінюють пайплайн, не лише фінальний вихід, — і у більшості команд немає тулінгу. Чесна відповідь у 2026 — тулінг multi-turn evals ще винаходиться; очікуйте, що поле інвестує туди далі.
- Вартість на найбільших сьютах. Серйозний eval-сьют серйозного AI-продукту може коштувати дорожче за CI-прогон, ніж увесь решта CI. Хитрого трюку, що це прибере, не існує. Вартістю керують тіерами, семплінгом і бюджетною дисципліною — або приймають, що покриття обмежене рахунком.
- Eval-набір як продукт. Сам eval-набір стає штукою, якою ви володієте, версіонуєте, рев’юєте і підтримуєте. Це ще одна кодова база, схована всередині вашої кодової бази. Команди, які не ставляться до цього серйозно, закінчують папкою з протухлими асертами, яку всі ненавидять ганяти. Команди, які ставляться до eval-набору як до першокласного артефакту — володіного, рев’юваного, рефакторованого, — отримують компаундну віддачу.
Чесна рамка: evals не підлягають обговоренню для відвантажуваних AI-продуктів у 2026, і вони важчі, ніж звучать. Команди, які володіють дисципліною, обганяють команди, які не володіють, не тому що інженери кращі, а тому що вони насправді знають, що відвантажують.
Кар’єрний кут: eval-інженер — нова роль
Три шари драбини, три різні ставки.
Джуніори. Найшвидший спосіб стати корисним на AI-команді — вибратися володіти eval-набором. Ніхто не хоче. Робота невдячна. Це також те місце, де ви вчите систему, виявляєте реальні моди відмови, і де сеньйори помітять вашу роботу, бо ви ловите їхні баги раніше за користувачів. Інженер, який прийшов на першому році і побудував реальний eval-сьют для реальної фічі, робить корисніщу роботу, ніж інженер поруч, що відвантажив удвічі більше рядків агентського коду. Важіль компаундиться так само, як з тестами, тільки сильніше, бо ціна пропущеної регресії вища.
Мід-левели. Кар’єрний ризик реальний. Якщо останні три роки ви ставали кращими у написанні AI-фіч і пропустили eval-дисципліну — ви інженер гірший, ніж думаєте. Відновлювальний хід — узяти найфлакі AI-фічу на команді і володіти її eval-сьютом end-to-end на квартал. За три місяці eval-роботи ви вивчите про продакшен-AI більше, ніж за рік фіча-роботи. Ви також будете єдиною людиною на команді, яка вміє відповісти «воно працює?» чимось крім вайбів — а це питання, що задають у кімнатах, де відбуваються підвищення.
Сеньйори і стафф. «Покажіть ваш eval-сьют» — це нове «покажіть ваш test coverage». Це питання, яке я тепер задаю на кожному AI-інженерному співбесіді, і якість відповіді каже про кандидата більше, ніж будь-який інший сигнал. На вашому рівні робота не у написанні evals — у володінні дисципліною. Установити планку, що блокується. Побудувати крос-функціональний м’яз, щоб тримати human review у петлі. Переконати фінанси профінансувати eval-рахунок. Домовитися з продактом відвантажувати з гейтом за pass-rate evals, а не за датою запуску. Це політичні і архітектурні задачі, замасковані під задачі тестування, і саме це робота, за яку платять сеньйорам.
Ринок не наздогнав. Кількість інженерів, здатних побудувати серйозний eval-сьют для агентської системи, достатньо мала, щоб хайринг-менеджери, з якими я говорю, описували це як навичку в одноцифрових відсотках. Премія зменшуватиметься, у міру того як дисципліна стає стандартною практикою, тим самим шляхом, що юніт-тестування між 2005 і 2015. Вікно, де ця навичка рідкісна, — це приблизно зараз — вісімнадцять місяців, два роки стеля.
Глибша думка
Специфікація — це істина. Контекст — це збірка. Evals — це доказ.
Це три різні артефакти, три різні дисципліни, три різні групи м’язів. Зрілий AI-інжиніринг 2026 робить усі три. Команди, з якими я працюю і які роблять лише одне, відвантажують демо. Команди, що роблять дві, відвантажують продукти, що тихо деградують. Команди, що роблять усі три, відвантажують продукти, які продовжують працювати — що виявляється єдиною фічею, яку може розрізнити хтось поза інженеркою.
Рамка, яку я найдовше внутрішньо приймав, така: у недетермінованій системі тест-сьют — це те, що робить систему реальною. Без evals ваша AI-фіча — це середнє трьох демо і ваша надія. З evals — це система, яку ви реально розумієте. Різниця — це різниця між інженером і екскурсоводом.
Якщо хочете глибше, курси нижче покривають частини дисципліни, які я викладаю найчастіше: Building LLM-Powered Apps: RAG & Agents для дизайну system-evals по retrieval і агентських пайплайнах, Building with Claude API: Production AI Apps with the Anthropic SDK для продакшен-рантайму, де evals живуть у CI, Building Agents with the Claude Agent SDK для тулінгу multi-turn агентських evals, і Claude Code Mastery: Agentic Coding for Engineers для щоденного воркфлоу поводження з eval-сьютом як з першокласним артефактом поруч зі специфікацією і контекстним пайплайном.