决定 Agent 能力的两个方面:工具和规划。
Artificial Intelligence: A Modern Approach (1995) defines an agent as anything that can be viewed as perceiving its environment through sensors and acting upon that environment through actuators.
《人工智能:一种现代方法》(1995 年)将 Agent 定义为任何可以通过传感器感知环境并通过执行器作用于环境的事物。
这意味着,一个 Agent 的特征在于它所处的环境和它能执行的一系列行动。如果开发一个 Agent 来玩游戏(例如,Minecraft、Go、Dota),那么该游戏就是它的环境。如果你希望 Agent 从互联网上抓取文档,那么互联网就是它的环境。自动驾驶汽车 Agent 的环境则是道路系统及其周边区域。
AI Agent 能够执行的一系列动作因其可访问的工具而得到增强。ChatGPT 就是一个 Agent,它能够搜索网页、执行 Python 代码以及生成图像。RAG 系统也是 Agent —— 文本检索器、图像检索器和 SQL 执行器是它们的工具。
Agent 的环境与其工具集之间存在强烈的依赖关系。 环境决定了 Agent 可能使用的工具。例如,如果环境是国际象棋游戏,Agent 唯一可能的动作就是有效的棋步。然而,Agent 的工具清单限制了其可操作的环境。例如,如果机器人的唯一动作是游泳,那么它将被限制在水环境中。
与非 Agent 用例相比,Agent 通常需要更强大的模型,原因有二:
- 复合错误:Agent 通常需要执行多个步骤来完成一项任务,随着步骤数量的增加,整体准确性会下降。如果模型每步的准确率为 95%,经过 10 步后,准确率将降至 60%,而经过 100 步后,准确率仅为 0.6%。
- 更高风险:借助工具,Agent 能够执行更具影响力的任务,但任何失败都可能带来更严重的后果。
每当我向一群人谈论自主 AI Agent 时,总会有人提到自动驾驶汽车。“如果有人黑进汽车绑架你怎么办?” 虽然自动驾驶汽车的例子因其物理性而显得直观,但 AI 系统无需存在于物理世界也能造成伤害。
任何希望利用人工智能的组织都需要认真对待安全与保障问题。然而,这并不意味着 AI 系统永远不应被赋予在现实世界中行动的能力。如果我们能信任机器将我们送入太空,我希望有一天,安全措施将足以让我们信任自主的 AI 系统。此外,人类也可能犯错。就我个人而言,相比让一个陌生人载我一程,我更信任自动驾驶汽车。
可以在同一个提示中将规划与执行结合起来。例如,给模型一个提示,要求它逐步思考(如使用思维链提示),然后在一个提示中执行这些步骤。但如果模型制定了一个 1000 步的计划,却未能达成目标呢?在没有监督的情况下,Agent 可能会运行这些步骤数小时,浪费时间和 API 调用费用,直到你意识到它毫无进展。
为避免无效执行,规划应与执行解耦。需要要求 Agent 首先生成计划,只有在计划经过验证后才执行。计划可以通过启发式方法进行验证。例如,一个简单的启发式方法是排除包含无效操作的计划。如果生成的计划需要进行 Google 搜索,而代理无法访问 Google 搜索,则该计划无效。另一个简单的启发式方法可能是排除所有步骤超过 X 的计划。
规划系统现在包含三个组件:一个用于生成计划,一个用于验证计划,另一个用于执行计划。如果将每个组件视为一个 Agent,这可以被视为一个多 Agent 系统。由于大多数 Agent 工作流程足够复杂,涉及多个组件,因此大多数 Agent 都是多 Agent 的。
解决一个任务通常涉及以下过程。需要注意的是,反思对 Agent 来说并非强制要求,但它将显著提升 Agent 的表现。
- 计划生成:制定完成此任务的计划。计划是一系列可管理的行动,因此此过程也称为任务分解。
- 反思与纠错:评估生成的计划。如果计划不佳,则生成一个新计划。
- 执行:按照生成的计划采取行动。这通常涉及调用特定函数。
- 反思与纠错:在收到行动结果后,评估这些结果并确定目标是否已达成。识别并纠正错误。如果目标未完成,则制定新计划。
将模型转变为计划生成器的最简单方法是使用 Prompt 工程。假设创建一个 Agent 来帮助客户了解 Kitty Vogue 的产品。该 Agent 提供了三个外部工具的访问权限:按价格检索产品、检索热门产品和检索产品信息。以下是一个用于计划生成的提示示例。此提示仅用于说明目的,实际生产中的提示可能更为复杂。
Propose a plan to solve the task. You have access to 5 actions:
* get_today_date()
* fetch_top_products(start_date, end_date, num_products)
* fetch_product_info(product_name)
* generate_query(task_history, tool_output)
* generate_response(query)
The plan must be a sequence of valid actions.
Examples
Task: "Tell me about Fruity Fedora"
Plan: [fetch_product_info, generate_query, generate_response]
Task: "What was the best selling product last week?"
Plan: [fetch_top_products, generate_query, generate_response]
Task: {USER INPUT}
Plan:
许多模型提供商为其模型提供工具使用功能,有效地将其模型转变为 Agent,工具即函数。因此,调用工具通常被称为函数调用。一般而言,函数调用的运作如下:
- 创建工具清单。声明可能希望模型使用的所有工具。每个工具由其执行入口点(例如,其函数名称)、参数及其文档(例如,函数的功能及其所需参数)描述。
- 指定 Agent 可用于查询的工具。由于不同的查询可能需要不同的工具,许多 API 允许为每个查询指定要使用的已声明工具列表。
例如,给定用户查询 “40 磅等于多少公斤?”,代理可能会决定需要使用工具 lbs_to_kg_tool
,并传入参数值 40。代理的响应可能如下所示。
response = ModelResponse(
finish_reason='tool_calls',
message=chat.Message(
content=None,
role='assistant',
tool_calls=[
ToolCall(
function=Function(
arguments=**'{"lbs":40}'**,
name='lbs_to_kg'),
type='function')
])
)
计划是概述完成任务所需步骤的路线图。路线图可以有不同的粒度级别。为一年做计划时,季度计划比月度计划更高层次,而月度计划又比周计划更高层次。
详细的计划更难制定,但更易于执行;而较高层次的计划则更易制定,却执行起来更具挑战。一种规避此权衡的方法是采用分层规划。首先,利用规划器生成高层次计划,如季度计划。随后,针对每个季度,使用相同或不同的规划器进一步细化出月度计划。
使用更自然的语言有助于计划生成器对工具 API 的变化具有更强的适应性。如果模型主要是在自然语言上训练的,那么它很可能更擅长理解和生成自然语言计划,并且不太可能出现幻觉。
这种方法的缺点是需要一个翻译器将每个自然语言动作翻译成可执行的命令。Chameleon(Lu 等,2023)将这个翻译器称为程序生成器。然而,翻译比规划简单得多,可以由较弱的模型完成,且幻觉风险较低。
控制流包括顺序、并行、if 语句和 for 循环。在评估 Agent 框架时,检查其支持的控制流程。 例如,如果系统需要浏览十个网站,它能否同时进行?并行执行可以显著减少用户感知的延迟。
即使是最好的计划也需要不断评估和调整,以最大限度地提高成功的可能性。虽然反思并非 Agent 运作的严格必要条件,但它是 Agent 取得成功所必需的。
反思和纠错是两种相辅相成的机制。反思产生洞察,有助于发现需要纠正的错误。 反思可以通过同一 Agent 使用自我批评提示来完成。也可以通过一个单独的组件来完成,例如一个专门的评分器:一个为每个结果输出具体分数的模型。
ReAct(Yao 等人,2022 年)提出交错推理与行动已成为智能体的常见模式。Yao 等人使用 “推理” 一词来涵盖规划与反思。在每一步中,智能体被要求解释其思考(规划),采取行动,然后分析观察结果(反思),直到智能体认为任务完成。
可以在多智能体环境中实现反思机制:一个智能体负责规划并执行行动,而另一个智能体则在每一步或若干步之后评估结果。如果 Agent 的响应未能完成任务,您可以提示 Agent 反思失败的原因及改进方法。基于此建议,Agent 生成新的计划。这使得 Agent 能够从错误中学习。
在 Reflexion 框架中,反思被分为两个模块:一个评估结果的分析器和一个分析出错原因的自省模块。使用术语 “trajectory(轨迹)” 来指代计划。在每一步骤后,经过评估与自我反思,Agent 会提出新的轨迹。
与计划生成相比,反思相对容易实现,并能带来令人惊讶的性能提升。这种方法的缺点是延迟和成本。思考、观察,有时甚至是行动,可能需要生成大量的 token,这增加了成本和用户感知的延迟,特别是对于具有许多中间步骤的任务。为了促使他们的 Agent 遵循格式,ReAct 和 Reflexion 的作者在他们的提示中使用了大量的示例。这增加了计算输入 token 的成本,并减少了可用于其他信息的上下文空间。
更多工具将赋予 Agent 更多能力。然而,工具越多,高效使用它们的难度就越大。 这类似于人类掌握大量工具的难度增加。添加工具还意味着增加工具描述,这可能无法适应模型的上下文。
与构建 AI 应用程序时的许多其他决策一样,工具选择也需要实验和分析。以下是一些可以帮助你做出决定的事项:
- 比较 Agent 在不同工具集下的表现;
- 进行消融研究,看看如果移除某种工具,Agent 的性能会下降多少。 如果可以在不降低性能的情况下移除工具,就移除它;
- 寻找 Agent 经常出错的工具。 如果某个工具对 Agent 来说太难使用,例如,大量的提示甚至微调都无法让模型学会使用它,那就更换工具;
- 绘制工具调用分布图,以查看哪些工具使用最多,哪些工具使用最少;
不同模型和任务表现出不同的工具使用模式。不同的任务需要不同的工具。ScienceQA(科学问答任务)比 TabMWP(表格数学问题解决任务)更依赖于知识检索工具。不同模型有不同的工具偏好。例如,GPT-4 似乎比 ChatGPT 选择了更广泛的工具集。ChatGPT 似乎更倾向于图像描述,而 GPT-4 则更倾向于知识检索。
规划是困难的,且可能以多种方式失败。最常见的规划失败模式是工具使用失败。Agent 可能会生成包含以下一个或多个错误的计划。
-
无效工具
例如,它生成了一个包含bing_search
的计划,而该工具不在工具清单中。 -
有效工具,无效参数。
例如,它调用lbs_to_kg
时传入了两个参数,但该函数仅需要一个参数lbs
。 -
有效工具,参数值不正确。
例如,它调用lbs_to_kg with
一个参数lbs
,但在应该使用 120 时却使用了值 100 来表示磅。
另一种规划失败的模式是目标失败:Agent 未能实现目标。这可能是因为计划未能解决任务,或者虽然解决了任务但未遵循约束条件。举例来说,假设你要求模型规划一次从旧金山到印度的两周旅行,预算为 5000 美元。Agent 可能会规划一次从旧金山到越南的旅行,或者为你规划一次从旧金山到印度的两周旅行,但费用远超预算。
在 Agent 评估中,一个常被忽视的常见约束是时间。在许多情况下,Agent 完成任务所需的时间并不那么重要,因为可以将任务分配给 Agent,只需在完成后检查即可。然而,在许多情况下,随着时间的推移,Agnet 的作用会降低。例如,如果你要求 Agent 准备一份资助提案,而 Agent 在资助截止日期后才完成,那么 Agent 的帮助就不大了。
Agent 可能使用正确的工具生成一个有效的计划来完成任务,但可能效率不高。以下是可能希望跟踪以评估 Agent 效率的几个方面:
- Agent 平均需要多少步骤来完成一个任务?
- Agent 完成任务的平均成本是多少?
- 每个操作通常需要多长时间?是否有特别耗时或昂贵的操作?
可以将这些指标与你的基线进行比较,基线可以是另一个 Agent 或人类。在将 AI Agent 与人类进行比较时,请记住人类和 AI 的操作模式截然不同,因此对人类来说高效的行为可能对 AI 来说是低效的,反之亦然。例如,访问 100 个网页对于一次只能访问一个页面的人类来说可能是低效的,但对于可以同时访问所有网页的 AI Agent 来说则是轻而易举的。