Skip to content
AI360Xpert
Gen AI

ReAct Pattern

ReAct combines Reasoning (thinking aloud) and Acting (using tools). The LLM thinks about what to do, takes an action, observes the result, and thinks again. It is the core loop of autonomous agents.

The ReAct loop forces the LLM to output a Thought, followed by an Action. The environment returns an Observation, triggering the next Thought.
The ReAct loop forces the LLM to output a Thought, followed by an Action. The environment returns an Observation, triggering the next Thought.

Why Does This Exist?

Prior to 2022, Large Language Models were separated into two distinct categories of research:

  1. Reasoning: Using techniques like Chain of Thought (CoT) to solve math and logic problems.
  2. Acting: Training models to play text-based games or navigate web browsers by outputting commands (like move_forward or click_button).

The breakthrough of the ReAct (Reason + Act) paper was combining these two domains. If an LLM just acts without reasoning, it clicks randomly and fails. If an LLM just reasons without acting, it cannot fetch real-time information or affect the outside world.

ReAct interleaves reasoning and acting. By forcing the LLM to "think out loud" before it takes an action, the LLM creates an actionable plan, executes it, and then evaluates the result. This simple loop is the foundational architecture for almost all modern AI agents (including Agentic RAG systems).

Think of It Like This

Cooking in a new kitchen

Acting Only: You walk into the kitchen, open a random drawer, pull out a whisk, turn on the oven, and grab an egg. Chaos ensues.

Reasoning Only: You sit at the kitchen table and write a brilliant, detailed plan for baking a cake. But you never actually stand up to bake it.

ReAct (Reason + Act): (Thought) "I want to bake a cake. First, I need to see if I have flour." (Action) Open pantry. (Observation) I see sugar and baking soda, but no flour. (Thought) "I cannot bake a cake without flour. I need to go to the store." (Action) Leave house.

You are constantly evaluating the environment and adjusting your plan.

How It Actually Works

Implementing ReAct requires a specific prompt structure and a Python execution loop (the "orchestrator").

1. The Prompt (The Rules of the Game)

The system prompt defines the tools available to the LLM and strictly enforces the formatting of the output. The LLM is instructed to output exactly one Thought: followed by one Action:.

You are a helpful AI assistant. You have access to the following tools:- Wikipedia(query): Searches Wikipedia and returns a summary.- Calculator(expression): Evaluates a math expression.
Use the following format:Question: the input question you must answerThought: you should always think about what to doAction: the action to take, should be one of [Wikipedia, Calculator]Action Input: the input to the actionObservation: the result of the action... (this Thought/Action/Observation can repeat N times)Thought: I now know the final answerFinal Answer: the final answer to the original input question

2. The Orchestrator Loop

The LLM generates text. As soon as it generates the Action: and Action Input: lines, the Python orchestrator stops the LLM.

The orchestrator reads the action (e.g., Calculator(5 * 8)), executes the Python code for that tool, and gets the result (40).

The orchestrator appends Observation: 40 to the text and sends the whole block back to the LLM. The LLM reads the observation, generates its next Thought:, and the loop continues until the LLM outputs Final Answer:.

Show Me the Code

This is a conceptual, simplified version of a ReAct orchestrator loop. Libraries like LangChain handle this parsing automatically, but seeing the raw loop is instructive.

import openaiimport re
def execute_tool(action, action_input):    print(f"  [Executing Tool]: {action} with input: '{action_input}'")    if action == "WeatherAPI":        if "Seattle" in action_input:            return "65 degrees and raining."        return "72 degrees and sunny."    return "Tool not found."
def react_loop(question, max_iterations=3):    system_prompt = """    You can use the tool: WeatherAPI(city).    You must format your response exactly as:    Thought: <your thought>    Action: <tool name>    Action Input: <input>    """        # We maintain a running log of the conversation (the "scratchpad")    conversation = [        {"role": "system", "content": system_prompt},        {"role": "user", "content": question}    ]        print(f"Question: {question}\n")        for i in range(max_iterations):        # 1. Call the LLM to get the next Thought + Action        response = openai.chat.completions.create(            model="gpt-4o",            messages=conversation,            stop=["Observation:"] # VERY IMPORTANT: Stop generation before it hallucinates the observation!        )                llm_output = response.choices[0].message.content        print(llm_output)                # Add the LLM's thought/action to the conversation history        conversation.append({"role": "assistant", "content": llm_output})                # 2. Check if the LLM reached the final answer        if "Final Answer:" in llm_output:            return                    # 3. Parse the action and execute it        action_match = re.search(r'Action:\s*(.*)', llm_output)        input_match = re.search(r'Action Input:\s*(.*)', llm_output)                if action_match and input_match:            action = action_match.group(1).strip()            action_input = input_match.group(1).strip()                        # Execute the python tool            observation = execute_tool(action, action_input)            print(f"Observation: {observation}\n")                        # Add the observation back to the conversation as if the user said it            conversation.append({"role": "user", "content": f"Observation: {observation}"})        else:            print("Error parsing action. Exiting loop.")            break
# --- Execution ---react_loop("What should I wear in Seattle today?")
# -> Question: What should I wear in Seattle today?# -> # -> Thought: I need to find the current weather in Seattle to recommend clothing.# -> Action: WeatherAPI# -> Action Input: Seattle# ->   [Executing Tool]: WeatherAPI with input: 'Seattle'# -> Observation: 65 degrees and raining.# -> # -> Thought: It is raining and mild. A raincoat and layers are appropriate.# -> Final Answer: You should wear a raincoat and carry an umbrella since it's 65 degrees and raining.

Watch Out For

The Parsing Nightmare

If you build a ReAct loop from scratch, you will quickly discover that LLMs constantly disobey formatting instructions. They will output Action: [WeatherAPI] (Seattle) instead of Action: WeatherAPI, crashing your regex parser. Modern agent frameworks rely heavily on strict JSON schemas or OpenAI's native Tool Calling API rather than pure text parsing to solve this fragility.

The Quick Version

  • ReAct combines "Chain of Thought" reasoning with environmental "Actions".
  • The LLM is placed inside a while loop orchestrated by Python code.
  • The LLM outputs a Thought and an Action.
  • The Python code halts the LLM, executes the requested tool (like a DB search or API call), and hands the result back to the LLM as an Observation.
  • The LLM repeats this loop until it has enough information to output the Final Answer.
  • Read Agentic RAG to see how ReAct is applied to complex document retrieval.
  • Read Chain of Thought to understand the purely analytical reasoning that powers ReAct.
  • Read Prompt Chaining for an alternative way to build multi-step workflows without handing autonomous control to the LLM.

Related concepts