3,583 papers
arXiv:2610.32876 84 23 окт. 2026 г. FREE

Verify-Show: проверка заявлений инструмента отдельным запросом, прежде чем модель на них опирается

КЛЮЧЕВАЯ СУТЬ
Обнаружено: LLM верит заметке «проверка есть» и перестаёт читать код. Из-за ложных заверений она пропускала настоящие уязвимости, и точность падала до 19 пунктов. Метод Verify-Show позволяет подключать к модели линтеры, сканеры и других агентов и не давать им усыпить её бдительность. Каждое утверждение инструмента проверяется отдельным запросом по исходнику, и основной модели показывают только опровергнутое. Модель перестаёт верить на слово и начинает сверяться с кодом. Результат: около +12 пунктов точности при ложных заверениях и ноль потерь при правдивых заметках.
Адаптировать под запрос
⚡

TL;DR

Verify-Show — это приём для связки «LLM + инструмент» (линтер, сканер, отчёт тестов, вывод другого агента). Каждое утверждение инструмента проверяется по исходнику в отдельном запросе. Основной проверяющей модели показывают только то, что не подтвердилось. Слепо скармливать ей заметки инструмента нельзя.

Главная находка: модель по-разному относится к заметкам «всё хорошо» и «тут опасно». Если инструмент говорит «тут проверка есть», модель часто верит и не смотрит в код. Из-за ложных «проверка есть» она пропускала настоящие уязвимости, до 19 пунктов точности. Если инструмент говорит «проверки нет», модель идёт в код, ищет её и чаще всего находит. Поэтому ложная тревога почти не вредит, а ложное заверение вредит сильно. Правдивые заметки при этом почти не помогают: прирост около нуля. Инструкция в промпте вроде «не доверяй заметкам, проверяй» тоже ненадёжна: лучшая формулировка не повторилась на новых данных.

Решение — вынести проверку из основного запроса. Шаг 1: каждое утверждение инструмента проверяется отдельно, по одному запросу на утверждение. Шаг 2: основной аудит получает код и только опровергнутые утверждения. На новых данных это вернуло около 12 пунктов точности при ложных заверениях и ничего не стоило при правдивых заметках.

🔬

Схема метода

ШАГ 1 (отдельный запрос НА КАЖДОЕ утверждение):
  код + одно утверждение инструмента → «подтверждается / опровергается» + цитата из кода

ШАГ 2 (основной запрос):
  код + только ОПРОВЕРГНУТЫЕ утверждения → итоговый вердикт

Шаги идут в разных запросах. Утверждения шага 1 не должны видеть друг друга и итоговую задачу.

🚀

Пример применения

Задача: Команда делает интеграцию с ЮKassa. Бот-ревьюер проверяет pull request по платёжному модулю. Статический анализатор в CI написал заметки: «сумма платежа проверяется на > 0», «повторный вебхук обрабатывается идемпотентно по order_id», «секрет вебхука сверяется до разбора тела». Если бот поверит заметке «идемпотентность есть», он может пропустить двойное списание. Метод даёт эффект там, где утверждение можно проверить по тому коду, который модель видит.

Промпт шага 1 (запускается отдельно для каждой заметки):

Ты проверяешь одно утверждение о коде. Не оценивай код в целом.

Код:
{код_функции}

Утверждение: «Повторный вебхук обрабатывается идемпотентно по order_id».

Найди в коде конкретные строки, которые это подтверждают или опровергают.
Ответ:
1. Вердикт: ПОДТВЕРЖДАЕТСЯ / ОПРОВЕРГАЕТСЯ / НЕЛЬЗЯ ПРОВЕРИТЬ ПО ЭТОМУ КОДУ
2. Цитата строк кода, на которые опираешься
3. Одно предложение: почему

Промпт шага 2:

Проведи ревью функции на ошибки в обработке платежей (двойное списание, 
пропуск проверки подписи, неверная сумма).

Код:
{код_функции}

Предыдущая проверка опровергла такие утверждения анализатора:
- «Повторный вебхук обрабатывается идемпотентно по order_id» — в коде нет 
  проверки статуса заказа перед списанием.

Оцени код сам. Дай вердикт: ЕСТЬ ПРОБЛЕМА / ПРОБЛЕМ НЕТ и перечисли найденное.

Результат: На шаге 1 придут короткие вердикты по каждой заметке с цитатами строк. Опровергнутые заметки отправляются на шаг 2. Итоговое ревью начинает с вопроса «почему анализатор ошибся», а не с готового «тут всё проверено».

🧠

Почему это работает

Слабость. Модель смотрит на заметку «проверка есть» как на готовый факт. Заметка снимает с неё работу: можно не искать проверку самому. Заметка «проверки нет» работает обратно: она запускает поиск, и модель находит защиту, если та есть. Правдивые заметки почти не помогают, потому что локальные утверждения о коде модель и так читает почти без ошибок. Её ошибки лежат в суждениях и пропусках. Из-за этого полезного в заметках мало, а вреда от ложных заверений много.

Сильная сторона. Узкую задачу «подтверждается ли это одно утверждение этой цитатой» модель решает хорошо. В отдельном запросе у неё нет повода верить: утверждение здесь просто гипотеза, а не вывод «авторитетного» инструмента. Код — источник истины, и проверка идёт именно против него.

Как метод использует это. Он отделяет проверку фактов от вынесения вердикта. На шаге 1 «заверения» теряют авторитет и становятся гипотезами. На шаге 2 основному аудитору показывают только то, что оказалось ложным, и он не расслабляется из-за приятных заметок.

Рычаги: - Что показывать на шаге 2. По статье показываются опровергнутые утверждения. В доступной мне части текста не уточнено, что делать с подтверждёнными. Их можно не передавать или передавать пометкой, это стоит проверить на своих данных. - Третий исход «НЕЛЬЗЯ ПРОВЕРИТЬ». Он защищает от выдуманных подтверждений там, где в коде нет нужной информации. - Цитата обязательна. Требование «процитируй строки» не даёт модели подтвердить утверждение по общему впечатлению. - Чем «тяжелее» утверждение, тем важнее его проверка. Первыми проверяй заверения («есть проверка», «безопасно», «сверено»), а потом уже тревоги.

📋

Шаблон промпта

В доступной части статьи нет дословных промптов, поэтому шаблон собран по описанной механике метода.

Шаг 1 (запускай отдельно для каждого утверждения):

Ты проверяешь ОДНО утверждение. Не оценивай {объект} в целом.

{объект_проверки}:
{текст_или_код}

Утверждение инструмента: «{утверждение}».

Найди в материале конкретные фрагменты, которые подтверждают или 
опровергают это утверждение.

Ответ:
1. Вердикт: ПОДТВЕРЖДАЕТСЯ / ОПРОВЕРГАЕТСЯ / НЕЛЬЗЯ ПРОВЕРИТЬ ПО ЭТОМУ МАТЕРИАЛУ
2. Цитата фрагмента, на который опираешься
3. Одно предложение: почему

Шаг 2 (основной запрос):

{основная_задача}

{объект_проверки}:
{текст_или_код}

Предыдущая проверка опровергла следующие утверждения инструмента:
{список_опровергнутых_утверждений_с_причинами}

Оцени материал самостоятельно. Дай вердикт и перечисли найденное.

Что подставлять: - {объект_проверки} — код, договор, отчёт, таблица, то, против чего проверяются утверждения. - {утверждение} — одна заметка инструмента, дословно. - {список_опровергнутых_утверждений_с_причинами} — собери из ответов шага 1 только те, где стоит ОПРОВЕРГАЕТСЯ.

🚀 Быстрый старт — вставь в чат:

Вот шаблон Verify-Show. Адаптируй под мою задачу: [твоя задача]. 
Задавай вопросы, чтобы заполнить поля.

[вставить шаблон выше]

LLM спросит, откуда берутся утверждения (линтер, другой агент, отчёт), что считать «источником истины» и какой итоговый вердикт нужен. Без этого нельзя разделить шаги: проверка идёт против источника, а вердикт выносится отдельно.

⚠️

Ограничения

⚠️ Инструкции в промпте не спасают: Формулировка вроде «относись к заметкам как к утверждениям, которые нужно проверить» дала прирост на данных разработки, но не повторилась на новых данных. Вставка «будь скептичен» не заменяет отдельный запрос.

⚠️ Эффект нестабилен между моделями: Для основной модели прирост составил около 12 пунктов и был значимым. Для второй модели он был вдвое меньше и незначимым. Проверь метод на своей модели и своих данных.

⚠️ Только то, что можно проверить по материалу: Утверждения про вызывающий код, соседние файлы или внешние данные модель по одной функции не проверит. Анализатор в исследовании не выходил за пределы одной функции. Область эксперимента: C/C++-функции, проверяемые изолированно.

⚠️ Цена: Каждое утверждение — отдельный запрос. Заметок много — вызовов много. Начинай с заверений («всё хорошо»): именно они опасны.

⚠️ Правдивые заметки почти бесполезны: Если в вашей связке инструмент в основном говорит правду, не ждите от заметок прироста качества. Метод страхует от ложных заверений, а не улучшает общую точность.

⚠️ Чек-листы и «пересмотри вердикт» могут навредить: В предварительном опыте оформление заметок как чек-листа обязательств увеличило число ложных «SAFE». Шаг «пересмотри вердикт с учётом замечаний» превратил исправленные функции в ложные тревоги.

🔍

Как исследовали

Исследователи сделали собственный анализатор для C/C++, который выдаёт «обязательства» для каждой опасной операции: какие проверки уже стоят на всех путях и чего функция не гарантирует. Потом взяли пары «уязвимая функция + исправленная» из PrimeVul (916 пар в четырёх непересекающихся наборах) и проверяли каждую функцию при шести условиях, различавшихся только заметками. Условия: без заметок, все правдивые, правдивые только про исправленное место, правдивые про другое, ложное заверение «проверка есть», ложная тревога «добавленной проверки нет». Всего вышло 16 572 аудита на 11 конфигурациях моделей от четырёх вендоров.

Ключевая идея дизайна: ложные заметки сравнивались с правдивыми про ту же операцию. Так разница в вердиктах объясняется именно правдивостью, а не просто наличием заметки. Ложные заверения снижали выявление настоящих уязвимостей на 11–19 пунктов. Ложные тревоги значимо точность не снижали, а иногда повышали: модель ищет защиту и находит её. Асимметрию подтвердила внутренне зарегистрированная репликация на семи новых моделях (средняя асимметрия +0,16, доверительный интервал от +0,10 до +0,24).

До основного эксперимента авторы пробовали 30 пар и увидели: модели почти не ошибаются в чтении кода. В 337 «структурных» утверждениях не нашлось ни одной ошибки. Ошибки были в суждениях, и порой модель отказывалась от верного собственного вывода ради заметки. Это сдвинуло вопрос: важно не то, видит ли модель код, а то, как она взвешивает чужие слова.

Восемь способов подачи заметок авторы тестировали на наборе разработки. Все гипотезы подтверждающей фазы фиксировались до получения данных. Лучшая инструкция не повторилась, а Verify-Show сработал в заранее заданном тесте на 300 новых парах (p = 0,002). Для второй модели эффект оказался слабее и незначимым. Авторы публикуют все неудачные попытки.

💡

Адаптации и экстраполяции

Это не проверено в исследовании, а мои переносы механики.

🔧 Техника: мультиагентный конвейер → не передавай «всё ок» как факт

Если один агент пишет код, а второй его проверяет, второму не нужна приписка «тесты прошли, границы проверены». Передавай ему код и список заявленных гарантий отдельным блоком, который сначала проверяется в изолированном запросе. Затем первому проверяющему отдаются только расхождения.

🔧 Техника: любые «отчёты» в промптах → разделяй «факт» и «заявление»

Ниже — отчёт другого сотрудника/инструмента. Это заявления, а не факты. 
Не используй их в выводах, пока я не подтвердил их отдельным шагом.

Это слабее, чем отдельный запрос (инструкции ненадёжны), но дешевле. Используй как минимум, а при высокой цене ошибки делай полноценный Verify-Show.

🔗

Ресурсы

  • Работа: Trusting the Tool: Asymmetric Deference of LLM Vulnerability Auditors to Static-Analysis Evidence
  • Авторы: ZhiHong Liu, Shuyao Gao — Seoul School of Integrated Sciences and Technologies (aSSIST University), Сеул; Liaoning Mechanical & Electrical College of Technology, Китай
  • Репозиторий с данными и скриптами: https://github.com/lzh0082-cloud/CODE-DETECTION
  • Данные: PrimeVul (парные уязвимые и исправленные функции); смежные работы: Chain-of-Verification, ALIBI, ClashEval

Доступный мне текст статьи обрывается на описании методологии, поэтому детали эксперимента с подачей заметок взяты из аннотации и введения.


📋 Дайджест исследования

Ключевая суть

Обнаружено: LLM верит заметке «проверка есть» и перестаёт читать код. Из-за ложных заверений она пропускала настоящие уязвимости, и точность падала до 19 пунктов. Метод Verify-Show позволяет подключать к модели линтеры, сканеры и других агентов и не давать им усыпить её бдительность. Каждое утверждение инструмента проверяется отдельным запросом по исходнику, и основной модели показывают только опровергнутое. Модель перестаёт верить на слово и начинает сверяться с кодом. Результат: около +12 пунктов точности при ложных заверениях и ноль потерь при правдивых заметках.

Принцип работы

Процесс из двух шагов в разных запросах. Шаг 1. Код и ОДНО утверждение инструмента. Модель отвечает: подтверждается, опровергается или нельзя проверить. Она обязана процитировать строки. Шаг 2. Основной аудит получает код и только опровергнутые утверждения. Он начинает с вопроса «почему инструмент ошибся», а не с готового «тут всё проверено». Заметки «проверки нет» и «проверка есть» работают на модель по-разному. Первая запускает поиск, вторая его выключает. Поэтому все заверения инструмента сначала проходят проверку на гипотезу. Как судья, который сначала слушает свидетелей по одному, а потом выносит приговор. Свидетели при этом не слышат друг друга и не знают, чем закончится дело.

Почему работает

Заметка «проверка есть» снимает с модели работу: искать самой уже не надо. Заметка «проверки нет» делает наоборот. Модель лезет в код, ищет защиту и чаще всего находит. Отсюда перекос: ложная тревога почти не вредит, ложное заверение бьёт сильно. Правдивые заметки почти ничего не дают, прирост около нуля. Локальные факты о коде модель и так читает почти без ошибок. Она ошибается в суждениях и пропусках. Узкую задачу «подтверждает ли эта цитата это утверждение» модель решает хорошо, а в отдельном запросе у неё нет повода верить авторитетному инструменту. Утверждение становится гипотезой, а код остаётся источником истины. Прикол: инструкция «не доверяй заметкам, проверяй» не спасает. Лучшая формулировка дала прирост на данных разработки и не повторилась на новых. Отдельный запрос работает надёжнее, чем просьба быть скептичной.

Когда применять

Проверка кода и документов → ревью платёжных модулей, разбор отчётов сканера безопасности, проверка вывода другого агента. Подходит особенно тогда, когда инструмент часто пишет «безопасно», «сверено», «проверка есть», а ошибка стоит дорого. Не подходит, если утверждение нельзя проверить по тому, что модель видит. Например, речь о вызывающем коде, соседних файлах или внешних данных. Не поможет и тогда, когда инструмент почти всегда говорит правду: метод страхует от ложных заверений, общую точность он не поднимает. Это одно исследование на C/C++-функциях, которые проверяли по одной. На второй модели эффект вдвое слабее и незначимый. Сначала проверь метод на своих данных.

Мини-рецепт

1. Собери утверждения: выпиши заметки инструмента по одной, дословно. Начни с заверений («есть проверка», «безопасно»), тревоги оставь на потом.
2. Запусти проверку по одному запросу на утверждение: дай модели код и одну заметку. Утверждения друг друга и итоговую задачу она видеть не должна.
3. Требуй цитату и третий исход: вердикт «подтверждается / опровергается / нельзя проверить по этому коду» плюс процитированные строки. Без цитаты модель подтвердит по общему впечатлению.
4. Отбери опровергнутое: в основной запрос идёт код и только то, что получило «опровергается», с причиной. Что делать с подтверждённым, статья не уточняет, проверь на своих данных.
5. Не добавляй лишнего: не оформляй заметки как чек-лист и не проси «пересмотри вердикт». В предварительных опытах от этого росло число ложных «безопасно» и ложных тревог.

Примеры

[ПЛОХО]: `Вот код платёжного вебхука и заметки анализатора: «повторный вебхук обрабатывается идемпотентно по order_id», «секрет сверяется до разбора тела». Найди ошибки.` [ХОРОШО] Шаг 1, отдельный запрос на каждую заметку: `Ты проверяешь ОДНО утверждение о коде. Не оценивай код в целом. Код: {код_функции}. Утверждение: «Повторный вебхук обрабатывается идемпотентно по order_id». Ответ: 1) вердикт: ПОДТВЕРЖДАЕТСЯ / ОПРОВЕРГАЕТСЯ / НЕЛЬЗЯ ПРОВЕРИТЬ ПО ЭТОМУ КОДУ; 2) цитата строк, на которые опираешься; 3) одно предложение: почему.` [ХОРОШО] Шаг 2, основной запрос: `Проведи ревью функции: двойное списание, пропуск проверки подписи, неверная сумма. Код: {код_функции}. Предыдущая проверка опровергла утверждение анализатора: «повторный вебхук обрабатывается идемпотентно» — в коде нет проверки статуса заказа перед списанием. Оцени код сам. Вердикт: ЕСТЬ ПРОБЛЕМА / ПРОБЛЕМ НЕТ, перечисли найденное.`
Источник: Trusting the Tool: Asymmetric Deference of LLM Vulnerability Auditors to Static-Analysis Evidence
ArXiv ID: 2610.32876 | Сгенерировано: 2026-10-26 15:10

Проблемы LLM

ПроблемаСутьКак обойти
Модель слепо верит заметкам «всё в порядке» от инструмента или другого агентаДаёшь модели код или документ и заметки внешней программы. Заметки бывают двух видов: «защита есть» и «защиты нет». Первым модель верит и не ищет сама. Из-за ложного «защита есть» пропускает настоящие ошибки. Вторые запускают поиск. Модель идёт в материал и обычно находит, что тревога ложная. Поэтому ложная тревога почти не вредит, а ложное заверение вредит сильно. Правдивые заметки при этом почти не повышают качествоНе показывай основной модели заверения «проверено», «безопасно», «сверено» как готовый факт. Сначала проверь каждое заверение отдельным запросом. Дальше действуй по методу ниже

Методы

МетодСуть
Проверка утверждений отдельным запросом — вердикт без внушённой уверенностиЧто делать. Раздели работу на два шага в РАЗНЫХ запросах. Шаг 1: один запрос на одно утверждение инструмента. Даёшь материал и одно утверждение. Просишь вердикт ПОДТВЕРЖДАЕТСЯ / ОПРОВЕРГАЕТСЯ / НЕЛЬЗЯ ПРОВЕРИТЬ ПО ЭТОМУ МАТЕРИАЛУ, цитату фрагмента и одно предложение «почему». Запрещаешь оценивать материал в целом. Шаг 2: основной запрос получает материал и только опровергнутые утверждения. Фраза: «Предыдущая проверка опровергла это: … Оцени сам». Почему работает: в отдельном запросе утверждение — гипотеза, а не вывод авторитета. Узкую задачу «подтверждает ли эта цитата это утверждение» модель решает хорошо. Основной запрос не получает приятных заверений и не расслабляется. Детали: цитата обязательна, иначе модель подтвердит «по впечатлению». Третий исход «нельзя проверить» защищает от выдуманных подтверждений. Утверждения на шаге 1 не должны видеть друг друга и итоговую задачу. Начинай с заверений: они опаснее тревог. Когда да: утверждение можно проверить по тексту, который модель видит. Источник утверждений — линтер, сканер, отчёт тестов, другой агент. Когда нет: утверждение про то, чего в материале нет (соседние файлы, внешние данные). Или инструмент почти всегда прав. Это стоит одного запроса на каждое утверждение. Эффект зависит от модели, проверь на своей
📖 Простыми словами

Trusting theTool: Asymmetric Deference ofLLMVulnerability Auditors to Static-Analysis Evidence

arXiv: 2610.32876

Нейросети феноменально ленивы, и когда ты скармливаешь им код вместе с отчётом сканера, срабатывает асимметричное доверие. Если тупой линтер ляпнет: «тут всё ровно, проверка есть», модель радостно выдохнет и забьёт болт. Архитектура LLM устроена так, что готовая положительная подсказка для неё — неоспоримый факт, снимающий задачу поиска. Она не перепроверяет чужое враньё и в упор пропускает критическую уязвимость, поверив мнимому авторитету.

Это как ленивый прораб на стройке, которому гастарбайтер крикнул: «Трубы спаяли намертво, зуб даю!» Прораб даже фонарик не включит — влепит подпись в акте и пойдёт пить чай, пока подвал заливает кипятком. Но если рабочий скажет: «Там протечка», прораб полезет лично всё осматривать. С моделями работает та же психология халтурщика: ложная похвала расслабляет булки, а сигнал о проблеме заставляет реально читать код.

Лекарство от этой лажи — метод Verify-Show. Перестань скармливать проверяющей модели всю простыню отчётов статического анализатора. Механика жёсткая: каждое утверждение тула прогоняется через изолированный запрос к сырому коду, где отдельная модель подтверждает факт. Главный трюк: финальному аудитору скармливают только неподтверждённые тезисы, отсекая ложное спокойствие. Если сканер наврал, что «проверка платежа на месте», модель получит не убаюкивающий отчёт, а команду перепроверить конкретный косяк.

В эксперименте гоняли уязвимости в коде, но принцип универсален. Правило бьёт по любой связке из LLM и внешнего инструмента: линтеров, тестов, RAG-поиска или соседних AI-агентов. Как только одна модель безоговорочно верит сводке другой программы, сложный пайплайн превращается в карточный домик. Ложные заверения убивают надёжность и в ревью кода, и в скоринге документов, и в умных поисковиках.

Короче: кормить модель готовыми «зелёными» галочками от сканеров — верный способ пропустить факап. Либо внедряй жестокую перепроверку фактов, либо не показывай аудитору чужие выводы вовсе. В реальном проде слепая вера в инструменты обернётся двойными списаниями и взломанными базами. Никогда не давай нейросети повода думать, что кто-то уже сделал работу за неё.

Работа с исследованием

Адаптируйте исследование под ваши задачи или создайте готовый промпт на основе техник из исследования.

0 / 2000
~0.5-2 N-токенов ~10-30с
~0.3-1 N-токенов ~5-15с