Transformers Agent 代理

Transformers Agent 是一个实验性的 API,随时可能更改。由于 API 或底层模型可能发生变化,代理返回的结果可能会有所不同。

Transformers 版本为 v4.29.0,构建在“工具”和“代理”概念的基础上。您可以在 此 Colab 中进行尝试。

简而言之,它在 Transformers 框架之上提供了自然语言 API:我们定义了一组经过精选的工具,并设计了一个代理来解释自然语言并使用这些工具。它具有可扩展性的设计;我们精选了一些相关工具,但我们将向您展示如何轻松地扩展系统以使用社区开发的任何工具。

让我们从一些使用这个新 API 可以实现的例子开始。当涉及多模态任务时,它特别强大,所以让我们试试用它来生成图片和朗读文本。

agent.run("Caption the following image", image=image)
Input Output
A beaver is swimming in the water (一只海狸正在水中游泳)

agent.run("Read the following text out loud", text=text)
Input Output
A beaver is swimming in the water

agent.run(
    "In the following `document`, where will the TRRF Scientific Advisory Council Meeting take place?",
    document=document,
)
Input Output
ballroom foyer

快速入门

在使用 agent.run 之前,您需要实例化一个代理,也就是一个大型语言模型 (LLM)。我们提供了对 OpenAI 模型以及来自 BigCode 和 OpenAssistant 的开源替代方案的支持。OpenAI 模型的性能更好(但需要您拥有 OpenAI API 密钥,所以不能免费使用);Hugging Face 目前为 BigCode 和 OpenAssistant 模型提供了免费访问端点的服务。

首先,请安装 agents 附加包以安装所有默认依赖项。

pip install transformers[agents]

要使用 OpenAI 模型,请在安装了 openai 依赖项后实例化 OpenAiAgent

pip install openai
from transformers import OpenAiAgent

agent = OpenAiAgent(model="text-davinci-003", api_key="<your_api_key>")

要使用 BigCode 或 OpenAssistant,首先登录以访问推理 API:

from huggingface_hub import login

login("<YOUR_TOKEN>")

然后,实例化代理:

from transformers import HfAgent

# Starcoder
agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder")
# StarcoderBase
# agent = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoderbase")
# OpenAssistant
# agent = HfAgent(url_endpoint="https://api-inference.huggingface.co/models/OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5")

这里使用的是 Hugging Face 提供的推理 API(目前是免费的)。如果您有自己的模型推理端点(或其他模型),可以将上面的 URL 替换为您的 URL 端点。

StarCoder 和 OpenAssistant 是免费使用的,在处理简单任务时表现出色。然而,当处理更复杂的提示时,检查点的表现不够理想。如果您遇到这样的问题,我们建议尝试 OpenAI 模型,虽然遗憾的是它不是开源的,但在当前时间点它的性能更好。

现在您已经准备完毕!让我们深入了解您现在可以使用的两个 API。

单次执行(run)

使用代理的 run() 方法时,是使用单次执行的方法:

agent.run("Draw me a picture of rivers and lakes.")

它会自动选择适合您要执行的任务的工具(或工具),并以适当的方式运行它们。它可以在同一指令中执行一个或多个任务(尽管您的指令越复杂,代理失败的可能性就越大)。

agent.run("Draw me a picture of the sea then transform the picture to add an island")

每个 run() 操作都是独立的,因此您可以连续运行多次,并执行不同的任务。

请注意,您的 agent 只是一个大型语言模型,因此提示中的小变化可能会产生完全不同的结果。重要的是要尽可能清楚地解释您想要执行的任务。我们在 此处 更详细地介绍了如何编写良好的提示。

如果您希望在执行之间保留状态或传递非文本对象给代理,可以通过指定代理要使用的变量来实现。例如,您可以生成第一张河流和湖泊的图片,并要求模型在此基础上添加一个岛屿,做法如下:

picture = agent.run("Generate a picture of rivers and lakes.")
updated_picture = agent.run("Transform the image in `picture` to add an island to it.", picture=picture)

当模型无法理解您的请求并混合使用工具时,这可能很有帮助。例如:

agent.run("Draw me the picture of a capybara swimming in the sea")

在这种情况下,模型可以有两种解释方式:

  • 使 text-to-image 生成一只在海中游泳的水豚

  • 或者,先生成水豚,然后使用 image-transformation 工具使其在海中游泳

如果您想强制使用第一种解释,可以通过将提示作为参数传递给它来实现:

agent.run("Draw me a picture of the `prompt`", prompt="a capybara swimming in the sea")

基于对话的执行(chat)

代理还可以使用 chat() 方法进行基于对话的方法:

agent.chat("Generate a picture of rivers and lakes")
agent.chat("Transform the picture so that there is a rock in there")

当您想要在指令之间保持状态时,这是一种有趣的方法。它更适用于实验,但通常比复杂指令更擅长处理单个指令(run() 方法更擅长处理复杂指令)。

如果您希望传递非文本类型或特定提示,此方法也可以接受参数。

⚠️ 远程执行

针对演示目的和以便在所有设置中使用,我们为代理程序提供了一些默认工具的远程执行程序。这些工具使用 推理端点 创建。如果想了解如何自行设置远程执行程序工具,请阅读 自定义工具指南

要使用远程工具运行,请只需将 remote=True 参数传递给 run()chat()

例如,以下命令可在任何设备上高效运行,无需大量 RAM 或 GPU:

agent.run("Draw me a picture of rivers and lakes", remote=True)

对于 chat(),同样适用:

agent.chat("Draw me a picture of rivers and lakes", remote=True)

这里发生了什么?什么是工具和代理?

代理

“代理” 是一个大型语言模型,我们这里通过对其进行提示,使其具备访问特定工具集的能力。

大语言模型擅长生成小代码片段,因此此 API 利用这一点,通过提示让大语言模型生成一小段代码,以便使用一组工具执行特定任务。这个提示由您给代理程序的任务和工具描述组成。这样,代理程序就能获得正在使用的工具的具体说明,特别是它们的输入和输出,从而生成相关代码。

工具

工具非常简单:它们是一个带有名称和描述的单个函数。然后,我们使用这些工具的描述来提示代理程序。通过提示,我们向代理程序展示了如何使用工具来执行查询中要求的任务。

这里使用的是全新的工具,而不是管道(pipelines),因为使用原子工具,代理程序可以生成更好的代码。管道是进行了更多的重构,通常将多个任务组合在一起。工具专注于一个非常简单的任务。

代码执行?!

然后,我们使用我们的小型 Python 解释器执行此代码,并传递您的工具所需要的输入。我们听到你在后面尖叫”任意代码执行!“,但是让我们解释一下为什么不是那么回事。

只能调用提供的工具和 print 函数,因此已经对可以执行的操作进行了限制。如果仅限于 Hugging Face 工具,那就应该是安全的。

此外,我们不允许任何属性查找或导入(对于传递输入/输出给一小组函数来说,这应该是不需要的),因此所有最明显的攻击(而且您需要提示大语言模型输出它们)都不应该成为问题。如果您想尽可能保守,可以以 return_code=True 的附加参数来执行 run() 方法,这样代理程序就会返回要执行的代码,您可以决定是否执行。

如果有任何意图执行非法操作的代码行或者有任何普通的 Python 错误,导致由代理程序生成的代码出错,执行过程会停止。

精选的工具集

我们确定出对这些代理程序非常有用的一组工具。以下是我们已集成到 transformers 中的工具的最新列表:

  • 文档问答:给定一个图像格式的文档(如 PDF),回答关于该文档的问题( Donut )。
  • 文本问答:给定一段长文本和一个问题,在文本中回答问题( Flan-T5 )。
  • 无条件的图像字幕生成:为图像添加字幕!( BLIP )。
  • 图像问答:给定一张图像,回答该图像上的问题( VILT )。
  • 图像分割:给定一张图像和一个提示,输出该提示的分割掩码( CLIPSeg )。
  • 语音转文字:给定一个人说话的音频记录,将语音转录为文字( Whisper )。
  • 文字转语音:将文本转换为语音( SpeechT5 )。
  • 零样本文本分类:给定一段文本和一系列标签,识别该文本最相关的标签( BART )。
  • 文本摘要:将长文本概括为一句或几句话( BART )。
  • 翻译:将文本翻译成指定语言( NLLB )。

这些工具已在 transformers 中进行了集成,也可以手动使用,例如:

from transformers import load_tool

tool = load_tool("text-to-speech")
audio = tool("This is a text to speech tool")

自定义工具

尽管我们确定了一组精选的工具,但我们坚信该实现提供的主要价值是能够快速创建和共享自定义工具。

通过将工具的代码推送到 Hugging Face Space 或模型仓库,然后您就能够直接与代理程序一起使用该工具了。我们在 huggingface-tools 组织 上添加了一些与 Transformers 无关的工具,例如:

  • 文本下载器:从 Web URL 下载文本。
  • 文本转图像:根据提示生成图像,利用稳定的扩散方法。
  • 图像转换:根据初始图像和提示修改图像,利用指导的 pix2pix 类型的稳定扩散方法。
  • 文本转视频:根据提示生成小视频,利用 damo-vilab。

我们从一开始就使用的文本转图像工具是一个远程工具,部署在 huggingface-tools/text-to-image !我们将继续在该组织和其他组织中发布此类工具,以进一步增强该实现。

代理程序默认可以访问部署在 huggingface-tools 上的工具。我们在 下一指南(custom_tools) 中解释如何编写和共享您自己的工具,以及如何利用 Hub 上驻留的任何自定义工具。

代码生成

到目前为止,我们只展示了如何使用代理程序代替您执行操作。但是,代理程序只是生成代码,然后我们使用非常受限制的 Python 解释器执行该代码。如果您希望在不同的环境中使用生成的代码,可以提示代理程序返回代码,并包含工具定义和准确的导入。

例如,以下指令:

agent.run("Draw me a picture of rivers and lakes", return_code=True)

将返回以下代码:

from transformers import load_tool

image_generator = load_tool("huggingface-tools/text-to-image")

image = image_generator(prompt="rivers and lakes")

然后,您可以修改并自行执行该代码。