Двадцать примеров: почему их хватает и когда не хватает
Совет «соберите двадцать примеров для оценки» звучит как выдумка. Я посчитал: он верен, но по причине, которую обычно не называют, — и у него есть слепая зона.
Совет кочует по всем руководствам: соберите два десятка примеров, гоняйте их после каждой правки промпта. Звучит как число, взятое с потолка, и я долго относился к нему именно так.
Потом посчитал. Число оказалось разумным, но не по той причине, которую обычно приводят, — а вместе с расчётом стало видно, чего эти двадцать примеров не увидят никогда.
Двадцать примеров как выборка — это ничто
Начнём с того, как совет понимают чаще всего: «двадцати примеров хватает, чтобы оценить качество».
Не хватает. Возьмём наблюдение 18 успехов из 20 — то есть 90%. Насколько точно мы знаем это число? Доверительный интервал Уилсона на 95%:
| Примеров | Наблюдали | 95% интервал | Ширина |
|---|---|---|---|
| 10 | 9/10 | 59.6% — 98.2% | 38.6% |
| 20 | 18/20 | 69.9% — 97.2% | 27.3% |
| 50 | 45/50 | 78.6% — 95.7% | 17.0% |
| 100 | 90/100 | 82.6% — 94.5% | 11.9% |
| 300 | 270/300 | 86.1% — 92.9% | 6.8% |
| 1000 | 900/1000 | 88.0% — 91.7% | 3.7% |
При двадцати примерах истинное качество лежит где-то между 70 и 97 процентами. Это не оценка, это диапазон, внутри которого помещается и отличная система, и посредственная.
Хуже с сравнением. Чтобы независимыми выборками отличить 90% от 80% — просадку в десять процентных пунктов, которую любой заметит на глаз в проде, — нужно около 199 примеров в каждой группе. Не двадцать. Двести.
Если бы совет означал то, что в нём слышат, он был бы вредным.
Он работает, потому что сравнение парное
Вся разница — в одном слове, которого в совете обычно нет: те же самые.
Вы не берёте двадцать примеров вчера и двадцать других сегодня. Вы прогоняете один и тот же набор до правки и после. И тогда считать надо не долю успехов, а расхождения: сколько примеров сломалось и сколько починилось.
Примеры, которые вели себя одинаково до и после, из расчёта выпадают целиком — они не несут информации об изменении. Остаются только те, что поменяли поведение. Это тест Макнемара, и он несравнимо чувствительнее, потому что каждый пример служит сам себе контролем: сложность задачи, её формулировка, особенности входа — всё это одинаково в обеих половинах и не мешает.
Порог: шесть
Точный биномиальный тест даёт конкретное число, и оно приятно маленькое. Если все расхождения смотрят в одну сторону — только поломки, ни одной починки, — то:
| Расхождений | p | Значимо при 0.05 |
|---|---|---|
| 3 | 0.250 | нет |
| 4 | 0.125 | нет |
| 5 | 0.0625 | нет, на волосок |
| 6 | 0.031 | да |
| 7 | 0.016 | да |
| 10 | 0.002 | да |
Шесть односторонних поломок — это уже не шум. Пять — почти, но формально нет: 0.0625 чуть больше порога, и это ровно та величина, ради которой стоит прогнать ещё раз, а не делать вид, что доказано.
Обратная сторона того же расчёта отрезвляет. Если сломалось пять примеров,
а починилось четыре — расхождений девять, но они разнонаправленные,
и p = 1.0. Различить такое изменение нельзя вообще. Это тот случай,
когда правка перетасовала поведение, не сдвинув качество, а инженеру
кажется, что он что-то улучшил, потому что он смотрел только на починенные.
Чего двадцать примеров не увидят
Теперь слепая зона, и она большая.
Всё сказанное относится к изменениям — сломалось после правки или нет. С поиском редких ошибок ситуация другая: пример должен сначала попасться.
Вероятность, что ошибка с такой-то частотой не встретится ни разу:
| Частота ошибки | n=20 | n=50 | n=100 |
|---|---|---|---|
| 30% | 0.1% | 0.0% | 0.0% |
| 20% | 1.2% | 0.0% | 0.0% |
| 10% | 12.2% | 0.5% | 0.0% |
| 5% | 35.8% | 7.7% | 0.6% |
| 2% | 66.8% | 36.4% | 13.3% |
| 1% | 81.8% | 60.5% | 36.6% |
Ошибка, срабатывающая в одном случае из ста, проскочит через двадцать примеров с вероятностью 82%. Через сто примеров — всё ещё 37%.
Отсюда вывод, который важнее всех предыдущих: набор для оценки не предназначен для поиска редких ошибок. Он ловит регрессии на частом пути. Редкое ловится другим — журналом продакшена, разбором обращений, мониторингом; и попадает в набор уже после того, как поймано там.
Это, кстати, объясняет, почему набор для оценки положено пополнять из инцидентов. Не «для полноты», а потому что это единственный способ затащить редкий случай внутрь: один раз найденная в проде ошибка, добавленная в набор, становится частотой 1/20 вместо 1/1000 и дальше проверяется на каждом прогоне.
Сколько же собирать
Из расчёта следует практический ответ, и он не «двадцать».
Двадцати хватает, если правка либо ломает заметную долю, либо не ломает ничего: настоящая регрессия даст шесть и больше поломок, и вы её увидите.
Двадцати не хватает, если вы ищете тонкое улучшение. Разница в два-три примера неотличима от перетасовки, и увеличение набора до сотни здесь окупается — на ней те же два-три процента дадут уже десяток расхождений.
Считать надо не примеры, а расхождения. Если после правки их меньше пяти, набор мал для этого вопроса — не потому что двадцать мало вообще, а потому что мало для эффекта такого размера.
Условие несогласия
Всё это применимо, когда «сломалось» и «починилось» — бинарные и определённые. На задачах, где результат оценивается по шкале «стало лучше или хуже», приведённые числа не работают: там нужен либо другой тест, либо разметка нескольких человек, потому что расхождения между оценщиками начнут превышать эффект правки.
И отдельно: статистика ничего не говорит о том, правильные ли примеры вы собрали. Двадцать примеров, взятых из удачных случаев, дадут безупречный прогон и полную слепоту. Набор собирается из провалов и пограничных входов, и никакой расчёт этого не заменяет.
Чего я делать не стал бы
Не стал бы считать долю успехов и сравнивать её между прогонами. На двадцати примерах это самая частая ошибка: 18/20 против 17/20 — это ноль информации, а выглядит как ухудшение на пять процентов.
Не стал бы обновлять набор одновременно с правкой промпта. Тогда непонятно, что изменилось — система или задача. Набор меняется отдельным шагом, и после его изменения предыдущие прогоны для сравнения не годятся.
Не стал бы гнаться за размером набора, пока в нём нет ни одного случая из настоящего инцидента. Двадцать реальных провалов полезнее двухсот придуманных.
Открытый вопрос
Расчёт даёт порог для одной правки. Но правок за неделю десятки, и каждая проверяется на том же наборе — а это множественные сравнения, при которых одно «значимое» ухудшение из двадцати проверок появится случайно примерно с вероятностью 64%. Формально надо поправлять порог; практически никто этого не делает, и я тоже не делаю, потому что цена ложной тревоги здесь — лишний прогон, а не потерянный релиз. Но правильного ответа у меня нет, есть только оправдание.