Уверенность (confidence) в Jev — как её читать
Вероятности — главное, что отличает Jev от LLM, но их легко понять неправильно. Разбираем, что показывают confidence и probabilities, чего не обещает калибровка и как подобрать пороги на своих данных.
Три числа в ответе
| Тип вопроса | Поле | Что показывает |
|---|---|---|
| Noul | noul |
Вероятность ответа «да», от 0 до 1 |
| Choice, Score | probabilities |
Распределение по вариантам или уровням, в сумме 1 |
| Choice, Score | confidence |
Насколько распределение сосредоточено на одном ответе, от 0 до 1 |
TypeSafe вычисляет confidence из probabilities. Если почти вся вероятность у одного варианта, уверенность высокая, если она размазана по нескольким — низкая. Вот два условных ответа на один и тот же вопрос об отделе:
[
{ "choice": "billing", "probabilities": { "billing": 0.97, "tech": 0.02, "sales": 0.01 }, "confidence": 0.95 },
{ "choice": "billing", "probabilities": { "billing": 0.52, "tech": 0.46, "sales": 0.02 }, "confidence": 0.3 }
]
Оба ответа говорят «billing». Но во втором обращение лежит на границе двух отделов, и код должен это видеть. Числа условные. Все поля ответа описаны в справочнике по API.
У Noul отдельного confidence нет. Исходов всего два, и значение noul описывает распределение полностью: 0,97 означает уверенное «да», 0,5 — что модель не знает.
TypeSafe называет свой confidence удобной мерой по умолчанию и прямо допускает, что для вашей задачи лучше подойдёт другая. Поэтому в ответе всегда есть полный probabilities, и из него легко посчитать, например, разрыв между первым и вторым вариантом:
def margin(probabilities: dict) -> float:
top = sorted(probabilities.values(), reverse=True)
return top[0] - (top[1] if len(top) > 1 else 0.0)
Что обещает калибровка, а что нет
Jev обучена методом RLCD (Reinforcement Learning for Calibrated Decisions). Его цель — откалиброванные вероятности: среди многих ответов с вероятностью 0,8 верными должны оказываться примерно 80%. Как устроен метод и чем он отличается от RLHF, рассказано в статье об RLCD.
Калибровка — свойство группы предсказаний, а не гарантия для отдельного ответа, и TypeSafe пишет об этом прямо. Отсюда три следствия.
confidence0,9 не означает «ошибётся один раз из десяти». Это мера формы распределения, а не вероятность правильности. Автор разбора на Хабре называет такое прочтение ловушкой.- Jev гарантирует, что ответ будет одним из ваших вариантов, но не что он верный. Модель может уверенно выбрать не тот вариант, подробнее — в статье о галлюцинациях Jev.
- Основной язык обучения — английский. Другие языки, по словам TypeSafe, модель обрабатывает хуже, и компания советует внимательнее следить за уверенностью при маршрутизации. Для русских текстов пороги тем более берите из своих измерений.
Низкая уверенность — полезный сигнал
TypeSafe формулирует это так: система, которая не умеет честно сказать «не знаю», не заслуживает доверия. Низкий confidence и есть такое «не знаю», и у него обычно понятные причины.
| Симптом | Вероятная причина | Что сделать |
|---|---|---|
| Вероятность делится между двумя вариантами Choice | Варианты пересекаются по смыслу | Развести описания, добавить «что сюда не относится» |
| Уверенность низкая на целом классе входов | В state не хватает контекста |
Добавить нужные поля или справочные данные |
| Score размазан по соседним уровням | Уровни нечёткие или шкала меряет несколько вещей сразу | Описать уровни ситуациями, разбить шкалу |
| Неуверенные или странные ответы даже на ясных входах | Инструкция и criteria противоречат друг другу, например true у Noul описывает «нет» |
Согласовать формулировки |
Как писать варианты и уровни, чтобы они не пересекались, разобрано в статье о Choice, Score и Noul. Одна оговорка из документации: если после правки описаний уверенность выросла, это ещё не доказывает, что ответы стали точнее. Проверяйте точность на размеченных примерах, а не только рост confidence.
Три пути для кода
TypeSafe предлагает начинать с трёх диапазонов уверенности:
- Высокая. Действовать автоматически.
- Средняя. Действовать осторожно: спросить подтверждение у пользователя, пометить для проверки или собрать больше данных.
- Низкая. Не действовать: передать человеку, уточнить запрос или отправить задачу в другую систему, например в большую LLM. Такая связка описана в статье о каскаде Jev и LLM.
Границы зависят от цены ошибки, причём разные действия в одной системе требуют разных порогов. Пример в духе документации TypeSafe — голосовой банк, где модель определяет намерение пользователя:
action = response.choices["intent"]
if action.confidence < 0.6:
route_to_support_agent() # модель не уверена: не гадаем
elif action.choice == "check_balance":
show_balance() # ошибка дешёвая, 0.6 достаточно
elif action.choice == "approve_transfer":
if action.confidence > 0.85:
approve_transfer() # дорогое действие, высокая уверенность
else:
ask_user_to_confirm() # дорогое действие, нужна проверка
else:
route_to_support_agent()
Показать баланс при уверенности 0,6 допустимо: в худшем случае пользователь услышит лишнюю справку. Перевод денег требует больше 0,85, иначе система переспрашивает. Как строить маршрутизацию по намерениям, рассказано в статье об intent routing.
Как подобрать порог на своих данных
- Возьмите 200–500 реальных примеров и разметьте их вручную.
- Прогоните примеры через Jev и сохраните ответ,
confidenceи версию модели из поляmodel. - Разбейте ответы на корзины по уверенности и посчитайте точность в каждой.
- Найдите уровень, выше которого ошибок столько, сколько вы готовы терпеть. Это порог автоматического решения.
- Посчитайте долю ответов выше порога: столько решений система примет без человека.
from collections import defaultdict
def accuracy_by_bucket(rows):
"""rows — список кортежей (confidence, ответ Jev, правильный ответ)."""
buckets = defaultdict(lambda: [0, 0]) # корзина -> [верных, всего]
for conf, predicted, expected in rows:
b = min(int(conf * 10), 9) # 0.93 -> корзина 9, то есть 0.9–1.0
buckets[b][0] += predicted == expected
buckets[b][1] += 1
for b in sorted(buckets, reverse=True):
ok, total = buckets[b]
print(f"{b / 10:.1f}–{(b + 1) / 10:.1f}: точность {ok / total:.0%}, примеров {total}")
Порог — всегда компромисс. Чем он выше, тем меньше ошибок и тем больше работы людям. Считайте порог отдельно для каждого вопроса и каждого действия, а не один на всю систему.
Следите за размером корзин. Если в диапазон 0,6–0,7 попало пять примеров, точность в нём ничего не говорит: добирайте данные или объединяйте соседние корзины. Если входы разнородные, например письма на русском и на английском или короткие чаты и длинные договоры, стройте таблицу для каждой группы отдельно. Пороги для них могут заметно различаться.
Пороги для Noul
Для Noul логика та же, только порог ставится на само значение noul. TypeSafe советует 0,5, когда ошибки в обе стороны стоят одинаково. Порог выше нужен, когда дорого ложное «да» (возврат денег, вызов дежурного), ниже — когда дорого пропустить «да» (сигнал о небезопасном действии). Середину отдавайте человеку.
Серая зона нужна не только для трудных случаев. В рецепте TypeSafe о самосогласованности один страховой случай 15 раз прогнали через 14 вопросов Noul, меняя в state только одноразовый идентификатор запроса. Среднее стандартное отклонение ответов Jev составило 0,0102, но один из ответов колебался от 0,43 до 0,53 и пересекал порог 0,5. Если порог стоит там, где плотно лежат ответы, решение может меняться от запуска к запуску. В том же рецепте значения от 0,30 до 0,70 уходят на проверку человеку.
Когда меняется версия модели
Алиас jev-latest переезжает на новые релизы, и вместе с моделью могут сдвинуться распределения. Если вы подбирали пороги на конкретной версии, указывайте её явно (сейчас это jev-1.13.0) и сохраняйте поле model из каждого ответа. Перед переходом на новую версию прогоните ту же размеченную выборку и сравните точность по корзинам. Что известно о текущей версии, собрано в статье о Jev 1.13.
Частые ошибки
- Один порог на всю систему. Показ справки и удаление данных требуют разной уверенности.
- Перенос порога между типами. По данным TypeSafe, один и тот же вопрос в виде Noul и в виде Choice «да или нет» даёт разные числа, поэтому порог для одного типа не подходит другому.
- Ставка на сумму в единицу. Вероятности вопроса и его отрицания, заданных двумя Noul, не обязаны давать в сумме 1: в примере TypeSafe вышло 0,72 и 0,47.
- Оценка формулировки по росту
confidence. Уверенность может вырасти и там, где точность не изменилась. Смотрите на размеченные примеры.
Частые вопросы
Если confidence равен 0,9, ответ верен с вероятностью 90%?
Не обязательно. Confidence описывает форму распределения, то есть насколько один вариант выделяется среди остальных. Реальную точность при такой уверенности нужно измерить на своих данных.
Какой порог уверенности выбрать?
Универсального нет. Прогоните размеченную выборку, посчитайте точность по диапазонам уверенности и выберите порог, при котором ошибок столько, сколько вы готовы допустить. Для дорогих действий порог выше.
Почему у Noul нет confidence?
У Noul всего два исхода, и значение noul описывает распределение полностью. Близко к 0 или 1 — модель уверена, около 0,5 — нет.
Чем probabilities отличается от confidence?
probabilities — вероятность каждого варианта или уровня, в сумме 1. Confidence — одно число от 0 до 1, которое TypeSafe считает по форме этого распределения.
Нужно ли пересчитывать пороги при обновлении модели?
Да. Алиас jev-latest переезжает на новые версии, и распределения могут сдвинуться. Зафиксируйте версию, например jev-1.13.0, и проверяйте пороги перед переходом.