Exercise 1: React Foundation
Overview
In this exercise, you'll build your first AI agent using the ReAct pattern.
ReAct stands for: Reason → Act → Observe → Repeat
Your agent will:
- Reason about a problem ("What do I need to do?")
- Act by calling tools ("Let me use this tool")
- Observe the result ("What happened?")
- Repeat until the goal is achieved
What You'll Build
A simple agent that:
- Reasons about mathematical problems
- Uses a calculator tool to solve expressions
- Observes results and adjusts approach
- Demonstrates the core ReAct loop
Example: Agent solves "What is (5 + 3) * 2?"
Agent reasons: "I need to solve a math expression"
Agent acts: Calls calculator(5 + 3)
Agent observes: Result is 8
Agent acts: Calls calculator(8 * 2)
Agent observes: Result is 16
Agent concludes: "The answer is 16"
Learning Outcomes
By completing this exercise, you'll understand:
- ✅ What agents are and how they think
- ✅ The ReAct pattern for agent reasoning
- ✅ How to define tools that agents can use
- ✅ Tool calling and result handling
- ✅ The agent loop (think → act → observe → repeat)
- ✅ LLM integration basics
Getting Started
Prerequisites
- Python 3.9+ OR Node.js 18+
- Basic familiarity with your chosen language
- Git installed and configured
Clone the Repository
cd /opt/exercises
git clone <repo-url>
cd exercise-1-react-foundation
Install Dependencies
Python:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
JavaScript/TypeScript:
npm install
Verify Setup
# Python
python test_basic.py
# JavaScript
npm test -- test-basic
You should see: ✅ All tests passing
Exercise Steps
Step 1: Understand the ReAct Loop (15 min)
File: docs/REACT_INTRO.md in the repo
Read about the ReAct pattern. Understand:
- Why agents need to reason
- Why acting on reasoning helps
- Why observing results is important
- How the loop repeats until success
Step 2: Define Your First Tool (15 min)
File: src/tools/calculator.py (Python) or src/tools/calculator.ts (TypeScript)
Implement a simple calculator tool with:
add(a, b)→ returns sumsubtract(a, b)→ returns differencemultiply(a, b)→ returns productdivide(a, b)→ returns quotient
Hint: Tools are just functions that agents can call.
Step 3: Create the Agent (30 min)
File: src/agent.py or src/agent.ts
Implement an agent class with:
think(problem)→ Plan what to doact(tool, args)→ Call a toolobserve(result)→ Process the resultsolve(problem)→ Main loop that ties it together
Hint: The agent loops: think → act → observe → think again
Step 4: Connect to an LLM (25 min)
File: src/llm.py or src/llm.ts
Use the LLM API to:
- Send the agent's current thinking to an LLM
- Get back the LLM's reasoning
- Extract which tool to call
- Store the reasoning for later review
Hint: The LLM does the "thinking" part of ReAct. Your agent handles the loop.
Step 5: Test Your Agent (15 min)
File: test_exercise.py or test_exercise.ts
Write tests that verify:
- Agent can solve simple math (2 + 2)
- Agent can solve complex expressions ((5 + 3) * 2)
- Agent calls the right tools
- Agent stops when goal is achieved
Run tests: npm test or pytest test_exercise.py
Concept Deep-Dive
The ReAct Pattern
┌─────────────────────────────────────┐
│ Problem: "What is (5 + 3) * 2?" │
└─────────────────────────────────────┘
↓
┌─────────────────┐
│ REASON: Think │
│ "I need a calc" │
└─────────────────┘
↓
┌─────────────────┐
│ ACT: Use tool │
│ calc(5 + 3) │
└─────────────────┘
↓
┌─────────────────┐
│ OBSERVE: Result │
│ Result: 8 │
└─────────────────┘
↓
Goal achieved?
↓ No
┌─────────────────┐
│ REASON AGAIN │
│ "Need to * by 2"│
└─────────────────┘
↓
┌─────────────────┐
│ ACT: calc(8*2) │
└─────────────────┘
↓
┌─────────────────┐
│ OBSERVE: 16 │
└─────────────────┘
↓
Goal achieved?
↓ Yes ✅
┌─────────────────┐
│ Return: 16 │
└ ─────────────────┘
Why ReAct?
The ReAct pattern is powerful because:
- Reasoning helps agents make good choices about which tools to use
- Action lets agents interact with the real world
- Observation provides feedback to improve reasoning
- Repetition allows complex problems to be solved step-by-step
This is how humans solve problems too!
Common Issues
Model not responding
Problem: LLM API calls timeout or error Solution:
- Check your API key in
.env - Verify network connectivity
- See Troubleshooting
Tool doesn't parse correctly
Problem: Agent can't extract tool name from LLM response Solution:
- Print the raw LLM response to debug
- Check the tool definition format
- Adjust parsing logic
Agent calls tools infinitely
Problem: Agent gets caught in a loop Solution:
- Add a max iterations limit
- Print debug output to see what agent is thinking
- Check if any tool is working correctly
Next Steps
After completing this exercise:
- Read the solution walkthrough below in the "Example Solution" section
- Try the Go Further challenges below
- Move on to Exercise 2: Jenkins MCP Server
Go Further (Optional Challenges)
Want to dive deeper? Try these after completing the main exercise:
Challenge 1: Memory
Add a memory system so the agent remembers previous results:
agent = Agent()
agent.solve("What is 2 + 2?") # Learns: 2 + 2 = 4
agent.solve("Add 1 to the previous result") # Uses memory: 4 + 1 = 5
Challenge 2: Multi-Tool Reasoning
Add more tools (calculator, string manipulation, data lookup) and have the agent choose the right one.
Challenge 3: Explain Reasoning
Have the agent explain its reasoning to a human:
agent = Agent()
solution, reasoning = agent.solve_with_explanation("What is 50 / 5 + 2?")
print(reasoning)
# Output: "I need to divide 50 by 5 to get 10, then add 2 to get 12"
Challenge 4: Error Recovery
Make the agent handle tool errors gracefully:
# Tool fails: divide(10, 0) → Error
# Agent recovers: "That didn't work, let me try differently"
Resources
- 📚 ReAct Paper - The full research paper
- 🔗 Tool Calling Patterns - How to define tools
- 💬 LLM API Reference - Including tool/function calling
Ready?
Time to build your first agent! 🚀