Skip to content

Commit 8a76990

Browse files
Update doc on tools
1 parent 3b600db commit 8a76990

File tree

2 files changed

+71
-32
lines changed

2 files changed

+71
-32
lines changed

docs/source/en/guided_tour.md

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,11 @@ Here are a few useful attributes to inspect what happened after a run:
155155

156156
## Tools
157157

158-
A tool is an atomic function to be used by an agent.
158+
A tool is an atomic function to be used by an agent. To be used by an LLM, it also needs a few attributes that constitute its API and will be used to describe to the LLM how to call this tool:
159+
- A name
160+
- A description
161+
- Input types and descriptions
162+
- An output type
159163

160164
You can for instance check the [`PythonInterpreterTool`]: it has a name, a description, input descriptions, an output type, and a `__call__` method to perform the action.
161165

@@ -190,8 +194,8 @@ from huggingface_hub import list_models
190194

191195
task = "text-classification"
192196

193-
model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
194-
print(model.id)
197+
most_downloaded_model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
198+
print(most_downloaded_model.id)
195199
```
196200

197201
This code can quickly be converted into a tool, just by wrapping it in a function and adding the `tool` decorator:
@@ -209,8 +213,8 @@ def model_download_tool(task: str) -> str:
209213
Args:
210214
task: The task for which
211215
"""
212-
model = next(iter(list_models(filter="text-classification", sort="downloads", direction=-1)))
213-
return model.id
216+
most_downloaded_model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
217+
return most_downloaded_model.id
214218
```
215219

216220
The function needs:
@@ -224,29 +228,48 @@ All these will be automatically baked into the agent's system prompt upon initia
224228
225229
Then you can directly initialize your agent:
226230
```py
227-
from smolagents import CodeAgent
228-
agent = CodeAgent(tools=[model_download_tool], model=model)
231+
from smolagents import CodeAgent, HfApiModel
232+
agent = CodeAgent(tools=[model_download_tool], model=HfApiModel())
229233
agent.run(
230234
"Can you give me the name of the model that has the most downloads in the 'text-to-video' task on the Hugging Face Hub?"
231235
)
232236
```
233237

234-
You get the following:
238+
You get the following logs:
235239
```text
236-
======== New task ========
237-
Can you give me the name of the model that has the most downloads in the 'text-to-video' task on the Hugging Face Hub?
238-
==== Agent is executing the code below:
239-
most_downloaded_model = model_download_tool(task="text-to-video")
240-
print(f"The most downloaded model for the 'text-to-video' task is {most_downloaded_model}.")
241-
====
240+
╭──────────────────────────────────────── New run ─────────────────────────────────────────╮
241+
│ │
242+
│ Can you give me the name of the model that has the most downloads in the 'text-to-video' │
243+
│ task on the Hugging Face Hub? │
244+
│ │
245+
╰─ HfApiModel - Qwen/Qwen2.5-Coder-32B-Instruct ───────────────────────────────────────────╯
246+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Step 0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
247+
╭─ Executing this code: ───────────────────────────────────────────────────────────────────╮
248+
│ 1 model_name = model_download_tool(task="text-to-video") │
249+
│ 2 print(model_name) │
250+
╰──────────────────────────────────────────────────────────────────────────────────────────╯
251+
Execution logs:
252+
ByteDance/AnimateDiff-Lightning
253+
254+
Out: None
255+
[Step 0: Duration 0.27 seconds| Input tokens: 2,069 | Output tokens: 60]
256+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Step 1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
257+
╭─ Executing this code: ───────────────────────────────────────────────────────────────────╮
258+
│ 1 final_answer("ByteDance/AnimateDiff-Lightning") │
259+
╰──────────────────────────────────────────────────────────────────────────────────────────╯
260+
Out - Final answer: ByteDance/AnimateDiff-Lightning
261+
[Step 1: Duration 0.10 seconds| Input tokens: 4,288 | Output tokens: 148]
262+
Out[20]: 'ByteDance/AnimateDiff-Lightning'
242263
```
243264

244-
And the output:
245-
`"The most downloaded model for the 'text-to-video' task is ByteDance/AnimateDiff-Lightning."`
265+
This is not the only way to build the tool: you can directly define it as a subclass of [`Tool`], which gives you more flexibility, for instance the possibility to initialize heavy class attributes.
266+
267+
Read more in the [dedicated tool tutorial](./tutorials/tools#what-is-a-tool-and-how-to-build-one)
246268

247269
## Multi-agents
248270

249-
Multi-agent has been introduced in Microsoft's framework [Autogen](https://huggingface.co/papers/2308.08155).
271+
Multi-agent systems have been introduced with Microsoft's framework [Autogen](https://huggingface.co/papers/2308.08155).
272+
250273
In this type of framework, you have several agents working together to solve your task instead of only one.
251274
It empirically yields better performance on most benchmarks. The reason for this better performance is conceptually simple: for many tasks, rather than using a do-it-all system, you would prefer to specialize units on sub-tasks. Here, having agents with separate tool sets and memories allows to achieve efficient specialization. For instance, why fill the memory of the code generating agent with all the content of webpages visited by the web search agent? It's better to keep them separate.
252275

docs/source/en/tutorials/tools.md

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,26 @@ Here, we're going to see advanced tool usage.
2222
> [!TIP]
2323
> If you're new to building agents, make sure to first read the [intro to agents](../conceptual_guides/intro_agents) and the [guided tour of smolagents](../guided_tour).
2424
25-
### Directly define a tool by subclassing Tool
25+
- [Tools](#tools)
26+
- [What is a tool, and how to build one?](#what-is-a-tool-and-how-to-build-one)
27+
- [Share your tool to the Hub](#share-your-tool-to-the-hub)
28+
- [Import a Space as a tool](#import-a-space-as-a-tool)
29+
- [Use gradio-tools](#use-gradio-tools)
30+
- [Use LangChain tools](#use-langchain-tools)
31+
- [Manage your agent's toolbox](#manage-your-agents-toolbox)
32+
- [Use a collection of tools](#use-a-collection-of-tools)
2633

27-
Let's take again the tool example from the [quicktour](../quicktour), for which we had implemented a `@tool` decorator. The `tool` decorator is the standard format, but sometimes you need more: use several methods in a class for more clarity, or using additional class attributes.
34+
### What is a tool, and how to build one?
2835

29-
In this case, you can build your tool following the fine-grained method: building a class that inherits from the [`Tool`] superclass.
36+
A tool is mostly a function that an LLM can use in an agentic system.
3037

31-
The custom tool needs:
32-
- An attribute `name`, which corresponds to the name of the tool itself. The name usually describes what the tool does. Since the code returns the model with the most downloads for a task, let's name it `model_download_counter`.
33-
- An attribute `description` is used to populate the agent's system prompt.
34-
- An `inputs` attribute, which is a dictionary with keys `"type"` and `"description"`. It contains information that helps the Python interpreter make educated choices about the input.
35-
- An `output_type` attribute, which specifies the output type.
36-
- A `forward` method which contains the inference code to be executed.
38+
But to use it, the LLM will need to be given an API: name, tool description, input types and descriptions, output type.
3739

38-
The types for both `inputs` and `output_type` should be amongst [Pydantic formats](https://docs.pydantic.dev/latest/concepts/json_schema/#generating-json-schema), they can be either of these: [`~AUTHORIZED_TYPES`].
40+
So it cannot be only a function. It should be a class.
3941

40-
Also, all imports should be put within the tool's forward function, else you will get an error.
42+
So at core, the tool is a class that wraps a function with metadata that helps the LLM understand how to use it.
43+
44+
Here's how it looks:
4145

4246
```python
4347
from smolagents import Tool
@@ -47,7 +51,6 @@ class HFModelDownloadsTool(Tool):
4751
description = """
4852
This is a tool that returns the most downloaded model of a given task on the Hugging Face Hub.
4953
It returns the name of the checkpoint."""
50-
5154
inputs = {
5255
"task": {
5356
"type": "string",
@@ -61,21 +64,34 @@ class HFModelDownloadsTool(Tool):
6164

6265
model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
6366
return model.id
67+
6468
tool = HFModelDownloadsTool()
6569
```
6670

67-
Now the custom `HfModelDownloadsTool` class is ready.
71+
The custom tool subclasses [`Tool`] to inherit useful methods. The child class also defines:
72+
- An attribute `name`, which corresponds to the name of the tool itself. The name usually describes what the tool does. Since the code returns the model with the most downloads for a task, let's name it `model_download_counter`.
73+
- An attribute `description` is used to populate the agent's system prompt.
74+
- An `inputs` attribute, which is a dictionary with keys `"type"` and `"description"`. It contains information that helps the Python interpreter make educated choices about the input.
75+
- An `output_type` attribute, which specifies the output type. The types for both `inputs` and `output_type` should be [Pydantic formats](https://docs.pydantic.dev/latest/concepts/json_schema/#generating-json-schema), they can be either of these: [`~AUTHORIZED_TYPES`].
76+
- A `forward` method which contains the inference code to be executed.
77+
78+
And that's all it needs to be used in an agent!
79+
80+
There's another way to build a tool. In the [guided_tour](../guided_tour), we implemented a tool using the `@tool` decorator. The [`tool`] decorator is the recommended way to define simple tools, but sometimes you need more than this: using several methods in a class for more clarity, or using additional class attributes.
81+
82+
In this case, you can build your tool by subclassing [`Tool`] as described above.
6883

6984
### Share your tool to the Hub
7085

71-
You can also share your custom tool to the Hub by calling [`~Tool.push_to_hub`] on the tool. Make sure you've created a repository for it on the Hub and are using a token with read access.
86+
You can share your custom tool to the Hub by calling [`~Tool.push_to_hub`] on the tool. Make sure you've created a repository for it on the Hub and are using a token with read access.
7287

7388
```python
7489
tool.push_to_hub("{your_username}/hf-model-downloads", token="<YOUR_HUGGINGFACEHUB_API_TOKEN>")
7590
```
7691

7792
For the push to Hub to work, your tool will need to respect some rules:
78-
- All method are self-contained, e.g. use variables that come either from their args,
93+
- All method are self-contained, e.g. use variables that come either from their args.
94+
- As per the above point, **all imports should be defined directky within the tool's functions**, else you will get an error when trying to call [`~Tool.save`] or [`~Tool.push_to_hub`] with your custom tool.
7995
- If you subclass the `__init__` method, you can give it no other argument than `self`. This is because arguments set during a specific tool instance's initialization are hard to track, which prevents from sharing them properly to the hub. And anyway, the idea of making a specific class is that you can already set class attributes for anything you need to hard-code (just set `your_variable=(...)` directly under the `class YourTool(Tool):` line). And of course you can still create a class attribute anywhere in your code by assigning stuff to `self.your_variable`.
8096

8197
Once your tool is pushed to Hub, you can load it with the [`~Tool.load_tool`] function and pass it to the `tools` parameter in your agent.

0 commit comments

Comments
 (0)