Introduction
In our last two lessons, we've built the foundational skills for creating an intelligent agent. First, you learned how to equip an agent with tools (function calling) to interact with the outside world. Then, you mastered advanced prompt engineering, specifically using Chain-of-Thought (CoT), to make an agent reason in a structured, step-by-step manner.
The question that naturally follows is: how do we combine these two capabilities? How does an agent autonomously decide when to think and when to act?
This lesson answers that question by introducing one of the most foundational patterns in agent design: ReAct (Reason + Act). The goal of this lesson is to empower you to design and implement an agent workflow using the ReAct framework. You will learn to build a system that can dynamically create a plan, execute tools to gather information, and reason about the results to solve complex problems—the core loop of any sophisticated agent.
Part 1: The ReAct Framework - Thought, Action, Observation
The ReAct framework is an elegant solution that synergizes reasoning and acting. It's an iterative loop that mimics a human's problem-solving process.

The loop consists of three key steps:
- Thought: The agent uses the LLM to analyze the current problem and its state. It thinks about what it knows, what it doesn't know, and what its next step should be to get closer to the solution. This is its internal monologue.
- Action: Based on its thought process, the agent decides to use one of its available tools. It specifies the tool to call and the input for that tool.
- Observation: The agent executes the action (i.e., calls the tool) and gets a result back. This result is the observation. The observation is then fed back into the agent to start the next cycle with a new "Thought".
This loop continues until the agent's "Thought" process concludes that it has enough information to provide a final answer, at which point it exits the loop.
To see a clear, high-level explanation of this concept, let's watch the beginning of the following video.
Python: Create a ReAct Agent from Scratch
The video 'Python: Create a ReAct Agent from Scratch' by Alejandro AO provides a fantastic conceptual overview of the ReAct pattern. This first segment explains the Thought-Action-Observation loop using a simple and effective analogy.
Please watch from 01:27 to 10:18. Focus on understanding the diagram and the example of how the agent breaks down the question 'what is the joint mass of all of the planets?' into a series of thoughts and actions.
Part 2: Building a ReAct Agent from Scratch
Given your background and preference for implementation, the best way to truly understand ReAct is to build it from the ground up. This will demystify what frameworks like LangChain do under the hood and give you full control over the agent's logic.
We will continue with the video from the previous section, as it provides a complete, code-along tutorial for building a ReAct agent using only Python and a fast LLM API (Groq).
2.1 The System Prompt: The Agent's Operating Instructions
The entire ReAct loop is orchestrated by a cleverly designed system prompt. This builds directly on the prompt engineering skills from our last lesson. The prompt must explicitly instruct the LLM to follow the Thought, Action, PAUSE, Observation sequence.
The video details how to craft such a prompt. You can also refer to the article "Create a ReACT agent from scratch..." for a similar prompt structure. Notice how it provides:
- A clear definition of the loop.
- A description of the available tools (
calculate,wikipedia). - A few-shot example showing the desired interaction pattern.
Python: Create a ReAct Agent from Scratch
This next segment of the video shows how to define the two critical components for our ReAct agent: the system prompt and the tools (as Python functions).
Watch from 21:36 to 29:12. Pay close attention to how the system prompt is structured to force the agent into the ReAct loop and how the calculate and get_planet_mass functions are defined as the agent's tools.
2.2 The Orchestration Loop: Automating the Cycle
Now for the core of the implementation: a Python loop that automates the agent's reasoning process. This loop will serve as the conductor, managing the conversation between the LLM and the tools.
The logic is as follows:
- Initialize the agent with the system prompt and the user's query.
- Start a
whileloop that runs for a maximum number of iterations (to prevent infinite loops). - In each iteration, call the agent (LLM) with the current prompt.
- Parse the LLM's response.
- If the response contains
Action:andPAUSE, use regular expressions to extract the tool name and its arguments. - Execute the corresponding Python function (the tool).
- Format the function's return value into an
Observation:string. This string becomes thenext_prompt. continueto the next loop iteration.- If the response contains
Answer:, the agent is finished.breakthe loop.
- If the response contains
- Return the final result.
The final part of the video walks through building this exact loop.
Python: Create a ReAct Agent from Scratch
This crucial section demonstrates how to build the Python loop that automates the agent's decision-making process. It's where the 'agent' truly comes to life.
Watch from 37:32 to 53:43. Follow along as the agent_loop function is constructed. The use of regular expressions (re.findall) to parse the action and the eval function to dynamically call the tool are key techniques to understand.
For your reference, here is the essential logic of the orchestration loop discussed in the video.
# Simplified logic of the agent loop
import re
# Assume 'agent' is an initialized class that calls the LLM
# Assume 'tools' is a dictionary mapping tool names to functions
next_prompt = "What is the mass of the Earth plus the mass of Mercury?"
max_iterations = 10
for i in range(max_iterations):
# 1. Call the LLM
result = agent(next_prompt)
print(result)
# 2. Check for final answer
if "Answer" in result:
print("Agent has finished.")
break
# 3. Check for an action
if "Action" in result and "PAUSE" in result:
# Parse the action and arguments
action_match = re.search(r"Action: (\w+): (.*)", result)
if action_match:
tool_name, tool_input = action_match.groups()
# Execute the tool
if tool_name in tools:
tool_function = tools[tool_name]
# Be cautious with eval in production; here it's used for clarity
observation = tool_function(eval(tool_input))
next_prompt = f"Observation: {observation}"
print(f"--- Observation Sent to Agent: {observation} ---")
else:
next_prompt = "Observation: Tool not found."
continue # Go to the next loop iteration
Test your understanding!
Imagine you want to equip your agent with a tool relevant to project finance. You define a new Python function: calculate_dscr(noi, debt_service).
- How would you modify the system prompt to make the agent aware of this new tool?
- Write a sample query that would likely cause the agent to use this tool in its reasoning process.
Show answer
-
Modify the System Prompt: You would add the
calculate_dscrtool to the list of available actions in the prompt, along with a clear description and an example.Your available actions are: calculate_dscr: e.g. calculate_dscr: 1000000, 800000 Calculates the Debt Service Coverage Ratio given Net Operating Income (NOI) and Debt Service. The first argument is NOI, the second is Debt Service. wikipedia: e.g. wikipedia: Project Finance Returns a summary from searching Wikipedia. -
Sample Query: A good query would be a multi-step problem that requires finding financial figures first and then calculating the ratio.
Query: "A solar project generates $2.5M in revenue with $1M in operating expenses. Its annual debt service is $1.2M. What is the project's DSCR?"
The agent's expected thought process would be:
- Thought: I need to first calculate the Net Operating Income (NOI), which is Revenue - Opex. Then I can use the
calculate_dscrtool. - Action:
calculate: 2500000 - 1000000 - Observation:
1500000 - Thought: Now I have the NOI ($1.5M) and I was given the debt service ($1.2M). I can calculate the DSCR.
- Action:
calculate_dscr: 1500000, 1200000 - Observation:
1.25 - Thought: I have the final answer.
- Answer: The project's DSCR is 1.25x.
- Thought: I need to first calculate the Net Operating Income (NOI), which is Revenue - Opex. Then I can use the
Part 3: Production-Ready ReAct with LangGraph
Building a ReAct agent from scratch is insightful, but for complex, real-world applications, using a framework is more robust and scalable. LangGraph is a library from the creators of LangChain designed specifically for building stateful, multi-agent applications by representing them as graphs. It provides a much cleaner way to implement the ReAct loop.
The core concepts in LangGraph are:
- State: A central object (like a Python dictionary) that holds the current state of the workflow (e.g., the list of messages).
- Nodes: Python functions that perform work and update the state. In our case, we'll have a
reasonernode (calls the LLM) and atoolsnode (executes tools). - Edges: Links that define the flow. We'll use a conditional edge to decide whether to call a tool or finish, and a regular edge to always go back to the reasoner after a tool is used.
This video provides an excellent walkthrough of this exact pattern.
Building a LangGraph ReAct Mini Agent
The video 'Building a LangGraph ReAct Mini Agent' by Sam Witteveen demonstrates the most common and useful ReAct pattern in LangGraph. It shows how to achieve the same loop we built manually, but in a more structured and extensible way.
Watch from the beginning to 09:18. The key things to focus on are: The Graph Pattern (00:00 - 01:26): Understand the simple, powerful graph: a 'reasoner' node, a 'tool' node, and a conditional edge connecting them. Tool & Model Setup (01:26 - 03:43): See how tools are defined and bound to the LLM. This is how the LLM knows what functions it can call. Graph Construction (03:43 - 08:18): This is the core of the implementation. Observe how the StateGraph is defined, how the ToolNode and tools_condition from LangGraph are used to simplify the logic, and how the edges create the loop. Seeing it in Action (08:18 - 09:18): The example 'what is two times Brad Pitt's age?' clearly shows the agent making multiple tool calls (search, then calculate) within the loop.
The key advantage of the LangGraph approach is that you are no longer manually parsing strings with regular expressions. The framework handles the function-calling mechanism, error handling, and state management, allowing you to focus on defining the nodes and the logic of the graph.
Conclusion
Today you have bridged the gap between reasoning and acting. You have implemented the core loop that drives autonomous agents, transforming your LLM from a simple text generator into a problem-solver that can formulate a plan and execute it.
Key Takeaways:
- ReAct = Reason + Act: This framework enables an agent to iteratively think about a problem, decide on an action (tool use), and observe the outcome to refine its next thought.
- The Prompt is the Conductor: A well-engineered system prompt is essential to force the LLM to follow the
Thought -> Action -> Observationstructure. - Orchestration is Key: Whether built from scratch with a Python loop or with a framework like LangGraph, an orchestration layer is needed to manage the flow between the LLM and the tools.
- Frameworks Abstract Complexity: LangGraph simplifies ReAct implementation by providing pre-built components for state management, tool execution, and conditional routing, making your agent more robust and easier to maintain.
In this lesson, our agent's "memory" was confined to the history of a single agent_loop execution. If you ran the loop again, it would start from scratch. In our next lesson, "Implement short-term memory for an agent to maintain context across multiple interactions," we will address this. You will learn how to give your agent a memory that persists across separate conversations, allowing it to remember past interactions and provide more contextual and personalized responses.