Agent Architectures: ReAct, Plan-and-Solve & Reflexion
Understand the cognitive reasoning loops that convert passive language models into dynamic problem solvers capable of self-reflection and multi-step planning.
1. The ReAct Framework (Reasoning + Acting)
Introduced by Yao et al. (Princeton & Google Brain), ReAct proved that interleaving internal reasoning traces (Thought) with external tool executions (Action) synergistically outperforms pure reasoning or pure acting alone:
The Tri-Partite ReAct Cycle
- Thought: The agent articulates its current mental model, analyzes past observations, and decides the next logical goal.
- Action: The agent picks a specific tool and passes structured arguments (e.g.,
search_database(query="...")). - Observation: The environment executes the tool and injects the raw output back into the context window.
Example Scratchpad Execution:
Question: What is the elevation difference between Denver and Death Valley?
Thought: I need to find the elevation of Denver first.
Action: search_elevation("Denver, Colorado")
Observation: 5,280 feet above sea level.
Thought: Now I need to find the elevation of Death Valley.
Action: search_elevation("Death Valley, California")
Observation: -282 feet (below sea level).
Thought: Now I calculate the difference: 5280 - (-282) = 5562 feet.
Action: finish(5562)2. Plan-and-Solve (BabyAGI Pattern)
While ReAct is greedy and decides one step at a time, Plan-and-Solve architectures (popularized by BabyAGI and Plan-and-Execute) separate planning from execution:
Phase 1: Planner Agent
Takes the complex goal and outputs a structured list of sub-tasks (e.g.,["1. Fetch financial report", "2. Extract EBITDA", "3. Calculate YoY growth"]).
Phase 2: Executor Agent & Re-Planner
Executes tasks sequentially or in parallel. After each step, a Re-Planner inspects the intermediate output and dynamically updates or modifies remaining tasks if needed.
3. Reflexion: Self-Critique & Memory Buffer
When a naive agent fails a task (e.g. a Python script fails with an IndexError), it often gets stuck repeating similar failing attempts. Reflexion (Shinn et al.) equips agents with verbal reinforcement learning:
- The Evaluator: Computes a scalar score or binary verdict on the agent's output.
- The Self-Reflection Generator: Prompts the LLM: "You failed task X. Analyze your past scratchpad. What specifically caused the failure, and what should you do differently?"
- Episodic Reflection Memory: The generated reflection is prepended to the prompt for the next trial, allowing the agent to learn from errors within 2 to 3 iterations.
4. Hands-On Python: Building a ReAct Loop from Scratch
Here is a clean implementation of a ReAct agent without heavyweight dependencies, using OpenAI client tools:
import json
# Define our mock tool functions
def query_stock_price(symbol: str) -> str:
prices = {"AAPL": "$230.50", "NVDA": "$135.20", "GOOGL": "$182.00"}
return prices.get(symbol.upper(), "Error: Symbol not found")
def calculate_portfolio(holdings: dict) -> str:
# Holdings format: {"AAPL": 10, "NVDA": 20}
total = 10 * 230.50 + 20 * 135.20
return f"Total Value: USD {total:.2f}"
tools_registry = {
"query_stock_price": query_stock_price,
"calculate_portfolio": calculate_portfolio
}
# The ReAct Agent Loop
def run_react_agent(query, llm_client):
messages = [
{"role": "system", "content": "You are a ReAct financial analyst. Use available tools to answer questions."},
{"role": "user", "content": query}
]
max_steps = 5
for step in range(max_steps):
print(f"\n--- Iteration Step {step + 1} ---")
response = llm_client.chat_completion(messages)
# Check if model wants to call tools
if not response.tool_calls:
print("Final Response Generated!")
return response.content
for tool_call in response.tool_calls:
name = tool_call.function.name
args = json.loads(tool_call.function.arguments)
print(f"[Action] Calling '{name}' with args {args}")
output = tools_registry[name](**args)
print(f"[Observation] Result: {output}")
# Append interaction to memory scratchpad
messages.append({"role": "assistant", "tool_calls": [tool_call]})
messages.append({"role": "tool", "content": output, "tool_call_id": tool_call.id})
return "Agent exceeded maximum iteration steps."Function Calling & Tool Use
Continue to the next advanced agentic AI engineering module.
Explore Related Tools
Hand-picked utilities and calculators related to this tool.
