English translation is not available yet. Showing Russian content.

Как вы делаете synthetic data для сложного рассуждения (math, code)?

Краткий тезис

Синтетические данные для сложного рассуждения (math, code) создаются через генерацию Chain-of-Thought (пошаговых рассуждений) с последующей валидацией: другой LLM проверяет логику, для кода — запуск в песочнице, а также через backward generation (ответ → вопрос) и self-consistency (множественные траектории с голосованием). Эти методы позволяют получать большие размеченные датасеты без ручной аннотации, что критически важно для обучения агентов, способных к многошаговому рассуждению в Agentic RAG.


1. Термин: Synthetic data для reasoning

Synthetic data — это искусственно сгенерированные данные, имитирующие реальные. В контексте сложного рассуждения (math, code) это пары (вопрос, пошаговое решение + ответ), созданные LLM без участия человека.

Зачем нужны синтетические данные

  • Ручная разметка сложных рассуждений (например, доказательств теорем или многошаговых алгоритмов) крайне дорога и трудоёмка.
  • Для обучения Agentic RAG (агентов, которые используют инструменты и делают несколько шагов) требуются тысячи примеров с цепочками действий.
  • Синтетические данные позволяют масштабировать датасеты и покрывать редкие сценарии.

Основные подходы (из черновика):


2. Chain-of-Thought (CoT) генерация

Chain-of-Thought — это методика, при которой LLM генерирует не только ответ, но и промежуточные шаги рассуждения. Для синтетических данных мы используем CoT-промпты, чтобы получить размеченные примеры.

Пример промпта для математики

Ты — репетитор по математике. Реши задачу пошагово, объясняя каждый шаг.
Задача: {question}
Решение:

Пример генерации

Задача: Если x + 2 = 5, чему равно x?
Решение:
1. Исходное уравнение: x + 2 = 5.
2. Вычтем 2 из обеих частей: x + 2 - 2 = 5 - 2.
3. Получаем: x = 3.
Ответ: 3.

Для кода промпт может требовать генерации кода с комментариями и выводом.

Проблема LLM может генерировать правдоподобные, но неверные рассуждения. Поэтому нужна валидация.


3. Проверка (Check) другим LLM

Используется второй LLM (или та же модель с другим промптом) для верификации корректности рассуждения.

Методы проверки

  • Проверка ответа совпадает ли финальный ответ с правильным (если известен).
  • Проверка шагов логически ли каждый шаг следует из предыдущего, нет ли ошибок в арифметике или синтаксисе кода.
  • Критерии для math — численная проверка, для code — запуск и сравнение вывода с ожидаемым.

Пример промпта для проверки

Проверь решение математической задачи. Укажи, верен ли каждый шаг, и есть ли ошибка в ответе.
Задача: {question}
Решение: {solution}
Вердикт (верно/неверно):

Таблица: плюсы и минусы проверки LLM

ПлюсыМинусы
Не требует внешних инструментовLLM может пропустить ошибки (hallucination)
Быстро и дешевоЗависит от качества модели-верификатора
МасштабируетсяТрудно проверить сложные логические цепочки

4. Симуляция для кода

Для задач, связанных с программированием, лучший способ валидации — запустить сгенерированный код в изолированной среде (песочнице) и проверить результат.

Процесс

  1. LLM генерирует код по описанию задачи.
  2. Код выполняется в контейнере (Docker, subprocess с ограничениями).
  3. Сравнивается вывод с ожидаемым (если есть тесты) или проверяется отсутствие ошибок.
  4. Если код не работает или выдаёт неверный результат — пример отбрасывается или модифицируется.

Пример на Python

import subprocess
import tempfile

def validate_code(code, test_input, expected_output):
    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
        f.write(code)
        f.flush()
        try:
            result = subprocess.run(
                ['python', f.name],
                input=test_input,
                capture_output=True,
                text=True,
                timeout=5
            )
            return result.stdout.strip() == expected_output.strip()
        except Exception:
            return False

Преимущество объективная проверка, не зависит от LLM. Недостаток нужно готовить тесты, что тоже может быть автоматизировано (LLM генерирует тесты).


5. Backward generation

Backward generation (обратная генерация) — метод, при котором сначала создаётся ответ или решение, а затем по нему генерируется вопрос. Это гарантирует, что вопрос имеет корректный ответ.

Алгоритм

  1. Выбираем тему (например, "линейные уравнения").
  2. LLM генерирует случайное корректное решение (например, x = 3).
  3. На основе решения LLM генерирует вопрос: "Придумай задачу, ответом на которую будет x = 3".
  4. Проверяем, что при решении сгенерированного вопроса получается исходный ответ (можно через CoT + проверку).

Пример:

  • Шаг 1: Решение: x = 3.
  • Шаг 2: Сгенерированный вопрос: "Решите уравнение: 2x + 1 = 7".
  • Шаг 3: Проверка: решаем уравнение — получаем x = 3. Совпало → пример корректен.

Преимущество гарантируется, что ответ правильный (если проверка пройдена). Недостаток вопросы могут быть однотипными или слишком простыми.


6. Self-consistency

Self-consistency — метод, при котором для одного вопроса генерируется несколько независимых цепочек рассуждений (CoT), а затем выбирается наиболее частый ответ (majority vote). Если ответы совпадают, пример считается надёжным.

Процесс

  1. Для вопроса Q LLM генерирует N рассуждений (например, 5).
  2. Из каждого извлекается финальный ответ.
  3. Выбирается ответ, который встречается чаще всего.
  4. Если все ответы разные — пример отбрасывается.

Пример для math

  • Вопрос: "Сколько будет 12 * 15?"
  • Рассуждение 1: "1210=120, 125=60, 120+60=180" → ответ 180.
  • Рассуждение 2: "1510=150, 152=30, 150+30=180" → ответ 180.
  • Рассуждение 3: "12*15=180" → ответ 180.
  • Majority vote: 180 → пример принимается.

Self-consistency повышает качество датасета, отсеивая случайные ошибки. Используется как финальный фильтр.


7. Комбинированные методы

На практике подходы комбинируют. Пример пайплайна для создания датасета по математике:

  1. Backward generation → получаем вопрос и гарантированный ответ.
  2. CoT генерация → LLM строит пошаговое решение.
  3. Проверка другим LLM → верификация шагов.
  4. Self-consistency → генерация 3 траекторий, majority vote.
  5. Фильтрация → оставляем только примеры, где все проверки пройдены.

Для кода дополнительно добавляется симуляция (запуск кода с тестами).

Таблица сравнения методов

МетодТип валидацииНадёжностьСтоимость
CoT + проверка LLMЛогическаяСредняяНизкая
Симуляция кодаИсполнениеВысокаяСредняя
Backward generationОбратная связьВысокая (при проверке)Средняя
Self-consistencyСтатистическаяВысокаяВысокая (много вызовов)

8. Инструменты и фреймворки

  • DSPy — фреймворк для программирования LLM, позволяет строить пайплайны генерации и валидации синтетических данных. Есть модули ChainOfThought, ReAct, Assertions.
  • LangChain — с помощью LLMChain и SequentialChain можно организовать многошаговую генерацию и проверку.
  • OpenAI / Anthropic API — прямые вызовы с кастомными промптами.
  • Собственные скрипты на Python с использованием asyncio для параллельной генерации.

Пример на DSPy (упрощённо):

import dspy

class GenerateCoT(dspy.Signature):
    question = dspy.InputField()
    reasoning = dspy.OutputField()
    answer = dspy.OutputField()

class VerifySolution(dspy.Signature):
    question = dspy.InputField()
    reasoning = dspy.InputField()
    answer = dspy.InputField()
    is_correct = dspy.OutputField(desc="True/False")

pipeline = dspy.Pipeline(GenerateCoT(), VerifySolution())

9. Связь с Agentic RAG

В Agentic RAG агент должен выполнять многошаговые рассуждения, использовать инструменты (поиск, калькулятор, код). Синтетические данные, созданные описанными методами, используются для:

  • Fine-tuning базовой LLM на рассуждения с инструментами.
  • Обучения политики агента (какой инструмент выбрать на каждом шаге).
  • Создания датасетов для оценки (benchmark) агентных систем.

Например, можно сгенерировать синтетические траектории, где агент сначала пишет код для вычисления, затем проверяет результат через калькулятор, а потом формулирует ответ. Такие данные улучшают способность агента к tool use и multi-step reasoning.


10. Проблемы и ограничения

  • Качество генерации LLM может генерировать правдоподобные, но неверные рассуждения (hallucination). Требуется многоуровневая фильтрация.
  • Перекос (bias): синтетические данные могут наследовать bias базовой модели, например, предпочтение определённых типов задач.
  • Стоимость генерация большого датасета с self-consistency и проверками требует много API-вызовов.
  • Разнообразие: backward generation может порождать однотипные вопросы. Нужны техники для увеличения разнообразия (например, случайные параметры, комбинирование тем).

Пет-проект для закрепления

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

Инструменты Python, OpenAI API (или локальная модель), библиотека sympy для проверки решений.

Шаги:

  1. Backward generation: сгенерировать 1200 случайных квадратных уравнений с помощью sympy (гарантированно корректные корни).
  2. CoT генерация для каждого уравнения попросить LLM (например, GPT-4) написать пошаговое решение через дискриминант.
  3. Проверка другой LLM проверяет каждый шаг. Отбрасываем примеры, где шаги нелогичны.
  4. Self-consistency для каждого уравнения генерируем 3 решения, оставляем только те, где ответы совпадают.
  5. Симуляция (опционально): для уравнений с комплексными корнями — проверка через sympy.
  6. Форматирование сохраняем в JSON (question, reasoning, answer).

Ожидаемый результат чистый датасет из 1000 примеров, готовый для fine-tuning модели на математические рассуждения.


Связь с другими вопросами

ВопросТема
697Как обучать агента для Agentic RAG?
699Как оценивать качество рассуждений агента?
700Как интегрировать инструменты (код, калькулятор) в агента?
701Как реализовать multi-step reasoning в агенте?
702Как обеспечить consistency в ответах агента?
703Какие метрики использовать для оценки агентных систем?

Навигация