3,583 papers
arXiv:2607.26244 76 28 июля 2026 г. FREE

Тесты в промпте для кода: помогают на простых задачах, но не гарантируют успех на сложных

КЛЮЧЕВАЯ СУТЬ
Обнаружено: модель не отличает тест с правильным ответом от теста из совсем другой задачи — внутри неё сигналы скачут одинаково сильно в обоих случаях. Тесты во входных данных позволяют поднять точность генерации кода — но надёжно это работает только на типовых задачах вроде парсеров и сортировок. На сложных нестандартных задачах тесты иногда работают как случайный шум в тексте — модель реагирует на них, но не разбирает смысл. Текстовое описание задачи важнее тестов — без него точность падает резко на любой сложности.
Адаптировать под запрос

TL;DR

Когда просишь LLM написать код и добавляешь в промпт тест-примеры (входы и ожидаемые выходы), модель не всегда реально «понимает» через них задачу. Иногда она честно разбирает логику тестов и пишет правильный код, а иногда просто реагирует на тесты как на дополнительный шум в тексте — и со стороны это выглядит одинаково хорошо, пока не подменишь тесты на неправильные или вообще чужие.

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

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


📌

Схема принципа

ШАГ 1: Оцени задачу → типовая/частая (парсер, сортировка, форматирование) или нестандартная/сложная (кастомная бизнес-логика, редкий алгоритм)
ШАГ 2: Если типовая → добавь 2-3 примера "вход → выход" в промпт → заметный рост точности
ШАГ 3: Если нестандартная → не жди чуда от тестов → делай упор на подробное словесное описание правил, границ, особых случаев
ШАГ 4: Всегда сохраняй текстовое описание задачи рядом с тестами → без него точность резко падает
ШАГ 5: Не закидывай много тестов "на всякий случай" → после 2-3 примеров эффект перестаёт расти

🚀

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

Задача: Ты ведёшь маленький интернет-магазин и просишь ChatGPT написать функцию расчёта скидки: для новых клиентов — 5%, для тех кто покупал больше 10 раз — 15%, но если сумма заказа меньше 500 рублей, скидка не действует, а в праздники (список дат) скидка удваивается, но не больше 30%.

Это не типовая задача (кастомная бизнес-логика с исключениями) — значит тесты не спасут, если описание нечёткое.

Промпт:

Напиши функцию на Python calculate_discount(customer, order_sum, date), которая рассчитывает скидку по правилам:

- Новый клиент (меньше 1 покупки в истории): скидка 5%
- Клиент с более чем 10 покупками: скидка 15%
- Если сумма заказа меньше 500 рублей — скидка не применяется вообще, независимо от статуса клиента
- Если дата входит в список праздников [8 марта, 23 февраля, 31 декабря] — скидка умножается на 2, но итоговая скидка не может превышать 30%
- Если клиент подходит под несколько условий одновременно — действует наибольшая скидка из применимых

Вот примеры для проверки логики (используй их, но помни: они не покрывают все пограничные случаи — подумай сам, что может пойти не так):

customer.purchases=0, order_sum=1000, date="обычный день" → скидка 5%
customer.purchases=15, order_sum=1000, date="8 марта" → скидка 30% (15% × 2, но капнуто на 30%)
customer.purchases=15, order_sum=400, date="8 марта" → скидка 0% (сумма меньше 500)

Перед финальным ответом проверь: проходит ли твоё решение все три примера, и учтён ли случай когда клиент новый И заказ в праздник.

Результат: Модель напишет функцию с условной логикой, учитывающей порядок правил (сначала проверка минимальной суммы, потом статус клиента, потом праздничный множитель с капом). Благодаря явному описанию правил, а не только тестам, модель не будет угадывать логику по 3 примерам — она получит полную спецификацию, а тесты послужат проверкой, а не единственным источником смысла.


🧠

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

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

Сильная сторона LLM: на частых, типовых паттернах (стандартные функции сортировки, парсинга, форматирования) модель отлично использует тесты как уточнение — они помогают увидеть недостающие детали формата, граничные случаи, которые не были явно описаны словами.

Как применять: добавляй тесты когда задача похожа на то, что модель "видела" тысячи раз в обучении. Если задача нестандартная — не экономь на текстовом описании в надежде, что тесты сами всё объяснят. И всегда проверяй код сам — большой сдвиг в «уверенности» модели (внутренние изменения) не значит, что она поняла задачу правильно.


⚠️

Ограничения

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

⚠️ Тесты не заменяют описание: если убрать текстовое описание задачи и оставить только тесты, точность падает резко и сильно — тесты работают только вместе с полной спецификацией.

⚠️ Больше тестов не значит лучше: эффект от добавления тестов быстро выходит на плато после 2-3 примеров, а иногда даже снижается — не нужно перегружать промпт тестами «на всякий случай».

⚠️ Неправильные тесты почти не хуже правильных: на части задач тесты с перепутанными ожидаемыми результатами работали почти так же, как правильные — значит нельзя слепо доверять, что «раз я дал тесты, модель точно поняла логику».


🔍

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

Исследователи взяли две модели для генерации кода (Qwen2.5-Coder-7B и более сильную Qwen3.6-27B) и прогнали их через три набора задач разной сложности: простые типовые задачи (MBPP+), задачи среднего уровня, которые модель уже решает хорошо (HumanEval+), и свежие сложные задачи с LeetCode и AtCoder (LiveCodeBench). Для каждой задачи сравнили шесть вариантов промпта: без тестов, с правильными тестами, с тестами где перепутаны ожидаемые результаты, с тестами из другой задачи, только с тестами без описания задачи, и с искусственно сгенерированными тестами от более мощной модели.

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


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

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

Обнаружено: модель не отличает тест с правильным ответом от теста из совсем другой задачи — внутри неё сигналы скачут одинаково сильно в обоих случаях. Тесты во входных данных позволяют поднять точность генерации кода — но надёжно это работает только на типовых задачах вроде парсеров и сортировок. На сложных нестандартных задачах тесты иногда работают как случайный шум в тексте — модель реагирует на них, но не разбирает смысл. Текстовое описание задачи важнее тестов — без него точность падает резко на любой сложности.

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

Не думай, что тест — это инструкция, которую модель обязана честно выполнить. Тест — это подсказка, которая срабатывает надёжно только если задача похожа на то, что модель видела тысячи раз при обучении. На непривычных задачах правильные тесты и тесты из совершенно другой задачи дают почти одинаковый результат — модель угадывает логику, а не читает её из примеров.

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

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

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

Генерация кода → конкретно для типовых функций: парсеры, сортировки, форматирование, стандартные алгоритмы, особенно когда нужно уточнить формат входа-выхода через пример. НЕ подходит как замена текстовому описанию для кастомной бизнес-логики или редких алгоритмов — там тесты не гарантируют, что модель поняла задачу, а просто дают ей случайный шанс угадать правильно.

Мини-рецепт

1. Оцени задачу: типовая (модель такое видела тысячи раз) или кастомная логика с исключениями.
2. Типовая задача: добавь 2-3 примера вход-выход, больше не нужно — эффект уже на плато.
3. Сложная задача: не жди чуда от тестов — распиши правила, границы, особые случаи словами.
4. Всегда: держи текстовое описание рядом с тестами, даже если кажется что примеры всё объясняют.
5. Проверяй сам: если модель уверенно поменяла код после теста — это не значит, что она поняла задачу правильно.

Примеры

[ПЛОХО] : Напиши функцию calculate_discount. Примеры: (0,1000,обычный день)->5%, (15,1000,8 марта)->30% — без описания правил модель угадывает логику по трём точкам.
[ХОРОШО] : Напиши функцию calculate_discount(customer, order_sum, date). Правила: новый клиент — скидка 5%, более 10 покупок — 15%, сумма меньше 500 рублей — скидка не действует, праздничные даты умножают скидку на 2 но не выше 30%. Вот примеры для проверки логики (используй их, но помни — они не покрывают все пограничные случаи): (0,1000,обычный)->5%, (15,1000,8 марта)->30%, (15,400,8 марта)->0%. Проверь решение на всех трёх примерах перед ответом.
Источник: Do Code Language Models Use Tests? A Behavioral and Representational Study of Test-Driven Code Generation
ArXiv ID: 2607.26244 | Сгенерировано: 2026-07-30 04:27

Проблемы LLM

ПроблемаСутьКак обойти
Тесты-примеры не гарантируют что модель поняла логику задачиНа сложных, нетиповых задачах модель не отличает полезный тест от случайного текста. Подставь неправильные тесты или тесты из совсем другой задачи — результат почти не изменится. Внутри модели сигналы меняются сильно в обоих случаях, но это не значит верное понимание задачиНа нестандартных задачах не давай только тесты. Пиши подробное текстовое описание правил, границ и особых случаев. Используй тесты как проверку готового решения, а не как единственный источник смысла

Методы

МетодСуть
Проверка типичности задачи перед добавлением тестовПеред тем как класть тесты в промпт, оцени: типовая задача (парсер, сортировка, форматирование) или уникальная бизнес-логика. Если типовая — добавь 2-3 примера "вход выход", точность заметно вырастет. Если уникальная — вложись в подробное текстовое описание правил, а тесты дай только как дополнительную проверку после описания. Почему работает: модель узнаёт частые паттерны кода из обучения, тесты лишь уточняют формат. На редких задачах такого узнавания нет, тесты смысл надёжно не передают. Когда да: стандартные функции, распространённые алгоритмы. Когда нет: кастомная логика, редкие комбинации условий

Тезисы

ТезисКомментарий
Больше тестов не значит лучше — эффект выходит на плато после 2-3 примеровМодель извлекает основную пользу из первых двух-трёх примеров "вход выход". Дальше точность почти не растёт, а иногда даже немного падает. Механизм: модель быстро улавливает общий паттерн, а лишние примеры превращаются в шум, отвлекающий от текстового описания. Применяй: не закидывай промпт десятком тестов "на всякий случай" — хватает 2-3 показательных примеров с разными случаями (обычный, граничный, особый)
📖 Простыми словами

Do CodeLanguageModelsUseTests? A Behavioral and Representational Study of Test-Driven Code Generation

arXiv: 2607.26244

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

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

Исследователи проверили это через поведенческий анализ и изучение внутренних состояний моделей. Выяснилось, что в простых задачах LLM еще как-то пытаются сопоставлять код с тестами, но как только алгоритм усложняется, начинается рандом. Модель может выдать правильный ответ, даже если тесты в промпте ведут к неправильному — она просто опирается на свои внутренние веса, а не на ту конкретику, которую ты ей «скормил». Это значит, что наличие тестов в промпте — это не гарантия качества, а скорее психологическая уловка для самой модели.

Этот принцип универсален для любой работы с промптами, будь то написание скриптов для магазина или сложная аналитика данных. Мы привыкли думать, что Few-Shot prompting (обучение на примерах) работает как жесткая логическая привязка, но на деле это часто просто настройка настроения нейронки. Если ты просишь рассчитать скидки для клиентов и даешь примеры, модель может выдать верный код просто потому, что видела похожие задачи миллион раз, а не потому, что она честно высчитала твои «15% при сумме от 500 рублей».

Короче: не надейся, что тесты в промпте сделают модель умнее — она всё равно может схалтурить. Доверие к коду от LLM без внешней проверки — это ловушка, потому что модель мастерски имитирует понимание там, где на самом деле просто плывет по контексту. Если хочешь реально рабочий код, не просто пихай тесты в промпт, а прогоняй результат через реальный интерпретатор. Иначе рискуешь получить программу, которая выглядит правильно, но ломается на первом же реальном клиенте, потому что нейронка просто так почувствовала.

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

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

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