237 lines
9.7 KiB
Plaintext
237 lines
9.7 KiB
Plaintext
# Let's Create Our First Agent Using smolagents
|
|
|
|
In the last section, we learned how we can create Agents from scratch using Python code, and we **saw just how tedious that process can be**. Fortunately, many Agent libraries simplify this work by **handling much of the heavy lifting for you**.
|
|
|
|
In this tutorial, **you'll create your very first Agent** capable of performing actions such as image generation, web search, time zone checking and much more!
|
|
|
|
You will also publish your agent **on a Hugging Face Space so you can share it with friends and colleagues**.
|
|
|
|
Let's get started!
|
|
|
|
|
|
## What is smolagents?
|
|
|
|
<img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/smolagents.png" alt="smolagents"/>
|
|
|
|
To make this Agent, we're going to use `smolagents`, a library that **provides a framework for developing your agents with ease**.
|
|
|
|
This lightweight library is designed for simplicity, but it abstracts away much of the complexity of building an Agent, allowing you to focus on designing your agent's behavior.
|
|
|
|
We're going to get deeper into smolagents in the next Unit. Meanwhile, you can also check this <a href="https://huggingface.co/blog/smolagents" target="_blank">blog post</a> or the library's <a href="https://github.com/huggingface/smolagents" target="_blank">repo in GitHub</a>.
|
|
|
|
In short, `smolagents` is a library that focuses on **codeAgent**, a kind of agent that performs **"Actions"** through code blocks, and then **"Observes"** results by executing the code.
|
|
|
|
Here is an example of what we'll build!
|
|
|
|
We provided our agent with an **Image generation tool** and asked it to generate an image of a cat.
|
|
|
|
The agent inside `smolagents` is going to have the **same behaviors as the custom one we built previously**: it's going **to think, act and observe in cycle** until it reaches a final answer:
|
|
|
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/PQDKcWiuln4?si=ysSTDZoi8y55FVvA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
|
|
|
Exciting, right?
|
|
|
|
## Let's build our Agent!
|
|
|
|
To start, duplicate this Space: <a href="https://huggingface.co/spaces/agents-course/First_agent_template" target="_blank">https://huggingface.co/spaces/agents-course/First_agent_template</a>
|
|
> Thanks to <a href="https://huggingface.co/m-ric" target="_blank">Aymeric</a> for this template! 🙌
|
|
|
|
|
|
Duplicating this space means **creating a local copy on your own profile**:
|
|
<img src="https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/duplicate-space.gif" alt="Duplicate"/>
|
|
|
|
After duplicating the Space, you'll need to add your Hugging Face API token so your agent can access the model API:
|
|
|
|
1. First, get your Hugging Face token from [https://hf.co/settings/tokens](https://hf.co/settings/tokens) if you don't already have one
|
|
2. Go to your duplicated Space and click on the **Settings** tab
|
|
3. Scroll down to the **Variables and Secrets** section and click **New Secret**
|
|
4. Create a secret with the name `HF_TOKEN` and paste your token as the value
|
|
5. Click **Save** to store your token securely
|
|
|
|
Throughout this lesson, the only file you will need to modify is the (currently incomplete) **"app.py"**. You can see here the [original one in the template](https://huggingface.co/spaces/agents-course/First_agent_template/blob/main/app.py). To find yours, go to your copy of the space, then click the `Files` tab and then on `app.py` in the directory listing.
|
|
|
|
Let's break down the code together:
|
|
|
|
- The file begins with some simple but necessary library imports
|
|
|
|
```python
|
|
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
|
|
import datetime
|
|
import requests
|
|
import pytz
|
|
import yaml
|
|
from tools.final_answer import FinalAnswerTool
|
|
```
|
|
|
|
As outlined earlier, we will directly use the **CodeAgent** class from **smolagents**.
|
|
|
|
|
|
### The Tools
|
|
|
|
Now let's get into the tools! If you want a refresher about tools, don't hesitate to go back to the [Tools](tools) section of the course.
|
|
|
|
```python
|
|
@tool
|
|
def my_custom_tool(arg1:str, arg2:int)-> str: # it's important to specify the return type
|
|
# Keep this format for the tool description / args description but feel free to modify the tool
|
|
"""A tool that does nothing yet
|
|
Args:
|
|
arg1: the first argument
|
|
arg2: the second argument
|
|
"""
|
|
return "What magic will you build ?"
|
|
|
|
@tool
|
|
def get_current_time_in_timezone(timezone: str) -> str:
|
|
"""A tool that fetches the current local time in a specified timezone.
|
|
Args:
|
|
timezone: A string representing a valid timezone (e.g., 'America/New_York').
|
|
"""
|
|
try:
|
|
# Create timezone object
|
|
tz = pytz.timezone(timezone)
|
|
# Get current time in that timezone
|
|
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
|
|
return f"The current local time in {timezone} is: {local_time}"
|
|
except Exception as e:
|
|
return f"Error fetching time for timezone '{timezone}': {str(e)}"
|
|
```
|
|
|
|
|
|
The Tools are what we are encouraging you to build in this section! We give you two examples:
|
|
|
|
1. A **non-working dummy Tool** that you can modify to make something useful.
|
|
2. An **actually working Tool** that gets the current time somewhere in the world.
|
|
|
|
To define your tool it is important to:
|
|
|
|
1. Provide input and output types for your function, like in `get_current_time_in_timezone(timezone: str) -> str:`
|
|
2. **A well formatted docstring**. `smolagents` is expecting all the arguments to have a **textual description in the docstring**.
|
|
|
|
### The Agent
|
|
|
|
It uses [`Qwen/Qwen2.5-Coder-32B-Instruct`](https://huggingface.co/Qwen/Qwen2.5-Coder-32B-Instruct) as the LLM engine. This is a very capable model that we'll access via the serverless API.
|
|
|
|
```python
|
|
final_answer = FinalAnswerTool()
|
|
model = HfApiModel(
|
|
max_tokens=2096,
|
|
temperature=0.5,
|
|
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
|
|
custom_role_conversions=None,
|
|
)
|
|
|
|
with open("prompts.yaml", 'r') as stream:
|
|
prompt_templates = yaml.safe_load(stream)
|
|
|
|
# We're creating our CodeAgent
|
|
agent = CodeAgent(
|
|
model=model,
|
|
tools=[final_answer], # add your tools here (don't remove final_answer)
|
|
max_steps=6,
|
|
verbosity_level=1,
|
|
grammar=None,
|
|
planning_interval=None,
|
|
name=None,
|
|
description=None,
|
|
prompt_templates=prompt_templates
|
|
)
|
|
|
|
GradioUI(agent).launch()
|
|
```
|
|
|
|
This Agent still uses the `InferenceClient` we saw in an earlier section behind the **HfApiModel** class!
|
|
|
|
We will give more in-depth examples when we present the framework in Unit 2. For now, you need to focus on **adding new tools to the list of tools** using the `tools` parameter of your Agent.
|
|
|
|
For example, you could use the `DuckDuckGoSearchTool` that was imported in the first line of the code, or you can examine the `image_generation_tool` that is loaded from the Hub later in the code.
|
|
|
|
**Adding tools will give your agent new capabilities**, try to be creative here!
|
|
|
|
The complete "app.py":
|
|
|
|
```python
|
|
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
|
|
import datetime
|
|
import requests
|
|
import pytz
|
|
import yaml
|
|
from tools.final_answer import FinalAnswerTool
|
|
|
|
from Gradio_UI import GradioUI
|
|
|
|
# Below is an example of a tool that does nothing. Amaze us with your creativity!
|
|
@tool
|
|
def my_custom_tool(arg1:str, arg2:int)-> str: # it's important to specify the return type
|
|
# Keep this format for the tool description / args description but feel free to modify the tool
|
|
"""A tool that does nothing yet
|
|
Args:
|
|
arg1: the first argument
|
|
arg2: the second argument
|
|
"""
|
|
return "What magic will you build ?"
|
|
|
|
@tool
|
|
def get_current_time_in_timezone(timezone: str) -> str:
|
|
"""A tool that fetches the current local time in a specified timezone.
|
|
Args:
|
|
timezone: A string representing a valid timezone (e.g., 'America/New_York').
|
|
"""
|
|
try:
|
|
# Create timezone object
|
|
tz = pytz.timezone(timezone)
|
|
# Get current time in that timezone
|
|
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
|
|
return f"The current local time in {timezone} is: {local_time}"
|
|
except Exception as e:
|
|
return f"Error fetching time for timezone '{timezone}': {str(e)}"
|
|
|
|
|
|
final_answer = FinalAnswerTool()
|
|
model = HfApiModel(
|
|
max_tokens=2096,
|
|
temperature=0.5,
|
|
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
|
|
custom_role_conversions=None,
|
|
)
|
|
|
|
|
|
# Import tool from Hub
|
|
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
|
|
|
|
with open("prompts.yaml", 'r') as stream:
|
|
prompt_templates = yaml.safe_load(stream)
|
|
|
|
agent = CodeAgent(
|
|
model=model,
|
|
tools=[final_answer], # add your tools here (don't remove final_answer)
|
|
max_steps=6,
|
|
verbosity_level=1,
|
|
grammar=None,
|
|
planning_interval=None,
|
|
name=None,
|
|
description=None,
|
|
prompt_templates=prompt_templates
|
|
)
|
|
|
|
|
|
GradioUI(agent).launch()
|
|
```
|
|
|
|
Your **Goal** is to get familiar with the Space and the Agent.
|
|
|
|
Currently, the agent in the template **does not use any tools, so try to provide it with some of the pre-made ones or even make some new tools yourself!**
|
|
|
|
We are eagerly waiting for your amazing agents output in the discord channel **#agents-course-showcase**!
|
|
|
|
|
|
---
|
|
Congratulations, you've built your first Agent! Don't hesitate to share it with your friends and colleagues.
|
|
|
|
Since this is your first try, it's perfectly normal if it's a little buggy or slow. In future units, we'll learn how to build even better Agents.
|
|
|
|
The best way to learn is to try, so don't hesitate to update it, add more tools, try with another model, etc.
|
|
|
|
In the next section, you're going to fill the final Quiz and get your certificate!
|
|
|