Cumulative Reasoning

[object Object]

Cumulative Reasoning (кумулятивное рассуждение) — техника, в которой несколько ролей итеративно строят граф верифицированных утверждений: Proposer предлагает новый шаг, Verifier проверяет его корректность, Reporter решает, достаточно ли накоплено для финального ответа. Ошибки отсекаются на каждом шаге, и в рабочую память попадают только подтверждённые элементы рассуждения.

В 2026 году CR полезнее воспринимать не как академическую “игру в три роли”, а как early pattern для verified reasoning loops. По сути это предок современных workflow-идей вроде proposer-critic, generator-judge и trace-gated execution.

Представьте строительство кирпичной стены. Каменщик (Proposer) кладёт кирпич. Прораб (Verifier) проверяет — ровно ли лежит, нет ли трещин. Если кирпич плохой — убирает. Архитектор (Reporter) смотрит: стена уже достаточно высокая? Если да — строительство завершено. Cumulative Reasoning работает так же: каждый новый шаг рассуждения проверяется, прежде чем стать основой для следующих шагов.

Суть в двух словах

В отличие от Chain of Thought, где модель генерирует всю цепочку рассуждений за раз (и ошибка на шаге 3 портит шаги 4-10), Cumulative Reasoning строит рассуждение инкрементально. Каждое новое утверждение:

  1. Опирается на уже верифицированные факты
  2. Проверяется Verifier перед добавлением
  3. Становится основой для следующих шагов только после подтверждения

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

ПромптClaude
Используй Cumulative Reasoning для решения: числа 1, 3, 4, 6 — получи 24, используя каждое число ровно один раз и операции +, -, ×, ÷.

Применяй три роли:
- Proposer: предложи следующий шаг
- Verifier: проверь корректность
- Reporter: достаточно ли для ответа?
Ответ модели

Раунд 1:

  • Proposer: 6 ÷ (1 - 3/4) = ?
  • Verifier: 3/4 = 0.75, 1 - 0.75 = 0.25, 6 ÷ 0.25 = 24. Но это использует дробь 3/4, а нужно число 3 и число 4 отдельно. ✗ Отклонено.

Раунд 2:

  • Proposer: попробуем пары. 1 × 4 = 4. Добавим: 4 + 3 = 7, 4 × 6 = 24. Но 4 уже использована.
  • Verifier: число 4 используется дважды (как множитель и в паре). ✗ Отклонено.

Раунд 3:

  • Proposer: 1 × 6 = 6 ✓ (проверенный факт). Далее: 6 × (3 + 4) = 6 × 7 = 42, не 24. ✗
  • Verifier: 42 ≠ 24. ✗ Промежуточный факт 1 × 6 = 6 верен, сохраняем.

Раунд 4:

  • Proposer: используя факт 1 × 6 = 6, попробуем 6 × 4 = 24. Остаётся 3 и 1. (1 × 6) × 4 = 24, но куда 3?
  • Verifier: число 3 не использовано. ✗ Отклонено.

Раунд 5:

  • Proposer: новый подход. 4 × (6 - 3 + 1) = 4 × 4 = 16. ✗
  • Verifier: 16 ≠ 24. ✗

Раунд 6:

  • Proposer: 6 × (4 - 1 + 1)? Нет, 1 дважды. Попробуем: 1 × 3 = 3. Затем 3 × (6 + something)... Или: (3 - 1) = 2. 2 × (6 + 4) = 20. Нет. (6 + 1 - 3) = 4. 4 × 4 = нет. Попробуем: 1 + 3 = 4. 4 × 6 = 24. ✓
  • Verifier: (1 + 3) = 4 ✓. 4 × 6 = 24 ✓. Все числа: 1, 3 (в сумме), 4 (результат), 6 (множитель). Но оригинальное 4 не использовано! Переформулируем: нам нужно использовать 1, 3, 4, 6. (1 + 3) × 4 = 16, нет.

Раунд 7:

  • Proposer: 4 × 6 × 1 = 24, осталось 3 → 4 × 6 × 1 + 0×3 нельзя. Попробуем: 4 × 6 = 24, × 1 = 24, - 3 + 3 = 24? Нельзя — каждое число один раз. Новый подход: 4 × (6 - 3 + 1) = 4 × 4 = 16. Нет. (6 ÷ 1) × (3 + ?) нет. 1 × (6 + 3 - 4) = 5. Нет. (6 - 4) × (1 + 3) нет, 2 × 4 = 8. Нет: 6 ÷ (1 - 3÷4) = 6 ÷ 0.25 = 24, и используем 1, 3, 4, 6!
  • Verifier: 3÷4 = 0.75. 1 - 0.75 = 0.25. 6÷0.25 = 24 ✓. Числа: 6, 1, 3, 4 — все использованы ровно по разу. ✓✓
  • Reporter: Все числа использованы, результат 24. ✓ Решение найдено: 6 ÷ (1 - 3÷4) = 24
Tree of Thoughts исследует множество путей, но не верифицирует каждый шаг. Cumulative Reasoning проверяет каждое промежуточное утверждение. Это делает финальный ответ надёжнее: если вы дошли до конца — все промежуточные шаги корректны.

Как работает Cumulative Reasoning

Три роли

DAG вместо цепочки

В отличие от линейной цепочки CoT, Cumulative Reasoning строит DAG (directed acyclic graph):

СтруктураCoTCumulative Reasoning
ТопологияЛинейная цепочка A→B→C→DDAG: A→C, B→C, C→D
ВерификацияПостфактум или никогдаНа каждом шаге
Ошибка на шаге 3Портит шаги 4-10Отсекается, не попадает в граф
ПараллельностьНетВозможна: независимые ветви

Бенчмарки

Сравнение с другими техниками (% точности)
CR — Game of 2498%
ToT — Game of 2474%
CR — FOLIO98%
CoT — FOLIO82%
CoT (линейная цепочка)
Шаг 1: вычисление ✓ Шаг 2: вывод ✓ Шаг 3: ошибка ✗ Шаг 4: опирается на ошибку ✗ Итог: неверный ответ
Cumulative Reasoning (DAG)
Факт 1: вычисление → Verifier: ✓ (добавлен) Факт 2: вывод → Verifier: ✓ (добавлен) Факт 3: ошибка → Verifier: ✗ (отклонён) Факт 3': новая попытка → Verifier: ✓ (добавлен) Итог: верный ответ

Плюсы

  • 98% на Game of 24 (+24% vs ToT)
  • Каждый шаг верифицирован — высокая надёжность
  • +43% на MATH Level 5 — сложнейшие математические задачи
  • Ошибки не накапливаются — DAG вместо линейной цепочки
  • Работает с логикой, математикой, рассуждениями

Минусы

  • Дорого: 3 LLM-роли × N итераций = десятки вызовов
  • Медленно: последовательные итерации, каждая с верификацией
  • Proposer может зациклиться: генерировать одни и те же неудачные утверждения
  • Verifier может быть ненадёжен: если та же модель, может не заметить свои ошибки
В оригинальной статье все три роли выполняет одна модель с разными промптами. Это слабое место: модель может не заметить свои ошибки. Для повышения надёжности используйте разные модели для Proposer и Verifier (например, Claude как Proposer, GPT-4o как Verifier).

Как понимать Cumulative Reasoning в 2026

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

  • evaluator-optimizer workflows
  • judge-based reasoning
  • trace gating в agent systems

То есть CR особенно полезен там, где важна не ширина поиска, а чистота накапливаемого reasoning state.

Где техника реально полезна

Подход особенно хорошо ложится на задачи, где:

  • промежуточные утверждения можно формально или полуформально проверять
  • одна ошибка в середине цепочки разрушает весь итог
  • нужна высокая explainability и auditability хода решения
  • можно позволить себе несколько циклов propose -> verify -> continue

Это делает CR интересным для formal-ish logic, constrained math, policy reasoning и safety-critical маршрутов, где нельзя просто “надеяться на хороший CoT”.

Где техника быстро становится слишком дорогой

Есть и чёткие ограничения:

  • если верификатор не лучше генератора, вы платите за цикл без реального роста качества
  • если шаги трудно проверять, verifier начинает выдавать псевдоуверенные verdicts
  • при длинных задачах стоимость и latency растут очень быстро

Поэтому на практике CR чаще полезен как selective route для сложных high-stakes задач, а не как дефолтная техника на весь трафик. Обычно хороший router должен сначала понять, требуется ли verified buildup вообще.

ПромптChatGPT
Используй Cumulative Reasoning для логической задачи:

Факты:
- Все программисты знают логику
- Некоторые программисты знают Python
- Все, кто знают Python, могут писать скрипты
- Алексей — программист, который знает Python

Вопрос: Может ли Алексей писать скрипты?
Ответ модели

Верифицированные утверждения:

[Proposer] Факт P1: Алексей — программист (из условия) [Verifier] ✓ Прямо указано в условии.

[Proposer] Факт P2: Алексей знает Python (из условия) [Verifier] ✓ Прямо указано в условии.

[Proposer] Факт P3: Алексей знает логику (из P1 + правило «все программисты знают логику») [Verifier] ✓ Modus ponens: Алексей — программист → все программисты знают логику → Алексей знает логику.

[Proposer] Факт P4: Алексей может писать скрипты (из P2 + правило «все, кто знают Python, могут писать скрипты») [Verifier] ✓ Modus ponens: Алексей знает Python → все, кто знают Python, могут писать скрипты → Алексей может писать скрипты.

[Reporter] Достаточно для ответа? Да — P4 прямо отвечает на вопрос.

Ответ: Да, Алексей может писать скрипты. Это следует из факта, что он знает Python, и правила, что все знающие Python могут писать скрипты.

Техническая реализация

CumulativeReasoner с DAG

from dataclasses import dataclass, field
from openai import OpenAI

client = OpenAI()

@dataclass
class VerifiedFact:
    """Верифицированное утверждение в DAG."""
    id: int
    content: str
    depends_on: list[int] = field(default_factory=list)  # ID зависимостей
    confidence: float = 1.0


PROPOSER_PROMPT = """Ты — Proposer в системе Cumulative Reasoning.

Задача: {task}

Уже подтверждённые факты:
{facts}

Предложи ОДНО новое утверждение — следующий шаг к решению.
Утверждение должно опираться на подтверждённые факты.
Формат: одно предложение, конкретное и проверяемое."""

VERIFIER_PROMPT = """Ты — Verifier в системе Cumulative Reasoning.

Задача: {task}

Подтверждённые факты:
{facts}

Новое утверждение для проверки:
{proposition}

Проверь:
1. Логически корректно?
2. Следует из подтверждённых фактов или условия задачи?
3. Нет арифметических или логических ошибок?

Ответь ОДНИМ словом: ВЕРНО или НЕВЕРНО. Затем кратко обоснуй."""

REPORTER_PROMPT = """Ты — Reporter в системе Cumulative Reasoning.

Задача: {task}

Подтверждённые факты:
{facts}

Достаточно ли фактов для финального ответа?
Если ДА — сформулируй ответ.
Если НЕТ — ответь «ПРОДОЛЖИТЬ»."""


class CumulativeReasoner:
    """Реализация Cumulative Reasoning с тремя LLM-ролями."""

    def __init__(self, model: str = "gpt-4o", max_rounds: int = 15):
        self.model = model
        self.max_rounds = max_rounds
        self.facts: list[VerifiedFact] = []
        self.fact_counter = 0

    def _format_facts(self) -> str:
        if not self.facts:
            return "(пока нет подтверждённых фактов)"
        return "\n".join(
            f"[F{f.id}] {f.content}"
            for f in self.facts
        )

    def _propose(self, task: str) -> str:
        """Proposer генерирует новое утверждение."""
        resp = client.chat.completions.create(
            model=self.model,
            messages=[{"role": "user", "content": PROPOSER_PROMPT.format(
                task=task, facts=self._format_facts()
            )}],
            temperature=0.7
        )
        return resp.choices[0].message.content.strip()

    def _verify(self, task: str, proposition: str) -> bool:
        """Verifier проверяет утверждение."""
        resp = client.chat.completions.create(
            model=self.model,
            messages=[{"role": "user", "content": VERIFIER_PROMPT.format(
                task=task, facts=self._format_facts(), proposition=proposition
            )}],
            temperature=0
        )
        answer = resp.choices[0].message.content.strip()
        return answer.upper().startswith("ВЕРНО")

    def _report(self, task: str) -> str | None:
        """Reporter проверяет, достаточно ли фактов."""
        resp = client.chat.completions.create(
            model=self.model,
            messages=[{"role": "user", "content": REPORTER_PROMPT.format(
                task=task, facts=self._format_facts()
            )}],
            temperature=0
        )
        answer = resp.choices[0].message.content.strip()
        if "ПРОДОЛЖИТЬ" in answer.upper():
            return None
        return answer

    def solve(self, task: str) -> dict:
        """Полный цикл Cumulative Reasoning."""
        self.facts = []
        self.fact_counter = 0

        for round_num in range(self.max_rounds):
            # Proposer
            proposition = self._propose(task)

            # Verifier
            is_valid = self._verify(task, proposition)

            if is_valid:
                self.fact_counter += 1
                self.facts.append(VerifiedFact(
                    id=self.fact_counter,
                    content=proposition
                ))

                # Reporter
                final_answer = self._report(task)
                if final_answer:
                    return {
                        "answer": final_answer,
                        "facts": [f.content for f in self.facts],
                        "rounds": round_num + 1,
                        "rejected": round_num + 1 - len(self.facts)
                    }

        return {
            "answer": "Не удалось найти ответ за отведённые раунды",
            "facts": [f.content for f in self.facts],
            "rounds": self.max_rounds,
            "rejected": self.max_rounds - len(self.facts)
        }


# Пример использования
reasoner = CumulativeReasoner(model="gpt-4o", max_rounds=15)

result = reasoner.solve(
    "Числа: 1, 3, 4, 6. Получи 24, используя каждое число один раз "
    "и операции +, -, ×, ÷."
)

print(f"Ответ: {result['answer']}")
print(f"Раундов: {result['rounds']}")
print(f"Отклонено: {result['rejected']}")
print(f"Верифицированные факты:")
for f in result["facts"]:
    print(f"  - {f}")

Кросс-модельная конфигурация

class CrossModelReasoner(CumulativeReasoner):
    """Разные модели для разных ролей — повышает надёжность."""

    def __init__(
        self,
        proposer_model: str = "claude-sonnet-4-20250514",
        verifier_model: str = "gpt-4o",
        reporter_model: str = "gpt-4o-mini",
        max_rounds: int = 15
    ):
        super().__init__(max_rounds=max_rounds)
        self.proposer_model = proposer_model
        self.verifier_model = verifier_model
        self.reporter_model = reporter_model

    def _propose(self, task: str) -> str:
        self.model = self.proposer_model
        return super()._propose(task)

    def _verify(self, task: str, proposition: str) -> bool:
        self.model = self.verifier_model
        return super()._verify(task, proposition)

    def _report(self, task: str) -> str | None:
        self.model = self.reporter_model
        return super()._report(task)
  1. Зацикливание Proposer — модель генерирует одни и те же отклонённые утверждения. Решение: передавайте историю отклонённых утверждений в промпт Proposer.
  2. Verifier всегда говорит «верно» — если та же модель, она склонна соглашаться сама с собой. Используйте разные модели или низкую temperature для Verifier.
  3. Reporter завершает слишком рано — иногда Reporter считает, что фактов достаточно, хотя решение неполное. Добавьте в промпт Reporter инструкцию перечислить, что именно следует из фактов.

Проверьте себя

Проверьте себя

1. Какие три роли используются в Cumulative Reasoning?

2. Чем DAG в Cumulative Reasoning лучше линейной цепочки в CoT?

3. Какой результат Cumulative Reasoning показал на Game of 24?