"""
Pattern 001: ReAct (Reasoning + Acting)
Description:
Agent alternates between reasoning about the task and taking actions.
The ReAct pattern combines reasoning traces with task-specific actions,
allowing the agent to reason about what to do and then take actions.
Components:
- Thought: Agent reasons about current state
- Action: Agent takes an action (e.g., tool use)
- Observation: Agent observes the result
- Loop continues until task is complete
Use Cases:
- Question answering with external knowledge
- Task completion requiring multiple steps
- Interactive problem solving
LangChain Implementation:
Uses LangChain's AgentExecutor with structured tools and ReAct prompt template.
"""
import os
from typing import List, Optional
from dotenv import load_dotenv
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import Tool
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
# Load environment variables
load_dotenv()
# Define example tools
def calculator(expression: str) -> str:
"""Evaluates a mathematical expression."""
try:
# Safe evaluation for demo purposes
result = eval(expression, {"__builtins__": {}}, {})
return f"Result: {result}"
except Exception as e:
return f"Error: {str(e)}"
def search_tool(query: str) -> str:
"""Simulates a search tool that retrieves information."""
# Simulated search results
knowledge_base = {
"capital of france": "Paris",
"population of tokyo": "approximately 14 million",
"height of mount everest": "8,848.86 meters (29,031.7 feet)",
"speed of light": "299,792,458 meters per second",
"boiling point of water": "100°C (212°F) at sea level",
}
query_lower = query.lower()
for key, value in knowledge_base.items():
if key in query_lower:
return f"Search result: {value}"
return f"Search result: Information about '{query}' not found in knowledge base."
def get_current_date() -> str:
"""Returns the current date."""
from datetime import datetime
return f"Current date: {datetime.now().strftime('%Y-%m-%d')}"
# Create tools list
tools = [
Tool(
name="Calculator",
func=calculator,
description="Useful for performing mathematical calculations. Input should be a valid mathematical expression."
),
Tool(
name="Search",
func=search_tool,
description="Useful for searching factual information. Input should be a search query."
),
Tool(
name="GetDate",
func=get_current_date,
description="Returns the current date. No input required."
)
]
# ReAct prompt template
REACT_PROMPT = """Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought: {agent_scratchpad}
"""
def create_react_agent_system():
"""Creates a ReAct agent using LangChain."""
# Initialize LLM
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0,
api_key=os.getenv("OPENAI_API_KEY")
)
# Create prompt template
prompt = PromptTemplate.from_template(REACT_PROMPT)
# Create agent
agent = create_react_agent(
llm=llm,
tools=tools,
prompt=prompt
)
# Create agent executor
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=10,
handle_parsing_errors=True
)
return agent_executor
def demonstrate_react_pattern():
"""Demonstrates the ReAct pattern with various examples."""
print("=" * 80)
print("PATTERN 001: ReAct (Reasoning + Acting)")
print("=" * 80)
print()
# Create the ReAct agent
agent_executor = create_react_agent_system()
# Test cases demonstrating ReAct pattern
test_questions = [
"What is the capital of France?",
"What is 25 * 4 + 10?",
"What is the population of Tokyo and what is 100 divided by that number in millions?",
"What's today's date?",
]
for i, question in enumerate(test_questions, 1):
print(f"\n{'=' * 80}")
print(f"Example {i}: {question}")
print('=' * 80)
try:
result = agent_executor.invoke({"input": question})
print(f"\n✓ Final Answer: {result['output']}")
except Exception as e:
print(f"\n✗ Error: {str(e)}")
print()
# Summary
print("\n" + "=" * 80)
print("REACT PATTERN DEMONSTRATION COMPLETE")
print("=" * 80)
print()
print("Key Features Demonstrated:")
print("1. Thought-Action-Observation loop")
print("2. Tool selection and usage")
print("3. Multi-step reasoning")
print("4. Dynamic decision making")
print("5. Interpretable reasoning traces")
print()
print("LangChain Components Used:")
print("- AgentExecutor: Manages agent execution loop")
print("- create_react_agent: Creates ReAct-style agent")
print("- Tool: Wraps functions as agent tools")
print("- PromptTemplate: Structures the ReAct prompt format")
print("- ChatOpenAI: LLM for reasoning and action selection")
print()
if __name__ == "__main__":
# Check for API key
if not os.getenv("OPENAI_API_KEY"):
print("Error: OPENAI_API_KEY not found in environment variables.")
print("Please set it in your .env file or environment.")
exit(1)
demonstrate_react_pattern()
Agentic Design Pattern: React
Pattern 001: React – Line-by-Line Explanation
Overview
This document provides a detailed line-by-line explanation of the React pattern implementation.
Pattern Description
Pattern 001: ReAct (Reasoning + Acting)
Description: Agent alternates between reasoning about the task and taking actions. The ReAct pattern combines reasoning traces with task-specific actions, allowing the agent to reason about what to do and then take actions.
Components: – Thought: Agent reasons about current state – Action: Agent takes an action (e.g., tool use) – Observation: Agent observes the result – Loop continues until task is complete
Use Cases: – Question answering with external knowledge – Task completion requiring multiple steps – Interactive problem solving
LangChain Implementation: Uses LangChain’s AgentExecutor with structured tools and ReAct prompt template.
File Statistics
- Total Lines: 209
- Classes: 0
- Functions: 5
- Constants: 1
Module Documentation
"""
Pattern 001: ReAct (Reasoning + Acting)
Description:
Agent alternates between reasoning about the task and taking actions.
The ReAct pattern combines reasoning traces with task-specific actions,
allowing the agent to reason about what to do and then take actions.
Components:
- Thought: Agent reasons about current state
- Action: Agent takes an action (e.g., tool use)
- Observation: Agent observes the result
- Loop continues until task is complete
Use Cases:
- Question answering with external knowledge
- Task completion requiring multiple steps
- Interactive problem solving
LangChain Implementation:
Uses LangChain's AgentExecutor with structured tools and ReAct prompt template.
"""
Purpose: This module implements the React pattern, providing a structured approach to agent design and implementation.
Import Statements
Standard Library Imports
import datetime.datetime
import langchain.agents.create_react_agent
import langchain_core.prompts.PromptTemplate
import os
import typing.List
import typing.Optional
Purpose: Core Python functionality:
– datetime.datetime: Date and time handling
– langchain.agents.create_react_agent: Regular expression operations
– langchain_core.prompts.PromptTemplate: Regular expression operations
– os: Environment variable access and system operations
– typing.List: Type hints for better code documentation (List, Dict, Any, Optional)
– typing.Optional: Type hints for better code documentation (List, Dict, Any, Optional)
LangChain Imports
from langchain.agents.AgentExecutor
from langchain.tools.Tool
from langchain_openai.ChatOpenAI
Purpose: LangChain framework components: – LLM Interface: Wrapper for OpenAI models – Chains: Composable building blocks for complex workflows – Agents: Autonomous decision-making entities – Tools: Functions that agents can invoke
Other Imports
from dotenv.load_dotenv
Purpose: Additional dependencies for specialized functionality.
Module Constants
REACT_PROMPT
REACT_PROMPT = """Answer the following questions as best you can. You have access to the following tools:
Line 94: Module-level constant definition.
Functions
calculator(expression)
Lines 38-45
Purpose:
Evaluates a mathematical expression.
Parameters:
– expression: Expression
Returns: str
search_tool(query)
Lines 48-64
Purpose:
Simulates a search tool that retrieves information.
Parameters:
– query: Input query or question
Returns: str
get_current_date()
Lines 67-70
Purpose:
Returns the current date.
Returns: str
create_react_agent_system()
Lines 116-145
Purpose:
Creates a ReAct agent using LangChain.
demonstrate_react_pattern()
Lines 148-198
Purpose:
Demonstrates the ReAct pattern with various examples.
Key Concepts Summary
Pattern Overview
The React pattern provides a structured approach to building AI agents with specific capabilities and behaviors. This implementation leverages LangChain’s composable components to create a robust and maintainable solution.
Core Components
- Agent Class: Main implementation of the pattern logic
- Prompt Engineering: Carefully crafted prompts to guide LLM behavior
- Tool Integration: Optional tools for extended functionality
- Memory Management: State handling across interactions
- Output Parsing: Structured response processing
When to Use
✅ Good for: – Scenarios requiring this specific pattern’s strengths – Applications needing structured agent behavior – Systems where explainability is important – Production environments requiring reliability
❌ Not ideal for: – Simple single-prompt tasks – Scenarios requiring different pattern characteristics – Resource-constrained environments (if computationally intensive)
Best Practices Demonstrated
1. Environment Configuration
- ✅ Use
.envfiles for API keys - ✅ Never hardcode credentials
- ✅ Validate environment variables on startup
2. Error Handling
- ✅ Graceful degradation on failures
- ✅ Informative error messages
- ✅ Logging for debugging
3. Prompt Engineering
- ✅ Clear, specific instructions
- ✅ Structured output formats
- ✅ Few-shot examples when beneficial
4. Code Organization
- ✅ Separation of concerns (class-based design)
- ✅ Type hints for clarity
- ✅ Docstrings for documentation
5. Performance Optimization
- ✅ Appropriate temperature settings
- ✅ Token budget management
- ✅ Caching where applicable
LangChain Components Used
- ChatOpenAI: OpenAI model interface
- Chains: Sequential component composition
- Agents: Autonomous decision-making
- Tools: External function calling
Why LangChain? – Composable abstractions for LLM applications – Rich ecosystem of integrations – Production-ready patterns – Active community and development
Execution Flow
1. Initialize agent with configuration
↓
2. Load environment and dependencies
↓
3. Prepare prompt with input data
↓
4. Invoke LLM through LangChain
↓
5. Parse and validate response
↓
6. Return formatted result
Key Decision Points: – Model selection (temperature, model type) – Prompt structure (few-shot vs zero-shot) – Error handling strategy – Output format validation
Performance Considerations
Computational Cost
- LLM Calls: Primary cost factor (based on tokens)
- Latency: Depends on model and input size
- Memory: Minimal for most patterns
Optimization Strategies
- Prompt Optimization: Minimize tokens while maintaining clarity
- Caching: Cache repeated queries/responses
- Model Selection: Use smaller models when appropriate
- Batch Processing: Group similar requests
- Streaming: For long responses, stream tokens
Cost Estimates (Approximate)
- GPT-3.5-turbo: ~$0.002 per request
- GPT-4: ~$0.03 per request
- GPT-4-turbo: ~$0.01 per request
Actual costs vary based on input/output token counts
Common Pitfalls to Avoid
1. Prompt Design Issues
❌ Vague or ambiguous instructions
✅ Clear, specific, testable prompts
2. Error Handling
❌ Ignoring API errors or rate limits
✅ Implement retry logic and graceful degradation
3. Token Management
❌ Exceeding model token limits
✅ Truncate inputs, chunk processing
4. Security
❌ Exposing API keys in code
✅ Use environment variables
5. Testing
❌ Only testing happy paths
✅ Test edge cases, failures, malformed inputs
6. Cost Management
❌ Unmonitored API usage
✅ Implement budgets, alerts, and monitoring
Further Improvements
Production Enhancements
- Monitoring: Add logging, metrics, tracing
- Validation: Input/output schema validation
- Rate Limiting: Implement request throttling
- Caching: Redis or in-memory cache for responses
- Async Support: Non-blocking operations for scalability
Feature Extensions
- Multi-Model Support: Switch between providers
- Fallback Models: Graceful degradation strategy
- Custom Tools: Domain-specific function calling
- Advanced Memory: Vector stores for long-term memory
- Evaluation: Automated testing and benchmarking
Code Quality
- Testing: Unit tests, integration tests
- Documentation: API docs, usage examples
- Type Safety: Stricter type hints
- Configuration: Externalized config files
Related Patterns
- Pattern 002
- Other Reasoning Patterns (001-011)
Pattern Families: – Reasoning Patterns (001-011) – Multi-Agent Patterns (012-019) – Tool Use Patterns (020-025) – Memory Patterns (026-031) – And many more…
Summary
The React pattern provides a powerful approach to building AI agents with specific capabilities. This implementation demonstrates:
✅ Key Strengths: – Clean, maintainable code structure – LangChain integration for composability – Type hints and documentation – Production-ready patterns
🎯 Best Use Cases: – Applications requiring this pattern’s characteristics – Systems needing structured agent behavior – Production environments requiring reliability
📚 Learning Resources: – LangChain Documentation: https://python.langchain.com/ – Pattern Documentation: See related patterns – OpenAI API Reference: https://platform.openai.com/docs/
File: 001_react.py
Total Lines: 209
Pattern Category: AI Agent Design Pattern #001
Generated from actual implementation code
For educational and reference purposes