
Tutorial: Building your first ReAct Agent from Scratch
Last Updated on April 15, 2025 by Editorial Team
Author(s): Arthur Kakande
Originally published on Towards AI.
Humans have this unique intelligence to combine actions and reasoning within our minds seamlessly. This ability plays a very important role in human cognition and enables one to self-regulate and strategise when completing a task. For instance, when trying to complete a baking task, one can reason between multiple actions, e.g., now that I have added flour, I should add sugar and salt. Now that the sugar and salt are added, I should add a small cup of milk. Between any of these actions, humans can reason internally within their minds as they track the progress of the task.
Maintaining the same baking example above, with this ability to reason and act, one can deduce and adjust their plan based on the current situation, e.g., now that the dough is still dry, I should add another cup of milk, or Since I donβt have any more milk, I should use water or even look for an external source for more information like a baking book. This continuous synergy between reasoning and acting enables one to perform complex tasks even under uncertainty. A couple of studies, like βReAct: Synergizing reasoning and acting in language modelsβ have explored the concept of combining this verbal reasoning with interactive decision-making in autonomous systems, specifically in LLMs β this is what we consider as ReAct agents.
Letβs dive in and build a simple ReAct agent from scratch.
In our illustration below, we will create a simple sales assistant that looks up available goods and informs the buyer whether the product is available or not and/or how much the product would cost.
Step 1:
Letβs import our libraries for our environment. We will use OpenAI in this illustration, but feel free to use other options you like. In this example, we are using Colab and have the API key added to the environment.
import openai
import re
import httpx
import os
from openai import OpenAI
from google.colab import userdata
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')
Next, we test out our connection to see if everything is in order. For this, we will ask the model (gpt-3.5-turbo) a simple question.
client = OpenAI()
chat_completion = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "What is the date today?"}]
)
chat_completion.choices[0].message.content
Step 2:
Since the model has responded fine above. letβs create our Agent. (In this illustration, we set the agent to take in a message from the system and then act as an assistant. The agent is then able to get AI responses and update the conversation history.)
class Agent:
def __init__(self, system=""):
self.system = system
self.messages = []
if self.system:
self.messages.append({"role": "system", "content": system})
def __call__(self, message):
self.messages.append({"role": "user", "content": message})
result = self.execute()
self.messages.append({"role": "assistant", "content": result})
return result
def execute(self):
completion = client.chat.completions.create(
model="gpt-3.5-turbo",
temperature=0,
messages=self.messages)
return completion.choices[0].message.content
Step 3:
Letβs add our prompt. You can read through the prompt to understand how our sales agent will perform the task. This is where we teach the agent to perform a task as it thinks through the next sequence of actions.
prompt = """
You run in a loop of Thought, Action, PAUSE, Observation.
At the end of the loop you output an Answer
Use Thought to describe your thoughts about the question you have been asked.
Use Action to run one of the actions available to you - then return PAUSE.
Observation will be the result of running those actions.
Your available actions are:
forex_conversion:
e.g. convert 100 usd to euros
Runs a forex conversion and returns the result - uses the following rates;
1 usd = 0.93 eur
1 eur = 1.07 usd
100 usd = 93 eur
calculate:
e.g. calculate: 2 * 10
Runs a calculation and returns the number - uses Python so be sure to use floating point syntax if necessary
check_item_price:
e.g. check_item_price: milk
returns price of an item when given the name
check_item_availability:
e.g. check_item_availablity: milk
returns availability of an item when given the name
Example session:
Question: How much does a bag cost in euros?
Thought: I should findout if we have a bag available using check_item_availablity
Action: check_item_availability: bag
PAUSE
You will be called again with this:
Observation: A bag is available
Thought: Since the item is available, I should findout how much it costs using check_item_price
Action: check_item_price: bag
PAUSE
You will be called again with this:
Observation: A bag costs 50 usd
Thought: I should convert the price to euros using forex_conversion
Action: forex_conversion: 50
PAUSE
You will be called again with this:
Observation: A bag costs 47.5 eur
You then output:
Answer: A bag costs 47.5 eur
""".strip()
Step 4:
Letβs create some tools and give them that we have introduced in the prompt above. The agent should interact with these tools and use them when completing tasks. For this illustration, we will create a forex conversion tool to convert product prices to euros, add a calculator in case multiple quantities and products are required, add a price look-up tool to find the price, and add a tool that checks if an item requested is in stock. We then give all these tools to the agent created.
def forex_conversion(usd_cost):
euro_cost = eval(usd_cost) * 0.93
return euro_cost
def calculate(what):
return eval(what)
def check_item_availability(name):
if name in "bag":
return("A bag is available")
elif name in "bread":
return("bread is availbale")
elif name in "Wine":
return("Wine is avaialable")
elif name in "Laptop":
return("A laptop is avaialble")
else:
return("The item is not avaialble")
def check_item_price(name):
if name in "bag":
return("A bag costs 50 usd")
elif name in "Wine":
return("A bottle of wine costs 25 usd")
elif name in "bread":
return("bread costs 6 usd")
elif name in "laptop":
return("A laptop costs 500 usd")
else:
return("Item has no price. check availablity")
known_actions = {
"forex_conversion": forex_conversion,
"calculate": calculate,
"check_item_availability": check_item_availability,
"check_item_price": check_item_price
}
Step 5:
Now, let's create a loop for the Agent. We would like the agent to keep checking whether it needs to perform another action or end and return a response
action_pondering = re.compile('^Action: (\w+): (.*)$') # a regular expression to selection action
def query(question, max_turns=7):
i = 0
chatbot = Agent(prompt)
next_prompt = question
while i < max_turns:
i += 1
result = chatbot(next_prompt)
print(result)
actions = [
action_pondering.match(a)
for a in result.split('\n')
if action_pondering.match(a)
]
if actions:
#If there is an action to run
action, action_input = actions[0].groups()
if action not in known_actions:
raise Exception("Unknown action: {}: {}".format(action, action_input))
print(" -- running {} {}".format(action, action_input))
observation = known_actions[action](action_input)
print("Observation:", observation)
next_prompt = "Observation: {}".format(observation)
else:
return
Step 6:
Our Agent is ready. Time to test it out!
question = """I want to buy a Laptop. How much does one cost in euros?"""
query(question)
question = """I want to buy bread and a bag. How much will this cost in euros?"""
query(question) # testing multiple items
question = """I want to buy a book. How much will this cost in euros?"""
query(question) # testing a missing item
There we go, our first simple ReAct Agent. Now you can adjust the above agent, making it as complex as you want. Happy learning!!
Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming aΒ sponsor.
Published via Towards AI