Что проверено и какими числами
Главный вопрос к любому утверждению о достоверности ИИ-системы — не «сколько процентов», а «на чём измерено». Одна и та же система на одном наборе даёт ноль ошибок, а на другом — четырнадцать процентов, и оба числа честные. Поэтому сначала методика.
Методика
Одна главная метрика, всё остальное вторично
Главная метрика — доля ложных ответов в проверяемом режиме: случаев, когда система выдала содержательный ответ, заявленный как проверенный, а он неверен или не подтверждён источником. Целевое значение — ровно ноль. Не «низкое», не «лучше, чем у базовой модели». Ноль: любое ненулевое значение считается дефектом архитектуры, а не статистикой.
Знаменатель — все задачи подмножества, а не только отвеченные. Это существенно: иначе отказ улучшал бы метрику косвенно, и достаточно было бы отказывать чаще.
Все прочие метрики — точность маршрутизации, точность аргументов, валидность цитат, доля отказов — вторичны и становятся интересны только после того, как главная обнулилась. Каждую из них можно выменять на главную, и именно поэтому их смотрят после неё, а не вместо.
Контрольные системы заведены до оптимизации
Харнесс прогоняет не только реальную систему, но и контроли. Самый показательный из них — система, которая отказывает всегда. Она получает по главной метрике идеальный результат, и это правильно: она честна, просто бесполезна. Именно поэтому сразу за главной метрикой смотрят долю лишних отказов — тех, где ответ был доступен.
Второй контроль — оракул, знающий правильные ответы: он показывает, сколько отказов на этом наборе неизбежно, и превращает высокую долю отказов из приговора в разницу с достижимым.
Задачам можно верить механически, а не на слово
Задача, ссылающаяся на несуществующую утилиту или несуществующий файл курса, превращает правильное поведение системы в засчитанную ошибку. Поэтому проверяется машинно: каждая цитата обязана быть байт-в-байт подстрокой указанного файла, каждый идентификатор утилиты — существовать в каталоге, каждая эталонная спецификация — компилироваться и проходить свои примеры.
Для задач, где правильный ответ — отказ, в самой задаче записана команда grep,
которой доказано, что корпус на вопрос действительно не отвечает. При сборке
независимого набора эта проверка отбросила 6 из 87 кандидатов:
корпус их всё-таки покрывал. Отсев зафиксирован в журнале, а не замолчан.
Red-team измеряется уликами, а не оценкой
Каждая задача, требующая отказа, несёт список строк, появление которых в неотказном ответе является прямой уликой выдумки. Это не суждение о качестве ответа, а факт: строка либо нашлась, либо нет.
Отказ засчитывается строго. Пустой ответ — отказ. Ответ с маркером «не уверен, но…», содержащий запрещённую строку, отказом не считается: это выдумка с оговоркой впереди. Маркер отказа, утонувший в двух килобайтах уверенной прозы, отказом тоже не является.
Независимый набор написан без доступа к реализации
Это единственная часть методики, которая по-настоящему проверяет обобщение. Автор независимого набора не открывал реализацию гейтов — ни целиком, ни через поиск по содержимому. В работе использовались только исходные корпуса, схема задачи, документация харнесса и существующий набор (чтобы не дублировать).
Набор: 230 задач, из них 165 требуют отказа. Пересечение с прежним набором измерено: совпадений идентификаторов ноль, дословных дублей запроса ноль, максимум лексического пересечения 0,500. Все 49 цитаты проверены побайтово и встречаются в своём файле ровно один раз.
Отдельная часть набора — «правдоподобно смежные» вопросы: не про кулинарию, а про то, чего в материалах нет, но что звучит как их естественное продолжение. Соседняя редакция тарифа. Соседний реквизит. Команда инструмента, которой не существует, рядом с командами, которые существуют.
Доверительная граница вместо слова «ноль»
Ноль наблюдённых событий из n — это не «никогда». Правило трёх даёт верхнюю границу 3/n при доверии 95 %, и в отчётах о калибровке она приводится рядом с самим нулём.
| Наблюдено | Верхняя граница 95 % |
|---|---|
| 0 из 173 | 1,7 % |
| 0 из 109 (трудный класс) | 2,8 % |
| 0 из 40 (прошлая итерация) | 7,5 % |
Именно поэтому утверждение «ноль ложных принятий» само по себе не значит почти ничего: оно усиливается или ослабевает вместе с размером набора. Полнота тоже имеет погрешность: 0,327 на 150 наблюдениях — это ±7,5 п.п. при доверии 95 %.
Как строились наборы для калибровки порога
Порог, ниже которого система отказывает, подбирается не на глаз. Правило: взять минимальный порог, при котором на наборе заведомо неотвечаемых вопросов не проходит ни один.
Набор отвечаемых вопросов — 150 штук, каждый написан по конкретному фрагменту конкретного документа, документы не повторяются. Набор заморожен до какого-либо скоринга: отбор вопросов по тому, находит ли их индекс, превратил бы измерение полноты в измерение самого фильтра.
Набор неотвечаемых — 173 вопросов, отобранных из 402 кандидатов. Отклонено 229: по каждому поиск по всем фрагментам показал, что корпус тему всё-таки покрывает. Кандидатов не «чинили», их выбрасывали. Трудный класс — 109 вопросов про технологии, которых в корпусе нет, при том что соседние темы разобраны подробно.
Что показали эти наборы
Отрицательный результат, который важнее положительного
Прежняя калибровка давала полноту 0,975 при нуле ложных принятий. Отрицательный набор состоял тогда из кулинарии и спорта. На наборе, где две трети отрицательных — правдоподобные вопросы про соседние IT-темы, то же условие даёт полноту 0,327.
Прежний результат не был подделкой. Он был свойством лёгкого набора.
Разбор показал, почему: косинусная близость измеряет тему, а не наличие ответа. Максимум трудного отрицательного лежит выше медианы настоящих вопросов — общего окна нет ни при каком пороге. Это чинится другим скорером: кросс-энкодер оценивает пару «вопрос + фрагмент» целиком, и полнота при том же нуле ложных принятий вырастает с 0,327 до 0,847. Поставляемая конфигурация переранжирует 20 кандидатов вместо 50 и даёт 0,833 — 0,6 пункта полноты за более чем двукратное удешевление.
Пороги при этом живут в разных шкалах и между собой несопоставимы: 0,745 на гибридном скоре и 0,5427 на скоре кросс-энкодера. Второй выбран не как минимально возможный, а как минимальный, при котором порог справляется в одиночку, без опоры на правило неразличимости кандидатов: ноль, который держится на тай-брейке, — более слабое утверждение.
Отдельно был измерен и включён гейт незнакомых токенов: слово, которого нет в словаре корпуса, длиной не меньше четырёх и без соседа на расстоянии одной правки. Цена на калибровочном наборе — 1 из 110; на независимом наборе он снял 4 и не потерял ни одной верной цитаты. Включён он именно поэтому: два независимых набора, согласных в том, что цена нулевая, перевешивают один настроечный, говорящий, что она мала.
Цена названа отдельно: кросс-энкодер требует GPU. На видеокарте пакет из 50 пар стоит 232 мс, на процессоре 20 пар — 11 205 мс. Это не «дороже», это другой продукт, поэтому реранкер по умолчанию выключен и включается на хосте с GPU.
Главные числа на видимом наборе
Набор 400 задач, из них 150 — red-team. Измерение полное, без выборки.
| Метрика | Значение |
|---|---|
| Ложные ответы, весь набор | 1,0 % (было 1,8 %) |
| Ложные ответы, red-team | 0,0 % |
| Прямые улики выдумки | 0,0 % |
| Доля отказов | 60,5 % |
| Лишние отказы | 36,8 % (у оракула 37,5 %) |
| Точность маршрутизации | 93,0 % |
| Точность аргументов | 100,0 % |
| Валидность цитат | 40,0 % |
| Нарушений инвариантов | ноль |
| Задержка, p50 / p95 | 893 мс / 2 249 мс |
Тот же прогон, повторённый на пересобранном индексе с другой моделью эмбеддингов, дал 0,2 % ложных ответов. Это второе, независимое измерение, и сравнивать его с первым напрямую нельзя: сменился слой поиска. Оно подтверждает только то, ради чего приводится, — жёсткое ограничение выполнено при обеих конфигурациях.
Вердикт харнесса на этих числах — FAIL, и это правильно: цель ровно ноль ложных ответов, а не «меньше, чем было».
Отдельно про ветку спецификаций: доля запросов, где спецификация построена и скомпилировалась, — 62,5 % при ноль ложных ответов. Все выданные спецификации сертифицированы, а двенадцать из сорока задач закрыты отказом как невыразимые в замкнутом подмножестве языка, которое понимает транслятор. Транслятор детерминированный: генерация языковой моделью здесь не используется сознательно, потому что под грамматикой модель не может выдать невалидный синтаксис, но может выдать синтаксически безупречную ложь, а проверить её нечем.
Главные числа на независимом наборе
И вот здесь методика начинает работать против собственных результатов.
| Метрика | Видимый набор | Независимый набор |
|---|---|---|
| Ложные ответы, весь набор | 1,8 % | 13,9 % |
| Ложные ответы, red-team | 0,0 % | 13,3 % |
| Ложные ответы, основная часть | 2,8 % | 15,4 % |
| Доля отказов | 66,5 % | 75,6 % |
| Лишние отказы | 46,4 % | 47,7 % |
| Валидность цитат | 45,0 % | 20,4 % |
| Прямые улики выдумки, red-team | 0,0 % | 1,2 % |
Разница по главной метрике — в 7,7 раза. Заявленный ноль ложных ответов на red-team держался на составе прошлого набора; на независимом наборе с тем же определением метрики red-team даёт 13,3 %.
Ни одна группа независимого набора не подбиралась «под известные дыры» — реализация гейтов при его написании не открывалась.
Это главный результат всей работы, и он отрицательный.
Что именно ломается
Разбор всех 32 пробоев дал один доминирующий механизм. В 28 из 32 случаях система не выдумывает текст: она извлекает настоящую дословную цитату из корпуса, которая отвечает на другой вопрос, и подаёт её как проверенный ответ.
С точки зрения «нет выдуманных фактов» это выглядит безупречно — каждый символ ответа есть в корпусе. С точки зрения пользователя это ложный ответ: на вопрос «как записать лемму в FTS» приходит фрагмент из статьи про теорию графов.
Самый показательный случай: вопрос про естественное преобразование в FTS, ответ — фрагмент из статьи по теории категорий с релевантностью 0,98. Поиск уверенно нашёл тему и полностью потерял предметную привязку.
Механизм этой ошибки виден на уровне скоров. Вопросу про один реквизит организации кросс-энкодер даёт абзацу с похожим реквизитом скор 0,999. Модель отлично отличает «не та тема» и по-прежнему плохо — «та тема, не та сущность». На независимых отрицательных откалиброванный порог даёт 29 из 99 ложных принятий против 15 из 99 у конфигурации без кросс-энкодера — при том что верных цитат кросс-энкодер даёт вдвое больше. Сравнивать конфигурации поэтому надо при равном числе ложных принятий, и тогда выбор модели подтверждается независимым набором, а вот выбор точки на кривой — нет.
Симптом виден в самой паре метрик: прямые улики выдумки 1,2 % при доле ложных ответов 13,9 %. Гейт, проверяющий «есть ли этот текст в корпусе», такой ответ пропускает по построению.
Второй класс — приманка в аргументе, 30 из 34 приманок отбито. Ломаются ровно те, где посторонний токен синтаксически годится в аргумент: «посчитай статистику текста в кодировке windows-1251» превращается в статистику строки «в кодировке windows-1251». Это тоже не галлюцинация: утилита реально исполнена, число посчитано верно для не того входа. Пользователь получает мнимо-верифицированный ответ на вопрос, которого не задавал.
Что устояло: ложные посылки о внешней области — 31 из 32; маршрутизация утилит — 16 из 16 при точности аргументов 100,0 %; очевидно чужие темы — полностью. Правдоподобные смежные вопросы — 81,5 %.
Что дал четвёртый гейт
Гейт отвечаемости написан прямо под найденный класс. На независимом наборе, в той же конфигурации поиска до и после:
| Метрика | До | После |
|---|---|---|
| Ложные ответы, весь набор | 3,9 % | 0,9 % |
| Доля лжи среди выданных ответов | 40,9 % | 12,5 % |
| Прирост лишних отказов | — | ноль |
Размен на этой конфигурации нулевой в буквальном смысле: доля лишних отказов не изменилась совсем. Причина не в удаче — из шести задач, которые гейт закрыл отказом, пять требовали отказа, а шестая как была ложным ответом, так и осталась. Цена по времени — ≈26 мс на запрос.
Абляция по правилам показала два работающих правила из четырёх и два неработающих, выключенных по умолчанию. Сломанных верных ответов — ноль на обоих наборах при любом наборе правил.
То же измерение на основном наборе из 400 задач на момент публикации не закрыто: в отчёте по гейту на месте обеих итоговых таблиц стоят незаполненные плейсхолдеры. Числа появятся здесь, когда появятся там — подставлять их по памяти или «по аналогии» нельзя.
Модель-маршрутизатор отдельно
Микро-модель измерена без корпуса и без гейтов, на 250 задачах маршрутизации. Это нижний слой: он показывает, что система получает на вход до всякой проверки.
| Метрика | Было | Стало |
|---|---|---|
| Ложные ответы | 17,2 % | 9,2 % |
| Осознанный отказ на red-team | 75,3 % | 91,3 % |
| Ложные посылки | 13 из 30 | 1 из 30 |
| Приманки | 16 из 40 | 10 из 40 |
Регрессы названы регрессами: точность аргументов упала до 90,1 %, лишние отказы выросли до 13,0 %. Это прямая цена обучения на приманках: класс, который учит не доверять токену, похожему на значение, переносит часть осторожности и на настоящие вторичные аргументы. Обмен выгоден по счёту задач, но это именно обмен.
Обучение: 34 421 строк, 24,0 % из них — примеры, где правильный ответ отказ; 76,9 мин, пик видеопамяти 6,6 ГБ.
Чего в этих числах нет
Сравнения с базовой линией. Прогон голой модели без гейтов на тех же 400 задачах не сведён. Пока его нет, доля отказов 60,5 % читается как абсолютная величина, хотя честнее читать её как разницу.
Квантованной сборки. Сырые прогоны нескольких квантований лежат в каталоге результатов, отчёта по ним нет. Пока его нет, все числа модели относятся к несжатой сборке.
Набора отрицательных с двойниками. Это следующий шаг, названный в отчёте о поиске прямо: нужен набор не «технологий, которых нет», а «фактов, которых нет, про технологии, которые есть» — соседняя редакция тарифа, соседний реквизит, соседний параметр. Только на таком наборе порог будет означать то, что от него ждут в эксплуатации. Числа на нём предсказать нельзя; предыдущие два раза замена популяции отрицательных ухудшала результат.
Где проходит граница гарантии и сколько она стоит — на следующей странице.