TL;DR
Исследование показывает, что решение модели по строке таблицы зависит от оформления запроса. Меняется порядок вариантов ответа, их названия, формат строки (список, JSON, Markdown, предложения) и порядок колонок. Если пересказать тот же запрос другим способом, модель может выдать другой ответ. Практический приём: задать вопрос ещё раз в другом оформлении, сравнить ответы и отправить на ручную проверку те строки, где ответы разошлись.
Главная боль в том, что итоговая точность почти не меняется, а отдельные ответы «плавают». По каждой модели в среднем примерно треть решений по строкам хотя бы раз меняется при переписывании таблицы. Если развернуть порядок вариантов, у части моделей меняется до 30% ответов, и почти все перескоки идут на вариант, который стоит первым в списке. Формат «да/нет» тоже опасен: одна из моделей отвечала «Да» так часто, что половина её ответов оказалась непригодной. Причина в том, что многие решения пограничные: модель колеблется между двумя вариантами, и мелкое изменение подачи перевешивает.
Метод простой: спросить одно и то же 2–5 раз в разной упаковке, смотреть на согласие ответов. Где ответы совпали, решение устойчиво. Где разошлись, это зона риска. Перезапрос только 25% самых неуверенных строк вернул большую часть выигрыша от перезапроса всех строк: 64–86% для LLM и 79–89% для моделей-решателей. Случайные 25% строк дали только 23–44%.
(Исследуют и «типизированные модели решений» (Jev, Clef и др.), которые возвращают вероятности вместо текста. Они доступны через API, а не через чат, поэтому ниже разобрано то, что работает в обычных LLM.)
Схема метода
ШАГ 1: Классификация строки в исходном формате → ответ A
ШАГ 2: Тот же вопрос, но другой формат строки + другой порядок/названия вариантов → ответ B
(опционально: ещё 1–3 формата → ответы C, D, E)
ШАГ 3: Сравнить ответы → совпали = устойчиво; разошлись = «хрупкое» решение
ШАГ 4: Хрупкие строки → голосование большинством или ручная проверка
Шаги 1–2 это отдельные запросы. В чате их можно сделать в одном диалоге, в автоматизации без кода это два блока подряд.
Пример применения
Задача: Отдел продаж онлайн-школы выгрузил из amoCRM 300 заявок. Колонки: источник, бюджет в рублях, город, число касаний, дней с последнего контакта. Нужно разметить заявки как «горячая / тёплая / холодная» и не пропустить заявки, на которых модель сама колеблется.
Промпт (запрос 1: массив значений, порядок «горячая, тёплая, холодная»):
Ты классифицируешь заявки онлайн-школы. Варианты ответа:
- горячая: готов купить в ближайшие 7 дней
- тёплая: интересуется, но не готов покупать сейчас
- холодная: вероятность покупки низкая
Колонки: источник, бюджет_руб, город, касаний, дней_с_контакта
Заявка 1: [«Яндекс Директ», 45000, «Казань», 4, 2]
Заявка 2: [«Telegram-канал», 15000, «Омск», 1, 19]
Заявка 3: [«VK Реклама», 80000, «Москва», 6, 1]
Ответь для каждой заявки одним словом из списка. Без пояснений.
Промпт (запрос 2: тот же смысл, другой формат и порядок вариантов):
Классифицируй заявки онлайн-школы. Возможные ответы (в таком порядке):
- холодная: вероятность покупки низкая
- тёплая: интересуется, но не готов покупать сейчас
- горячая: готов купить в ближайшие 7 дней
Заявка 1:
- источник: Яндекс Директ
- бюджет_руб: 45000
- город: Казань
- касаний: 4
- дней_с_контакта: 2
[…аналогично заявки 2 и 3 в виде списка…]
Ответь для каждой заявки одним словом из списка. Без пояснений.
Результат: Модель вернёт по одному слову на заявку в каждом запросе. Затем вы сравниваете два столбца. По совпавшим заявкам можно верить ответу. Разошедшиеся заявки идут в ручную проверку или в третий запрос с новым форматом, например с JSON, и решаются большинством голосов.
Почему это работает
Слабость LLM. Модель читает таблицу как текст, а не как структуру. Поэтому порядок строк, формат записи и порядок вариантов для неё часть смысла. Многие решения лежат на границе двух классов, и маленький сдвиг в подаче переворачивает ответ. Общая точность при этом почти не меняется: перескоки в одну сторону и в другую взаимно гасятся.
Сильная сторона LLM. Там, где модель «уверена», ответ держится при любой упаковке. Устойчивость хорошо видна по согласию нескольких ответов. В исследовании согласие десяти повторных ответов ранжировало «хрупкие» решения заметно лучше, чем уверенность, которую модель называет сама. Заявленная модельная уверенность («я уверен на 90%») оказалась самым слабым индикатором.
Как метод использует это. Мы не пытаемся угадать правильный формат. Лучший формат для разных моделей разный, а самым слабым у шести из семи моделей оказался исходный массив значений. Мы используем разногласие ответов как датчик риска. Это дешевле, чем перепроверять всё, и точнее, чем верить словам модели про уверенность.
Рычаги управления: - Число форматов (2–5) → больше форматов дают надёжнее голосование, но дороже. - Доля перепроверяемых строк → 25% самых спорных вернули основную часть выигрыша. - Формат строки (список, JSON, Markdown, предложения) → менять, чтобы получить независимые «взгляды» на данные. - Порядок и названия вариантов → переворачивать между запросами, чтобы выявить «тяготение к первому варианту». - Формулировка вопроса → избегай переформулировки в «да/нет», если модель слабая: часть моделей отвечает «Да» по умолчанию.
Шаблон промпта
Классифицируй {объекты} по правилу: {критерий}.
Варианты ответа (в этом порядке):
{вариант_1}: {описание_1}
{вариант_2}: {описание_2}
{вариант_3}: {описание_3}
Данные ({формат_строки}):
{строки_данных}
Для каждой строки ответь одним вариантом из списка. Без пояснений.
Второй запрос (для сверки): возьми тот же шаблон, но поменяй {формат_строки} (например, список «поле: значение» вместо массива) и переверни порядок вариантов.
Сверка:
Вот ответы на один и тот же набор в двух запросах: {ответы_1} и {ответы_2}.
Выведи таблицу: № строки | ответ 1 | ответ 2 | совпало (да/нет).
В конце — список номеров, где ответы разошлись.
Что подставлять: {объекты}: заявки, обращения, отзывы, транзакции. {критерий}: понятное правило с описаниями классов. {формат_строки}: массив, список, JSON, Markdown-таблица или предложения.
Ограничения
⚠️ Устойчивость ≠ правильность: Если модель стабильно ошибается, перекрёстные запросы этого не покажут. «Стабильные ошибки» составили заметную долю решений (почти пятую часть в классификации строк и в поиске аномалий), и ни один сигнал неустойчивости их не ловит.
⚠️ Ни одна модель не защищена от формата таблицы: Все семь моделей меняют ответы при переписывании таблицы. Переход на «лучшую модель» проблему не снимает.
⚠️ Примеры в промпте тоже чувствительны: Если дать 16 размеченных примеров, но перемешать их порядок или сменить формат, у значительной доли строк ответ меняется.
⚠️ Дороже в несколько раз: Перезапрос всех строк в нескольких форматах увеличивает расход пропорционально числу форматов. Выгода от выборочного перезапроса есть только если вы умеете определить «неуверенные» строки, а в чате это требует нескольких прогонов.
⚠️ Модели-решатели недоступны в чате: Основное «чудо» (вероятности вместо текста, устойчивость к порядку вариантов) относится к специальным API. Для вас остаётся только общий вывод про устойчивость и способ проверки.
⚠️ Классификация строк с малым обучающим набором: От примерно 64 размеченных строк обычные методы машинного обучения догоняют или обгоняют LLM. Если разметки много, LLM не лучший инструмент.
Как исследовали
Команда взяла семь моделей: четыре «типизированные модели решений» (возвращают вероятности вариантов за один запрос) и три обычные LLM. Проверяли на трёх задачах: классификация строк на 10 наборах данных, проверка фактов по таблице (TabFact, 2 000 утверждений) и поиск аномалий (20 источников, 5 059 образцов). Главный трюк в том, что каждый запрос отправляли в исходном виде и в 21 переписанной версии с тем же смыслом: переименованные варианты, развёрнутый порядок, формат JSON, Markdown, предложения, перемешанные колонки. Для честности ввели «долю повторной отправки»: что меняется, если один и тот же запрос отправить дважды. Так видно, какая часть перескоков вызвана шумом, а какая переписыванием.
Результат оказался двойным. Точность почти не страдает, но от трети решений на модель хоть раз меняется. Это значит, что итоговый процент вводит в заблуждение. Удивило то, что закрытая модель решений от OpenAI оказалась такой же чувствительной к порядку вариантов, как обычные LLM: устойчивость не гарантируется самим форматом «вероятности вместо текста». Инсайт для практики в том, что уверенность отражает стабильность сильнее, чем правильность, поэтому перекрёстная проверка в разных упаковках служит хорошим фильтром неуверенных решений.
Адаптации и экстраполяции
🔧 Техника: добавить «разворот» вариантов → ловить тяготение к первому
Во втором запросе перечисли варианты в обратном порядке. Если ответ перескакивает на другой «первый» вариант, модель выбирала по позиции, а не по смыслу. Помечай такие строки как ненадёжные.
🔧 Техника: замена формата вопроса → сравнение «да/нет» и «выбери из списка»
Спроси «Это горячая заявка? да/нет» вместо выбора из трёх. Если ответ противоречит выбору из списка, строка пограничная.
Экстраполяция: сочетание с голосованием большинством для текстовых решений (модерация, приоритеты тикетов):
Прогони это решение три раза с разным порядком вариантов: {варианты_А}, {варианты_Б}, {варианты_В}.
Если два из трёх ответов совпали — зафиксируй. Если все три разные — пометь «на ручную проверку».
Это перенос принципа на другой тип задач, в самом исследовании он проверен только на таблицах.
Ресурсы
- Typed Decision Models on Tabular Data — Baowen Zhang (University of Wisconsin–Madison), Hangting Ye (School of AI, Jilin University), Hongyuan Zha (School of Data Science, Chinese University of Hong Kong, Shenzhen).
- Используемые наборы: TabLLM и FeatLLM (классификация строк), TabFact (проверка фактов), ReTabAD (поиск аномалий).
