Dafny принимает 99,1% кода Opus 4.7 на HumanEval, но лишь 1,9% привязаны к спецификации

Авторы препринта показали, что единая цифра «верифицировано» скрывает три разных свойства кода. В воспроизведении конвейера Li et al. на Claude Opus 4.7 Dafny-верификатор принял 99,1% решений HumanEval, но лишь 1,9% содержат постусловие, привязанное к предикату из спецификации. Поэтому в отчётах о проверенном ИИ-коде нужно указывать минимум две метрики, а не одну.

AI-обработка оригинала arXiv cs.AI; редакция Hamidun News
Dafny принимает 99,1% кода Opus 4.7 на HumanEval, но лишь 1,9% привязаны к спецификации
Источник: arXiv cs.AI. Коллаж: Hamidun News.
Слушать статью
Паспорт материала и цифры
ПараметрДанные
ПервоисточникarXiv cs.AI ↗
Главный редактор
Ключевой факт #1В Rust-конвейере VCG 11,48% и 14,82% проверенных решений провалили скрытые тесты
Ключевой факт #2На VeriContest VCG выдал End2End 7,79% против 1,88% у одного вызова Opus 4.7
Ключевой факт #3Проверка привязки постусловия — статический разбор AST за миллисекунды

Когда конвейер генерации кода сообщает, что «верифицировано N% решений», за этой цифрой может скрываться почти пустая гарантия. Prasenjit Dey, Ashish Jagmohan и Ravi Kokku опубликовали на arXiv работу «Verified but Vacuous». Они предлагают разложить понятие «проверенный код, написанный LLM» на три независимо измеряемых уровня и показывают на данных, что эти уровни расходятся очень сильно. В одном из экспериментов Dafny-верификатор принял 99,1% решений на HumanEval, а постусловие, привязанное к спецификации, нашлось только у 1,9%.

Три поверхности отказа

Авторы называют их поверхностями A, B и C. Поверхность A — верификатор принял доказательство (для Dafny это нулевой код возврата). Это необходимое, но самое слабое условие. Поверхность B — привязывается ли доказываемое утверждение к чему-то осмысленному: хотя бы одно постусловие (ensures) должно ссылаться на предикат или функцию из парной спецификации. Поверхность C — отражает ли сама спецификация исходное требование пользователя.

Аудит идёт по цепочке: B считают на тех образцах, что прошли A, а C — на тех, что прошли B. Авторы оговаривают, что это условные выборки, а не логическая иерархия свойств.

Для поверхности B они предложили ensures-binding gate — статический обход AST, который работает за миллисекунды на компонент. Для поверхности C используют проверку Post2Exe из бенчмарка VeriContest: постусловие компилируют в исполняемый предикат и прогоняют на положительных и отрицательных тестах. Если предикат пропускает ответ, который отрицательный тест должен отвергнуть, спецификация неполна.

Два примера на задаче «вернуть максимум массива» показывают разницу. Метод r := 0 без ensures верификатор принимает: функциональной гарантии просто нет. Если же ensures ссылается на предикат r >= 0, привязка формально есть, но спецификация слишком слабая, и ловит это только поведенческая проверка.

Что показало воспроизведение Li et al.

Команда воспроизвела на Claude Opus 4.7 конвейер Li et al., где Dafny служит промежуточным представлением. Тестировали три Python-бенчмарка задач уровня LeetCode: HumanEval, LeetCodeDataset и LiveCodeBench v6. Верификатор принимал 92–99% образцов, а доля с привязкой к предикату из спецификации оставалась очень малой. На HumanEval она составила 1,9%. Ещё у 3,4% образцов постусловие было, но ни на какой предикат из спецификации не ссылалось. По оценке авторов, разрыв между принятием и привязкой — примерно сорок раз.

Доля образцов с постусловием растёт вместе со сложностью: с 5,3% на HumanEval до 10,61% на LiveCodeBench v6 (1 032 из 9 731; 10,9% на подмножестве из 9 448 образцов, прошедших тесты). Модель пишет больше постусловий на трудных задачах, но привязанных к спецификации от этого не становится больше.

Авторы подчёркивают: это не дефект конвейера Li et al. Few-shot-промпт из их статьи содержит метод без тела и без постусловия, а также фикстуру, которая проверяет ожидания во время выполнения. На такой форме входа принятие верификатором означает лишь корректность остальных статических обязательств, но не функциональную правильность. Ошибка, по их словам, в том, как такой конвейер принято описывать.

Даже по построению верифицированное не равно верное

Собственный конвейер авторов, VCG, устроен иначе: Planner разбивает задачу, SpecAgent пишет спецификации на Dafny, ImplementationAgent — реализации, ProverAgent крутит цикл проверки и исправления с ensures-gate. Проверенные компоненты транспилируются в Rust. Привязка к спецификации там выполняется для 100% компонентов по построению. Тем не менее 11,48% образцов на MBPP-Rust и 14,82% на срезе LC из VeriContest провалили скрытые тесты. Авторы называют это операционным приближением к соответствию требованиям, а не точным диагнозом ошибки спецификации.

На срезе LC из VeriContest сквозная метрика End2End у VCG — 7,79% (535 из 6 870). Опубликованные внешние показатели: 5,51% у GPT-5.5 и 1,88% у однократного запуска Opus 4.7. Это разница в 2,3 процентного пункта и в 4,14 раза. Но бюджеты задач, число попыток исправления и тестовые обвязки различаются (у VCG десять сэмплов на задачу, у внешнего сравнения один), поэтому авторы не заявляют сопоставимого превосходства.

Ограничения и практический вывод

В работе приведены точечные оценки без доверительных интервалов. Сам ensures-gate грубый: он может отвергнуть осмысленное встроенное постусловие, а тавтологию с громким именем пропустит. Заявленные 27% структурных отказов в предрелизном аудите VCG и 98% у Li@Opus не проверены независимой разметкой на семантическую пустоту.

Практическая рекомендация конкретна. Любой конвейер, который выдаёт сертификаты, должен публиковать вместе с принятием верификатора хотя бы одну из метрик B или C, а лучше обе. Только B оставляет семантическое слепое пятно, как на VCG. Только C оставляет синтаксическое, как на Li@Opus. Для команд, которые собираются отправлять в продакшен код с «формальной верификацией» от LLM, это готовый чек-лист того, о чём стоит спросить поставщика.

Сюжет

Вопросы и ответы по материалу

Что известно по теме: три поверхности отказа?

Авторы называют их поверхностями A, B и C. Поверхность A — верификатор принял доказательство (для Dafny это нулевой код возврата). Это необходимое, но самое слабое условие. Поверхность B — привязывается ли доказываемое утверждение к чему-то осмысленному: хотя бы одно постусловие (ensures) должно ссылаться на предикат или функцию из парной спецификации. Поверхность C — отражает ли сама спецификация исходное требование пользователя.

Что известно по теме: что показало воспроизведение Li et al?

Команда воспроизвела на Claude Opus 4.7 конвейер Li et al., где Dafny служит промежуточным представлением. Тестировали три Python-бенчмарка задач уровня LeetCode: HumanEval, LeetCodeDataset и LiveCodeBench v6. Верификатор принимал 92–99% образцов, а доля с привязкой к предикату из спецификации оставалась очень малой. На HumanEval она составила 1,9%. Ещё у 3,4% образцов постусловие было, но ни на какой предикат из спецификации не ссылалось. По оценке авторов, разрыв между принятием и привязкой — примерно сорок раз.

Что известно по теме: даже по построению верифицированное не равно верное?

Собственный конвейер авторов, VCG, устроен иначе: Planner разбивает задачу, SpecAgent пишет спецификации на Dafny, ImplementationAgent — реализации, ProverAgent крутит цикл проверки и исправления с ensures-gate. Проверенные компоненты транспилируются в Rust. Привязка к спецификации там выполняется для 100% компонентов по построению. Тем не менее 11,48% образцов на MBPP-Rust и 14,82% на срезе LC из VeriContest провалили скрытые тесты.

ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ Единое AI-пространство · Nomad

Протестируйте новые LLM и мультимодальные модели в одном окне

Платформа Nomad AI (nomadnet.ai) даёт прямой доступ к Claude Opus 5.5, GPT-6, Gemini 3.1, DeepSeek и автономным агентам без VPN, зарубежных карт и зоопарка подписок.

Открыть Nomad AI →Автономный Nomad Agent
Что вы думаете?
Загружаем комментарии…