AI Agents: Mastering 3 Essential Patterns (ReAct)
These articles are AI-generated summaries. Please check the original sources for full details.
The ReAct Pattern (Reason + Act) – When the Agent Starts “Talking to Itself”
With the “Tool Using” pattern, AI agents gained the ability to interact with the external world. The ReAct pattern (Reason + Act), proposed in 2022, equips agents with a “functional brain” by enabling an internal monologue for more complex problem-solving.
Unlike simple stimulus-response models, ReAct allows agents to plan, investigate, and course-correct, mirroring human thought processes. This is crucial because real-world problems often require multiple steps and adaptation, whereas a linear model quickly fails when facing ambiguity or incomplete information.
Why This Matters
Traditional AI models often struggle with multi-step reasoning and can quickly become unreliable when faced with complex tasks requiring information gathering and analysis. The cost of these failures can range from inaccurate data analysis leading to poor business decisions, to critical errors in automated systems, potentially amounting to millions in losses.
Key Insights
- ReAct introduced in 2022: Proposed by researchers at Princeton and Google, establishing a new standard in AI agent design.
- Internal Monologue: The core concept of ReAct, allowing the agent to articulate its thought process (“Thought Trace”) before taking action.
- Agno Framework: A tool used to implement the ReAct pattern, streamlining the Think → Act → Observe → Repeat loop, and utilized by developers for rapid prototyping.
Working Example
import os
import sys
import logging
import traceback
from typing import List, Optional
from dotenv import load_dotenv, find_dotenv
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.tavily import TavilyTools
# 1. Global Logging and Error Handling Configuration
LOG_DIR = os.path.join(os.path.dirname(__file__), "log")
LOG_FILE = os.path.join(LOG_DIR, "logs.txt")
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[
logging.FileHandler(LOG_FILE, encoding="utf-8"),
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
def global_exception_handler(exctype, value, tb):
"""Captures unhandled exceptions and records them in the log."""
error_msg = "".join(traceback.format_exception(exctype, value, tb))
logger.error(f"Unhandled exception:\n{error_msg}")
sys.__excepthook__(exctype, value, tb)
sys.excepthook = global_exception_handler
# 2. Environment Variables Loading
env_path = find_dotenv()
if env_path:
load_dotenv(env_path)
logger.info(f".env file loaded from: {env_path}")
else:
logger.warning(".env file not found")
# 3. Tool Definitions
def calculate(expression: str) -> str:
"""
Solves a simple mathematical expression (addition, subtraction, multiplication, division).
Useful for calculating year or date differences.
Args:
expression (str): The mathematical expression to evaluate (e.g., "2024 - 1789").
"""
try:
# Allow only safe characters for basic eval
allowed_chars = "0123456789+-*/(). "
if all(c in allowed_chars for c in expression):
result = eval(expression)
return f"Result: {result}"
else:
return "Error: Disallowed characters in expression."
except Exception as e:
return f"Error while calculating: {str(e)}"
# 4. Agno Agent Configuration (ReAct Pattern)
model_id = os.getenv("BASE_MODEL", "gpt-4o")
agent = Agent(
model=OpenAIChat(id=model_id),
tools=[TavilyTools(), calculate],
instructions=[
"You are a researcher using the ReAct (Reason + Act) method.",
"1. Think step-by-step about what information you need to answer the user's question.",
"2. Use the search tool (Tavily) to find specific dates, facts, or data.",
"3. Use the calculator ('calculate') for any mathematical operation or time calculation.",
"4. Do not guess historical information. If you don't have a piece of data, look it up.",
"5. Show your reasoning clearly: 'Thought:', 'Action:', 'Observation:'.",
"6. Continue investigating until you have a complete and verified answer."
],
)
# 5. User Interface
def main():
logger.info("Starting Historical Detective Agent (ReAct)...")
print("--- Historical Detective - ReAct Pattern ---")
print("Type 'exit' to quit.\n")
while True:
try:
user_input = input("Researcher, what is your question?: ")
if user_input.lower() == "exit":
logger.info("The user has ended the session.")
break
if not user_input.strip():
continue
logger.info(f"User query: {user_input}")
print("\nInvestigating...\n")
agent.print_response(user_input, stream=True, show_tool_calls=True)
print("\n")
except KeyboardInterrupt:
logger.info("Keyboard interrupt detected.")
break
except Exception as e:
logger.error(f"Error in main loop: {str(e)}")
print(f"\nAn error occurred: {e}")
if __name__ == "__main__":
main()
Practical Applications
- Coding Assistants: Tools like Devin and Copilot leverage ReAct to iteratively write, execute, and debug code.
- Customer Support: Level 2 tech support systems can use ReAct to diagnose and resolve complex issues by gathering information from multiple sources.
- Financial Analysis: ReAct enables agents to analyze market trends and generate investment recommendations by combining data from news sources and historical data.
References:
Continue reading
Next article
My First Steps into Kubernetes: From Installation to Running Pods
Related Content
Hermes vs OpenClaw: Comparing the Leading AI Agent Frameworks of 2026
OpenClaw leads with 374k GitHub stars, while Hermes focuses on self-improving loops to redefine personal AI agents.
Scaling AI Agents: A Three-File State Management Pattern for 24/7 Production
Patrick's 5-agent system runs 24/7 on a Mac Mini using a three-file state management pattern, solving the 80% of production failures caused by state issues.
Vigil Crest: A Custom Hermes Agent for Hackathon Triage
L Cordero built Vigil Crest, a Hermes Agent that triages hackathons using Claude Sonnet 4.6 and Playwright to optimize developer time.