smolagents 文档
什么是 Agent?🤔
并获得增强的文档体验
开始使用
什么是 Agent?🤔
Agentic 系统简介。
任何使用 AI 的高效系统都需要为大型语言模型(LLM)提供某种与现实世界的连接:例如,调用搜索工具以获取外部信息,或对特定程序进行操作以解决任务。换句话说,LLM 应该拥有 **代理能力(agency)**。Agentic 程序是 LLM 连接外部世界的门户。
AI Agent 是 **LLM 输出控制工作流的程序**。
任何利用 LLM 的系统都会将 LLM 的输出集成到代码中。LLM 输入对代码工作流的影响程度就是 LLM 在系统中的代理能力水平。
请注意,根据这个定义,“Agent”并非一个离散的、0 或 1 的定义:相反,“代理能力”在一个连续的谱系上演变,取决于你赋予 LLM 对你的工作流多少权力。
请看下表,了解代理能力在不同系统中如何变化
代理能力等级 | 描述 | 简称 | 代码示例 |
---|---|---|---|
☆☆☆ | LLM 输出对程序流没有影响 | 简单处理器 | process_llm_output(llm_response) |
★☆☆ | LLM 输出控制 if/else 开关 | 路由器 | if llm_decision(): path_a() else: path_b() |
★★☆ | LLM 输出控制函数执行 | 工具调用 | run_function(llm_chosen_tool, llm_chosen_args) |
★★☆ | LLM 输出控制迭代和程序继续执行 | 多步智能体 | while llm_should_continue(): execute_next_step() |
★★★ | 一个代理工作流可以启动另一个代理工作流 | 多智能体 | if llm_trigger(): execute_agent() |
★★★ | LLM 在代码中操作,可以定义自己的工具 / 启动其他 Agent | 代码 Agent | def custom_tool(args): ... |
多步 Agent 具有这种代码结构
memory = [user_defined_task]
while llm_should_continue(memory): # this loop is the multi-step part
action = llm_get_next_action(memory) # this is the tool-calling part
observations = execute_action(action)
memory += [action, observations]
这个 Agentic 系统在一个循环中运行,每一步执行一个新的动作(该动作可以涉及调用一些预定义的**工具**,这些工具只是函数),直到其观察结果表明已达到令人满意的状态以解决给定任务。这是一个多步 Agent 如何解决一个简单数学问题的示例

✅ 何时使用 Agent / ⛔ 何时避免使用 Agent
当你需要 LLM 决定应用程序的工作流时,Agent 会很有用。但它们通常是杀鸡用牛刀。问题是:我真的需要工作流的灵活性才能有效解决手头的任务吗?如果预定工作流经常力不从心,那意味着你需要更多的灵活性。举个例子:假设你正在开发一个处理冲浪旅行网站客户请求的应用程序。
你可能事先知道请求将属于两个类别中的一个(根据用户选择),并且你为这两种情况都预定义了工作流。
- 想了解旅行信息?⇒ 让他们访问搜索栏来搜索你的知识库
- 想与销售交谈?⇒ 让他们填写联系表格。
如果这种确定性工作流适合所有查询,那么尽管放心地将所有内容编码!这将为你提供一个 100% 可靠的系统,没有任何因让不可预测的 LLM 干预你的工作流而引入错误的风险。为了简洁和健壮性,建议尽量不使用任何 Agentic 行为。
但是,如果工作流无法事先确定得那么好呢?
例如,用户想问:“我周一能来,但我忘了护照,所以可能会延迟到周三,周二早上可以带我和我的东西去冲浪吗,有取消保险吗?”这个问题取决于许多因素,上面预先确定的标准可能都不足以满足这个请求。
如果预设的工作流经常无法满足需求,那意味着你需要更大的灵活性。
这时,Agentic 设置就派上用场了。
在上面的例子中,你可以简单地创建一个多步 Agent,它能够访问天气 API 获取天气预报、Google Maps API 计算出行距离、员工可用性仪表板以及你的知识库上的 RAG 系统。
直到最近,计算机程序还受限于预设的工作流程,通过堆叠 if/else 开关来处理复杂性。它们专注于极其狭窄的任务,例如“计算这些数字的总和”或“找出图中最短路径”。但实际上,大多数现实生活中的任务,比如我们上面提到的旅行示例,都不符合预设的工作流程。Agentic 系统为程序打开了广阔的现实世界任务的大门!
为什么选择 smolagents?
对于一些低级别的 Agent 用例,例如链或路由器,你可以自己编写所有代码。这样做会更好,因为它可以让你更好地控制和理解你的系统。
但是一旦你开始追求更复杂的行为,比如让 LLM 调用函数(这就是“工具调用”)或者让 LLM 运行 while 循环(“多步 Agent”),一些抽象就变得必要了。
- 对于工具调用,你需要解析 Agent 的输出,所以这个输出需要一个预定义的格式,比如“Thought: 我应该调用工具‘get_weather’。Action: get_weather(Paris).”,你用一个预定义的函数来解析它,并且给 LLM 的系统提示应该通知它这个格式。
- 对于 LLM 输出决定循环的多步 Agent,你需要根据上次循环迭代中发生的事情给 LLM 不同的提示:所以你需要某种内存。
看到了吗?通过这两个例子,我们已经发现需要一些元素来帮助我们
- 当然,作为驱动系统的引擎的 LLM
- Agent 可以访问的工具列表
- 一个系统提示,指导 LLM 的 Agent 逻辑:反射 -> 动作 -> 观察的 ReAct 循环,可用的工具,要使用的工具调用格式…
- 一个解析器,用于从 LLM 输出中提取工具调用,其格式由上面的系统提示指定。
- 记忆
但是等等,既然我们允许 LLM 做决策,它们肯定会犯错误:所以我们需要错误日志记录和重试机制。
所有这些元素都需要紧密耦合才能形成一个运行良好的系统。这就是为什么我们决定需要构建基本模块,让所有这些东西协同工作。
代码 Agent
在多步 Agent 中,LLM 在每个步骤中都可以编写一个动作,形式是调用外部工具。编写这些动作的常用格式(Anthropic、OpenAI 和许多其他公司使用)通常是“将动作写成包含工具名称和要使用的参数的 JSON,然后解析它以知道执行哪个工具以及使用哪些参数”的不同变体。
多篇 研究 论文 表明,将 LLM 的动作写成代码片段是一种更自然、更灵活的编写方式。
其原因很简单:**我们设计编程语言就是为了表达计算机执行的动作**。换句话说,我们的 Agent 将编写程序来解决用户的问题:你认为它们用 Python 块还是 JSON 来编程会更容易?
下图取自可执行代码动作能更好地激发 LLM Agent,说明了用代码编写动作的一些优点

用代码而非类似 JSON 的片段编写动作,能提供更好的
- **可组合性:** 您可以将 JSON 操作相互嵌套,或者定义一组 JSON 操作供以后重用,就像您可以定义一个 Python 函数一样吗?
- **对象管理:** 如何在 JSON 中存储
generate_image
等操作的输出? - **通用性:** 代码旨在简单地表达计算机可以做的任何事情。
- **LLM 训练数据中的表示:** 大量高质量的代码操作已经包含在 LLM 的训练数据中,这意味着它们已经为此做好了训练!