构建并集成智能体工具

本节将为 Alfred 赋予网络访问能力,使其能够获取实时新闻与全球资讯。 同时还将集成天气数据和 Hugging Face Hub 模型下载统计功能,帮助其进行时效性话题交流。

赋予智能体网络访问能力

请记住,我们希望 Alfred 能够展现出一位真正的文艺复兴主持人的风采,并对世界有着深刻的了解。

为此,我们需要确保 Alfred 能够获取有关世界的最新新闻和信息。

让我们从为 Alfred 创建一个网络搜索工具开始吧!

使用 smolagents

from smolagents import DuckDuckGoSearchTool

# 初始化 DuckDuckGo 搜索工具
search_tool = DuckDuckGoSearchTool()

# 示例用法
results = search_tool("Who's the current President of France?")
print(results)

预期输出:

法国现任总统为 Emmanuel Macron。

使用 llama-index

from llama_index.tools.duckduckgo import DuckDuckGoSearchToolSpec
from llama_index.core.tools import FunctionTool

# 初始化 DuckDuckGo 搜索工具
tool_spec = DuckDuckGoSearchToolSpec()

search_tool = FunctionTool.from_defaults(tool_spec.duckduckgo_full_search)
# 示例用法
response = search_tool("Who's the current President of France?")
print(response.raw_output[-1]['body'])

预期输出:

法兰西共和国总统是法国的国家元首。现任总统是 Emmanuel Macron,于2017年5月14日就任,并在2017年5月7日举行的总统选举第二轮中击败 Marine Le Pen。法国第五共和国总统名单 编号 肖像 姓名 ...

使用 langgraph

from langchain_community.tools import DuckDuckGoSearchRun

search_tool = DuckDuckGoSearchRun()
results = search_tool.invoke("Who's the current President of France?")
print(results)

预期输出:

Emmanuel Macron (1977年12月21日生于亚眠)法国政治家,2017年当选总统...

创建天气信息工具(烟花调度)

完美的庆典应该在晴朗的天空下燃放烟花,我们需要确保烟花不会因为恶劣天气而取消。

让我们创建一个自定义工具,用于调用外部天气 API 并获取指定位置的天气信息。

提示:为了简单起见,我们在本例中使用了一个虚拟的天气 API。如果您想使用真实的天气 API,您可以实现一个使用 OpenWeatherMap API 的天气工具,就像 Unit 1 中提到的那样。

使用 smolagents

from smolagents import Tool
import random

class WeatherInfoTool(Tool):
    name = "weather_info"
    description = "Fetches dummy weather information for a given location."
    inputs = {
        "location": {
            "type": "string",
            "description": "The location to get weather information for."
        }
    }
    output_type = "string"

    def forward(self, location: str):
        # 虚拟天气数据
        weather_conditions = [
            {"condition": "Rainy", "temp_c": 15},
            {"condition": "Clear", "temp_c": 25},
            {"condition": "Windy", "temp_c": 20}
        ]
        # 随机选择一种天气状况
        data = random.choice(weather_conditions)
        return f"Weather in {location}: {data['condition']}, {data['temp_c']}°C"

# 初始化工具
weather_info_tool = WeatherInfoTool()

使用 llama-index

import random
from llama_index.core.tools import FunctionTool

def get_weather_info(location: str) -> str:
    """Fetches dummy weather information for a given location."""
    # 虚拟天气数据
    weather_conditions = [
        {"condition": "Rainy", "temp_c": 15},
        {"condition": "Clear", "temp_c": 25},
        {"condition": "Windy", "temp_c": 20}
    ]
    # 随机选择一种天气状况
    data = random.choice(weather_conditions)
    return f"Weather in {location}: {data['condition']}, {data['temp_c']}°C"

# 初始化工具
weather_info_tool = FunctionTool.from_defaults(get_weather_info)

使用 langgraph

from langchain_core.tools import Tool
import random

def get_weather_info(location: str) -> str:
    """Fetches dummy weather information for a given location."""
    # 虚拟天气数据
    weather_conditions = [
        {"condition": "Rainy", "temp_c": 15},
        {"condition": "Clear", "temp_c": 25},
        {"condition": "Windy", "temp_c": 20}
    ]
    # 随机选择一种天气状况
    data = random.choice(weather_conditions)
    return f"Weather in {location}: {data['condition']}, {data['temp_c']}°C"

# 初始化工具
weather_info_tool = Tool(
    name="get_weather_info",
    func=get_weather_info,
    description="Fetches dummy weather information for a given location."
)

为有影响力的 AI 开发者创建 Hub 统计工具

出席此次盛会的都是 AI 开发者的精英。Alfred 希望通过讨论他们最受欢迎的模型、数据集和空间来给他们留下深刻印象。我们将创建一个工具,根据用户名从 Hugging Face Hub 获取模型统计数据。

使用 smolagents

from smolagents import Tool
from huggingface_hub import list_models

class HubStatsTool(Tool):
    name = "hub_stats"
    description = "Fetches the most downloaded model from a specific author on the Hugging Face Hub."
    inputs = {
        "author": {
            "type": "string",
            "description": "The username of the model author/organization to find models from."
        }
    }
    output_type = "string"

    def forward(self, author: str):
        try:
            # 列出指定作者的模型,按下载次数排序
            models = list(list_models(author=author, sort="downloads", direction=-1, limit=1))

            if models:
                model = models[0]
                return f"The most downloaded model by {author} is {model.id} with {model.downloads:,} downloads."
            else:
                return f"No models found for author {author}."
        except Exception as e:
            return f"Error fetching models for {author}: {str(e)}"

# 初始化工具
hub_stats_tool = HubStatsTool()

# 示例用法
print(hub_stats_tool("facebook")) # Example: Get the most downloaded model by Facebook

预期输出:

Facebook 下载次数最多的模型是 facebook/esmfold_v1,下载次数为 12,544,550 次。

使用 llama-index

import random
from llama_index.core.tools import FunctionTool
from huggingface_hub import list_models

def get_hub_stats(author: str) -> str:
    """Fetches the most downloaded model from a specific author on the Hugging Face Hub."""
    try:
        # 列出指定作者的模型,按下载次数排序
        models = list(list_models(author=author, sort="downloads", direction=-1, limit=1))

        if models:
            model = models[0]
            return f"The most downloaded model by {author} is {model.id} with {model.downloads:,} downloads."
        else:
            return f"No models found for author {author}."
    except Exception as e:
        return f"Error fetching models for {author}: {str(e)}"

# 初始化工具
hub_stats_tool = FunctionTool.from_defaults(get_hub_stats)

# 示例用法
print(hub_stats_tool("facebook")) # Example: Get the most downloaded model by Facebook

预期输出:

Facebook 下载次数最多的模型是 facebook/esmfold_v1,下载次数为 12,544,550 次。

使用 langgraph

from langchain_core.tools import Tool
from huggingface_hub import list_models

def get_hub_stats(author: str) -> str:
    """Fetches the most downloaded model from a specific author on the Hugging Face Hub."""
    try:
        # 列出指定作者的模型,按下载次数排序
        models = list(list_models(author=author, sort="downloads", direction=-1, limit=1))

        if models:
            model = models[0]
            return f"The most downloaded model by {author} is {model.id} with {model.downloads:,} downloads."
        else:
            return f"No models found for author {author}."
    except Exception as e:
        return f"Error fetching models for {author}: {str(e)}"

# 初始化工具
hub_stats_tool = Tool(
    name="get_hub_stats",
    func=get_hub_stats,
    description="Fetches the most downloaded model from a specific author on the Hugging Face Hub."
)

# 示例用法
print(hub_stats_tool.invoke("facebook")) # Example: Get the most downloaded model by Facebook

预期输出:

Facebook 下载次数最多的模型是 facebook/esmfold_v1,下载次数为 13,109,861 次。

借助 Hub Stats 工具,Alfred 现在可以通过讨论他们最受欢迎的模型来打动有影响力的 AI 开发者。

将工具与 Alfred 集成

现在我们已经拥有了所有工具,让我们将它们集成到 Alfred 的智能体中:

使用 smolagents

from smolagents import CodeAgent, InferenceClientModel

# 初始化 Hugging Face 模型
model = InferenceClientModel()

# 使用所有工具创建 Alfred
alfred = CodeAgent(
    tools=[search_tool, weather_info_tool, hub_stats_tool],
    model=model
)

# Alfred 在庆典期间可能会收到的示例查询
response = alfred.run("What is Facebook and what's their most popular model?")

print("Alfred's Response:")
print(response)

预期输出:

Alfred's Response:
Facebook 是一个社交网站,用户可以在这里互相联系、分享信息并互动。Facebook 在 Hugging Face Hub 上下载次数最多的模型是 ESMFold_v1。

使用 llama-index

from llama_index.core.agent.workflow import AgentWorkflow
from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI

# 初始化 Hugging Face 模型
llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
# 使用所有工具创建 Alfred
alfred = AgentWorkflow.from_tools_or_functions(
    [search_tool, weather_info_tool, hub_stats_tool],
    llm=llm
)

# Alfred 在庆典期间可能会收到的示例查询
response = await alfred.run("What is Facebook and what's their most popular model?")

print("Alfred's Response:")
print(response)

预期输出:

Alfred's Response:
Facebook 是一家总部位于加利福尼亚州门洛帕克的社交网络服务和科技公司。它由马克·扎克伯格创立,允许用户创建个人资料、与亲朋好友联系、分享照片和视频,以及加入基于共同兴趣的群组。Facebook 在 Hugging Face Hub 上最受欢迎的模型是“facebook/esmfold_v1”,下载量达 13,109,861 次。

使用 langgraph

from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages
from langchain_core.messages import AnyMessage, HumanMessage, AIMessage
from langgraph.prebuilt import ToolNode
from langgraph.graph import START, StateGraph
from langgraph.prebuilt import tools_condition
from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace

# 生成聊天界面,包括工具
llm = HuggingFaceEndpoint(
    repo_id="Qwen/Qwen2.5-Coder-32B-Instruct",
    huggingfacehub_api_token=HUGGINGFACEHUB_API_TOKEN,
)

chat = ChatHuggingFace(llm=llm, verbose=True)
tools = [search_tool, weather_info_tool, hub_stats_tool]
chat_with_tools = chat.bind_tools(tools)

# 生成 AgentState 和 Agent 图
class AgentState(TypedDict):
    messages: Annotated[list[AnyMessage], add_messages]

def assistant(state: AgentState):
    return {
        "messages": [chat_with_tools.invoke(state["messages"])],
    }

## 构建流程图
builder = StateGraph(AgentState)

# 定义节点:这些节点完成工作
builder.add_node("assistant", assistant)
builder.add_node("tools", ToolNode(tools))

# 定义边:这些决定了控制流如何移动
builder.add_edge(START, "assistant")
builder.add_conditional_edges(
    "assistant",
    # If the latest message requires a tool, route to tools
    # Otherwise, provide a direct response
    tools_condition,
)
builder.add_edge("tools", "assistant")
alfred = builder.compile()

messages = [HumanMessage(content="Who is Facebook and what's their most popular model?")]
response = alfred.invoke({"messages": messages})

print("Alfred's Response:")
print(response['messages'][-1].content)

预期输出:

Alfred's Response:
Facebook 是一家社交媒体公司,以其社交网站 Facebook 以及 Instagram 和 WhatsApp 等其他服务而闻名。Facebook 在 Hugging Face Hub 上下载次数最多的模型是 facebook/esmfold_v1,下载量达 13,202,321 次。

结论

通过集成这些工具,Alfred 现在可以处理各种任务,从网页搜索到天气更新和模型统计。这确保他始终是晚会上最了解情况、最有魅力的主持人。

提示:尝试实现一个可用于获取特定主题最新消息的工具。

完成后,在 tools.py 文件中实现您的自定义工具。

小结

  • 智能体的能力通过工具扩展:网络搜索、天气查询、Hub 统计分别对应“感知外部世界”的不同维度。
  • 同一组工具在 smolagents(Tool/CodeAgent)、LlamaIndex(FunctionTool)、LangGraph(Tool + 状态图)三种框架下写法不同,但职责一致。
  • 自定义工具需声明名称、描述、输入输出类型与实现逻辑;smolagents 用 Tool 子类与 forward,另两者多用 FunctionTool.from_defaults。
  • 将工具列表传入智能体(如 CodeAgent(tools=[...]) 或 AgentWorkflow.from_tools_or_functions)即可让 Alfred 综合调用。
  • Hugging Face Hub 统计工具借助 huggingface_hub.list_models 按下载量排序,可动态展示作者最受欢迎的模型。

参考与延伸阅读