Саморефлексия агентов и автоматическое исправление ошибок
Урок: Саморефлексия агентов и автоматическое исправление ошибок
Добро пожаловать в один из самых захватывающих разделов курса по Gemini 3 API. Сегодня мы переходим от создания агентов, которые просто «выполняют команды», к агентам, которые умеют думать о собственном мышлении.
В когнитивной науке это называется метакогниция. В мире LLM мы называем это саморефлексией (Self-Reflection).
Почему это критически важно?
Даже самые мощные модели, включая Gemini 3, могут ошибаться. Они могут галлюцинировать, допускать синтаксические ошибки в коде или неверно интерпретировать сложные инструкции. В традиционном программировании ошибка ведет к падению программы. В агентных системах ошибка — это просто сигнал для обучения.
Если ваш агент выдал неверный ответ, а вы просто приняли его — система ненадежна. Но если агент:
- Выдал ответ.
- Проверил его (сам или с помощью инструментов).
- Обнаружил ошибку.
- Исправил её и выдал финальный результат.
...тогда вы получаете автономную систему промышленного уровня.
Архитектура цикла рефлексии (The Reflection Loop)
Базовая схема работы автономного агента обычно выглядит линейно: Ввод -> Модель -> Вывод. Для внедрения самокоррекции мы превращаем линию в цикл.
Существует несколько популярных паттернов для реализации этого:
- ReAct (Reason + Act): Агент рассуждает, выполняет действие, наблюдает результат. Если результат не соответствует ожиданию, он генерирует новое рассуждение.
- Reflexion: Более продвинутый фреймворк, где агент хранит «вербальную память» о прошлых ошибках, чтобы не повторять их в следующих попытках.
- Actor-Critic (Актор-Критик): Использование двух разных промптов (или даже моделей). Один генерирует решение (Актор), второй жестко критикует его и ищет уязвимости (Критик).
Рассмотрим, как это выглядит на практике при работе с кодом. Это самый наглядный пример, так как код либо работает, либо нет — критерий успеха бинарен и объективен.
import google.generativeai as genai
import traceback
import io
import sys
# Настройка модели (предполагаем, что API ключ уже в окружении)
model = genai.GenerativeModel('gemini-3-pro')
def execute_generated_code(code_string):
"""
Пытается выполнить Python-код и возвращает результат или текст ошибки.
"""
# Перехват stdout для захвата вывода print()
buffer = io.StringIO()
sys.stdout = buffer
try:
# Внимание: exec() опасен в продакшене без песочницы!
# Используем здесь только для демонстрации логики.
exec(code_string, globals())
output = buffer.getvalue()
return True, output
except Exception:
# Если произошла ошибка, захватываем полный traceback
error_msg = traceback.format_exc()
return False, error_msg
finally:
sys.stdout = sys.__stdout__
# Пример того, как мы будем использовать это дальше
# code = "print(10 / 0)"
# success, result = execute_generated_code(code)
# print(f"Success: {success}, Result: {result}")
Паттерн «Самоисцеляющийся код» (Self-Healing Code)
Теперь, когда у нас есть инструмент для выполнения кода и получения текста ошибки (функция выше), мы можем замкнуть цикл обратной связи.
Алгоритм действий:
- Генерация: Просим Gemini написать функцию.
- Исполнение: Запускаем код через
exec(). - Проверка:
- Если код сработал успешно -> Возвращаем результат.
- Если возникло исключение -> Берем текст ошибки (Traceback).
- Рефлексия и исправление: Отправляем модели историю диалога: «Вот твой код, а вот ошибка, которую он вызвал: [Traceback]. Проанализируй причину, исправь код и верни только исправленную версию».
- Повтор: Повторяем цикл до успеха или исчерпания лимита попыток.
Этот метод невероятно эффективен. Gemini 3 отлично понимает сообщения об ошибках интерпретатора Python и быстро находит пропущенные импорты, синтаксические ошибки или логические несостыковки.
def generate_and_fix_code(prompt, max_attempts=3):
chat = model.start_chat(history=[])
# Шаг 1: Первичный запрос
response = chat.send_message(
f"{prompt}\nВАЖНО: Ответ должен содержать ТОЛЬКО исполняемый код Python, без маркдауна и объяснений."
)
current_code = response.text.replace('```python', '').replace('```', '').strip()
print(f"--- Попытка 1: Сгенерирован код ---\n{current_code}\n")
for attempt in range(max_attempts):
# Шаг 2: Исполнение
success, output = execute_generated_code(current_code)
if success:
print(f"SUCCESS! Результат выполнения:\n{output}")
return current_code
else:
print(f"ERROR на попытке {attempt + 1}:\n{output}")
# Шаг 3: Рефлексия (обратная связь)
feedback_prompt = (
f"Код вызвал следующую ошибку:\n{output}\n"
"Пожалуйста, проанализируй traceback, объясни причину ошибки "
"(в мыслях) и напиши ИСПРАВЛЕННЫЙ код. Верни только код."
)
response = chat.send_message(feedback_prompt)
current_code = response.text.replace('```python', '').replace('```', '').strip()
print(f"--- Исправление от Gemini ---\n{current_code}\n")
print("Не удалось исправить код за отведенное число попыток.")
return None
# Запуск агента с заведомо сложной задачей или провокацией на ошибку
# Например, попросим использовать библиотеку, которой может не быть, или сложную логику
task = "Напиши функцию, которая считает факториал числа 5, но используй рекурсию без базового случая (ошибка глубины), а потом исправь это."
# В реальности мы даем нормальную задачу, но модель может ошибиться сама.
# generate_and_fix_code("Напиши код, который создает список из 5 элементов и пытается обратиться к 10-му элементу.")
Рефлексия без выполнения кода (Logical Reflection)
Что делать, если задача не связана с написанием кода? Например, написание аналитической записки или суммаризация текста. Здесь нет компилятора, который выдаст «Ошибку 404».
В этом случае мы используем технику «Двухшапочного мышления» (Two-Cap Thinking) или архитектуру Актор-Критик внутри одного чата.
Промпт для самокритики
Вместо того чтобы просить «Напиши статью», мы разбиваем процесс:
- Шаг 1 (Черновик): «Напиши черновик статьи о квантовых компьютерах.»
- Шаг 2 (Критика): «Теперь представь, что ты — строгий редактор научного журнала. Прочитай текст выше. Найди логические ошибки, повторения, слишком сложные термины без объяснений и 'воду'. Составь список из 3-5 пунктов для улучшения.»
- Шаг 3 (Финализация): «Используя эту критику, перепиши статью начисто.»
Исследования показывают, что LLM значительно лучше находят ошибки в уже сгенерированном тексте, чем предотвращают их в процессе генерации. Разделение генерации и проверки — ключ к качеству.
Создайте агента 'JSON Validator'. <br><br>Задача:<br>1. Агент должен получать описание объекта (например, 'Создай профиль RPG-персонажа').<br>2. Агент должен генерировать JSON строку.<br>3. Ваш скрипт должен пытаться распарсить эту строку через json.loads().<br>4. Если парсинг падает (JSONDecodeError), скрипт должен автоматически отправить ошибку обратно агенту и попросить исправить JSON.<br>5. Если в JSON отсутствуют обязательные поля (например, 'hp' или 'inventory'), это тоже считается ошибкой логики, о которой нужно сообщить агенту.
Продвинутая стратегия: Self-Consistency (Самосогласованность)
Для задач, требующих сложных рассуждений (математика, логика), простой рефлексии может быть недостаточно. Агент может уверенно настаивать на неправильном решении.
В таких случаях используется метод Self-Consistency:
- Мы запускаем один и тот же промпт 3-5 раз (параллельно, выставив
temperature > 0.5для вариативности). - Мы получаем 5 разных путей рассуждения.
- Агент анализирует все 5 ответов и выбирает тот, который встречается чаще всего (голосование большинством), либо синтезирует финальный ответ, объединяя лучшие части.
В Gemini 3 это можно реализовать через параметр candidate_count (если поддерживается API) или просто циклом запросов, а затем отправкой всех результатов новому инстансу модели с ролью «Судья» для вынесения вердикта.
Какая главная причина, по которой мы разделяем процесс генерации контента и процесс его критики (рефлексии) в разные шаги?
Заключение
Автоматическое исправление ошибок переводит взаимодействие с ИИ на новый уровень. Вы перестаете быть «нянькой» для модели, постоянно проверяющей её ответы, и становитесь архитектором системы, которая сама следит за своим качеством.
Ключевые выводы урока:
- Ошибки агента — это нормальная часть процесса, а не конец работы.
- Используйте внешние инструменты (интерпретаторы кода, валидаторы JSON) как источник объективной истины для рефлексии.
- Для текстовых задач используйте ролевые модели (Актор-Критик), чтобы модель сама улучшала свой черновик.
В следующем модуле мы объединим эти знания для создания мультиагентной системы, где разные агенты будут специализироваться на разных задачах и проверять друг друга.