Score доверия к ответу модели: как считать его честно
Показываем, как вводить score доверия к ответу модели: какие сигналы брать из retrieval, проверок и истории ошибок, чтобы не завышать уверенность.

Почему уверенный тон ничего не доказывает
Модель умеет звучать спокойно и убедительно даже тогда, когда ей почти не на что опереться. Ей не "неловко", если retrieval принес мало документов, факты устарели или часть ответа она достроила по шаблону. Для пользователя это ловушка: текст выглядит собранным и потому кажется правильным.
Один и тот же ровный тон скрывает совсем разные сбои. В одном случае модель перепутала дату в документе. В другом выбрала не тот источник. В третьем ответила на похожий вопрос, а не на тот, который ей задали. Снаружи все три ответа звучат одинаково уверенно, хотя риск у них разный.
Команда обычно замечает это поздно. Пока в системе нет отдельного score доверия, риск всплывает после жалобы, ручной проверки или странного действия пользователя. До этого в логах лежит "нормальный" ответ без явного сигнала тревоги. Такой режим дорогой: ошибки копятся тихо, а разбор начинается уже после инцидента.
Пользователь тоже редко отличает гладкий текст от точного ответа. Если формулировка чистая, без оговорок и пауз, мозг автоматически дает ей больше доверия. Во внутренних системах это особенно опасно: люди ждут быстрый и четкий ответ и не хотят каждый раз сверять первоисточник.
Тон почти ничего не говорит о причине ошибки. Он не показывает, сколько релевантных фрагментов нашлось, согласуются ли они между собой, прошел ли ответ простые проверки и ошибалась ли модель на похожих вопросах раньше. А именно эти сигналы и дают честную оценку уверенности.
Если команда маршрутизирует несколько моделей через единый шлюз, например RU LLM, путаницы становится больше. Ответы приходят в одном формате и выглядят одинаково аккуратно, но слабые места у моделей разные. Без отдельного score легко решить, что все ответы равны по надежности, хотя это не так.
Хорошее правило простое: модель не "объясняет", насколько она уверена. Это считает система вокруг нее. Иначе вы измеряете стиль текста, а не шанс ошибки.
Из чего собирать score доверия
Честный score доверия не берут из формулировок вроде "похоже" или "я уверен". Его собирают из наблюдаемых сигналов, которые можно проверить и потом разобрать по шагам. Иначе команда получает красивую цифру, но не понимает, почему ответу можно верить или почему его лучше отдать на ручную проверку.
Обычно достаточно трех групп сигналов:
- retrieval: что нашлось, насколько это близко к запросу, хватает ли покрытия по теме, нет ли конфликта между найденными фрагментами
- проверки: прошел ли ответ правила, валидацию полей, сверку с фактами, ограничения формата и бизнес-условия
- история ошибок: как эта модель, этот промпт и этот тип задачи вели себя раньше на похожих запросах
Такой разрез полезен по простой причине. Retrieval отвечает на вопрос "у модели была опора или она додумала". Проверки отвечают на вопрос "ответ не сломался по дороге". История ошибок показывает, где система уже ошибалась, даже если текущий ответ звучит гладко.
Не сводите все к одному числу слишком рано. Храните сырые значения: score ретривера, число найденных документов, долю пройденных проверок, тип последней ошибки, частоту исправлений оператором. Потом из них можно собрать итоговый балл, но исходные данные нужны для калибровки, отладки и разбора инцидентов.
Вес каждого сигнала должен быть понятным и привязанным к цене ошибки. Если ответ строится на внутренних документах, retrieval часто весит больше истории. Если вы генерируете строгое JSON-поле для процесса в банке или телекоме, проверки формата и правил обычно важнее семантической близости. Один и тот же набор весов для всех сценариев почти всегда дает перекос.
Полезно задавать веса не "на глаз", а от последствий. Неверная дата платежа и неточный пересказ длинного регламента - это разный риск. В первом случае провал валидации должен резко ронять score. Во втором сильный retrieval может частично это компенсировать, если остальные проверки пройдены.
Пользователю лучше показывать не только итог, но и причину низкой оценки рядом с ответом. Короткая пометка вроде "низкое доверие: найден один слабый источник, проверка сумм не пройдена" полезнее, чем число 0.42 без пояснений. Для внутренних систем это еще и ускоряет разбор: команда сразу видит, проблема в поиске, в правилах или в самой модели.
Если вы работаете через единый шлюз вроде RU LLM, сырые сигналы удобно хранить в одном формате по разным моделям и провайдерам. Тогда вы сравниваете не общие впечатления, а реальные причины ошибок.
Какие сигналы брать из retrieval
Retrieval дает первые признаки того, можно ли вообще верить ответу. Если поиск сработал слабо, модель часто пишет уверенно, но опирается на случайные куски текста. Поэтому score доверия лучше начинать не с генерации, а с качества найденного контекста.
Смотрите сразу на несколько показателей. Один top-1 score легко обманывает: документ может случайно совпасть по формулировке вопроса, хотя по смыслу он мимо. Обычно имеет смысл считать score первого документа, средний score по top-k, разрыв между первым и вторым результатом, пустую выдачу и долю дубликатов в top-k, а еще покрытие ответа источниками.
Разрыв между первым и вторым документом часто говорит больше, чем абсолютное число. Если первый результат заметно выше второго, поиск, скорее всего, нашел явный источник. Если scores почти равны, у вас не один сильный кандидат, а несколько похожих версий. Это повод снижать доверие.
Пустая выдача почти всегда должна опускать score вниз. То же самое с дубликатами. Если retriever вернул пять фрагментов, а по сути это один и тот же абзац из одного документа, модель не получила пять независимых подтверждений. Она получила одно подтверждение, повторенное несколько раз.
Отдельно полезно считать покрытие ответа источниками. Вопрос простой: сколько утверждений в финальном ответе можно привязать к найденным фрагментам. Если модель ответила в шести пунктах, а в контексте есть опора только для трех, высокий score ставить нельзя. Даже хороший retrieval не оправдывает догадки в оставшейся части.
Свежесть документов тоже меняет картину. Для справочника по внутренним правилам документ месячной давности может быть нормальным, а для тарифов, лимитов или регуляторных требований уже нет. Если retriever нашел старую редакцию, score нужно снижать, даже когда текст очень похож на запрос.
Еще один сильный сигнал - конфликт между документами. Если один фрагмент говорит одно, а второй ему противоречит, высокий уровень доверия ставить нельзя. В такой ситуации лучше отдать ответ с пометкой о спорных источниках или попросить человека проверить первичный документ.
Правило простое: retrieval повышает доверие только тогда, когда он нашел свежие, разные и согласованные фрагменты, которые покрывают большую часть ответа. Все остальное не повышает уверенность, а маскирует пробелы.
Что брать из проверок и валидации
Score доверия нельзя считать только по тому, как гладко звучит текст. Намного полезнее смотреть на простые проверки, которые либо проходят, либо нет. Если модель назвала дату, сумму, номер договора или имя, система должна сверить это с источником, а не верить формулировке.
Для ответов с цифрами лучше вообще не полагаться на общий "здравый смысл" модели. Берите поля из найденного документа и сравнивайте их явно: дата совпала, сумма совпала, имя клиента совпало. Если совпадений нет, score нужно снижать заметно, даже если остальной ответ выглядит аккуратно.
Формат тоже важен. Если вы ждете JSON, таблицу или набор полей для CRM, проверка должна смотреть на схему, а не на внешний вид текста. Модель часто пишет "почти правильный" ответ: одно поле пропущено, тип не тот, дата в свободной форме вместо ISO. Для пользователя это уже ошибка.
Отдельный класс сбоев - отказ модели и выдуманные ссылки. Иногда модель отвечает уклончиво, но делает вид, что все в порядке. Иногда ссылается на документ, которого не было в retrieval. Такие случаи лучше ловить отдельными правилами: искать фразы отказа, проверять, что каждая ссылка, цитата или номер документа действительно есть в наборе источников.
На частых запросах полезен короткий эталон. Не идеальный "золотой" ответ на абзац, а компактная проверка смысла. Например, для вопроса о лимите перевода эталон может содержать три пункта: текущий лимит, исключения и дату вступления правила. Если ответ модели не покрыл один из них или придумал лишний факт, score должен падать.
Результаты проверок лучше сохранять по причинам, а не одной общей меткой "не прошло". Удобно держать хотя бы такой набор:
fact_mismatch- факт не совпал с источникомschema_error- формат или тип поля неверныйunsupported_refusal- модель ушла в отказ без причиныfake_citation- ссылка или документ не существуютreference_gap- ответ не покрыл обязательный пункт эталона
Такой разрез помогает и считать score, и чинить систему. Если чаще всего падает schema_error, правьте форматный слой. Если растет fake_citation, усиливайте проверку источников. А если у вас уже есть аудит-трейл на каждый запрос, как в RU LLM, причину провала удобно хранить рядом с ответом и потом разбирать по типам ошибок.
Как использовать историю ошибок
История ошибок нужна, чтобы score доверия опирался на факты, а не на красивый текст. Если модель часто ошибается на одном классе вопросов, прошлые сбои должны тянуть оценку вниз даже тогда, когда текущий ответ звучит убедительно.
Не складывайте все промахи в одну папку. Делите их по типам: фактическая ошибка, неверный формат, пропуск обязательного поля, ссылка на несуществующий документ, ответ не по политике, отказ без причины. Тогда видно, где у модели слабое место, а где был случайный шум.
По каждому сбою полезно хранить несколько полей: тип ошибки, шаблон запроса или кластер похожих запросов, версию модели и промпта, время инцидента и факт правки оператором.
Отдельно смотрите на срывы формата. Для продакшена это частая боль: JSON ломается, поля меняют тип, обязательный блок исчезает, даты приходят в разном виде. Если модель трижды за день сломала один и тот же формат на похожих запросах, это сильный сигнал. Даже хороший retrieval тут не спасает.
Повторы важнее одиночных сбоев. Один неудачный ответ еще ничего не значит. Но если один и тот же вопрос снова приводит к той же ошибке, это уже не случайность, а устойчивый дефект. Такие повторы стоит считать отдельно и штрафовать сильнее. Часто хватает простого правила: первый сбой дает мягкий минус, второй и третий на том же паттерне режут score заметно.
Старые инциденты тоже не равны свежим. Ошибка месячной давности после смены модели может мало говорить о текущем качестве. А вчерашний сбой после релиза говорит много. Поэтому вес инцидента должен убывать со временем. Удобно использовать короткое окно, например 7-14 дней, и более длинный хвост для редких, но дорогих ошибок.
Правки оператора дают особенно честный сигнал. Если сотрудник после ответа модели исправил сумму, статью регламента или статус заявки, это прямое указание на ошибку, даже если формальная проверка ничего не поймала. Сохраняйте не только сам факт правки, но и ее размер: одна исправленная запятая и замена решения по заявке - это разный риск.
На практике правила могут быть простыми: повторяемые ошибки штрафуют сильнее, свежие инциденты штрафуют сильнее, правки человека штрафуют сильнее обычного лога. Тогда история ошибок работает как память системы, а не как архив забытых проблем.
Как считать score по шагам
Если собрать десятки факторов сразу, score быстро превратится в черный ящик. Лучше начать с 5-7 сигналов, которые уже есть в пайплайне и правда влияют на риск ошибки.
Для старта обычно хватает силы retrieval, числа и согласованности найденных фрагментов, проверки на противоречия, результата бизнес-валидатора, свежести источника и частоты прошлых ошибок на похожих запросах. Этого достаточно, чтобы score не выглядел выдуманным.
- Выберите 5-7 сигналов и заранее решите, что для каждого считается хорошим и плохим значением.
- Приведите все сигналы к одной шкале, чаще всего от 0 до 1. Если один сигнал измеряется в процентах, а другой в количестве документов, их нельзя складывать как есть.
- Соберите базовый score из весов. Для старта хватает простой линейной формулы без сложной математики.
- Добавьте жесткие штрафы. Пустой retrieval, провал валидации, конфликт с источником или запрет по политике ответа должны резко снижать итоговый score, а иногда и ограничивать его потолок.
- Проверьте формулу на размеченной выборке и сравните score с реальным качеством ответов. Если ответы со score 0.8 часто ошибаются, формула врет.
Жесткие штрафы обычно полезнее, чем тонкая настройка весов. Если система не нашла ни одного релевантного документа, нет смысла оставлять ответу 0.74 только потому, что остальные сигналы выглядят неплохо. В таком случае лучше сразу уронить score до низкого уровня или отправить ответ на повторный проход.
Для старта подходит простая схема: 60-70% веса дают retrieval и опора на источники, еще 20-30% дают проверки, остальное берет история ошибок. Потом формулу стоит откалибровать на размеченных данных. Подойдет набор вопросов, где команда уже знает, какие ответы были верными, частично верными и неверными.
Внутренний score и то, что увидит пользователь, лучше разделить. Внутри системы можно хранить число 0.00-1.00, штрафы, вклад каждого сигнала и причину снижения. Пользователю обычно хватает трех состояний: "можно использовать", "нужна проверка", "нет надежной опоры в данных". Так команда сохраняет контроль, а интерфейс не делает вид, что различает 0.71 и 0.73 с научной точностью.
Пример для внутреннего помощника банка
Сотрудник банка спрашивает внутреннего помощника: "Какой сейчас лимит по продукту и какая комиссия?" Вопрос простой. Именно на таких запросах модель часто звучит уверенно даже тогда, когда данные спорят друг с другом.
Поиск находит два документа. Первый - карточку продукта, обновленную в марте. Второй - тарифный регламент, который меняли в июне. Оба текста относятся к нужному продукту, но цифры не совпадают: в одном документе лимит 300 000 рублей и комиссия 1,5%, в другом - 500 000 рублей и 2%.
Если ответить сразу, модель легко выберет более свежий документ и скажет цифры как факт. Для пользователя это звучит нормально. Для score доверия такой ответ слабый, потому что retrieval принес конфликт, а не одно ясное основание.
Проверка после генерации должна смотреть не на тон ответа, а на то, на что модель опирается. Система вытаскивает из найденных документов суммы, проценты и даты обновления, а потом сравнивает их между собой. Как только проверка видит расхождение в лимите и комиссии, она снижает балл. Условно: retrieval дал 0.78, но валидация срезала итог до 0.41 из-за конфликта по двум полям.
После этого системе лучше не притворяться точной. Она может попросить уточнить канал или версию продукта, показать оба варианта с датами обновления или перевести диалог на оператора, если клиенту нужен официальный ответ прямо сейчас.
Хороший ответ в такой ситуации звучит проще: "Нашел два документа с разными условиями. Уточните, о какой версии продукта идет речь, или я передам запрос оператору". Это честнее, чем уверенный, но спорный ответ.
В лог стоит записывать, какие документы retrieval поднял, когда их обновляли, какие поля не сошлись, какая проверка сработала и почему система запросила уточнение или позвала оператора. Такой след помогает разбирать ошибки по делу. В банковском контуре это особенно удобно: по аудит-трейлу видно, какой документ повлиял на ответ, где возник конфликт и почему помощник не выдал финальную цифру. Если запросы идут через RU LLM, встроенные аудит-трейлы на каждом запросе упрощают такой разбор без ручного сбора следов из разных систем.
Где команды ошибаются чаще всего
Частая ошибка проста: команда берет logprobs и делает вид, что этого достаточно. Модель пишет уверенно даже там, где у нее нет нормальной опоры на документы, а высокий logprob часто означает только одно - следующий токен выглядел правдоподобно. Если retrieval принес слабые источники, мало релевантных фрагментов или вообще пустой результат, score доверия не должен оставаться высоким.
Вторая проблема - все сигналы склеивают в одно число без расшифровки. На дашборде появляется 0.81, но никто не понимает, откуда он взялся: retrieval сработал хорошо, а валидация провалилась, или наоборот? Такое число трудно чинить и еще труднее объяснять бизнесу, комплаенсу и собственной поддержке.
Нормальный score лучше раскладывать хотя бы на три части: качество найденных источников, результат проверок и поведение модели на похожих задачах в прошлом. Тогда сразу видно, что именно сломалось.
Еще один частый промах - веса настраивают один раз и больше не трогают. Система меняется, документы меняются, промпты меняются, пользователи задают новые вопросы. Если за последний месяц модель стала чаще ошибаться в одном типе запросов, а формула score этого не замечает, вы копите ложную уверенность.
Средний score по всему ответу тоже часто маскирует риск. Допустим, из пяти абзацев четыре нормальные, а один содержит неверную ставку, срок или ссылку на не тот регламент. Среднее число выглядит прилично, но опасен именно один фрагмент. Для операционных сценариев полезнее считать score по кускам ответа и отдельно помечать слабые места.
Есть и более приземленная ошибка: интерфейс показывает число, но не подсказывает действие. Пользователь видит 62% и не понимает, что делать дальше. Намного полезнее короткая подсказка рядом: ответ можно использовать сразу, стоит открыть источники и проверить один фрагмент, нужен уточняющий вопрос или ответ лучше отправить человеку.
Многие команды сначала рисуют красивый индикатор, а честную механику под ним строят потом. На проде такая схема ломается первой.
Чек перед запуском
Перед релизом полезнее не спорить о формуле, а прогнать систему на реальных кейсах команды. Если score доверия нельзя разобрать по частям, он подведет в первом же спорном инциденте.
- Разведите два порога. Один решает, можно ли сразу показать ответ пользователю. Второй решает, когда надо звать оператора, просить уточнение или отправлять запрос на другой маршрут.
- Показывайте причину падения оценки. Команда должна видеть, что именно уронила score: пустой retrieval, слабое совпадение документов, провал проверки фактов, старая версия источника или плохая статистика по такому типу вопросов.
- Останавливайте запрос до генерации, если retrieval пустой или слишком слабый. Это дешевле и честнее, чем сначала получить гладкий текст, а потом объяснять низкую уверенность.
- Храните логи так, чтобы через неделю можно было восстановить весь ход запроса: сам вопрос, найденные документы, их оценки, версию промпта, модель, результат проверок, итоговый score и причины, почему он стал таким.
- Прогоните расчет на старых ошибках. Если система ставит высокий балл на ответах, которые команда уже признала неверными, формула врет. Лучше поймать это до релиза на наборе из 50-100 проблемных кейсов.
Отдельно проверьте, понимает ли это дежурная команда без автора системы рядом. Если инженер не может за две минуты ответить, почему запрос ушел в эскалацию, логов или объяснимости пока мало.
Для команд с несколькими моделями и провайдерами это заметно сразу. Если вы работаете через единый шлюз, полезно логировать не только финальную модель, но и маршрут запроса, потому что ошибки часто прячутся именно там.
Если хотя бы два пункта из этого списка не закрыты, выводить score в интерфейс рано. Сначала доберите наблюдаемость и проверьте расчет на старых сбоях.
Что делать дальше
Если хочется внедрить score доверия быстро, не стройте сразу общую систему для всех задач. Возьмите один сценарий, где ошибка заметна и дорога. Например, ответы на внутренние регламенты, где сотрудник потом все равно сверяет текст с базой знаний.
Хороший первый шаг - разметить 100-200 ответов вручную. Для каждого ответа хватит простых меток: можно ли доверять без проверки, нужен ли просмотр человеком, ответ явно неверный. Такой набор быстро покажет, какие сигналы правда помогают, а какие только создают видимость точности.
Дальше идите от дешевых сигналов к дорогим. Сначала берите то, что у вас уже есть почти бесплатно: число найденных документов, разброс score в retrieval, длину цитаты, наличие пустых полей, сработавшие правила валидации, частоту прошлых ошибок на похожих запросах. Если эти признаки уже хорошо отделяют надежные ответы от слабых, не спешите добавлять сложные проверки и отдельные модели.
Для пилота обычно хватает пяти шагов:
- выбрать один сценарий и собрать небольшой датасет
- посчитать простые сигналы из retrieval, валидации и истории ошибок
- запустить пилот без показа числа пользователю
- использовать score внутри системы для флага, эскалации или отказа от ответа
- записывать причины отказа, ручные правки и итог после проверки
Число лучше не показывать пользователю на первом этапе. Иначе команда быстро начнет спорить о 0.62 против 0.71, хотя вопрос обычно в другом: помог ли score сократить риск. Намного полезнее сначала проверить, стал ли ассистент реже придумывать факты и чаще звать человека там, где сам не справляется.
Отдельно настройте аудит. Сохраняйте не только запрос и ответ, но и причину отказа, сработавшие проверки, версию промпта, версию ретривера и историю правок после ручного просмотра. Через месяц именно эти данные покажут, где score ошибается системно, а не случайно.
Если вы строите LLM-сервис в РФ, заранее продумайте, где вам удобнее вести трассировку и аудит запросов с учетом локального хранения данных. В RU LLM такие вещи уже привязаны к каждому запросу: аудит-трейлы, маскирование PII, хранение логов и бэкапов в РФ. Это не заменяет саму методику score доверия, но заметно упрощает разбор ошибок и проверку спорных ответов.