AutoGen 作为一个强大的多智能体对话框架,正在改变大模型应用开发的格局。它允许开发者通过编排多个智能体之间的对话,以协作的方式解决复杂任务。AutoGen集成了LLM(大型语言模型)、工具以及人类输入,实现了高度灵活和可定制化的智能体交互模式。本文将深入探讨AutoGen的核心概念、关键特性和应用场景,帮助开发者更好地理解和利用这一框架,构建更智能、更高效的大模型应用。

智能体(Agent)的核心概念

AutoGen的核心构建块是智能体。在AutoGen中,智能体通常是ConversableAgent的实例,这个类可以根据不同的需求进行定制。每个智能体都可以配置不同的组件,例如:

  • LLM配置(llm_config):指定智能体使用的LLM模型,例如“gpt-4”,以及API密钥和其他配置参数。
  • 代码执行器(code executor):允许智能体执行生成的代码,从而完成计算、数据分析等任务。
  • 工具执行器(tool executor):允许智能体调用预定义的函数或工具,例如计算器、数据库API等。
  • 人机交互模块(human-in-the-loop module):允许智能体在需要时征求人类的反馈或干预。

通过灵活配置这些组件,开发者可以创建各种类型的智能体,例如:

  • 只具备LLM能力的智能体,用于生成文本、回答问题等。
  • 具备代码执行能力的智能体,用于解决编程问题、进行数据分析等。
  • 能够调用外部工具的智能体,用于访问外部知识、执行特定操作等。
  • 需要人类参与的智能体,用于处理需要人工判断或决策的任务。

例如,你可以创建一个“学生”智能体和一个“老师”智能体,两者都使用GPT-4模型,让它们互相提问和回答问题,从而模拟教学场景。这个例子展示了如何通过定义智能体的角色和系统消息来定制它们的行为。

多智能体对话框架的核心优势

AutoGen的多智能体对话框架的核心优势在于它能够简化LLM的协调工作,并克服单个模型的局限性。通过将复杂的任务分解为多个子任务,并分配给不同的智能体协同完成,AutoGen可以有效地利用多个LLM的优势,提高任务完成的质量和效率。

任务分解多智能体对话框架的核心策略。例如,要开发一个自动生成营销方案的应用,可以将其分解为以下几个子任务:

  1. 市场调研:一个智能体负责收集目标市场的信息,包括用户画像、竞争对手分析、行业趋势等。
  2. 创意生成:另一个智能体负责根据市场调研的结果,生成多个营销方案的创意。
  3. 方案评估:第三个智能体负责评估各个营销方案的创意,并选择最佳方案。
  4. 文案撰写:第四个智能体负责撰写营销方案的文案,包括广告语、推广内容等。
  5. 方案优化:第五个智能体负责根据实际效果,优化营销方案。

通过将任务分解为多个子任务,并分配给不同的智能体,可以更有效地利用LLM的能力,提高营销方案的质量和效果。

对话终止机制:保障对话的安全与可控

多智能体对话工作流中,定义对话的终止条件至关重要。AutoGen提供了两种主要的终止对话的方式:

  1. initiate_chat参数:可以通过设置max_turns参数限制对话的总轮数,或者通过stop_conversation_func参数指定一个函数,当满足特定条件时,该函数返回True,从而终止对话。
  2. 智能体自身的配置:可以配置智能体自身来发出终止信号。例如,可以为UserProxyAgent设置is_termination_msg函数,当收到包含“TERMINATE”的消息时,该函数返回True,从而终止对话。还可以设置max_consecutive_auto_reply参数,限制智能体在没有人工输入的情况下自动回复的次数。

这些终止机制可以有效地防止对话无限期地进行下去,从而保障对话的安全和资源控制。例如,你可以设置max_turns=2来限制智能体之间的对话轮数,防止对话过于冗长。

以下代码示例演示了如何使用max_turns参数来限制对话的轮数:

import os
from autogen import ConversableAgent

cathy = ConversableAgent(
    "cathy",
    system_message="Your name is Cathy and you are a part of a duo of comedians.",
    llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.9, "api_key": os.environ.get("OPENAI_API_KEY")}]},
    human_input_mode="NEVER",  # Never ask for human input.
)

joe = ConversableAgent(
    "joe",
    system_message="Your name is Joe and you are a part of a duo of comedians.",
    llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.7, "api_key": os.environ.get("OPENAI_API_KEY")}]},
    human_input_mode="NEVER",  # Never ask for human input.
)

result = joe.initiate_chat(cathy, message="Cathy, tell me a joke.", max_turns=2)

人机交互:灵活的人工干预模式

AutoGen支持人机交互,允许智能体在需要时征求人类的反馈。每个智能体都有一个human_input_mode设置,可以设置为以下三种模式:

  • NEVER智能体完全自主运行,不需要人工输入。
  • TERMINATE智能体在需要时向人类请求帮助,如果人类发出终止信号,则停止运行。
  • ALWAYS智能体总是将控制权交给人类。

TERMINATE模式表示“请求人类继续或停止”,而ALWAYS模式表示“立即将控制权交给人类”。这种特性允许开发者根据需要灵活地混合自动LLM响应和人工监督。

例如,你可以将UserProxyAgenthuman_input_mode设置为TERMINATE,使其在生成回复之前,先向用户征求意见。这样可以确保智能体的输出符合用户的期望,并及时纠正错误。

代码执行器:赋予智能体编程能力

AutoGen可以自动执行在对话过程中生成的代码,从而使智能体能够解决编程任务或使用计算工具。它提供了两种主要的执行器类型:

  • 命令行代码执行器(LocalCommandLineCodeExecutor):在shell中运行代码,可以选择使用Docker。
  • Jupyter执行器(Jupyter executor):在Jupyter内核中运行代码。

例如,LocalCommandLineCodeExecutor会将每个代码块写入一个文件,并在本地执行它,然后捕获输出和错误。开发者可以配置可用的执行器(本地或基于Docker)及其特性。

智能体输出一个代码块时(使用Markdown三反引号),UserProxyAgent默认会将它发送到配置的执行器执行。需要注意的是,运行LLM生成的代码可能存在风险,因此AutoGen包含了警告,并允许开发者使用code_execution_config=False禁用代码执行。

以下代码示例演示了如何创建一个使用本地命令行代码执行器的智能体

import tempfile
from autogen import ConversableAgent
from autogen.coding import LocalCommandLineCodeExecutor

# Create a temporary directory to store the code files.
temp_dir = tempfile.TemporaryDirectory()

# Create a local command line code executor.
executor = LocalCommandLineCodeExecutor(
    timeout=10,  # Timeout for each code execution in seconds.
    work_dir=temp_dir.name,  # Use the temporary directory to store the code files.
)

# Create an agent with code executor configuration.
code_executor_agent = ConversableAgent(
    "code_executor_agent",
    llm_config=False,  # Turn off LLM for this agent.
    code_execution_config={"executor": executor},  # Use the local command line code executor.
    human_input_mode="ALWAYS",  # Always take human input for this agent for safety.
)

工具的使用:安全可控的智能体行为

AutoGen的工具使用特性允许智能体调用预定义的函数或工具,而不是编写任意代码。工具本质上是Python函数(带有类型注解),开发者可以将它们注册到智能体。在对话中,智能体可以决定调用一个工具(例如,计算器或数据库API),并接收结果。

这种方式可以约束智能体的行为,并允许开发者控制其行动。开发者可以定义一个工具(例如,def calculator(x: int, y: int) -> int),然后注册它:一个智能体必须被允许调用该工具(通过register_for_llm),而另一个智能体(或同一个智能体)必须能够执行它(通过register_for_execution)。

例如,智能体可以调用计算器工具来加数字,而不是试图“思考”答案。由于开发者控制该函数,因此可以安全地管理智能体的行动。需要注意的是,工具目前与OpenAI兼容的函数调用一起工作,因此模型必须支持该API。

多种对话模式:灵活应对复杂任务

AutoGen支持多种多智能体对话模式,而不仅仅是简单的双智能体聊天。这些模式包括:

  • 双智能体聊天(Pair Chat):最基本的模式,其中两个智能体交换消息。一个智能体调用另一个智能体initiate_chat方法;发起者发送初始消息,然后它们轮流进行对话。在对话结束后,可以选择使用摘要器将对话内容合并到ChatResult中。
  • 顺序聊天(Sequential Chat):一系列双智能体聊天,其中一个聊天的输出作为下一个聊天的输入。这对于多步骤工作流非常有用。例如,可以先与一个“规划者”智能体聊天,将任务分解为子任务,然后依次与另一个智能体聊天,以执行每个子任务。
  • 群聊(Group Chat):多个智能体之间的对话。AutoGen提供了GroupChat类和GroupChatManager来协调多智能体聊天。所有智能体都将消息提交给中央管理器,然后由管理器广播它们。开发者可以使用诸如轮询、随机、手动(人类选择下一个发言者)或“自动”(LLM选择下一个发言者)等策略来控制轮流发言。
  • 嵌套聊天(Nested Chat):可以在另一个对话中嵌入一个完整的对话。可以将一个智能体配置为在被触发时,在一组子智能体之间运行内部聊天。这允许将一个子问题打包为一个嵌套的工作流。例如,一个助手可以根据需要启动专家之间的一个简短的内部对话,然后使用他们的联合结果来继续。

这些对话模式为设计LLM工作流提供了极大的灵活性。AutoGen的文档通过示例说明了每种模式:从简单的问答(双智能体聊天)到多轮辩论(群聊)和递归规划(嵌套聊天)。

OpenAI助手:集成OpenAI的强大工具

OpenAI助手部分介绍了GPTAssistantAgent,它使用OpenAI Assistant API。该智能体可以将OpenAI的专用工具(如代码解释器和文件搜索)集成到AutoGen中。它可以持久地管理对话线程,并可以自动处理函数调用。GPTAssistantAgent的关键特性包括“多工具掌握”(使用内置工具和自定义函数)和“简化的对话管理”(自动处理消息历史记录)。

例如,可以将智能体配置为使用OpenAI的代码解释器工具,从而允许智能体编写Python代码,并通过OpenAI的环境安全地执行它。该指南展示了创建GPTAssistantAgent和启用工具的代码示例,演示了这种专用智能体如何以最少的样板简化复杂应用程序的构建。

处理长上下文:保持对话的效率与相关性

过长的聊天记录可能会超出LLM令牌限制或变得不相关,因此AutoGen提供了转换来预处理消息。

特别是,TransformMessages特性允许开发者插入关于传入上下文的规则。例如,MessageHistoryLimiter转换只保留最后N条消息,删除较旧的消息,以保持在令牌预算内。这确保了效率和相关性:模型会看到最新的对话上下文。其他转换可以将单个消息截断为最大长度,或删除很少有用的轮次。该指南包含说明这些转换的代码示例。

总之,处理长上下文部分教开发者如何自动修剪聊天记录,以便LLM在不丢失关键信息的情况下在令牌约束下运行。

LLM缓存:节省成本与提高效率

AutoGen支持缓存LLM API请求。如果一个智能体两次发出完全相同的请求,缓存可以返回之前的响应,而不是为新的API调用付费。这在开发或批量实验期间对于可重复性和节省成本特别有用。AutoGen的缓存模块是autogen.cache。例如,将调用包装在Cache.disk中可以持久地存储结果。在实践中,开发者可能会缓存聊天结果或单次调用完成。文档指出,使用种子或密钥启用缓存允许开发者重新运行示例并获得一致的输出,或跳过已知的昂贵调用。

智能体可观测性:深入了解智能体行为

可观测性特性在智能体可观测性部分中介绍。AutoGen提供了广泛的日志记录和监视挂钩,因此开发者可以跟踪智能体所做的事情。内置日志记录会自动记录每条消息、工具调用和代码执行,开发者可以通过提供程序与外部监视工具集成。例如,开发者可以插入Azure Application Insights或第三方仪表板来收集指标(例如,使用的LLM令牌数量、错误、聊天持续时间)。

这有助于调试复杂的智能体工作流。该指南解释了日志记录配置和使用AgentOps或其他可观测性平台的示例。关键在于,AutoGen不会作为一个黑盒运行;开发者可以通过日志和跟踪器检查多智能体对话的每个步骤。

LLM配置:灵活选择LLM模型

LLM配置部分详细介绍了如何为每个智能体指定模型。正如在引言中提到的,每个智能体都接受一个带有“config_list”键的llm_config字典。config_list是模型配置的列表。每个条目都是一个字典,至少有一个模型名称(例如,“gpt-4”或Azure部署名称),如果需要,还有api_keybase_url和其他参数,所有有效的键(例如,api_type: "azure"、Azure的api_version)。这允许智能体交替查询多个端点或模型。例如,开发者可以在config_list中列出GPT-4和GPT-3.5,以便智能体在其中一个模型失败时可以回退。该指南提供了示例,展示了如何为不同的模型类型设置llm_config。简而言之,本节解释了llm_config的模式以及如何使用它来控制智能体使用的LLM。

提示与推理:提升智能体的认知能力

AutoGen鼓励使用高级LLM提示技术。提示与推理部分介绍了诸如思维链(ReAct)和自我反思之类的策略。例如,文档展示了如何将智能体包装在一个循环中,要求它批判自己的答案(LLM反思)。他们演示了使用嵌套聊天来实现一个两步过程:一个智能体生成答案,另一个智能体(或反思模式下的同一智能体)审查它。AutoGen为ReAct(智能体使用工具进行规划)、反思(自我批判)和其他多轮推理模式提供了笔记本示例。重要的信息是,开发者可以使用AutoGen的嵌套聊天支持和提示工程接口轻松地实现这些众所周知的LLM方法。

检索增强生成:融合外部知识

检索增强生成(RAG)部分展示了如何将LLM与外部知识相结合。RAG将相关文档或数据提供给智能体,以改进答案。例如,AutoGen提供了一个RetrieveUserProxyAgent,给定一个用户查询,可以搜索文档数据库或嵌入,并将结果包含在提示中。

这允许智能体使用最新的或特定于领域的信息来回答问题。该指南提供了使用各种向量存储(例如,chromadb、PGVector)以及配置分块和嵌入模型的代码示例。总之,AutoGen中的检索增强是通过在智能体聊天之前或期间挂钩检索步骤来实现的,从而使用外部知识增强LLM的输出。

任务分解:化繁为简的策略

任务分解页面演示了如何使用AutoGen将复杂的任务分解为更简单的步骤。它介绍了以下方法:1)使用首先概述子任务的规划器智能体(作为工具函数),然后让助手遵循该计划;2)采用群聊或顺序聊天,其中一个智能体的输出作为下一个智能体的输入;以及3)嵌套聊天,其中智能体生成一个子团队来处理部分任务。例如,显示的一种方法是双智能体聊天,其中一个(规划者)创建逐步计划,然后由助手智能体执行(包括运行代码)。另一种方法是使用嵌套聊天或多个智能体并行处理问题的每个部分。

总结与展望

AutoGen作为一款强大的多智能体对话框架,为大模型应用开发带来了革命性的改变。通过灵活的智能体配置、多种对话模式、强大的工具集成以及丰富的可观测性特性,AutoGen赋能开发者构建更智能、更高效、更可控的大模型应用。随着大模型技术的不断发展,AutoGen有望在更多领域发挥重要作用,推动人工智能应用的创新与普及。AutoGen的多智能体对话框架,将成为未来AI应用开发的重要基石,助力开发者在LLM的时代创造更多可能性。