Код владеет порогом, модель даёт только вероятность
Поставьте рядом несколько сотен реальных проектов, и самая устойчивая общая черта такая:
Модель отвечает «насколько вероятно». Ваш код отвечает «достаточно ли этого».
Это не вопрос стиля. Это единственный безопасный вывод из того факта, что самозаявленной уверенности доверять нельзя — и за этим стоят независимые измерения в Можно ли доверять вероятностям.
Как это выглядит конкретно
Choice и Score возвращают ответ с прикреплённой confidence; Noul возвращает
вероятность от 0 до 1 напрямую. Сам интерфейс за вас не выносит суждение —
порог ваш. В реальных проектах это превращается во что-то очень конкретное:
- Фильтр нецензурной лексики на Cloudflare Worker держит свой порог, свою политику агрегации
max()и свою публичную схему OpenAPI целиком в коде Worker’а. Модель — просто одна функция, которую он вызывает. - Расширение для браузера, скрывающее комментарии, держит 0.85 / 0.7 / 0.5 зашитыми в расширении и остаётся скрытым, когда проверка не проходит — это предпочтение тоже часть политики порогов.
- Инструмент триажа инцидентов определяет «разбудить кого-то» как
P(SEV1) + P(SEV2) ≥ 0.80, и это 0.80 живёт в его собственном конфиге, а не в модели.
Все три делят одно свойство: замените модель — порог не сдвинется; перенастройте порог — модель не сдвинется. Отдайте порог модели, и эти две вещи станут одной — и тогда «настроить мой порог» означает редактировать промпт.
Почему принцип важен
Потому что он держит два рода отказов порознь:
- Модель ответила плохо — меняйте вопрос, меняйте состояние, меняйте модель.
- Порог задан плохо — меняйте число в коде.
Смешайте их, и «точность недостаточно хороша» может быть и тем и другим, без способа понять, чем именно. Инструмент триажа может вписать 0.80 прямо в конфиг именно потому, что это число можно рассмотреть само по себе.
Контрпример, который нужно знать
Принцип опирается на одно допущение: что число, которое вы получаете, — калиброванная вероятность.
Независимый пересчёт обнаружил, что confidence, возвращаемая для вопросов Score,
часто представляет собой просто дробную часть score, причём эти выводы плотно
сгруппированы (121 из них). Это не «модель уверена» — это похоже на значение,
выведенное из самого score.
Разница важна:
- Если это калиброванная вероятность, 0.85 поддерживает рассуждение «я буду прав примерно в 85% таких случаев».
- Если это функция score, 0.85 означает лишь «этот набрал высоко» и ничего не говорит о том, как часто он прав — а задать на нём порог значит задать планку для числа без вероятностного смысла.
Отдельно, отчёт о независимом измерении проверил самозаявленные поля модели против истины и обнаружил, что значения куда менее гранулярны, чем предполагает описание (см. Публичная критика).
Что делать вместо этого
Три шага, и порядок важен:
- Используйте порог операционально, а не семантически. Означает ли 0.8 «80% верных» — неважно. Важно то, на ваших данных, измеримо ли случаи выше 0.8 точнее. Это вы можете проверить на отложенной выборке.
- Подбирайте порог на своих метках. Инструментарий существует ровно для этого: возьмите свои размеченные данные, подберите порог для каждого вопроса, достигающий вашей целевой точности, проверьте на отложенной выборке — и ломайте CI, когда обновление модели ломает зафиксированный порог.
- Впишите порог в код и дайте ему дату пересмотра. Пороги устаревают вместе с версиями модели, как цены. Это то, на что человек должен взглянуть снова, а не то, что вы задали один раз.
В одном предложении
Надёжность модели должна проявляться в вашем пороге, а не в её собственном заявленном числе. Первое вы можете измерить на своих данных; второе — нет.