3,583 papers
arXiv:2508.03678 77 5 авг. 2025 г. FREE

PartialOrderEval: как детализация промпта влияет на качество кода от LLM

КЛЮЧЕВАЯ СУТЬ
"Больше деталей в промпте = лучше код" — логично, но неправильно. На сложных задачах (параллельное программирование C++) детализация даёт +30% pass@1. На простых — плато при 100 словах, дальше качество проседает на 3-6%. PartialOrderEval позволяет найти оптимальную точку детализации. Не слишком мало — модель теряется в вариантах. Не слишком много — когнитивная перегрузка от лишних деталей. Метод создаёт спектр из 40 промптов убывающей детализации для каждой задачи. Тестирование на спектре показывает где точка перегрузки — дальше детализировать бесполезно или даже вредно. Вывод: 67% точности на кратком vs 96% на детальном, но только если задача сложная.
Адаптировать под запрос

TL;DR

PartialOrderEval — фреймворк для оценки LLM, который показывает как меняется pass@1 при увеличении детализации промпта от минимальной (только сигнатура функции) до максимальной (подробное описание с примерами и edge cases). Вместо одного промпта на задачу исследователи создают целый спектр — от "напиши функцию sort()" до "напиши функцию сортировки: вход — список целых чисел от -10⁵ до 10⁵, длина ≤ 1000, выход — тот же список по возрастанию, используй quicksort, обработай пустой массив...".

Главная находка: на сложных задачах (ParEval — parallel computing на C++/OpenMP) детализация промпта даёт прирост до +30% pass@1. На лёгких (HumanEval) — эффект минимальный, плато уже при средней детализации. Это значит: проблема не в том, что модель "не знает" параллельное программирование, а в том, что промпт недостаточно конкретный. Модель может решить сложную задачу, если ей объяснить детально.

Качественный анализ 284 промптов выявил, какие детали дают максимальный эффект: explicit I/O спецификации, обработка граничных случаев (пустой массив, max значения), пошаговая декомпозиция (шаг 1: проверь input, шаг 2: примени алгоритм, шаг 3: проверь output). Абстрактные описания алгоритмов ("используй сортировку") дают меньший прирост — модель и так понимает стратегию, но теряется в деталях реализации.


📌

Схема исследования

ИСТОЧНИК: HumanEval (164 задачи Python) + ParEval (120 задач C++/OpenMP)
↓
ДЛЯ КАЖДОЙ ЗАДАЧИ:
 1. Создать ptop (максимально детальный промпт) → pass@1 ≥ 0.8
 2. Сгенерировать 39 промптов убывающей детализации:
 - LLM Summarization (7 вариантов): 200→150→100→75→50→25→10 слов
 - Paragraph Sampling (16 вариантов): удалить 20%/40%/60%/80% параграфов
 - Sentence Block Masking (16 вариантов): вырезать блоки предложений
 3. pbot (минимальный промпт) — только сигнатура
↓
ОЦЕНКА: 8 моделей (Qwen2.5-Coder 1.5B→14B, Llama-3.x 1B→70B)
МЕТРИКА: pass@1 для каждого уровня детализации
↓
РЕЗУЛЬТАТ: Графики "детализация → pass@1" для каждой модели и бенчмарка

📌

Пример исследуемого феномена

Задача из ParEval-Serial:

// Оригинальный промпт (краткий):
// Напишите функцию prefix_sum, которая вычисляет префиксную сумму массива.

// Максимально детальный промпт (ptop):
// Напишите функцию prefix_sum для вычисления префиксной суммы.
// 
// ВХОД:
// - arr: массив целых чисел длиной n (1 ≤ n ≤ 10^6)
// - n: размер массива
// 
// ВЫХОД:
// - Массив той же длины, где result[i] = sum(arr[0]...arr[i])
// 
// EDGE CASES:
// - Если n = 1, вернуть копию arr
// - Если arr пустой (n = 0), вернуть пустой массив
// - Обработать переполнение при sum > INT_MAX
// 
// АЛГОРИТМ:
// 1. Создать result[n]
// 2. result[0] = arr[0]
// 3. Для i от 1 до n-1: result[i] = result[i-1] + arr[i]
// 4. Вернуть result
// 
// ПРИМЕР:
// arr = [1, 2, 3, 4], n = 4 → [1, 3, 6, 10]
// arr = [-1, 1], n = 2 → [-1, 0]

Результат:

  • Оригинальный промпт: Qwen2.5-14B — 66.7% pass@1
  • Детальный промпт (ptop): Qwen2.5-14B — 96.7% pass@1
  • Прирост: +30%

🧠

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

Слабость LLM: Модели обучены на коде из GitHub, где функции окружены контекстом — импорты, другие функции, комментарии, примеры использования. В бенчмарках этого контекста нет. Модель видит только сигнатуру prefix_sum(arr, n) и должна угадать все детали реализации. На простых задачах (HumanEval: "перевернуть строку") контекста не нужно — паттерн однозначен. На сложных (ParEval: параллельная prefix sum с OpenMP) — модель теряется в вариантах.

Сильная сторона LLM: Модели отлично следуют структурированным инструкциям, если они explicit. Когда промпт содержит спецификацию I/O, edge cases, пошаговый алгоритм — модель не угадывает, а следует протоколу. Это снижает вариативность и повышает корректность. Особенно это работает на задачах, где один неучтённый edge case ломает все тесты (например, пустой массив или переполнение).

Рычаги управления детализацией:

  • Длина промпта — короткий (10-50 слов) vs развёрнутый (150-200 слов). На HumanEval плато при 100 словах, на ParEval — нужно 200+.
  • Тип деталей — I/O спецификация даёт больший прирост, чем абстрактное описание алгоритма.
  • Структура — пошаговая декомпозиция (1. проверь input, 2. примени алгоритм) работает лучше, чем общее описание.

Diminishing returns: На HumanEval добавление деталей после 100 слов снижает pass@1 (с 92.1% при 200 словах до 86% при ptop). Избыточная информация создаёт когнитивную перегрузку — модель теряет фокус среди лишних деталей.


📋

Ключевые инсайты для промптинга

📌

Таксономия эффективных деталей

Исследователи проанализировали 284 промпта и выделили 23 типа деталей, разбитых на 4 категории. Вот топ-10 по влиянию на pass@1:

Высокий рост с детализацией (критичные):

  • 1.3 Input Specification — типы, структуры, ограничения входных данных
  • 1.4 Output Specification — формат возвращаемого значения
  • 1.5 Core Behavior — что именно должна делать функция
  • 2.3 Edge Case Handling — обработка пустых массивов, max значений
  • 3.4 Implementation Sketch — пошаговая декомпозиция или псевдокод

Умеренный рост (полезные):

  • 1.1 Task Goal — одно предложение о цели (есть в 100% промптов)
  • 3.1 Algorithmic Strategy — общая стратегия (сортировка, рекурсия)
  • 3.2 Data Structure — какие структуры использовать (array, hash map)
  • 3.5 Implementation Patterns — типовые паттерны (two-pointer, prefix sum)

Практический вывод: Приоритет — explicit I/O, edge cases, пошаговая инструкция. Абстрактные описания алгоритмов дают меньший эффект — модель и так понимает стратегию.


📌

Когда детализация не помогает

⚠️ Лёгкие задачи: На HumanEval (простые алгоритмы) детализация даёт +6% pass@1, плато при 100 словах.

⚠️ Избыточная детализация: Промпты длиннее 200 слов могут снизить pass@1 на 3-6% из-за когнитивной перегрузки.

⚠️ Модели-малыши: Llama-3.2-1B не догоняет Qwen2.5-14B даже с максимально детальным промптом. Размер модели важнее промпта.


🔍

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

Команда взяла два бенчмарка: HumanEval (164 задачи Python, простые алгоритмы) и ParEval (120 задач C++/OpenMP, научное и параллельное программирование). Для каждой задачи сгенерировали максимально детальный промпт через GPT-4.1 так, чтобы Qwen2.5-14B выдавал pass@1 ≥ 0.8. Затем автоматически создали 39 промптов убывающей детализации через три стратегии: суммаризация LLM (от 200 до 10 слов), случайное удаление параграфов (20-80%), вырезание блоков предложений (20-80%).

Протестировали 8 моделей (Qwen2.5-Coder 1.5B→14B, Llama-3.x 1B→70B) на всех 284 задачах × 41 промпт = 11,644 оценки. Построили графики "детализация → pass@1" для каждой модели. Результаты показали, что:

  • На ParEval кривые растут медленно и не достигают потолка даже при максимальной детализации.
  • На HumanEval кривые быстро выходят на плато (при 100 словах) и иногда падают при избыточной детализации.
  • Разница между большими и малыми моделями на ParEval достигает 34% pass@1 (Qwen2.5-14B vs 1.5B при детализации 80%).

Удивительно: с максимально детальными промптами (ptop) модели достигают 98.3% на ParEval-Serial и 96.7% на ParEval-OMP — это выше HumanEval (86%), который считался "лёгким". Значит, ParEval не сложнее HumanEval по природе задач — просто оригинальные промпты ParEval недостаточно детальные.

Качественный анализ провели через таксономию 23 типов деталей, созданную с помощью o3 и применённую Claude Sonnet 4 ко всем 284 промптам. Это позволило увидеть, какие детали появляются чаще при росте pass@1.


🔗

Ресурсы

More Than a Score: Probing the Impact of Prompt Specificity on LLM Code Generation

Yangtian Zi (Northeastern University), Harshitha Menon (Lawrence Livermore National Laboratory), Arjun Guha (Northeastern University)


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

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

"Больше деталей в промпте = лучше код" — логично, но неправильно. На сложных задачах (параллельное программирование C++) детализация даёт +30% pass@1. На простых — плато при 100 словах, дальше качество проседает на 3-6%. PartialOrderEval позволяет найти оптимальную точку детализации. Не слишком мало — модель теряется в вариантах. Не слишком много — когнитивная перегрузка от лишних деталей. Метод создаёт спектр из 40 промптов убывающей детализации для каждой задачи. Тестирование на спектре показывает где точка перегрузки — дальше детализировать бесполезно или даже вредно. Вывод: 67% точности на кратком vs 96% на детальном, но только если задача сложная.

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

Минимум (pbot): только сигнатура функции — модель угадывает всё остальное. Максимум (ptop): полная спецификация с типами входа/выхода, ограничениями (n ≤ 10^6), граничными случаями (пустой массив, переполнение), пошаговым алгоритмом, примерами. Между ними — 39 вариантов убывающей детализации. Главный инсайт: на простых задачах плато при 100 словах, на сложных нужно 200+ слов с явными граничными случаями. Дальше начинается diminishing returns или даже снижение качества.

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

LLM обучены на коде из GitHub — функции окружены контекстом: импорты, комментарии, примеры использования. В бенчмарках этого контекста нет. Модель видит только сигнатуру и должна угадать детали. На простых задачах контекст не нужен — паттерн однозначен. На сложных (параллельная сортировка с OpenMP) — модель теряется в 10+ вариантах реализации. Explicit инструкции заменяют недостающий контекст. Когда промпт содержит I/O спецификацию, граничные случаи, пошаговый алгоритм — модель не угадывает, а следует протоколу. Результат: минус 30% ошибок от неучтённых граничных случаев. Но избыточная детализация создаёт когнитивную перегрузку. Модель теряет фокус среди лишних деталей.

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

Сложные задачи → системное программирование (параллелизм, многопоточность, низкоуровневые операции), особенно когда один неучтённый граничный случай ломает все тесты (переполнение, пустой массив, race conditions). НЕ подходит для простых алгоритмов (reverse string, find max) — там детализация даёт +3-6%, не стоит усилий.

Мини-рецепт

1. Запусти на минимуме: дай модели только сигнатуру без описания. Получи базовый уровень pass@1 (процент прохождения тестов с первой попытки).

2. Добавляй детали блоками:
- Блок 1: типы входа/выхода + ограничения (n ≤ 10^6, значения от -10^5 до 10^5)
- Блок 2: граничные случаи (пустой массив, один элемент, максимальные значения)
- Блок 3: пошаговый алгоритм (1. проверь input, 2. примени логику, 3. вернуть result)

3. Найди точку перегрузки: если pass@1 перестал расти или упал — стоп, не добавляй больше деталей.

Примеры

[ПЛОХО] : Напиши функцию для вычисления префиксной суммы массива
[ХОРОШО] : Напиши функцию prefix_sum. ВХОД: arr (целые числа, длина 1-10^6), n (размер). ВЫХОД: массив той же длины, result[i] = sum(arr[0]...arr[i]). ГРАНИЧНЫЕ СЛУЧАИ: если n=1 вернуть копию arr, если n=0 вернуть пустой массив, обработать переполнение при sum > INT_MAX. АЛГОРИТМ: 1) создать result[n] 2) result[0]=arr[0] 3) для i от 1 до n-1: result[i]=result[i-1]+arr[i]. ПРИМЕР: [1,2,3,4] → [1,3,6,10]
Источник: More Than a Score: Probing the Impact of Prompt Specificity on LLM Code Generation
ArXiv ID: 2508.03678 | Сгенерировано: 2026-01-12 02:29

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

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

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