Multi-Agent Debate

Несколько агентов обмениваются аргументами и пересматривают ответы по раундам, чтобы ловить ошибки в reasoning, а не только голосовать.

Multi-Agent Debate (мультиагентные дебаты) — техника, при которой несколько LLM-агентов обсуждают задачу в раундах. Каждый агент генерирует ответ, затем видит ответы других и пересматривает свой. Ключевое отличие от простого голосования: агенты обмениваются рассуждениями, а не только финальными ответами.

В 2026 году debate-подход полезнее понимать как disagreement amplification pattern. Его задача — не имитировать человеческий спор ради красоты, а сделать видимыми альтернативные траектории reasoning и дать шанс одной траектории опровергнуть другую.

Представьте экзамен, где три студента решают задачу, а потом сравнивают ответы. Если двое получили 42, а один — 38, они не просто голосуют за 42. Тот, кто получил 38, показывает свои выкладки, остальные находят в них ошибку и объясняют, где он ошибся. Он пересчитывает и тоже получает 42. Дебаты работают так же: агенты не просто голосуют, а обсуждают логику решения.

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

Multi-Agent Debate — это итеративное обсуждение между несколькими экземплярами LLM. В каждом раунде:

  1. Все агенты видят ответы друг друга (с рассуждениями)
  2. Каждый агент пересматривает свой ответ
  3. Если все согласны — консенсус достигнут

Ключевое отличие от Self-Consistency (мажоритарное голосование): агенты видят рассуждения, а не только финальные ответы. Это позволяет агенту с неправильным ответом понять свою ошибку и исправить её, а не просто быть «переголосованным».

ПромптClaude
Проведи дебаты между 3 агентами для задачи: «Если поезд проехал 180 км за 2.5 часа, а затем ещё 120 км за 1.5 часа, какова средняя скорость?»

Раунд 1 — каждый агент отвечает. Раунд 2 — видят ответы друг друга и пересматривают.
Ответ модели

Раунд 1 (независимые ответы):

Агент A: Средняя скорость = (180/2.5 + 120/1.5) / 2 = (72 + 80) / 2 = 76 км/ч.

Агент B: Общее расстояние = 180 + 120 = 300 км. Общее время = 2.5 + 1.5 = 4 ч. Средняя скорость = 300/4 = 75 км/ч.

Агент C: Скорость 1 = 72 км/ч, скорость 2 = 80 км/ч. Средняя = 76 км/ч.

Раунд 2 (видят ответы друг друга):

Агент A: Вижу, что B получил 75. Он считал правильно — общее расстояние делить на общее время. Я ошибся: нельзя усреднять скорости, когда участки разные по длине и времени. Пересчитываю: 300/4 = 75 км/ч.

Агент B: Подтверждаю свой ответ. A и C взяли среднее двух скоростей, но это работает только при равных отрезках (по времени или расстоянию). 75 км/ч.

Агент C: B прав — нужно делить общий путь на общее время. Мой метод (среднее скоростей) даёт неверный результат. Исправляю: 75 км/ч.

Консенсус: 75 км/ч (достигнут за 2 раунда).

Self-Consistency: 3 ответа → голосуем → побеждает большинство. Если 2 из 3 ошибаются одинаково, ошибка побеждает. Multi-Agent Debate: 3 ответа → обсуждение → агенты находят ошибки в рассуждениях и исправляют их. Даже если большинство ошиблось, аргументированный правильный ответ может убедить остальных.

Как работают дебаты

Процесс

Почему рассуждения важнее ответов

МетодЧто видят агентыКогда ломается
Мажоритарное голосованиеТолько финальные ответы2 из 3 ошибаются одинаково → ошибка побеждает
Multi-Agent DebateПолные рассужденияСложнее обмануть: ошибка в логике видна другим

Бенчмарки

Прирост Multi-Agent Debate над baseline (%)
Arithmetic15%
GSM8K8%
MMLU7%
Chess (move validity)12%
Self-Consistency (голосование)
Агент 1: 76 км/ч (неверно) Агент 2: 75 км/ч (верно) Агент 3: 76 км/ч (неверно) Голосование: 76 (2 голоса) → неверный ответ
Multi-Agent Debate (обсуждение)
Раунд 1: ответы 76, 75, 76 Раунд 2: Агент 2 объясняет ошибку Агенты 1 и 3 пересчитывают Консенсус: 75 → верный ответ

Плюсы

  • Находит и исправляет ошибки в рассуждениях
  • +14.8% на арифметике, +8% на GSM8K
  • Работает с одной моделью (разные экземпляры) или разными
  • Улучшает фактологическую точность (factuality)
  • Прозрачность: весь процесс обсуждения видим

Минусы

  • Дорого: N агентов × R раундов × длинные промпты с историей
  • Задержка: раунды последовательны
  • Groupthink: все агенты могут сойтись на неправильном ответе
  • На простых задачах: Self-Consistency проще и дешевле при той же точности
Если все агенты — одна модель с одинаковыми предубеждениями, они могут «убедить» друг друга в неправильном ответе. Решение: использовать разные модели (Claude + GPT-4o + Gemini) или разные temperature для создания разнообразия мнений.

Как понимать Multi-Agent Debate в 2026

Практически debate сегодня стоит рядом с self-consistency, proposer-critic loops, judge-based verification и cross-model review. То есть это не всегда “настоящая мультиагентность”, а часто просто организованный способ столкнуть несколько reasoning traces и посмотреть, выдерживают ли они критику.

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

Подход окупается, когда:

  • ответы можно аргументированно оспаривать;
  • ошибка часто сидит в логике, а не только в финальном числе;
  • задача стоит дороже, чем несколько дополнительных раундов.

Это делает debate полезным для math-ish reasoning, legal/policy analysis, structured critique и сложных QA-сценариев.

Где лучше не устраивать дебаты

Debate не нужен, если задача тривиальна и Self-Consistency решает её дешевле, у агентов нет реального diversity, а у системы нет явного механизма остановки и выбора победителя. В production debate чаще всего оправдан как selective escalation path: если обычный ответ недостаточно надёжен, маршрут уходит в спор/критику, а не наоборот.

ПромптChatGPT
Проведи дебаты между тремя агентами: верно ли утверждение «Все чётные числа больше 2 являются составными»?

Раунд 1 — независимые ответы. Раунд 2 — обсуждение.
Ответ модели

Раунд 1:

Агент A: Да, верно. Чётные числа делятся на 2, значит у них есть делитель помимо 1 и себя. Примеры: 4=2×2, 6=2×3, 8=2×4.

Агент B: Да, верно. Определение: чётное число > 2 можно записать как 2k, где k > 1. Значит 2 — делитель, и число составное.

Агент C: Да, это следствие определения. Чётное число делится на 2. Если оно больше 2, то у него есть как минимум три делителя: 1, 2 и само число.

Раунд 2:

Агент A: Все согласны. Добавлю формальное доказательство: для n > 2, n чётное → n = 2k, k ≥ 2 → n делится на 2 и на k → n составное (если k ≠ n, но k = n/2 < n).

Агент B: Согласен с A и C. Отмечу, что 2 — единственное чётное простое, поэтому условие «больше 2» важно.

Агент C: Подтверждаю. Утверждение верно.

Консенсус: Да, утверждение верно. Достигнут за 1 раунд — все агенты сразу пришли к одному ответу с разными, но непротиворечивыми обоснованиями.

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

DebateAgent и цикл дебатов

from dataclasses import dataclass, field
from openai import OpenAI

client = OpenAI()

DEBATE_SYSTEM = """Ты — участник дебатов. Решаешь задачу и обсуждаешь с другими агентами.

Правила:
1. Дай свой ответ с подробным рассуждением
2. Если видишь ответы других — проанализируй их аргументы
3. Если находишь ошибку в чужом рассуждении — укажи конкретно
4. Если твой ответ был неверен — признай и исправь
5. Не соглашайся просто потому, что большинство так считает — нужны аргументы"""


@dataclass
class DebateAgent:
    """Один агент в дебатах."""
    id: int
    model: str = "gpt-4o"
    temperature: float = 0.7
    history: list[str] = field(default_factory=list)

    def respond(self, task: str, other_responses: list[str] | None = None) -> str:
        """Сгенерировать ответ (первый раунд или пересмотр)."""
        if other_responses:
            others_text = "\n\n".join(
                f"Агент {i+1}: {r}" for i, r in enumerate(other_responses)
            )
            prompt = (
                f"Задача: {task}\n\n"
                f"Ответы других агентов:\n{others_text}\n\n"
                f"Твой предыдущий ответ: {self.history[-1]}\n\n"
                f"Пересмотри свой ответ с учётом аргументов других. "
                f"Если считаешь, что прав — аргументируй."
            )
        else:
            prompt = f"Задача: {task}"

        resp = client.chat.completions.create(
            model=self.model,
            messages=[
                {"role": "system", "content": DEBATE_SYSTEM},
                {"role": "user", "content": prompt}
            ],
            temperature=self.temperature
        )
        answer = resp.choices[0].message.content.strip()
        self.history.append(answer)
        return answer


def extract_final_answer(response: str) -> str:
    """Извлечь финальный ответ из рассуждения."""
    for marker in ["Ответ:", "Final answer:", "Итого:", "**Ответ"]:
        if marker.lower() in response.lower():
            idx = response.lower().index(marker.lower())
            return response[idx:].split("\n")[0].strip()
    # Последнее предложение
    return response.strip().split("\n")[-1].strip()


def check_consensus(responses: list[str]) -> bool:
    """Проверить, совпадают ли финальные ответы."""
    answers = [extract_final_answer(r) for r in responses]
    return len(set(answers)) == 1


def multi_agent_debate(
    task: str,
    n_agents: int = 3,
    max_rounds: int = 4,
    models: list[str] | None = None
) -> dict:
    """Полный цикл мультиагентных дебатов."""
    if models is None:
        models = ["gpt-4o"] * n_agents

    agents = [
        DebateAgent(id=i, model=models[i], temperature=0.5 + i * 0.2)
        for i in range(n_agents)
    ]

    # Раунд 1: независимые ответы
    responses = [agent.respond(task) for agent in agents]

    if check_consensus(responses):
        return {
            "answer": extract_final_answer(responses[0]),
            "rounds": 1,
            "consensus": True,
            "debate_log": [responses]
        }

    # Раунды дебатов
    debate_log = [responses]
    for round_num in range(2, max_rounds + 1):
        new_responses = []
        for i, agent in enumerate(agents):
            other = [r for j, r in enumerate(responses) if j != i]
            new_responses.append(agent.respond(task, other))

        responses = new_responses
        debate_log.append(responses)

        if check_consensus(responses):
            return {
                "answer": extract_final_answer(responses[0]),
                "rounds": round_num,
                "consensus": True,
                "debate_log": debate_log
            }

    # Fallback: мажоритарное голосование
    from collections import Counter
    answers = [extract_final_answer(r) for r in responses]
    most_common = Counter(answers).most_common(1)[0][0]
    return {
        "answer": most_common,
        "rounds": max_rounds,
        "consensus": False,
        "debate_log": debate_log
    }


# Пример использования
result = multi_agent_debate(
    task="Если поезд проехал 180 км за 2.5 часа, а затем "
         "ещё 120 км за 1.5 часа, какова средняя скорость?",
    n_agents=3,
    max_rounds=3
)

print(f"Ответ: {result['answer']}")
print(f"Раундов: {result['rounds']}")
print(f"Консенсус: {result['consensus']}")

Кросс-модельные дебаты

def cross_model_debate(task: str) -> dict:
    """Дебаты между разными моделями — борьба с groupthink."""
    return multi_agent_debate(
        task=task,
        n_agents=3,
        max_rounds=3,
        models=["gpt-4o", "claude-sonnet-4-20250514", "gemini-1.5-pro"]
    )
  1. Одинаковая temperature для всех — агенты будут генерировать похожие ответы, снижая ценность дебатов. Разнесите temperature: 0.3, 0.5, 0.7 или используйте разные модели.
  2. Слишком много раундов — после 3-4 раундов агенты уже не меняют мнение. 2-3 раунда — оптимально.
  3. extract_final_answer по шаблону — в реальном приложении используйте LLM для извлечения финального ответа из рассуждения, а не regex.

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

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

1. Чем Multi-Agent Debate отличается от Self-Consistency?

2. Что такое groupthink в контексте дебатов?

3. Сколько раундов оптимально для дебатов?