跳到主要内容

smolagents — 架构与原理

30 秒导读: smolagents 是 Hugging Face 的一个极简 agent 库。它最大的赌注是——让大模型不要用 JSON 描述「我要调用哪个工具」,而是直接写一段 Python 代码来行动。这段代码跑在一个它自己手写的、逐行解释 AST 的「迷你 Python」里,只放行白名单里的模块和函数。核心 agent 循环压到约一千行。

本项目较大(源码约 1.3 万行,多个子系统),文档拆成多章。本页是 Layer 0(这是什么)+ Layer 1(顶层全景)+ 阅读地图;各机制的细节在分章里。


1. 这是什么(零基础也能懂)

一句话定义: smolagents 是一个「让 LLM 反复地思考→行动→看结果」的 agent 框架,而它的行动方式是写代码

它想解决的问题。 你想让 AI 自动完成一个多步骤任务(「查一下猎豹全速跑过这座桥要几秒」),这需要:上网搜、把数字抠出来、做算术、给出答案。单靠一次模型调用做不到——模型不会上网、不会精确算术。于是需要一个循环:模型说一步,系统执行一步,把结果喂回去,再问下一步。这类系统叫 agent(智能体)

它和别的 agent 框架不同在哪。 多数框架让模型输出结构化的「工具调用」(一段 JSON:工具名 + 参数)。smolagents 的主打是另一条路——CodeAgent:模型直接写 Python。想连续调三个工具、把结果存进变量、写个循环?一段代码就搞定,不用来回三轮对话。

它能做什么:

  • 两种 agent:CodeAgent(写代码行动)和 ToolCallingAgent(传统 JSON 工具调用)。
  • 模型无关:HF Inference、LiteLLM(100+ 家)、OpenAI、Bedrock、本地 Transformers/vLLM/MLX 都接。
  • 工具无关:自带 web 搜索/访问网页;能从 MCP server、LangChain、HF Hub Space 拉工具。
  • 代码执行有多档隔离:本地受限解释器,或 E2B / Docker / Modal / Blaxel 远程沙箱。
  • agent 可嵌套(一个 agent 当另一个的「工具」,即 managed agents),可存取 Hub。

用起来什么样:

from smolagents import CodeAgent, WebSearchTool, InferenceClientModel

model = InferenceClientModel()
agent = CodeAgent(tools=[WebSearchTool()], model=model)
agent.run("猎豹全速跑过巴黎艺术桥要多少秒?")

agent.run(...) 内部会转起一个循环:模型写一段代码 → 解释器执行 → 把打印输出和返回值当「观测」喂回 → 直到模型调用 final_answer(...) 收尾。

一句话直觉: 把 agent 想成一个「只会用 Python 交互的实习生」——你给它一套函数(工具),它写代码调用它们、串联它们;它每写一段你就帮它跑一段,把结果念给它听,直到它说「这就是最终答案」。


2. 顶层全景(它大概怎么转)

2.1 部件一句话职责

部件干什么主要文件
MultiStepAgentReAct 循环的骨架:排步骤、插规划、管记忆、判终止src/smolagents/agents.py:268
CodeAgent把「行动」实现成写代码 + 交给执行器跑src/smolagents/agents.py:1505
ToolCallingAgent把「行动」实现成传统 JSON 工具调用src/smolagents/agents.py:1215
LocalPythonExecutor手写的受限 Python 解释器(招牌)src/smolagents/local_python_executor.py:1688
RemotePythonExecutor 家族把代码送到 E2B/Docker/Modal/Blaxel 沙箱跑src/smolagents/remote_executors.py:53
Tool工具抽象:一个可调用对象 + 元数据(名/描述/入参/出参)src/smolagents/tools.py:106
Model统一各家 LLM 的接口,产出 ChatMessagesrc/smolagents/models.py:452
AgentMemory存每一步(任务/规划/行动),又能回灌成消息列表src/smolagents/memory.py:214

2.2 主线走一遍(高层,不进代码)

下图是一次 CodeAgent.run(task) 的主循环。怎么读:从上到下是一步(step)内的顺序;右侧虚线是「没结束就回到顶部开下一步」。

agent.run(task)
│ 把 task 塞进记忆(TaskStep),把工具/变量灌进执行器

┌─────────────────────────────────────────────┐
│ 一个 step(ReAct 的一轮): │ ◄─┐
│ │ │
│ ① 记忆 → 消息列表 write_memory_to_messages │ │
│ ② 模型生成一段带 <code>…</code> 的回答 │ │
│ ③ 从回答里抠出代码 parse_code_blobs │ │
│ ④ 执行器跑这段代码 python_executor(code) │ │
│ ⑤ 把「打印输出 + 返回值」写回记忆当观测 │ │
│ │ │
│ 代码里调了 final_answer(x) 吗? │ │
│ 否 ──────────────────────────────────────┼───┘ 下一步
│ 是 → 返回 x,循环结束 │
└─────────────────────────────────────────────┘

三个要点先记住,后面各章展开:

  • 「行动」= 一段代码,不是一次函数调用。这让「连续多个工具 + 变量 + 控制流」在一步内完成(见 02-code-agent.md)。
  • 终止靠 final_answer。它不是普通返回值,而是靠抛一个特殊异常打断执行(见 02 §5)。
  • 记忆是「可逆」的:每步既存成结构化对象(给回放/序列化),又能 to_messages() 变回对话喂给模型(见 05-models-and-memory.md)。

3. 阅读地图(建议顺序)

  1. 01-agent-loop.md — 先懂通用循环:run / _run_stream / 一步的生命周期、规划步、记忆回灌。这是所有 agent 的共同骨架。
  2. 02-code-agent.md — 再看 CodeAgent 怎么把「行动」变成写代码:停止序列、代码抠取、final_answer 终止。
  3. 03-local-python-executor.md — 招牌深潜:一个逐节点解释 AST 的迷你 Python,如何用白名单 + 返回值检查 + 计步器/超时把代码关起来。想学到精华就重点读这章。
  4. 04-tools.md — 工具抽象:同一个工具的两副面孔(代码签名 vs JSON schema)、校验、@tool 装饰器、MCP/Hub 来源。
  5. 05-models-and-memory.md — Model 如何抹平各家 API;Memory 每步存什么、又怎么变回消息。
  6. 06-remote-execution-and-boundaries.md — 远程沙箱、安全边界的诚实交代、和兄弟项目的横向对比、总代码地图。

给 AI agent 的提示:keyTopics 匹配任务再下钻单章即可,不必读全部。要改代码执行/安全相关的,直接跳 0306;要接新模型或改上下文拼装,跳 05;要加工具,跳 04