smolagents 文档
Agent 简介
并获得增强的文档体验
开始使用
Agent 简介
🤔 什么是 Agent?
任何使用 AI 的高效系统都需要为 LLM 提供某种访问真实世界的方式:例如,调用搜索工具以获取外部信息,或者操作某些程序以解决任务的可能性。换句话说,LLM 应该具有 自主性。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 输出控制迭代和程序继续 | 多步骤 Agent | while llm_should_continue(): execute_next_step() |
★★★ | 一个 Agentic 工作流程可以启动另一个 Agentic 工作流程 | 多 Agent | if llm_trigger(): execute_agent() |
多步骤 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 非常有用。但它们通常是过度使用。问题是:我真的需要工作流程中的灵活性来有效地解决手头的任务吗?如果预先确定的工作流程经常不足,那就意味着您需要更多的灵活性。让我们举个例子:假设您正在制作一个应用程序,用于处理冲浪旅行网站上的客户请求。
您可以提前知道,请求将属于 2 个类别中的任何一个(基于用户选择),并且您为这 2 种情况中的每一种都预定义了工作流程。
- 想要了解有关旅行的一些知识?⇒ 让用户访问搜索栏以搜索您的知识库
- 想与销售人员交谈?⇒ 让用户填写联系表单。
如果这种确定性的工作流程适合所有查询,那么请务必将所有内容都编码!这将为您提供一个 100% 可靠的系统,不会因让不可预测的 LLM 干预您的工作流程而引入错误风险。为了简单性和稳健性,建议规范化为不使用任何 Agentic 行为。
但是,如果工作流程无法提前很好地确定呢?
例如,用户想问:“我星期一可以来,但我忘记带护照了,所以可能会延迟到星期三,是否可以在星期二早上带我和我的东西去冲浪,并购买取消保险?”
这个问题取决于许多因素,并且可能上述任何预先确定的标准都不足以满足此请求。
如果预先确定的工作流程经常不足,那就意味着您需要更多的灵活性。
这就是 Agentic 设置有所帮助的地方。
在上面的示例中,您可以创建一个多步骤 Agent,它可以访问天气 API 以获取天气预报,访问 Google Maps API 以计算旅行距离,访问员工可用性仪表板以及访问您知识库上的 RAG 系统。
直到最近,计算机程序还仅限于预先确定的工作流程,试图通过堆积 if/else 开关来处理复杂性。它们专注于极其狭窄的任务,例如“计算这些数字的总和”或“找到该图中的最短路径”。但实际上,大多数现实生活中的任务,例如我们上面的旅行示例,都不适合预先确定的工作流程。Agentic 系统为程序打开了广阔的现实世界任务!
为什么选择 smolagents?
对于一些低级别的 Agentic 用例,例如链或路由器,您可以自己编写所有代码。这样做会更好,因为它将使您更好地控制和理解您的系统。
但是,一旦您开始进行更复杂的行为,例如让 LLM 调用函数(即“工具调用”)或让 LLM 运行 while 循环(“多步骤 Agent”),一些抽象就变得必要了
- 对于工具调用,您需要解析 Agent 的输出,因此此输出需要预定义的格式,例如“Thought: I should call tool ‘get_weather’. Action: get_weather(Paris).”,您可以使用预定义的函数解析它,并且提供给 LLM 的系统提示应通知它有关此格式。
- 对于 LLM 输出决定循环的多步骤 Agent,您需要根据上一次循环迭代中发生的事情向 LLM 提供不同的提示:因此您需要某种形式的记忆。
看到了吗?通过这两个例子,我们已经发现了我们需要一些项目来帮助我们
- 当然,一个充当系统引擎的 LLM
- Agent 可以访问的工具列表
- 一个从 LLM 输出中提取工具调用的解析器
- 与解析器同步的系统提示
- 记忆
但是等等,既然我们在决策中为 LLM 留出了空间,那么它们肯定会犯错误:所以我们需要错误日志记录和重试机制。
所有这些元素都需要紧密耦合才能构成一个运行良好的系统。这就是为什么我们决定我们需要制作基本的构建块,使所有这些东西协同工作。
代码 Agent
在多步骤 Agent 中,在每个步骤中,LLM 都可以编写一个动作,形式是调用外部工具。编写这些动作的常用格式(Anthropic、OpenAI 和许多其他公司使用)通常是不同形式的“将动作编写为工具名称和要使用的参数的 JSON,然后您解析 JSON 以了解要执行哪个工具以及使用哪些参数”。
其原因很简单,我们专门设计了我们的代码语言,使其成为表达计算机执行的动作的最佳方式。如果 JSON 片段是更好的表达方式,那么 JSON 将成为顶级编程语言,而编程将是人间地狱。
下图取自 Executable Code Actions Elicit Better LLM Agents,说明了在代码中编写动作的一些优势

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