开源 AI 食谱文档

让多个代理在多代理层次结构中协作 🤖🤝🤖

Hugging Face's logo
加入 Hugging Face 社区

并获得增强文档体验的访问权限

开始使用

Open In Colab

让多个代理在多代理层次结构中协作 🤖🤝🤖

作者:Aymeric Roucher

本教程属于高级内容。您应该先了解另一本食谱中的概念!

在本笔记本中,我们将构建一个 **多代理网页浏览器:一个代理系统,它使用多个代理协作来解决使用网络的问题!**

它将是一个简单的层次结构,使用 ManagedAgent 对象来包装受控的网页搜索代理

              +----------------+
              | Manager agent  |
              +----------------+
                       |
        _______________|______________
       |                              |
  Code interpreter   +--------------------------------+
       tool          |         Managed agent          |
                     |      +------------------+      |
                     |      | Web Search agent |      |
                     |      +------------------+      |
                     |         |            |         |
                     |  Web Search tool     |         |
                     |             Visit webpage tool |
                     +--------------------------------+

让我们设置这个系统。

⚡️ 我们的代理将由 meta-llama/Meta-Llama-3.1-70B-Instruct 提供支持,使用 HfApiEngine 类,该类使用 HF 的推理 API:推理 API 允许快速轻松地运行任何 OS 模型。

运行以下代码行以安装所需的依赖项

!pip install markdownify duckduckgo-search "transformers[agents]" --upgrade -q

我们选择使用 Qwen/Qwen2.5-72B-Instruct 来驱动我们的模型,因为它非常强大并且可以在 HF API 中免费使用。

model = "Qwen/Qwen2.5-72B-Instruct"

🔍 创建一个网页搜索工具

对于网页浏览,我们已经可以使用现有的 DuckDuckGoSearchTool 工具来提供类似谷歌搜索的功能。

但是,我们还需要能够查看 DuckDuckGoSearchTool 找到的页面。为此,我们可以导入库的内置 VisitWebpageTool,但我们将重新构建它以了解其工作原理。

因此,让我们使用 markdownify 从头开始创建我们的 VisitWebpageTool 工具。

import re
import requests
from markdownify import markdownify as md
from requests.exceptions import RequestException
from transformers.agents 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 = md(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)}"

好的,现在让我们初始化并测试我们的工具!

>>> print(visit_webpage("https://en.wikipedia.org/wiki/Hugging_Face")[:500])
Hugging Face \- Wikipedia

[Jump to content](#bodyContent)

Main menu

Main menu
move to sidebar
hide

 Navigation
 

* [Main page](/wiki/Main_Page "Visit the main page [z]")
* [Contents](/wiki/Wikipedia:Contents "Guides to browsing Wikipedia")
* [Current events](/wiki/Portal:Current_events "Articles related to current events")
* [Random article](/wiki/Special:Random "Visit a randomly selected article [x]")
* [About Wikipedia](/wiki/Wikipedia:About "Learn about Wikipedia and how it works")
* [Co

构建我们的多代理系统 🤖🤝🤖

现在我们有了所有工具 searchvisit_webpage,我们可以使用它们来创建网页代理。

选择哪个配置来构建此代理?

  • 网页浏览是一个单时间线任务,不需要并行工具调用,因此 JSON 工具调用对于这种情况非常适用。因此,我们选择 ReactJsonAgent
  • 此外,由于有时网页搜索需要浏览多个页面才能找到正确答案,因此我们更愿意将 max_iterations 的数量增加到 10。
from transformers.agents import (
    ReactCodeAgent,
    ReactJsonAgent,
    HfApiEngine,
    ManagedAgent,
)
from transformers.agents.search import DuckDuckGoSearchTool

llm_engine = HfApiEngine(model)

web_agent = ReactJsonAgent(
    tools=[DuckDuckGoSearchTool(), visit_webpage],
    llm_engine=llm_engine,
    max_iterations=10,
)

然后,我们将此代理包装到一个 ManagedAgent 中,该代理将使其可以被其管理代理调用。

managed_web_agent = ManagedAgent(
    agent=web_agent,
    name="search",
    description="Runs web searches for you. Give it your query as an argument.",
)

最后,我们创建一个管理代理,并在初始化时将其管理代理传递给 managed_agents 参数。

由于此代理负责规划和思考,因此高级推理将是有益的,因此 ReactCodeAgent 将是最佳选择。

此外,我们想要问一个涉及当前年份的问题:因此让我们添加 additional_authorized_imports=["time", "datetime"]

manager_agent = ReactCodeAgent(
    tools=[],
    llm_engine=llm_engine,
    managed_agents=[managed_web_agent],
    additional_authorized_imports=["time", "datetime"],
)

就这样!现在让我们运行我们的系统!我们选择一个需要一些计算的问题,并且

manager_agent.run("How many years ago was Stripe founded?")

我们的代理成功地有效地协作以解决任务!✅

💡 您可以轻松地将其扩展到更多代理:一个代理执行代码,一个代理执行网页搜索,一个代理处理文件加载……

🤔💭 甚至可以考虑进行更复杂的树状层次结构,其中一个 CEO 代理管理多个中层管理人员,每个管理人员都有几个下属。

我们甚至可以添加更多中间管理层,每个层都有多个日常会议,大量的敏捷内容以及 scrum 主管,每个新组件都会增加足够的摩擦来确保任务永远无法完成……呃,等等,不,让我们坚持使用简单的结构。

< > 更新 在 GitHub 上