In the history of technology, there's a recurring theme: building tools that amplify human capabilities. From the printing press to the internet, each innovation has extended our reach. AI agents are the latest in this lineage, promising to transform how we interact with and leverage information.
This tutorial explores the ReAct pattern, a modern design approach for AI assistants, and takes you through the steps of building one. It's designed to be accessible to technology professionals at all levels. Whether you're a developer keen on building cutting-edge AI solutions, a manager looking to understand the potential of AI agents in your organisation, or an enthusiast eager to explore the latest advancements in AI, this guide will provide you with a foundation of knowledge and skills needed to create effective AI agents.
2. The ReAct Pattern: A Game Changer
The ReAct pattern is a simple yet profound idea. It stands for Reason + Act, encapsulating a loop where the AI agent reasons about the input, takes an action, pauses to observe the results, and then integrates this new information to provide a response. This cycle of Thought, Action, Pause, Observation, and Answer transforms an AI agent from a passive responder into an active participant.
2.1. The ReAct Loop
The ReAct pattern is powerful because it mimics how humans operate. High-performing humans don't just do; they think, act, observe, and refine their understanding. By embedding this loop into AI agents, we make them more flexible, accurate, and capable. Here's how a ReAct agent works:
Step 1 - Thought: The agent processes the input and decides what needs to be done.
Step 2 - Action: It performs the chosen action — searching for information, making calculations, etc.
Step 3 - Pause: The agent waits for the action to complete.
Step 4 - Observation: It observes the results and analyses the new information.
Step 5 - Answer: Finally, it generates a response based on its observations.
This approach is particularly useful for tasks that require high accuracy and quality, such as content moderation or sensitive data handling. You can learn more about ReAct and other advanced agentic strategies here.
Deliver commercially viable solutions that offer real value, not just great engineering.
3. Tools and Libraries: The Building Blocks
Building an AI agent from scratch might seem daunting, but with the right tools, it's surprisingly manageable. Python, with its simplicity and extensive library support, is our language of choice. We'll also use the OpenAI API for its advanced language models, and httpx for handling asynchronous HTTP requests.
3.1. Setting Up the Environment
First, let's set up our development environment:
3.1.1. Download and Install Python 3.12
3.1.2. Create a Virtual Environment
Creating a virtual environment is an essential step in managing dependencies for your Python projects. It ensures that the libraries you install for this project do not interfere with those installed for other projects. Follow these steps to create and activate a virtual environment:
python -m venv ai_agent_env
source ai_agent_env/bin/activate # On Windows, use `ai_agent_env\Scripts\activate`
python -m venv ai_agent_env: This command creates a new virtual environment named ai_agent_env in your current directory.
source ai_agent_env/bin/activate: This command activates the virtual environment on Unix or macOS. For Windows, use ai_agent_env\Scripts\activate.
Once activated, your terminal prompt will change to indicate that you are now working within the virtual environment. This is where you will install the required libraries for this project.
3.1.3. Install Required Libraries
With your virtual environment activated, you can now install the necessary libraries for building your AI assistant. These libraries include httpx for handling asynchronous HTTP requests and openai for interacting with OpenAI's language models. Use the following command to install these libraries with the specified versions:
pip install httpx==0.27.0 openai==1.40.6
httpx==0.27.0: This library is a powerful HTTP client for Python, supporting both synchronous and asynchronous requests. It will be used to interact with external APIs, such as Wikipedia.
openai==1.40.6: This library provides the tools to interact with OpenAI's language models, such as GPT-4o. It will be used to generate responses and perform various actions within the AI assistant.
By specifying the versions, you ensure that you are using stable and compatible releases of these libraries, which helps avoid potential issues with newer updates. Once the command completes, the required libraries will be installed in your virtual environment, and you are ready to proceed with building your AI assistant.
3.2. Getting an OpenAI API Key
To interact with the OpenAI API, you'll need an API key. Here’s how to get one:
Deliver commercially viable solutions that offer real value, not just great engineering.
4. Building the AI Agent
Create a file named agent.py into which you will copy or type the following code. All the code snippets provided should be included in this file.
4.1. Importing Libraries and Setting Up the Client
Add the following code to agent.py:
import httpx
from openai import OpenAI
import re
# Use environment variables to hide the API key if you upload the code to GitHub or deploy it to another machine.
client = OpenAI(
api_key="<INSERT YOUR KEY HERE>",
)
This snippet imports the necessary libraries (httpx, openai, and re) and sets up the OpenAI client with your API key. Remember to replace "<INSERT YOUR KEY HERE>" with your actual OpenAI API key. If you plan to upload this code to GitHub or deploy it to another machine, use environment variables to hide the API key.
4.2. Defining the ChatBot Class
Now append this code to agent.py:
class ChatBot:
def __init__(self, system=""):
# Initialise the chatbot with an optional system message
self.system = system
self.messages = []
if self.system:
self.messages.append({"role": "system", "content": system})
def __call__(self, message):
# Add user message and generate response
self.messages.append({"role": "user", "content": message})
result = self.execute()
self.messages.append({"role": "assistant", "content": result})
return result
def execute(self):
# Send message history to OpenAI API and return the assistant's response
response = client.chat.completions.create(
model="gpt-4o",
messages=self.messages
)
return response.choices[0].message.content.strip()
This defines the ChatBot class, which handles interactions with the OpenAI API. The __init__ method initialises the class with an optional system message. The __call__ method adds user messages and generates responses using the execute method. The execute method sends the message history to the OpenAI API and returns the assistant's response.
4.3. Defining the ReAct Prompt
Next, we'll extend agent.py with the prompt for our assistant:
# Define the ReAct prompt
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:
calculate:
e.g. calculate: 4 * 5 / 3
Runs a calculation and returns the number - uses Python so be sure to use floating point
syntax if necessary
wikipedia:
e.g. wikipedia: AI assistant
Returns a summary from searching Wikipedia
Example session:
Question: What is the capital of Australia?
Thought: I should look up Australia on Wikipedia
Action: wikipedia: Australia
PAUSE
You will be called again with this:
Observation: Australia is a country. The capital is Canberra.
You then output:
Answer: The capital of Australia is Canberra
""".strip()
This snippet defines the prompt that guides the AI agent through the ReAct loop. The prompt includes instructions for Thought, Action, Pause, Observation, and Answer, along with examples of actions the agent can perform.
4.4. Defining the Query Function
Add the following code after the promp:
# Compile regular expression for detecting actions
action_re = re.compile(r'^Action: (\\w+): (.*)')
def query(question, max_turns=5):
# Run the ReAct loop
i = 0
bot = ChatBot(prompt)
next_prompt = question
while i < max_turns:
i += 1
result = bot(next_prompt)
print(result)
actions = [action_re.match(a) for a in result.split('\\n') if action_re.match(a)]
if actions:
action, action_input = actions[0].groups()
if action not in known_actions:
raise Exception(f"Unknown action: {action}: {action_input}")
print(" -- running {} {}".format(action, action_input))
observation = known_actionsaction
print("Observation:", observation)
next_prompt = f"Observation: {observation}"
else:
return result
This function runs the ReAct loop by sending the question to the AI agent, parsing the actions, executing them, and feeding the observations back into the loop. It uses regular expressions to identify actions and manage the reasoning process.
4.5. Implementing Actions
Add the following code after the promp:
def wikipedia(q):
# Fetch a summary from Wikipedia
response = httpx.get("https://en.wikipedia.org/w/api.php", params={
"action": "query",
"list": "search",
"srsearch": q,
"format": "json"
})
return response.json()["query"]["search"][0]["snippet"]
def calculate(what):
# Perform a calculation
return eval(what)
# Map action names to their corresponding functions
known_actions = {
"wikipedia": wikipedia,
"calculate": calculate
}
These functions define the actions the AI agent can perform. The wikipedia function fetches a summary from Wikipedia, and the calculate function performs mathematical calculations. The known_actions dictionary maps action names to their corresponding functions.
4.6. Add questions
Append the following questions to the end of agent.py:
# Test the AI agent with sample queries
print(query("What does England share borders with?"))
print(query("Fifteen * twenty five"))
When you run the program, the AI assistant will process these questions, perform the necessary actions, and print its reasoning process and answers to the terminal.
4.7. Complete agent.py File
Here is the complete content of the agent.py file, to assist you in completing the tutorial:
import httpx
from openai import OpenAI
import re
# Use environment variables to hide the API key if you upload the code to GitHub or deploy it to another machine.
client = OpenAI(
api_key="<INSERT YOUR KEY HERE>",
)
class ChatBot:
def __init__(self, system=""):
# Initialise the chatbot with an optional system message
self.system = system
self.messages = []
if self.system:
self.messages.append({"role": "system", "content": system})
def __call__(self, message):
# Add user message and generate response
self.messages.append({"role": "user", "content": message})
result = self.execute()
self.messages.append({"role": "assistant", "content": result})
return result
def execute(self):
# Send message history to OpenAI API and return the assistant's response
response = client.chat.completions.create(
model="gpt-4o",
messages=self.messages
)
return response.choices[0].message.content.strip()
# Define the ReAct prompt
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:
calculate:
e.g. calculate: 4 * 5 / 3
Runs a calculation and returns the number - uses Python so be sure to use floating point
syntax if necessary
wikipedia:
e.g. wikipedia: AI assistant
Returns a summary from searching Wikipedia
Example session:
Question: What is the capital of Australia?
Thought: I should look up Australia on Wikipedia
Action: wikipedia: Australia
PAUSE
You will be called again with this:
Observation: Australia is a country. The capital is Canberra.
You then output:
Answer: The capital of Australia is Canberra
""".strip()
# Compile regular expression for detecting actions
action_re = re.compile(r'^Action: (\\w+): (.*)')
def query(question, max_turns=5):
# Run the ReAct loop
i = 0
bot = ChatBot(prompt)
next_prompt = question
while i < max_turns:
i += 1
result = bot(next_prompt)
print(result)
actions = [action_re.match(a) for a in result.split('\\n') if action_re.match(a)]
if actions:
action, action_input = actions[0].groups()
if action not in known_actions:
raise Exception(f"Unknown action: {action}: {action_input}")
print(" -- running {} {}".format(action, action_input))
observation = known_actionsaction
print("Observation:", observation)
next_prompt = f"Observation: {observation}"
else:
return result
def wikipedia(q):
# Fetch a summary from Wikipedia
response = httpx.get("https://en.wikipedia.org/w/api.php", params={
"action": "query",
"list": "search",
"srsearch": q,
"format": "json"
})
return response.json()["query"]["search"][0]["snippet"]
def calculate(what):
# Perform a calculation
return eval(what)
# Map action names to their corresponding functions
known_actions = {
"wikipedia": wikipedia,
"calculate": calculate
}
# Test the AI agent with sample queries
print(query("What does England share borders with?"))
print(query("Fifteen * twenty five"))
Deliver commercially viable solutions that offer real value, not just great engineering.
5. Testing Your Assistant
Now that you have built your AI assistant, it's time to test its functionality and ensure it operates as expected. Testing is a crucial step in the development process, as it allows you to verify that the assistant can handle various queries, perform the necessary actions, and provide accurate responses. In this section, you will learn how to run the program, observe the assistant's reasoning process, and understand its responses. If you planned to operationalise your agent, this would help you identify any issues or areas for improvement before deploying the assistant in a production environment.
5.1. Running the Program
To test your AI agent, run the agent.py file:
python agent.py
The assistant will print its reasoning process to the terminal to answer the questions that you asked:
print(query("What does England share borders with?"))
print(query("Fifteen * twenty five"))
Feel free to ask other questions to see how the AI assistant responds.
5.2. Adding More Actions
To add more actions to the assistant, follow these steps:
Step 1 - Define the New Action Function:
def weather(city):
# Implement a function to fetch weather information for the given city
pass
Step 2 - Add the Action to the known_actions Dictionary:
known_actions["weather"] = weather
Step 3 - Update the ReAct Prompt:
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:
calculate:
e.g. calculate: 4 * 5 / 3
Runs a calculation and returns the number - uses Python so be sure to use floating point
syntax if necessary
wikipedia:
e.g. wikipedia: AI assistant
Returns a summary from searching Wikipedia
weather:
e.g. weather: London
Fetches the current weather for the specified city
Example session:
Question: What is the capital of Australia?
Thought: I should look up Australia on Wikipedia
Action: wikipedia: Australia
PAUSE
You will be called again with this:
Observation: Australia is a country. The capital is Canberra.
You then output:
Answer: The capital of Australia is Canberra
""".strip()
Explanation: This prompt includes an additional action for fetching weather information, demonstrating how to extend the capabilities of the AI assistant.
6. Moving Towards a Production-Ready Solution
This tutorial provides a basic example of building an AI assistant using the ReAct pattern. However, creating a production-ready solution requires further enhancements to ensure robustness, scalability, and efficiency. Here are some key areas to consider:
6.1. Enhancing Information Retrieval
Combine information retrieval with language generation to overcome the constraints of context windows. In a Retrieval-Augmented Generation (RAG) system, the process typically involves two main stages:
6.2. Fine-Tuning
Fine-tuning involves training of a pre-trained model on a specific dataset that closely matches the target use case. This process helps the model learn the nuances and specific patterns of the new data, improving its accuracy, relevance, and response speed for the specific tasks it will handle.
6.3. Adopting a Multi-Agent Strategy
Use a modular approach to orchestrate and execute tasks. In this multi-agent architecture, one agent manages the overall workflow, while other specialised agents handle individual steps. This separation of responsibilities allows for more efficient task management and execution.
Multi-Agent Framework | Credit: Microsoft
If you've completed this tutorial, you now have a foundation of concepts and techniques to create high-performing AI assistants. This knowledge not only empowers you to manage AI assistant implementations effectively but also lays the groundwork for acquiring more specialised skills in this rapidly evolving field.
1. What is the ReAct pattern in AI?
The ReAct pattern (Reason + Act) involves implementing additional actions that an AI agent can take, such as searching Wikipedia or running calculations, and teaching the agent to request these actions and process their results. This pattern enhances the agent's ability to reason about input, perform actions, and integrate observations into its responses.
2. How can I add more actions to my AI assistant?
To add more actions to your AI assistant, define a new function for the action and add it to the known_actions dictionary. For example, to add a weather information action, you would create a weather function and then update the known_actions dictionary to include this new action.
3. How can I test and debug my AI assistant effectively?
To test and debug your AI assistant, run the program with various sample queries and observe the assistant's reasoning process and responses printed to the terminal. This helps you understand how the assistant arrives at its answers. Additionally, you can add logging to track the agent’s actions and observations, validate inputs to prevent errors, and implement error handling to manage exceptions gracefully.
4. What are some advanced techniques to optimise AI assistant performance for production?
Advanced techniques to optimise AI assistant performance include fine-tuning the language model on a specific dataset, employing Retrieval-Augmented Generation (RAG) for better information retrieval, using prompt engineering to guide model responses, and adopting a multi-agent strategy to handle complex tasks more efficiently.
5. How can I ensure the ethical use of AI assistants
Ensuring the ethical use of AI assistants involves implementing safe AI practices such as avoiding harmful or biased outputs, maintaining transparency, and adhering to guidelines on fairness, accountability, and transparency. Regularly evaluating the AI assistant's responses for biases and inaccuracies and updating the model and prompts as necessary can help maintain ethical standards.
Deliver commercially viable solutions that offer real value, not just great engineering.
Insights
About Cognis
Cognis helps organisations to transition to an AI-powered future.
We equip and enable you to harness the power of AI to create new revenue streams, reimagine customer experiences, and transform operations.
NEWSLETTER
Sign up to our newsletter.
© Cognis Pty Ltd