smolagents 文档

Agent 简介

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

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 种情况中的每一种都预定义了工作流程。

  1. 想要了解有关旅行的一些知识?⇒ 让用户访问搜索栏以搜索您的知识库
  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 以了解要执行哪个工具以及使用哪些参数”。

多篇 研究 论文 表明,在代码中调用工具 LLM 更好。

其原因很简单,我们专门设计了我们的代码语言,使其成为表达计算机执行的动作的最佳方式。如果 JSON 片段是更好的表达方式,那么 JSON 将成为顶级编程语言,而编程将是人间地狱。

下图取自 Executable Code Actions Elicit Better LLM Agents,说明了在代码中编写动作的一些优势

在代码中编写动作而不是类似 JSON 的片段提供了更好的

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