~ / посты / probability-instead-of-self-assessment

Вероятность вместо самооценки_

агенты отказ

Хотел, чтобы разбор банковской выписки сам раскладывал строки по конвертам и честно говорил, когда не уверен. Классификация делалась генерацией JSON с полем confidence, и порог «уверенно / спросить человека» опирался на это поле.

Споткнулся 20 сентября: модель с confidence 0,9+ отправила курсовую разницу в налоговый конверт. Уверенность она придумала сама — это слово в JSON, а не измерение. Модель, которая пишет «0,95», ничего не считала: она продолжила текст самым правдоподобным образом. Порог на такой цифре — фикция.

Идею подсказал внешний «сервис решений»: варианты — метки, ответ — распределение. Сам сервис не подошёл: весов не отдаёт, а строки выписки наружу отправлять нельзя. Но принцип переносится на локальный рантайм.

Решил сделать отдельный примитив решения. Варианты получают однобуквенные метки; грамматика llama-server ограничивает ответ одним токеном; из logprobs этого токена получается распределение — вероятность считает код, а не модель словами. Порядок вариантов перемешивается, ответ усредняется по двум прогонам, чтобы модель не хватала «первое попавшееся». Размышление в решениях выключено. Калибровка температурой — своя на пару клиент-задача. Чувствительное идёт только в локальную строгую роль, без облака.

Первый живой вызов: «комиссия банка», p = 0,99, 450 мс. Прогон эталона на синтетике из 24 строк: точность 0,958, уверенных ошибок (p ≥ 0,8 и неверно) — ноль, подобранная температура 0,495.

Чем плачу и что не доказано. Синтетика не доказывает ничего про боевые строки — она нужна, чтобы работали конвейер и калибровка, а не чтобы хвалиться точностью. Реальный набор впереди, и переход клиента на новый путь решается только по нему: уверенных ошибок должно стать меньше, чем на пути с JSON, при не худшей точности. Второе: два прогона вместо одного — дешевле JSON, но не бесплатно. Третье: примитив живёт только на этой машине, и прод от него не зависит.

#агенты #отказ

$ echo "читать серию"

← Все посты