Mastering ReAct: Turn LLMs into Thoughtful, Actionable AI Agents

This article explains the ReAct (Reasoning + Acting) design pattern for large language model agents, detailing its thought‑action‑observation loop, concrete examples, prompt engineering tips, full Python implementations, common pitfalls, and references to the original Google research.

Qborfy AI
Qborfy AI
Qborfy AI
Mastering ReAct: Turn LLMs into Thoughtful, Actionable AI Agents

What Is ReAct?

ReAct (Reasoning + Acting) is a simple yet powerful paradigm that makes an LLM behave like a detective: it repeatedly thinks , acts using tools, and observes the results until the problem is solved. Unlike the classic one‑question‑one‑answer interaction, ReAct continuously asks itself "What should I do next?" and executes the chosen action.

ReAct workflow diagram
ReAct workflow diagram

Core Loop

Thought (Reasoning) : The model analyses the current state and decides what information is missing.

Action (Acting) : Based on the thought, it selects a tool (e.g., search, calculator) and provides the required input.

Observation : The tool returns a result, which becomes part of the next round of reasoning.

These three steps repeat until a final_answer is produced.

Concrete Example

Suppose we ask the agent "What is Tesla's stock price multiplied by 10?" The reasoning proceeds as follows:

Thought: I need the current Tesla price.

Action: call search with query "Tesla stock price".

Observation: "Current Tesla stock price 250 USD".

Thought: Now I can compute 250 * 10.

Action: call calculator with expression "250*10".

Observation: "2500".

Thought: I have the answer, respond to the user.

Action: output "2500 USD".

The whole process mirrors a careful human problem‑solver who never guesses without evidence.

Implementation Sketch

A minimal ReAct agent can be built with a simple while loop that alternates between prompting the LLM and handling tool calls. The core class looks like this:

class ReActAgent:
    def __init__(self, llm, tools):
        self.llm = llm  # large language model
        self.tools = tools  # dictionary of tool objects
        self.memory = []

    def run(self, query):
        self.memory = [{"role": "user", "content": query}]
        while True:
            response = self.llm.chat(self.memory)
            if "final_answer" in response:
                return response["final_answer"]
            if "action" in response:
                tool_name = response["action"]["name"]
                tool_input = response["action"]["input"]
                result = self.tools[tool_name].run(tool_input)
                self.memory.append({"role": "observation", "content": result})
            else:
                break
        return "No answer found"

The loop stops when the model emits a final_answer or when a safety limit (max iterations) is reached.

Prompt Design

Prompt format is crucial. A robust template forces the model to output exactly three sections (Thought, Action, Action Input) or a Final Answer when ready:

You are an intelligent assistant. Solve the problem by repeating:

Thought: [what you know / what you need]
Action: [tool name]
Action Input: [parameters]

When you have enough information, output:
Thought: [summary]
Final Answer: [result]

Available tools:
- search(query)
- calculator(expression)
- read_file(path)

Without strict formatting the model may drift, produce malformed output, or enter an infinite loop.

Full Working Example

The following script ties everything together, using OpenAI's gpt‑4 model and a mock tool set. It demonstrates the complete ReAct cycle, including system prompt, tool dispatch, observation logging, and a safety‑check on iteration count.

import json
from openai import OpenAI

client = OpenAI()

class Tools:
    @staticmethod
    def search(query):
        mock_db = {
            "特斯拉股价": "当前特斯拉股价 250 美元",
            "马斯克": "埃隆·马斯克是 Tesla、SpaceX 创始人",
            "openai": "OpenAI 是 ChatGPT 的开发商"
        }
        return mock_db.get(query, f"没有找到关于:{query} 的信息")

    @staticmethod
    def calculate(expression):
        try:
            return str(eval(expression))
        except:
            return "计算出错"

def react_agent(user_query, max_iterations=5):
    tools = Tools()
    system_prompt = """你是一个 ReAct 智能助手。按照 "思考 → 行动 → 观察" 的循环来解决问题。每次只输出三个阶段的内容,格式如下:

Thought: [你现在掌握什么信息?还需要什么?打算怎么做?]
Action: [要调用的工具名]
Action Input: [传给工具的参数]

当信息足够回答用户问题时,输出:
Thought: [思考过程]
Final Answer: [给用户的最终回答]

可用工具:
- search(query): 搜索信息
- calculate(expression): 数学计算
"""
    messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": user_query}]
    for i in range(max_iterations):
        response = client.chat.completions.create(model="gpt-4", messages=messages)
        content = response.choices[0].message.content
        print(f"
=== 第 {i+1} 轮 ===")
        print(content)
        if "Final Answer:" in content:
            return content.split("Final Answer:")[1].strip()
        if "Action:" in content and "Action Input:" in content:
            action = content.split("Action:")[1].split("
")[0].strip()
            action_input = content.split("Action Input:")[1].strip()
            if action == "search":
                observation = tools.search(action_input)
            elif action == "calculate":
                observation = tools.calculate(action_input)
            else:
                observation = "未知工具"
            messages.append({"role": "assistant", "content": content})
            messages.append({"role": "user", "content": f"Observation: {observation}"})
        else:
            break
    return "达到最大循环次数,未找到答案"

query = "特斯拉股价乘以10是多少?"
result = react_agent(query)
print(f"
✅ 最终答案: {result}")

Running this script prints each reasoning step, tool call, and observation, finally yielding the answer "2500".

Practical Tips

Set a maximum loop count to avoid endless cycles on hard problems.

Enforce a strict prompt format so the model’s output can be reliably parsed.

Make tool returns explicit ; ambiguous results confuse the reasoning process.

Cold Facts

ReAct has nothing to do with the React front‑end framework; the name only sounds similar.

The method originates from a 2022 Google Research paper titled "ReAct: Synergizing Reasoning and Acting in Language Models".

LangChain’s default AgentExecutor is a thin wrapper around the ReAct pattern.

ReAct pairs naturally with OpenAI’s Function Calling feature, which yields structured tool‑call outputs.

It is one of several agent architectures; alternatives include Reflexion and Plan‑and‑Solve.

References

ReAct paper (arXiv:2210.03629)

LangChain ReAct Agent documentation

OpenAI Function Calling guide

PythonAI agentsLLMprompt engineeringReActOpenAItool usage
Qborfy AI
Written by

Qborfy AI

A knowledge base that logs daily experiences and learning journeys, sharing them with you to grow together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.