6.2 KiB
Orchestrate a multi-agent system 🤖🤝🤖
In this notebook we will make a multi-agent web browser: an agentic system with several agents collaborating to solve problems using the web!
It will be a simple hierarchy, using a ManagedAgent
object to wrap the managed web search agent:
+----------------+
| Manager agent |
+----------------+
|
_______________|______________
| |
Code interpreter +--------------------------------+
tool | Managed agent |
| +------------------+ |
| | Web Search agent | |
| +------------------+ |
| | | |
| Web Search tool | |
| Visit webpage tool |
+--------------------------------+
Let's set up this system.
Run the line below to install the required dependencies:
!pip install markdownify duckduckgo-search smolagents --upgrade -q
Let's login in order to call the HF Inference API:
from huggingface_hub import notebook_login
notebook_login()
⚡️ Our agent will be powered by Qwen/Qwen2.5-Coder-32B-Instruct using HfApiModel
class that uses HF's Inference API: the Inference API allows to quickly and easily run any OS model.
Note: The Inference API hosts models based on various criteria, and deployed models may be updated or replaced without prior notice. Learn more about it here.
model = "Qwen/Qwen2.5-Coder-32B-Instruct"
🔍 Create a web search tool
For web browsing, we can already use our pre-existing DuckDuckGoSearchTool
tool to provide a Google search equivalent.
But then we will also need to be able to peak into the page found by the DuckDuckGoSearchTool
.
To do so, we could import the library's built-in VisitWebpageTool
, but we will build it again to see how it's done.
So let's create our VisitWebpageTool
tool from scratch using markdownify
.
import re
import requests
from markdownify import markdownify
from requests.exceptions import RequestException
from smolagents import tool
@tool
def visit_webpage(url: str) -> str:
"""Visits a webpage at the given URL and returns its content as a markdown string.
Args:
url: The URL of the webpage to visit.
Returns:
The content of the webpage converted to Markdown, or an error message if the request fails.
"""
try:
# Send a GET request to the URL
response = requests.get(url)
response.raise_for_status() # Raise an exception for bad status codes
# Convert the HTML content to Markdown
markdown_content = markdownify(response.text).strip()
# Remove multiple line breaks
markdown_content = re.sub(r"\n{3,}", "\n\n", markdown_content)
return markdown_content
except RequestException as e:
return f"Error fetching the webpage: {str(e)}"
except Exception as e:
return f"An unexpected error occurred: {str(e)}"
Ok, now let's initialize and test our tool!
print(visit_webpage("https://en.wikipedia.org/wiki/Hugging_Face")[:500])
Build our multi-agent system 🤖🤝🤖
Now that we have all the tools search
and visit_webpage
, we can use them to create the web agent.
Which configuration to choose for this agent?
- Web browsing is a single-timeline task that does not require parallel tool calls, so JSON tool calling works well for that. We thus choose a
JsonAgent
. - Also, since sometimes web search requires exploring many pages before finding the correct answer, we prefer to increase the number of
max_iterations
to 10.
from smolagents import (
CodeAgent,
ToolCallingAgent,
HfApiModel,
ManagedAgent,
)
from smolagents.default_tools import DuckDuckGoSearchTool
model = HfApiModel(model)
web_agent = ToolCallingAgent(
tools=[DuckDuckGoSearchTool(), visit_webpage],
model=model,
max_iterations=10,
)
We then wrap this agent into a ManagedAgent
that will make it callable by its manager agent.
managed_web_agent = ManagedAgent(
agent=web_agent,
name="search",
description="Runs web searches for you. Give it your query as an argument.",
)
Finally we create a manager agent, and upon initialization we pass our managed agent to it in its managed_agents
argument.
Since this agent is the one tasked with the planning and thinking, advanced reasoning will be beneficial, so a CodeAgent
will be the best choice.
Also, we want to ask a question that involves the current year: so let us add additional_authorized_imports=["time"]
manager_agent = CodeAgent(
tools=[],
model=model,
managed_agents=[managed_web_agent],
additional_authorized_imports=["time"],
)
That's all! Now let's run our system! We select a question that requires some calculation and
manager_agent.run("How many years ago was Stripe founded?")
Our agents managed to efficiently collaborate towards solving the task! ✅
💡 You can easily extend this to more agents: one does the code execution, one the web search, one handles file loadings...