中文翻译暂不可用,显示俄语原文。

Что такое 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 → ActionObservation → (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 → ActionObservation) можно отследить и понять, почему агент пришёл к такому выводу.
ГибкостьАгент может динамически выбирать, какой инструмент использовать, и менять план на основе наблюдений.
ОтладкаЛегко увидеть, где агент ошибся: неверное рассуждение, неправильный вызов инструмента или некорректное наблюдение.
Простота реализацииБазовый цикл 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.

Шаги:

  1. Определить два инструмента:
    • calculator(expression) — возвращает результат математического выражения (использовать eval с ограничениями или sympy).
    • search_wikipedia(query) — возвращает краткое описание первого результата.
  2. Написать системный промпт, объясняющий агенту, что он может использовать эти инструменты, и как форматировать действия (в JSON или через function calling).
  3. Реализовать цикл ReAct с max_steps=7.
  4. Протестировать на запросах: «Сколько будет 2+2?», «Что такое RAG?», «Найди столицу Франции и прибавь к ней 5» (должен найти «Париж» и ответить 5+? – правильный ответ: не число, нужно объяснить).
  5. Добавить механизм early stopping: если Thought повторяется дважды подряд, прерывать.
  6. Измерить количество токенов и шагов для трёх разных запросов. Оптимизировать.

Ожидаемый результат Рабочий агент в виде скрипта или Jupyter ноутбука, который логирует каждый шаг (Thought, Action, Observation). Продемонстрировать корректное завершение, а также обработку ошибок (некорректный запрос к Википедии, деление на ноль в калькуляторе).


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

ВопросТема
46Что такое AI Agent и как он строится?
48Чем ReAct отличается от Plan-and-Execute?
49Как вы проектируете память для AI-агентов?
50Как добавить инструменты (tools) в агента?
51Как fine‑tune LLM для задач агентов?
52Что такое Reflexion и как он улучшает агентов?

Навигация