Smolagents 入门:实用指南

open-source入门12 分钟阅读2026/7/20

上周,我正在写一个研究自动化脚本。我需要个能自己搜索网页、抓取实时数据,并根据这些数据做决定的工具——整个过程完全不需要我一步步盯着。我一开始还是走老路子用 LangChain,但跟链式定义、回调处理程序还有各种导入错误死磕了一个小时后,我发现自己光是为了搭个基础管线就写了 200 行代码。肯定有更简单的办法。

就在这时候,同事给我推荐了 smolagents,这是 Hugging Face 出的一个极简 Agent 库。它整个 Agent 的核心逻辑大概只有 1000 行代码。不是一万,也不是十万,就是一千行。我一开始挺怀疑的——通常说“极简”,潜台词就是“以后需要的功能肯定没有”——但我还是决定试一把。以下是我用它搭第一个 Agent 时学到的经验,包括中间踩过的一些坑。

为什么 smolagents 吸引了我

smolagents 最核心的差异化在于 Agent 推理行动的方式。大多数 Agent 框架都是生成 JSON 或结构化文本来决定调用哪个工具。Smolagents 却换了个路子:它的 Agent 是代码 Agent,意思是它们会直接写真正的 Python 代码片段来编排自己的行动。

听起来是个小细节,但实际影响巨大。当 Agent 写代码而不是 JSON 时,它就能写循环、用 try/except 处理错误、定义变量,还能很自然地组合各种操作。这就好比填表和写脚本的区别。Agent 可以尽情发挥 Python 的全部表达力。

除此之外,smolagents 不绑定特定模型。OpenAI、Anthropic、Hugging Face 自家的模型,甚至本地模型它都支持。它还支持多模态输入(文本、视觉、视频、音频),并且能跟 LangChain 的工具、Anthropic 的 MCP 以及 Hugging Face Spaces 完美配合。

搭建环境

首先——安装:

pip install smolagents

这就完了。不用折腾额外的依赖,也没有复杂的构建步骤。比起我平时搭框架的套路,这已经让我小惊喜了一把。

现在,在写 Agent 代码之前,你需要先配置好模型提供方。Smolagents 需要一个大语言模型(LLM)来驱动推理,所以你得备好 API 密钥。我一开始用的是 OpenAI 的 GPT-4o,因为我手头正好有密钥:

import os
from smolagents import CodeAgent, DuckDuckGoSearchTool, OpenAIServerModel

model = OpenAIServerModel(
    model_id="gpt-4o",
    api_base="https://api.openai.com/v1",
    api_key=os.environ["OPENAI_API_KEY"],
)

踩坑 #1: 我一开始图省事,把 API 密钥直接硬编码在脚本里了。千万别这么干,一定要用环境变量。我在 shell 配置文件里用 export OPENAI_API_KEY="sk-..." 设置好,然后通过 os.environ 来读取。这虽然是件小事,但我见过太多人一不小心就把密钥提交到 Git 里了。

如果你更喜欢 Anthropic,或者想白嫖 Hugging Face 的免费推理端点,smolagents 也完全支持。用 HfApiModel 类,你不需要 OpenAI 账号也能用上开源模型:

from smolagents import HfApiModel

model = HfApiModel(model_id="Qwen/Qwen2.5-Coder-32B-Instruct")

不到 10 行代码搭个极简 Agent

咱们先从最简单的 Agent 搞起——一个能联网搜索的 Agent:

agent = CodeAgent(
    tools=[DuckDuckGoSearchTool()],
    model=model,
)

result = agent.run("What is the current population of Tokyo?")
print(result)

跑一下这段代码,Agent 会:

  1. 读取你的问题
  2. 决定需要联网搜索
  3. 编写调用 DuckDuckGoSearchTool 的 Python 代码
  4. 在沙盒环境中执行这段代码
  5. 返回答案

我第一次跑的时候,干坐在那等,心里犯嘀咕它到底在工作没。然后输出结果出来了——不仅有最终答案,还有完整的执行轨迹,展示了 Agent 写了什么代码、调用了什么工具,以及每一步的推理过程。这种透明度是 smolagents 最强大的特性之一。你真的能看清 Agent 在什么以及为什么这么做,这对调试来说简直是无价之宝。

搭个自定义天气 Agent

内置的搜索工具确实不错,但真正的威力在于写你自己的工具。我决定搭一个能抓取实时数据的天气 Agent。下面是完整代码——大概 40 行:

import os
import requests
from smolagents import CodeAgent, Tool, OpenAIServerModel

class WeatherTool(Tool):
    name = "get_weather"
    description = "Gets the current weather for a given city using Open-Meteo API."
    inputs = {
        "city": {
            "type": "string",
            "description": "The city name to get weather for, e.g. 'London' or 'Tokyo'"
        }
    }
    output_type = "string"

    def forward(self, city: str) -> str:
        # 首先,对城市进行地理编码以获取坐标
        geocode_url = "https://geocoding-api.open-meteo.com/v1/search"
        geo_response = requests.get(geocode_url, params={"name": city, "count": 1})
        geo_data = geo_response.json()

        if not geo_data.get("results"):
            return f"Could not find location: {city}"

        lat = geo_data["results"][0]["latitude"]
        lon = geo_data["results"][0]["longitude"]

        # 接着获取天气
        weather_url = "https://api.open-meteo.com/v1/forecast"
        weather_response = requests.get(weather_url, params={
            "latitude": lat,
            "longitude": lon,
            "current_weather": True
        })
        weather_data = weather_response.json()

        current = weather_data["current_weather"]
        return (
            f"Weather in {city}: {current['temperature']}°C, "
            f"wind speed {current['windspeed']} km/h, "
            f"weather code {current['weathercode']}"
        )

# 设置 Agent
model = OpenAIServerModel(
    model_id="gpt-4o",
    api_base="https://api.openai.com/v1",
    api_key=os.environ["OPENAI_API_KEY"],
)

agent = CodeAgent(
    tools=[WeatherTool()],
    model=model,
)

# 运行
result = agent.run("What's the weather like in Paris right now? Should I bring a jacket?")
print(result)

惊喜 #1: Agent 并没有只返回干巴巴的温度。因为我问了“需要带外套吗?”,它通过我的工具获取了天气数据,然后对结果进行了推理——得出结论:14°C 加上风,大概率得穿件外套。这就是代码 Agent 的威力:大模型能解读工具的输出并做出判断,而不是单纯地搬运数据。

踩坑 #2: 我一开始忘了在虚拟环境里装 requests 库。Agent 的代码执行沙盒捕获到了 ImportError 并给出了清晰的报错,但我愣是过了一分钟我才意识到问题不是出在 smolagents 本身。一定要确保你的环境里装好了你的工具所需的各种依赖。

搞懂工具的结构

我来拆解一下在 smolagents 里自定义工具是怎么跑起来的。每个工具都需要:

  • name:大模型用来调用该工具的简短标识符
  • description:清晰说明该工具的功能——这非常关键,因为大模型要根据它来决定什么时候调用工具
  • inputs:一个字典,定义了预期的参数、参数类型和描述
  • output_type:工具的返回类型(通常是 "string")
  • forward():实际的执行逻辑

description 字段值得特别关注。我一开始写得很模糊,类似“获取天气数据”。结果 Agent 有时候不用这个工具,因为它搞不清这工具到底啥时候该用。当我改成“获取指定城市的当前天气”后,只要遇到跟天气相关的查询,Agent 每次都能稳定调用。把你的工具描述当成 API 文档来写——描述越清晰,工具调用越靠谱。

幕后发生了什么

当你调用 agent.run() 时,流程是这样的:

  1. Agent 把你的查询和工具定义一起发给大模型
  2. 大模型编写调用相应工具的 Python 代码
  3. Smolagents 在沙盒环境中执行这段代码
  4. 执行结果反馈给大模型
  5. 大模型要么接着写代码(如果还需要更多信息),要么直接给出最终答案
  6. 这个循环会一直持续,直到 Agent 得出结论

代码执行是在沙盒里进行的,这意味着 Agent 不会不小心删了你的文件,或者搞出系统级的破坏。话虽如此,如果在生产环境里,没有额外的安全防护,我绝不会给 Agent 不受限制的网络访问权限。

实战经验分享

用强一点的大模型起步。 我一开始试着用较小的开源模型跑,结果生成的代码很不靠谱——要么瞎编函数名,要么写出语法错误的 Python。GPT-4o 和 Claude 3.5 Sonnet 处理代码 Agent 任务要靠谱得多。如果你用的是 HfApiModel,尽量选那些大尺寸的指令微调版本。

工具描述要精准。 就像我前面说的,描述模糊会导致工具调用失败或出错。要明确说清每个工具是干嘛的、期望什么输入、返回什么结果。

注意步数限制。 默认情况下,Agent 有个最大执行步数限制,用来防止死循环。如果你发现 Agent 好像没跑完就停了,可以通过 CodeAgentmax_steps 参数调大这个限制。我发现简单任务用默认值通常就够了,但复杂的多步查询有时确实得调大点。

多看执行轨迹。 出问题是迟早的事——而 smolagents 详细的执行轨迹是你最好的调试利器。你能清楚地看到 Agent 到底写了什么代码、出了什么错,以及它是怎么尝试恢复的。千万别无视这些输出。

实话实说的局限性

Smolagents 并非完美无缺。沙盒代码执行会增加延迟——每一步都要启动环境、跑代码、解析结果。对于简单的查询来说,比起直接调 API,这种开销还是感觉得到的。

这个库也比较新。我碰到了几个粗糙的边界情况,报错信息不太给力。文档正在完善中,但还有缺口,尤其是高级的多 Agent 协同配置方面。

另外,虽然代码 Agent 的路子很强大,但并非总是必需的。如果你只是需要一个简单的工具调用管线,不需要复杂的逻辑,其他框架那种基于 JSON 的方式可能反而更简单、更快速。

总结

花了一个周末折腾 smolagents 后,我把我的研究自动化脚本重写了一遍,代码量只有之前方案的四分之一。对于需要组合多种操作或处理边界情况的任务,代码 Agent 的范式真的管用——Agent 能写循环、写条件判断、写错误处理,这些是 JSON 工具调用根本表达不出来的。

如果你之前被其他 Agent 框架的复杂度劝退过,smolagents 绝对值得你花点时间试试。它真正做到了极简而不简陋。从内置工具起步,再进阶到自定义工具,你几分钟就能跑通一个 Agent,不用几小时,更不用几天。

相关 Agent

O

OpenClaw

开源 AI Agent 框架,用于构建自主工作流

了解更多 →