Что такое ReAct Agent и как он работает?
Краткий тезис
ReAct Agent (Agent|Reason + Act) — это паттерн построения AI-агента, в котором языковая модель итеративно генерирует мысли (Thought), выполняет действия (Action) через внешние инструменты и получает обратную связь в виде наблюдений (Observation). Этот цикл повторяется, пока агент не сформулирует окончательный ответ (Final Answer). ReAct сочетает рассуждение (reasoning) с взаимодействием со средой (acting), что повышает интерпретируемость и точность, но может приводить к зацикливанию и высоким затратам токенов.
1. Происхождение и ключевая идея
ReAct впервые описан в статье "ReAct: Synergizing Reasoning and Acting in Language Models" (Yao et al., 2022, Princeton). Идея в том, чтобы совместить цепочку рассуждений (Chain-of-Thought) с выполнением действий (использование инструментов). LLM не просто генерирует ответ, а рассуждает о том, что нужно сделать, действует (call|вызов API, поиск в БД, выполнение кода), наблюдает результат и адаптирует свои следующие шаги.
Термин «Agent» здесь означает программу, которая способна автономно выполнять задачи, используя LLM в качестве «мозга» и внешние инструменты как «руки».
2. Цикл ReAct: Thought → Action → Observation → (Final)
Базовая последовательность шагов:
Thought: LLM анализирует текущий контекст и решает, что делать.
Action: Вызов инструмента (например, поиск погоды).
Observation: Результат вызова (например, JSON с температурой).
Thought: LLM оценивает результат и решает, достаточно ли данных.
Action: Или ещё один вызов, или вывод Final Answer.
Пример из черновика, расширенный:
User: Какая погода в Москве?
Thought: Нужно узнать текущую погоду в Москве. У меня есть инструмент get_weather.
Action: get_weather("Москва")
Observation: {"temperature": 15, "condition": "дождь"}
Thought: 15°C и дождь. Могу ответить пользователю.
Action: Final Answer: В Москве сейчас 15°C и идёт дождь.
Важно: Final Answer — это не действие, а вывод, который возвращается пользователю. Он может быть как отдельным действием, так и просто завершением цикла.
3. Формальное описание и псевдокод
Цикл ReAct можно описать следующим образом:
def react_agent(query, tools, llm, max_steps=10):
messages = [{"role": "user", "content": query}]
for step in range(max_steps):
# 1. LLM генерирует next action (возможно, Thought)
response = llm.invoke(messages)
# 2. Парсим ответ: проверяем, есть ли вызов инструмента
action = parse_action(response)
if action["type"] == "final":
return action["content"]
elif action["type"] == "tool_call":
# 3. Выполняем инструмент
tool_name = action["name"]
arguments = action["arguments"]
observation = tools[tool_name](**arguments)
# 4. Добавляем наблюдение в историю
messages.append({"role": "assistant", "content": response})
messages.append({"role": "tool", "content": str(observation)})
else:
# Ошибка парсинга: прерываемся
return "Failed to parse action."
return "Max steps reached."
На практике обычно используют структурированные действия (JSON, function calling) — например, в OpenAI API есть параметр tools, который возвращает чёткие вызовы функций.
4. Плюсы и сильные стороны
| Преимущество | Описание |
|---|---|
| Интерпретируемость | Каждый шаг (Thought → Action → Observation) можно отследить и понять, почему агент пришёл к такому выводу. |
| Гибкость | Агент может динамически выбирать, какой инструмент использовать, и менять план на основе наблюдений. |
| Отладка | Легко увидеть, где агент ошибся: неверное рассуждение, неправильный вызов инструмента или некорректное наблюдение. |
| Простота реализации | Базовый цикл ReAct можно реализовать с помощью одной LLM и списка инструментов без сложного планирования. |
| Хорошая производительность на задачах, требующих поиска информации | Показано, что ReAct превосходит Chain-of-Thought на задачах с внешними инструментами (Wikipedia QA, HotpotQA). |
5. Минусы и ограничения
| Недостаток | Описание |
|---|---|
| Зацикливание | Агент может повторять одни и те же действия, попадая в бесконечный цикл (например, бесконечно уточнять погоду). Решение — max_steps прерывание. |
| Высокая стоимость токенов | Каждый шаг генерирует мысль и результат наблюдения. Для сложных задач количество шагов может быть 10+, а каждое наблюдение — большой текст. |
| Зависимость от LLM | Если LLM плохо понимает структуру инструментов или генерирует некорректные действия, ReAct деградирует. |
| Отсутствие долгосрочного планирования | ReAct — это «жадный» алгоритм: он думает только на один шаг вперёд. Для задач, требующих многошагового плана, лучше подходят паттерны вроде Plan-and-Execute. |
| Непредсказуемость | Длина последовательности может сильно варьироваться – от 2 шагов до десятков. |
6. Модификации для production
В промышленных системах ReAct часто дорабатывают:
- max_steps — жёсткий лимит итераций (5–10). Если превышен, возвращаем частичный ответ или сообщение об ошибке.
- Early stopping — если Thought повторяет ранее высказанную мысль без прогресса, прерываем цикл.
- Структурированный парсинг действий — вместо свободной генерации JSON используем function calling (OpenAI, Anthropic) или structured output (JSON mode). Это снижает вероятность неверного парсинга.
- Логирование и мониторинг — сохраняем всю трассу шагов для отладки и анализа стоимости.
- Тайм-ауты на выполнение инструментов — если вызов инструмента зависает, прерываем его и даём наблюдение "Timeout".
- Пул инструментов с описаниями — подаём в системный промпт список доступных функций с четкими сигнатурами и примерами.
7. Сравнение с другими паттернами агентов
| Паттерн | Подход | Когда использовать |
|---|---|---|
| ReAct | Итеративное рассуждение → действие → наблюдение | Задачи с поиском информации, простые API-вызовы (погода, новости, БД). |
| Plan-and-Execute | Сначала составить план из шагов, затем выполнять последовательно | Сложные многошаговые инструкции (сварить кофе, построить отчёт). |
| Reflexion | После выполнения задачи анализировать ошибки и повторять с улучшениями | Задачи, где важна самокоррекция (генерация кода, написание эссе). |
| AutoGPT / BabyAGI | Динамическое создание подзадач и памяти | Полностью автономные агенты с долгосрочными целями (но нестабильно). |
| Chain-of-Thought (CoT) | Только рассуждение без внешних действий | Вопросы, не требующие инструментов (математика, логика). |
8. Пример реализации простого ReAct агента
Покажу минимальный пример на Python с использованием OpenAI API (функциональное представление):
import json
from openai import OpenAI
client = OpenAI()
def get_weather(city: str) -> str:
"""Имитация получения погоды."""
data = {"Москва": "15°C, дождь", "Лондон": "10°C, облачно"}
return json.dumps({"city": city, "weather": data.get(city, "Unknown")})
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Узнать погоду в городе",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Название города"}
},
"required": ["city"]
}
}
}
]
def react(query, max_steps=5):
messages = [{"role": "user", "content": query}]
for step in range(max_steps):
response = client.chat.completions.create(
model="gpt-4",
messages=messages,
tools=tools,
tool_choice="auto"
)
msg = response.choices[0].message
messages.append(msg)
if msg.tool_calls:
for call in msg.tool_calls:
if call.function.name == "get_weather":
args = json.loads(call.function.arguments)
obs = get_weather(args["city"])
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": obs
})
else:
# Если agent не вызывает инструмент, считаем финальным ответом
return msg.content
return "Max steps reached"
print(react("Какая погода в Москве?"))
В production добавляем max_steps, логирование, обработку ошибок.
Пет-проект для закрепления
Задача Создать ReAct агента, который умеет отвечать на вопросы, используя калькулятор и поиск в Википедии.
Инструменты Python, OpenAI API (или локальная LLM через Ollama), библиотеки wikipedia-api, requests, json.
Шаги:
- Определить два инструмента:
- Написать системный промпт, объясняющий агенту, что он может использовать эти инструменты, и как форматировать действия (в JSON или через function calling).
- Реализовать цикл ReAct с max_steps=7.
- Протестировать на запросах: «Сколько будет 2+2?», «Что такое RAG?», «Найди столицу Франции и прибавь к ней 5» (должен найти «Париж» и ответить 5+? – правильный ответ: не число, нужно объяснить).
- Добавить механизм early stopping: если Thought повторяется дважды подряд, прерывать.
- Измерить количество токенов и шагов для трёх разных запросов. Оптимизировать.
Ожидаемый результат Рабочий агент в виде скрипта или Jupyter ноутбука, который логирует каждый шаг (Thought, Action, Observation). Продемонстрировать корректное завершение, а также обработку ошибок (некорректный запрос к Википедии, деление на ноль в калькуляторе).
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 46 | Что такое AI Agent и как он строится? |
| 48 | Чем ReAct отличается от Plan-and-Execute? |
| 49 | Как вы проектируете память для AI-агентов? |
| 50 | Как добавить инструменты (tools) в агента? |
| 51 | Как fine‑tune LLM для задач агентов? |
| 52 | Что такое Reflexion и как он улучшает агентов? |
Навигация
- Предыдущий: 46
- Следующий: 48
- Индекс: 00. Индекс разборов