3,583 papers
arXiv:2607.11346 77 13 июля 2026 г. FREE

Compile & Page: псевдокод вместо прозы для надёжного следования сложным инструкциям

КЛЮЧЕВАЯ СУТЬ
Одни и те же инструкции — другой формат — и модель перестаёт пропускать шаги. +16 пунктов точности без изменения содержания. Метод Compile & Page позволяет надёжно прогонять сложные многошаговые процедуры через LLM — квалификацию заявок, проверку по чеклисту, согласование по правилам. Фишка: не объяснять процедуру текстом, а переписать её в псевдокод с явными if/else и subroutines — модель обучена на миллионах строк кода, поэтому структура функции это не текст для интерпретации, а каркас, который нельзя переставить местами.
Адаптировать под запрос

TL;DR

Когда вы пишете LLM длинную инструкцию текстом — "сначала проверь X, потом если Y то сделай Z, иначе откажи" — модель пропускает шаги, путает условия, выполняет действие до проверки. Исследовательская группа обнаружила: переписать ту же инструкцию в виде псевдокода (с явными if/else, именованными подпроцедурами и явным возвратом доказательств) поднимает точность следования на 16 пунктов — при неизменном содержании, только другой формат.

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

Авторы предложили два слоя. Первый — компиляция: переписать инструкцию в структурированный псевдокод с явными условиями, подпрограммами-проверками и возвратом доказательств. Второй — пэйджинг: показывать модели только активный шаг, а не весь документ. Первый слой работает сам по себе и безопасен. Второй зависит от "дисциплины состояния" модели — слабым LLM он вредит.


🔬

Схема метода

ШАГ 1 — КОМПИЛЯЦИЯ (один раз, офлайн)
  Берём инструкцию в виде текста
  → Переписываем в псевдокод:
      · process_function — один на цель/задачу
      · rule_subroutine — проверка + рецепт верификации + возврат {результат, доказательство}
      · явные if/else для условий отказа
  → Получаем программу, живёт в системном промпте

ШАГ 2 — ПЭЙДЖИНГ (опционально, только для сильных моделей)
  Вместо всей программы → показываем только активный фрейм
  Каждый запрос = один шаг программы
  → При call/return — вставляем следующий фрейм

! Оба шага выполняются в обычном чате, без кода
! Шаг 1 работает отдельно — Шаг 2 без Шага 1 не имеет смысла

🚀

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

Задача: Вы — основатель небольшого SaaS для B2B в России. Хотите, чтобы Claude квалифицировал входящие заявки строго по вашей процедуре: проверил бюджет, сроки, ЛПР, и либо записал на демо, либо вежливо отказал. Обычно пишете это текстом — Claude иногда записывает всех подряд, иногда забывает проверить бюджет.

Промпт (псевдокод-формат):

Ты — квалификационный ассистент. Следуй программе строго.

function qualify_lead(company, contact):

    # ШАГ 1: Проверка ЛПР
    result1 = check_decision_maker(contact)
    if result1.holds != true:
        refuse("Нужно общаться с ЛПР. " + result1.evidence)
        return

    # ШАГ 2: Проверка бюджета
    result2 = check_budget()
    if result2.holds != true:
        refuse("Бюджет не соответствует. " + result2.evidence)
        return

    # ШАГ 3: Проверка срочности
    result3 = check_timeline()
    if result3.holds != true:
        refuse("Сроки не совпадают. " + result3.evidence)
        return

    # Только если все проверки пройдены:
    schedule_demo(company, contact)
    return {action: "demo_scheduled", evidence: [result1, result2, result3]}

subroutine check_decision_maker(contact):
    # Задай вопрос: принимает ли контакт решение о покупке?
    # Верни: {holds: true/false, evidence: цитата из ответа клиента}

subroutine check_budget():
    # Задай вопрос: есть ли бюджет от 50 000 руб/мес?
    # Верни: {holds: true/false, evidence: цитата из ответа клиента}

subroutine check_timeline():
    # Задай вопрос: планируют ли внедрение в течение 3 месяцев?
    # Верни: {holds: true/false, evidence: цитата из ответа клиента}

Начни с: "Здравствуйте! Расскажите о вашей задаче."
Веди диалог, собирая данные для каждой проверки по очереди.
ВАЖНО: не переходи к следующему шагу без завершения текущего.
ВАЖНО: при отказе — всегда цитируй конкретный ответ клиента как доказательство.

Результат: Модель поведёт диалог строго по процедуре — сначала выяснит роль контакта, потом бюджет, потом сроки. При несоответствии любого критерия — откажет с явным объяснением и цитатой из разговора. До записи на демо дойдёт только если все три проверки вернули holds: true. Вы увидите в ответе не просто "записал/отказал", а структурированный вывод с доказательной базой.


🧠

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

Слабость LLM: проза сжимает структуру. Когда вы пишете "сначала проверь X, потом если не выполнено — откажи, иначе проверь Y" — модель видит одно длинное предложение. Границы условий размыты. Порядок не закреплён. Чем длиннее инструкция, тем сильнее ранние правила давят на поздние. Модель "видит" всё сразу, но удерживает неравномерно.

Сильная сторона LLM: следовать явным структурам. Модель хорошо обучена на коде — исходников в её обучающих данных было много. Синтаксис if/else, call, return, именованные функции — это однозначный язык: нет двусмысленности в порядке, нет слияния "что" и "как", каждое условие — отдельная единица. Псевдокод не нужно исполнять технически. Он работает как структурная метка — помогает модели генерировать текст по нужному паттерну.

Как метод использует это: Компиляция переводит неоднозначную прозу в формат, где порядок зафиксирован явно, условия выхода (refuse + return) отделены от шагов выполнения, а проверки возвращают доказательство — не просто "да/нет". Это убирает главный источник ошибок: "додумывание" порядка и пропуск шагов.

Рычаги управления: - return {holds, evidence} → убери evidence, если хочешь краткий ответ; добавь поля, если нужна подробная аудитория - Глубина subroutines → для простых задач объедини в одну функцию; для сложных — выноси каждую проверку отдельно - Явные refuse + return → замени на другое поведение: escalate, ask_more, suggest_alternative - Количество шагов → чем больше критических шагов — тем сильнее выигрыш от псевдокода над прозой


📋

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

Ты — [роль]. Следуй программе строго.

function {название_процедуры}({параметры}):

    result1 = {проверка_1}()
    if result1.holds != true:
        {действие_при_отказе_1}(result1.evidence)
        return

    result2 = {проверка_2}()
    if result2.holds != true:
        {действие_при_отказе_2}(result2.evidence)
        return

    # Все проверки пройдены:
    {целевое_действие}({параметры})
    return {result: "success", evidence: [result1, result2]}

subroutine {проверка_1}():
    # Что спросить / что проверить
    # Верни: {holds: true/false, evidence: [конкретная цитата или факт]}

subroutine {проверка_2}():
    # Что спросить / что проверить
    # Верни: {holds: true/false, evidence: [конкретная цитата или факт]}

ПРАВИЛА ВЫПОЛНЕНИЯ:
- Не переходи к следующему шагу без завершения текущего
- При отказе — всегда цитируй конкретное основание из evidence
- Не выполняй {целевое_действие} без прохождения всех проверок

Плейсхолдеры: - {роль} — кто ведёт процедуру: "квалификационный менеджер", "редактор", "аналитик" - {название_процедуры} — что делаем: qualify_lead, approve_content, review_request - {проверка_N} — конкретная проверка: check_budget, verify_source, confirm_deadline - {действие_при_отказе} — что делать при несоответствии: refuse, escalate, request_revision - {целевое_действие} — финальный шаг, если всё ОК: schedule_demo, publish, approve


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

Вот шаблон для составления псевдокод-инструкции. 
Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить все поля.

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

LLM спросит про шаги процедуры, условия отказа и что считать доказательством — потому что без этого псевдокод-структура не заполнится. Она возьмёт паттерн из шаблона и адаптирует под твою процедуру.


⚠️

Ограничения

⚠️ Слабые модели: Пэйджинг (показ только активного фрейма) вредит моделям без "дисциплины состояния" — они теряются без глобального контекста. Компиляция в псевдокод при этом безопасна для всех. Если используете небольшую или менее мощную модель — применяйте только шаблон, без пошагового пэйджинга.

⚠️ Субъективные задачи: Метод создан для процедур с чёткими критериями "выполнено / не выполнено". Для творческих задач (оценка качества текста, генерация идей) псевдокод-формат даёт меньше прироста — там нет чётких holds: true/false.

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

⚠️ Нужна предварительная работа: Чтобы написать псевдокод, сначала нужно самому чётко знать процедуру. Если процесс размыт в голове — псевдокод это обнажит. Это плюс для качества процесса, но требует усилий на старте.


🔍

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

Команда из Polytechnic University Hong Kong взяла SOPBench — специальный бенчмарк с задачами из банковской сферы, здравоохранения, библиотек, DMV и других доменов. Каждая задача — это сценарий: агент должен либо выполнить операцию (если все условия выполнены), либо корректно отказать (если нет). Оценщик проверяет не только финальное решение, но и порядок вызовов инструментов.

Три конфигурации сравнивали на одном наборе задач: официальный текст SOP (проза), тот же SOP в виде псевдокода без runtime, и псевдокод с пэйджинг-рантаймом. Шесть моделей разного уровня — от слабых (GPT-4o-mini, Qwen2.5-7B) до сильных (DeepSeek-V4-Flash, Qwen3.7-Plus). Это важная деталь дизайна: авторы специально хотели поймать порог способностей.

Результат оказался неожиданно чистым: компиляция в псевдокод помогла всем сильным моделям и не навредила никому. Пэйджинг разделил поле надвое — сильные модели улучшились ещё, слабые потеряли катастрофически (−26 пунктов для GPT-4o-mini). Авторы проверили механизм через "зонды": выяснилось, что слабые модели могли реконструировать глобальный контекст из памяти — проблема не в забывчивости. Проблема в том, что без полного текста перед глазами они теряли спонтанную дисциплину: начинали делать дополнительные вызовы после завершения задачи, путали порядок.

Самый практичный вывод: компилируй всегда, пэйджинг — только после проверки модели.


💡

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

🔧 Техника: вложенные subroutines → разбивка сложных проверок

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

subroutine verify_payment_capacity():
    step1 = check_monthly_revenue()
    step2 = check_existing_debts()
    if step1.holds and not step2.holds:
        return {holds: false, evidence: "доход есть, но есть долги: " + step2.evidence}
    return {holds: step1.holds, evidence: step1.evidence}

🔧 Техника: "аудит-трейл" в финальном ответе

Добавьте в финальный return явный список всех пройденных проверок с доказательствами. Получаете структурированный протокол решения — удобно для согласования с командой или логирования:

return {
    decision: "demo_scheduled",
    audit: [
        {check: "ЛПР", result: true, evidence: "..цитата.."},
        {check: "бюджет", result: true, evidence: "..цитата.."},
        {check: "срочность", result: true, evidence: "..цитата.."}
    ]
}

🔧 Комбинация с Chain-of-Thought: Псевдокод фиксирует что проверять и в каком порядке. CoT добавляет как рассуждать внутри каждого шага. Вставьте внутри subroutine явную инструкцию: # Рассуждай вслух перед тем как вернуть результат — получите и структуру, и прозрачность рассуждений.


🔗

Ресурсы

Название: Compile, Then Page: Executable SOP Programs and a Capability-Gated Runtime for Procedural LLM Agents

Авторы: Chenglin Yu, Li Yin, Ying Yu, Hongxia Yang, Ming Li

Организации: The Hong Kong Polytechnic University, The University of Hong Kong, Zhejiang Normal University

Связанное: SOPBench [Li et al., 2025], InfiAgent runtime, DSPy, StateFlow


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

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

Одни и те же инструкции — другой формат — и модель перестаёт пропускать шаги. +16 пунктов точности без изменения содержания. Метод Compile & Page позволяет надёжно прогонять сложные многошаговые процедуры через LLM — квалификацию заявок, проверку по чеклисту, согласование по правилам. Фишка: не объяснять процедуру текстом, а переписать её в псевдокод с явными if/else и subroutines — модель обучена на миллионах строк кода, поэтому структура функции это не текст для интерпретации, а каркас, который нельзя переставить местами.

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

Проза — это одно длинное предложение для модели. Все условия сливаются. Порядок держится на интонации, не на синтаксисе. Чем дальше правило в тексте — тем реже оно применяется. Псевдокод меняет это. Каждое условие — отдельная единица: if result.holds != true: refuse() return. Порядок закреплён структурой, а не формулировкой. Подпрограмма subroutine отделяет «что должно быть правдой» от «как это проверить». Возврат {holds, evidence} требует не просто ответа, а доказательства. Модель не «читает» инструкцию — она «исполняет» программу. Точнее, генерирует текст по паттерну программы — что для неё одно и то же. Важная оговорка: авторы предлагают два слоя. Первый — компиляция в псевдокод — работает отдельно и безопасен для любых моделей. Второй — пэйджинг (показывать только активный шаг) — требует сильной модели. Слабым моделям без «дисциплины состояния» пэйджинг вредит: без глобального контекста они теряются.

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

LLM обучалась на огромном количестве кода. Синтаксис if/else, именованные функции, return {holds, evidence} — однозначный язык без двусмысленности. Проза многозначна: «сначала проверь X, если не выполнено — откажи» можно прочитать по-разному. if x.holds != true: refuse() — нельзя. Псевдокод не исполняется технически — он работает как структурная метка. Направляет генерацию токенов по нужному паттерну, убирая главный источник ошибок: «додумывание» порядка и слияние условий. Плюс: явный return после отказа не даёт модели «пробежать дальше по инерции» — что проза не гарантирует никак.

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

Процедуры с 3+ зависимыми шагами и условной логикой — квалификация входящих заявок, проверка контента по редполитике, согласование запросов по правилам, многошаговые диагностики. Особенно когда важен жёсткий порядок шагов и нужны явные основания для отказа, а не просто «нет». НЕ подходит для творческих задач без чётких критериев «выполнено / не выполнено» — оценка качества текста, генерация идей. Там нет чего возвращать в holds: true/false, и псевдокод не даст прироста. Для одношаговых инструкций — переусложнение без пользы.

Мини-рецепт

1. Выпиши процедуру: какие шаги, в каком порядке, что является жёстким условием отказа — не на ходу, а заранее. Если сваливается в «ну примерно так» — псевдокод это обнажит.

2. Создай основную функцию: каждый шаг — вызов отдельной подпрограммы. После каждого вызова — проверка: if result.holds != true: refuse(result.evidence) return. Финальное действие — только в конце, когда все проверки прошли.

3. Опиши каждую подпрограмму: что спросить или проверить, и что вернуть — {holds: true/false, evidence: цитата из ответа}. Поле evidence важно — без него модель скажет «отказал», но не объяснит почему.

4. Добавь правила выполнения в конце: не переходить к следующему шагу без завершения текущего, при отказе всегда цитировать основание, не выполнять финальное действие без всех проверок.

5. Проверь на слабой модели отдельно: компиляция безопасна для всех. Пэйджинг (показ только активного шага) — только если модель держит состояние между запросами.

Примеры

[ПЛОХО] : Проверь бюджет клиента и сроки, потом если всё подходит — запиши на демо, иначе вежливо откажи
[ХОРОШО] : Ты — квалификационный ассистент. Следуй программе строго. function qualify_lead(company, contact): result1 = check_budget() if result1.holds != true: refuse("Бюджет не соответствует. " + result1.evidence) return result2 = check_timeline() if result2.holds != true: refuse("Сроки не совпадают. " + result2.evidence) return schedule_demo(company, contact) return {action: "demo_scheduled", evidence: [result1, result2]} subroutine check_budget(): # Спроси: есть ли бюджет от 50 000 руб/мес? # Верни: {holds: true/false, evidence: цитата из ответа} subroutine check_timeline(): # Спроси: планируют ли внедрение в течение 3 месяцев? # Верни: {holds: true/false, evidence: цитата из ответа} ПРАВИЛА: - Не переходи к следующему шагу без завершения текущего - При отказе — всегда цитируй конкретное основание из evidence - Не записывай на демо без прохождения всех проверок Модель поведёт диалог строго по порядку. Пропустить бюджет и сразу спросить про сроки — не сможет. Записать без проверки бюджета — не сможет. При отказе выдаст цитату из разговора, а не абстрактное «не подходите».
Источник: Compile, Then Page: Executable SOP Programs and a Capability-Gated Runtime for Procedural LLM Agents
ArXiv ID: 2607.11346 | Сгенерировано: 2026-07-14 06:26

Проблемы LLM

ПроблемаСутьКак обойти
Проза размывает порядок и условия в длинных инструкцияхКогда пишешь "сначала проверь X, потом если Y — откажи, иначе делай Z" — модель видит один длинный текст. Границы условий размыты. Порядок шагов не закреплён. Чем длиннее инструкция — тем сильнее ранние правила давят на поздние. Итог: модель пропускает шаги, путает условия, делает действие до проверки. Проблема растёт с каждым добавленным шагомПерепиши инструкцию в псевдокод: явные if/else, именованные подпроцедуры, явный return с результатом. Содержание то же — только формат другой

Методы

МетодСуть
Псевдокод-структура для процедурных инструкцийПерепиши многошаговую инструкцию как программу. Одна главная функция — одна цель. Каждая проверка — отдельная подпроцедура с явным return {holds: true/false, evidence: "..."}. Условия отказа — явные if result.holds != true: refuse(result.evidence); return. Почему работает: модель обучалась на огромных объёмах кода. Синтаксис if/else, call, return — однозначный язык. Нет размытости в порядке. Каждое условие — отдельная единица. Псевдокод не нужно исполнять технически — он работает как структурная метка. Когда применять: 3+ зависимых шага с условной логикой (квалификация, согласование, роутинг). Когда не работает: один шаг, творческие или субъективные задачи без чётких критериев

Тезисы

ТезисКомментарий
Явный синтаксис кода точнее прозы для условной логикиПроза — размытый формат. Слова "сначала", "если", "иначе" сливаются в один поток. Код — однозначный формат. if/else ставит жёсткую границу. return закрывает ветку. Порядок нельзя перепутать. Модель лучше следует структуре кода — потому что кода в её обучении было очень много. Применяй: когда пишешь "сначала X, потом Y, если не так — откажи" — переключись на if/else-форму. Не нужен настоящий код. Нужна структура
📖 Простыми словами

Compile, Then Page: Executable SOP Programs and a Capability-Gated Runtime for ProceduralLLMAgents

arXiv: 2607.11346

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

Это как пытаться объяснить пьяному другу сложный маршрут до бара по телефону. Ты ему: «Поверни налево у аптеки, но только если там горит свет, иначе иди прямо», а он слышит только «аптека» и «иди прямо». В итоге он уходит в другой район, потому что его мозг не вывез сложную логику в разговорном формате. Модели ведут себя точно так же — они отлично понимают слова, но отвратительно держат структуру ветвления в обычном абзаце.

Решение оказалось до смешного простым: нужно превратить инструкцию в исполняемый код. Исследователи внедрили метод Compile, Then Page, где вместо «человеческого» описания используется жесткий псевдокод с явными if/else, именованными функциями и обязательным возвратом доказательств. Когда ты упаковываешь ту же самую задачу в формат алгоритма, точность следования правилам взлетает на 16 пунктов. Содержание не изменилось ни на йоту, поменялась только «упаковка» логики.

Этот принцип универсален и применим везде, где от агента нужна дисциплина: от квалификации лидов в B2B до сложной модерации контента. Тестировали на строгих процедурах, но фишка работает для любого промпта, который длиннее пары предложений. SEO для мозгов AI теперь выглядит так: заменяй художественные описания на структурированные алгоритмы. Если хочешь, чтобы Claude или GPT не тупили на развилках, перестань с ними «разговаривать» и начни их «программировать».

Короче, хватит надеяться на здравый смысл нейронки — его там нет, есть только статистика предсказания следующего слова. Хочешь результат без косяков — пиши псевдокодом. Это дает модели четкие визуальные якоря и не позволяет игнорировать условия. Либо ты тратишь время на структурирование промпта, либо потом разгребаешь последствия того, что твой AI-ассистент формально всё прочитал, но всё перепутал.

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

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

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