TL;DR
CBIT — техника, при которой LLM не создаёт контент напрямую, а пишет программу-генератор, которая потом производит нужный контент. Вместо "напиши 10 похожих задач" → "напиши программу, которая будет создавать похожие задачи". Исходно разработан для генерации математических задач-близнецов (изоморфных задач) в образовании.
Главная находка: Когда LLM генерирует много похожих элементов подряд, она либо начинает пропускать часть запрошенного, либо делает математические ошибки. Причина — модель пытается держать в "голове" и структуру, и содержание, и числовые связи одновременно. При генерации 100 элементов напрямую успех падает до 1%. Но если попросить LLM написать программу-генератор — успех остаётся на уровне 83%, а стоимость падает в 42 раза.
Механика решения: Разделить задачу на два уровня. Первый — LLM пишет "чертёж" (blueprint): программу с логикой генерации и шаблоном. Второй — программа исполняется детерминированно и выдаёт сколько угодно корректных вариантов. LLM работает только один раз, дальше — чистая математика без галлюцинаций.
Схема метода
ШАГ 1: Шаблонизация → выделить постоянную структуру + переменные слоты
ШАГ 2: LLM пишет программу-генератор → код с логикой заполнения слотов
ШАГ 3: Программа исполняется → N корректных вариантов из разных seed
Ключевое отличие: LLM не генерирует контент — она генерирует механизм генерации контента.
Пример применения
Задача: Репетитор по математике готовит ученика к ОГЭ. Нужно 20 вариантов задачи на квадратные уравнения — одинаковая структура, разные числа. Вручную писать долго, просить LLM "сгенерируй 20 задач" — половина будет с ошибками в ответах.
Промпт:
Вот задача-образец:
"Решите уравнение x² - 5x + 6 = 0. Найдите сумму корней."
Решение: По теореме Виета, сумма корней = 5. Ответ: 5
Напиши Python-программу, которая генерирует изоморфные задачи:
1. Выдели шаблон с переменными (коэффициенты a, b, c)
2. Добавь ограничения: дискриминант > 0, корни — целые числа от 1 до 10
3. Программа должна принимать seed и возвращать: текст задачи, решение, ответ
Программа должна гарантировать математическую корректность — ответ вычисляется, а не придумывается.
Результат:
Модель выдаст Python-код с функцией generate_problem(seed). Код содержит:
- Шаблон текста с плейсхолдерами
- Логику генерации коэффициентов (сначала выбираются корни, потом вычисляются коэффициенты — так гарантируется целочисленность)
- Детерминированный расчёт ответа
Запуская код с разными seed (1, 2, 3...), получаешь 20 гарантированно корректных задач.
Почему это работает
Слабость LLM: При генерации множества похожих элементов модель теряет точность. Она пытается одновременно: (1) помнить структуру, (2) варьировать числа, (3) проверять связи между числами. Когнитивная нагрузка растёт — ошибки накапливаются. Исследование показало: при запросе 100 задач напрямую успех падает до 1%.
Сильная сторона LLM: Модели отлично понимают паттерны и умеют писать код. Программирование для них — способ "экстернализировать" логику: вынести вычисления наружу, где они выполняются детерминированно, без галлюцинаций.
Как метод это использует: CBIT переносит вычислительную работу из "головы" модели в исполняемый код. LLM работает на мета-уровне — создаёт генератор один раз. Дальше программа производит сколько угодно вариантов без повторных обращений к модели. Математическая корректность гарантируется кодом, а не надеждой на внимательность LLM.
Рычаги управления:
- Ограничения в коде → меняй диапазоны чисел, условия корректности под свою задачу
- Шаблон текста → адаптируй формулировки, сохраняя плейсхолдеры
- Seed → каждый seed = новый вариант, воспроизводимость гарантирована
Шаблон промпта
Вот образец контента:
{образец_с_числами}
Напиши Python-программу для генерации изоморфных вариантов:
1. Выдели шаблон: что остаётся постоянным, что меняется (пометь как переменные)
2. Определи ограничения: какие связи между переменными должны сохраняться
3. Функция generate(seed) должна:
- Принимать seed для воспроизводимости
- Генерировать корректные значения переменных
- Возвращать: {формат_вывода}
Критично: все вычисляемые значения (ответы, промежуточные результаты) должны рассчитываться в коде, а не вставляться вручную.
Плейсхолдеры:
{образец_с_числами}— конкретный пример того, что нужно размножить{формат_вывода}— что должна возвращать функция (текст, решение, ответ и т.д.)
🚀 Быстрый старт — вставь в чат:
Вот шаблон CBIT для генерации вариантов. Адаптируй под мою задачу: [твоя задача].
Задавай вопросы, чтобы понять структуру.
[вставить шаблон выше]
LLM спросит: какой образец взять за основу, какие элементы должны меняться, какие ограничения соблюдать — потому что это определяет логику генератора. Она напишет код, который ты запустишь в Code Interpreter или локально.
Ограничения
⚠️ Требуется выполнение кода: Метод работает в полную силу только если можешь запустить Python — в ChatGPT с Code Interpreter, в Claude с computer use, или локально. Без исполнения кода получаешь только "чертёж", но не готовые варианты.
⚠️ Числовые задачи: CBIT заточен под контент, где корректность определяется числовыми связями (математика, финансы, статистика). Для задач с чисто логической структурой (загадки про лжецов/правдолюбцев) или субъективных критериев (оценка креатива) метод не применим.
⚠️ Нужен качественный образец: Программа-генератор наследует структуру исходного примера. Если образец плохо структурирован или содержит неявные зависимости — генератор их не уловит.
Как исследовали
Команда из корейского EdTech-стартапа Turing взяла 195 задач из школьной программы (4-12 класс), охватывающих 67 тем — от дробей до интегралов. Каждую задачу разобрали на "символьные связи" — получилось 2,410 зависимостей между числами, которые нужно сохранять.
Сравнили три подхода: базовый AIC-Batch (LLM генерирует задачи напрямую + пишет верификатор), BIT (LLM генерирует только "абстракцию" с числами, текст добавляется по шаблону), и финальный CBIT (LLM пишет программу-генератор).
Результаты удивили масштабом разрыва. При запросе 100 задач: AIC-Batch — успех 1%, стоимость $30 за 1000 задач. CBIT — успех 83%, стоимость $0.71. Разница в 42 раза по стоимости при радикально более высокой точности.
Но главное — реальный деплой: 32,131 задач от CBIT показали 6,732 ученикам, получили 186,870 попыток решения. Процент ошибок: 0.19% у CBIT против 0.23% у задач от экспертов-людей. Автоматика оказалась на 17.8% надёжнее человеческих авторов.
Инсайт: переход от "генерируй контент" к "генерируй генератор контента" — это не просто оптимизация, это качественный скачок. Когда LLM перестаёт "придумывать" числа и начинает "вычислять" их через код, галлюцинации исчезают.
Оригинал из исследования
def genTwin(seed):
symbolized_question = {...}
symbolized_solution = {
"From the equation $x^#SY04#-#SY05#x+#SY06#=#SY07#$,",
"$\qquad (x-#SY08#)(x-#SY09#)=#SY10#"
}
random.seed(seed)
### Start - LLM заполняет этот блок ###
sy_04 = 2
sy_07 = 0
sy_08, sy_09 = sample(range(1, 6), 2)
sy_05 = sy_08 + sy_09
sy_06 = sy_08 * sy_09
### End ###
twin_question = assign_symbol(symbolized_question, [sy_01, sy_02, ...])
twin_solution = assign_symbol(symbolized_solution, [sy_04, sy_05, ...])
return twin_question, twin_solution
```
**Контекст:** Исследователи дают LLM "скелет" функции с шаблоном и плейсхолдерами (`#SY04#`, `#SY05#`). LLM заполняет только блок между `### Start ###` и `### End ###` — логику генерации чисел. Ключевой момент: **корни уравнения выбираются первыми**, потом из них вычисляются коэффициенты — это гарантирует, что уравнение всегда имеет целые корни.
---
## Адаптации и экстраполяции
### 💡 Адаптация для задач без кода
Если нет доступа к Code Interpreter, можно использовать **облегчённую версию принципа** — попросить LLM описать генератор словами:
```
Вот задача-образец: [задача]
Опиши алгоритм генерации похожих задач:
1. Какие элементы постоянные, какие переменные?
2. Какие ограничения между переменными?
3. В каком порядке генерировать значения, чтобы гарантировать корректность?
Потом применяй этот алгоритм и сгенерируй 5 вариантов, показывая каждый шаг.
```
Это менее надёжно (LLM всё ещё может ошибиться в вычислениях), но лучше чем "просто сгенерируй 5 задач".
---
### 🔧 Техника: расширение за пределы математики
Принцип "генерируй генератор" применим к любому **структурированному контенту с вариациями**:
**Тестовые данные для QA:**
```
Образец: {"user_id": 12345, "order_total": 1500, "items": 3, "discount": 0.1}
Напиши функцию generate_test_order(seed), которая создаёт валидные тестовые заказы:
- order_total = сумма цен items
- discount применяется если order_total > 1000
- user_id уникален для каждого seed
```
**Шаблоны договоров:**
```
Образец: Договор аренды с суммой 50000 руб/мес, срок 12 месяцев, депозит = 2 месяца
Напиши генератор вариантов:
- Сумма от 30000 до 100000
- Срок 6/12/24 месяца
- Депозит всегда = 2 × месячная сумма (вычисляется, не вставляется)Ресурсы
Работа: "Computational Blueprints: Generating Isomorphic Mathematics Problems with Large Language Models"
Авторы: Jeong-Hoon Kim, Jinwoo Nam, Geunsik Jo — Turing Co. Ltd. (Корея)
Репозиторий: https://github.com/eric-jhoon/IMPG — бенчмарк + инструменты верификации
Ключевые отсылки: Program-of-Thought prompting (Chen et al., 2023) — идея выносить вычисления в код для повышения надёжности
