规划器的视觉输入
简介
我们已为TaskWeaver中的Planner角色支持视觉输入功能。 Planner角色负责生成任务的高层计划。 视觉输入是一种包含图像的新型输入方式。 当任务需要视觉理解时,该功能非常实用。
我们已为TaskWeaver中的Planner角色支持视觉输入功能。 Planner角色负责生成任务的高层计划。 视觉输入是一种包含图像的新型输入方式。 当任务需要视觉理解时,该功能非常实用。
智能体能够监听用户请求、理解上下文、制定计划、采取行动、观察结果并响应用户。其行为由推理过程驱动,这是智能体智能的核心。
我们已在Experience中介绍了experience模块的设计动机,并在Handcrafted Experience中讲解了如何创建手工定制经验。本篇博客将深入探讨经验模块中关于经验选择的进阶话题。
TaskWeaver中的每个角色都可以配置自己的经验目录,这可以通过在项目配置文件中设置role_name.experience_dir字段来实现。对于Planner和CodeInterpreter角色,您可以分别通过设置planner.experience_dir和code_generator.experience_dir字段来配置经验目录。默认的经验目录是项目目录中的experience。
角色名称默认是角色实现文件的文件名(不含扩展名),除非你在实现文件中通过调用_set_name来指定角色名称。
通过为不同角色配置不同的经验目录,
您可以以静态方式为不同角色提供不同的体验。
以Planner角色为例,您可以使用以下项目配置文件
来启用Planner角色的经验选择功能。
{
"planner.use_experience": true,
"planner.experience_dir": "planner_exp_dir"
}
本博文介绍的功能可能会导致与之前版本的TaskWeaver存在兼容性问题,如果您已为规划器和代码解释器自定义了示例。通过将示例更改为新架构,可以轻松解决此问题。更多详情请参阅我们在TaskWeaver中如何实现约束生成部分。
我们注意到许多反馈问题抱怨在本地部署较小规模语言模型(如7B或13B参数)时运行TaskWeaver存在困难。经过问题排查,发现主要原因是这些模型无法按照提示词中的格式要求生成响应。例如,我们发现规划器的响应中缺少必需的send_to字段,而这个字段原本用于确定消息接收方。
过去,我们尝试通过在提示中添加更多示例来解决这个问题,但效果并不理想,尤其是对这些相对较小的模型而言。另一个想法是要求模型重新生成响应,如果它没有遵循格式的话。我们在提示中包含格式错误,以帮助模型理解错误并纠正它。然而,这种方法效果也不佳。
前提条件:为了更好地理解插件概念及其开发流程,请参考简介和插件开发页面。
在TaskWeaver中,插件是扩展智能体功能的核心组件。
具体来说,插件是一段封装在类中的代码,可以被智能体在生成的代码片段中作为函数调用。
以下是一个生成n个随机数的简单插件示例:
from taskweaver.plugin import Plugin, register_plugin
@register_plugin
class RandomGenerator(Plugin):
def __call__(self, n: int):
import random
return [random.randint(1, 100) for _ in range(n)]
在这个例子中,RandomGenerator类继承了Plugin类并实现了__call__方法,这意味着它可以像函数一样被调用。那么这个插件的函数签名会是什么样呢?它是在关联的YAML文件中定义的。例如,RandomGenerator插件的YAML文件如下所示:
name: random_generator
enabled: true
required: true
description: >-
This plugin generates n random numbers between 1 and 100.
examples: |-
result = random_generator(n=5)
parameters:
- name: n
type: int
required: true
description: >-
The number of random numbers to generate.
returns:
- name: result
type: list
description: >-
The list of random numbers.
YAML文件定义了插件的名称、描述、参数和返回值。
当大语言模型生成代码片段时,它会使用YAML文件中的信息来生成函数签名。
我们没有检查Python实现中的函数签名与YAML文件之间是否存在差异。
因此,保持它们的一致性非常重要。
examples字段用于向大语言模型提供插件使用示例。
评估大型语言模型智能体的性能并非易事。 现有的评估方法通常将LLM智能体视为一个将输入数据映射到输出数据的函数。 如果要评估智能体在多步骤任务中的表现,评估过程就像多次调用一个有状态函数的链条。 为了判断智能体的输出,通常会将其与标准答案或参考输出进行比较。 由于智能体的输出是自然语言,评估通常通过匹配输出中的关键词或短语与标准答案来完成。
这种评估方法由于其刚性本质存在局限性。 有时很难使用关键词匹配来评估智能体的输出,特别是当输出内容冗长复杂时。 例如,如果答案是日期或数字,该评估方法可能无法处理不同的格式。 此外,评估方法应该能更接近人类行为,能够理解上下文和输出的含义。 例如,当要求不同智能体执行相同任务时,它们的行为可能不同,但仍能产生正确输出。
We frame TaskWeaver as a code-first agent framework. The term "code-first" means that the agent is designed to convert the user's request into one or multiple runnable code snippets and then execute them to generate the response. The philosophy behind this design is to consider programming languages as the de facto language for communication in cyber-physical systems, just like the natural language for human communication. Therefore, TaskWeaver translates the user's request in natural language into programming languages, which can be executed by the system to perform the desired tasks.
在这种设计下,当开发者需要扩展智能体的能力时,他们可以编写一个新的插件。 插件是一个封装在类中的代码片段,可以被智能体在生成的代码片段中作为函数调用。 让我们看一个例子:智能体被要求加载一个CSV文件并对数据进行异常检测。 智能体的工作流程如下图所示。用变量表示待处理数据,用代码片段表示这项任务,这种表达方式非常自然。