微软AutoGen介绍:Agents与AgentChat代理合作并开始使用

介绍

大家好,今天给大家分享的内容是微软AutoGen框架的核心功能Agents。今天分享的内容比较多,请大家耐心看完,我相信大家肯定会有所收获,那么我们直接进入正题。

Agents

AutoGenAgentChat提供了一组预设智能体,每个智能体对消息的响应方式各不相同。所有智能体都具有以下属性和方法:

  • name:智能体的唯一名称。
  • description:用文本对智能体(agent)进行的描述。
  • on_messages():向智能体发送一系列ChatMessage,以获取一个Response。需要注意的是,智能体应具有状态记忆,并且该方法应使用新消息调用,而非完整的消息历史记录。
  • on_messages_stream():其功能与on_messages()相同,但返回一个迭代器,该迭代器包含AgentEventChatMessage类型的元素,且最后一个元素为Response
  • on_reset():智能体重置为其初始状态。
  • run()和run_stream():这是一些便捷方法,它们分别调用on_messages()on_messages_stream(),但提供与Teams相同的接口 。

AssistantAgent

AssistantAgent是一个使用语言模型并具有使用工具能力的内置智能体

代码演示

from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_agentchat.ui import Console
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClient


# 定义一种用于在网络上搜索信息的工具。
async def web_search(query: str) -> str:
    """在网上查找信息"""
    return "AutoGen is a programming framework for building multi-agent applications."


# 创建一个使用OpenAI的GPT-3.5-Turbo模型的智能体。
model_client = OpenAIChatCompletionClient(
    model="gpt-3.5-turbo",
    # api_key="你的OPENAI_API_KEY",
)
agent = AssistantAgent(
    name="assistant",
    model_client=model_client,
    tools=[web_search],
    system_message="Use tools to solve tasks.",
)

获取响应

我们可以使用该on_messages()方法来获取智能体对给定消息的响应。

代码演示

async def assistant_run() -> None:
    response = await agent.on_messages(
        [TextMessage(content="Find information on AutoGen", source="user")],
        cancellation_token=CancellationToken(),
    )
    print(response.inner_messages)
    print(response.chat_message)

asyncio.run(assistant_run())

完整代码

import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClient


# 定义一种用于在网络上搜索信息的工具。
async def web_search(query: str) -> str:
    """在网上查找信息"""
    return "AutoGen is a programming framework for building multi-agent applications."


# 创建一个使用OpenAI的GPT-3.5-Turbo模型的智能体。
model_client = OpenAIChatCompletionClient(
    model="gpt-3.5-turbo",
    # api_key="你的OPENAI_API_KEY",
)
agent = AssistantAgent(
    name="assistant",
    model_client=model_client,
    tools=[web_search],
    system_message="Use tools to solve tasks.",
)


async def assistant_run() -> None:
    response = await agent.on_messages(
        [TextMessage(content="Find information on AutoGen", source="user")],
        cancellation_token=CancellationToken(),
    )
    print(response.inner_messages)
    print(response.chat_message)

asyncio.run(assistant_run())

运行结果

[ToolCallRequestEvent(source='assistant', models_usage=RequestUsage(prompt_tokens=65, completion_tokens=15), content=[FunctionCall(id='call_hqVC7UJUPhKaiJwgVKkg66ak', arguments='{"query":"AutoGen"}', name='web_search')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='assistant', models_usage=None, content=[FunctionExecutionResult(content='AutoGen is a programming framework for building multi-agent applications.', call_id='call_hqVC7UJUPhKaiJwgVKkg66ak')], type='ToolCallExecutionEvent')]
source='assistant' models_usage=None content='AutoGen is a programming framework for building multi-agent applications.' type='ToolCallSummaryMessage'

进程已结束,退出代码为 0

该方法的调用on_messages()返回一个Response包含智能体最终响应的属性chat_message,以及inner_messages属性中的内部消息列表,其中存储了导致最终响应的智能体的“思维过程”。

我们也可以调用run()方法,这是一个用于调用on_messages()方法的便捷方法。它遵循与Teams相同的接口,并返回一个TaskResult对象。

流式消息

我们还可以使用该方法流式传输智能体生成的每条消息on_messages_stream(),并使用Console在消息出现在控制台上时将其打印出来。

代码演示

async def assistant_run_stream() -> None:
    # 选项 1:从流中读取每条消息(如前一个示例所示)。
    # async for message in agent.on_messages_stream(
    #     [TextMessage(content="Find information on AutoGen", source="user")],
    #     cancellation_token=CancellationToken(),
    # ):print(message)

    # 选项 2:使用控制台在所有消息出现时将其打印出来。
    await Console(
        agent.on_messages_stream(
            [TextMessage(content="Find information on AutoGen", source="user")],
            cancellation_token=CancellationToken(),
        )
    )


asyncio.run(assistant_run_stream())

完整代码

import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_agentchat.ui import Console
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClient


# 定义一种用于在网络上搜索信息的工具。
async def web_search(query: str) -> str:
    """在网上查找信息"""
    return "AutoGen is a programming framework for building multi-agent applications."


# 创建一个使用OpenAI的GPT-3.5-Turbo模型的智能体。
model_client = OpenAIChatCompletionClient(
    model="gpt-3.5-turbo",
    # api_key="你的OPENAI_API_KEY",
)

agent = AssistantAgent(
    name="assistant",
    model_client=model_client,
    tools=[web_search],
    system_message="Use tools to solve tasks.",
)


async def assistant_run_stream() -> None:
    # 选项 1:从流中读取每条消息(如前一个示例所示)。
    # async for message in agent.on_messages_stream(
    #     [TextMessage(content="Find information on AutoGen", source="user")],
    #     cancellation_token=CancellationToken(),
    # ):print(message)

    # 选项 2:使用控制台在所有消息出现时将其打印出来。
    await Console(
        agent.on_messages_stream(
            [TextMessage(content="Find information on AutoGen", source="user")],
            cancellation_token=CancellationToken(),
        )
    )


asyncio.run(assistant_run_stream())

运行结果

---------- assistant ----------
[FunctionCall(id='call_fSp5iTGVm2FKw5NIvfECSqNd', arguments='{"query":"AutoGen"}', name='web_search')]
---------- assistant ----------
[FunctionExecutionResult(content='AutoGen is a programming framework for building multi-agent applications.', call_id='call_fSp5iTGVm2FKw5NIvfECSqNd')]
---------- assistant ----------
AutoGen is a programming framework for building multi-agent applications.

进程已结束,退出代码为 0

on_messages_stream()方法返回一个异步生成器,该生成器产生智能体生成的每个内部消息,其中最后一项是chat_message属性中的响应消息。

从消息中,我们可以观察到AssistantAgent利用该web_search工具收集信息并根据搜索结果做出回应。

我们也可以使用run_stream()方法来获得与on_messages_stream()相同的流式传输行为。它遵循与Teams相同的接口。

使用工具

大型语言模型(LLM)通常仅限于生成文本或代码响应。但是,许多复杂任务受益于使用执行特定操作的外部工具的能力,例如从API或数据库获取数据。

为了解决这一限制,现代LLM现在可以接受可用工具模式列表(工具及其参数的描述)并生成工具调用消息。此功能称为工具调用或函数调用,正在成为构建基于智能智能体的应用程序的流行模式。

AgentChat中,AssistantAgent可以使用工具执行特定操作。该web_search工具就是这样一种工具,它允许AssistantAgent在网络上搜索信息。自定义工具可以是一个Python函数,也可以是基础工具类(BaseTool)的一个子类。

默认情况下,AssistantAgent运行工具时,工具会在其响应中以字符串形式返回其输出。如果使用的工具未以自然语言返回格式正确的字符串,我们可以添加反射步骤,让模型总结工具的输出,方法是在构造函数中ToolCallSummaryMessage设置参数reflect_on_tool_use=True

Langchain工具

除了自定义工具之外,我们还可以通过将Langchain库中的工具封装在LangChainToolAdapter中加以使用。

完整代码

代码需要提前安装pandas库和langchain_experimental库,安装命令分别如下:

pip install pandas
pip install langchain_experimental
import asyncio
import pandas as pd
from langchain_experimental.tools.python.tool import PythonAstREPLTool
from autogen_ext.tools.langchain import LangChainToolAdapter
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.messages import TextMessage
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.ui import Console
from autogen_core import CancellationToken


async def main() -> None:
    df = pd.read_csv("https://raw.githubusercontent.com/pandas-dev/pandas/main/doc/data/titanic.csv")  # type: ignore
    tool = LangChainToolAdapter(PythonAstREPLTool(locals={"df": df}))
    model_client = OpenAIChatCompletionClient(model="gpt-3.5-turbo")
    agent = AssistantAgent(
        "assistant",
        tools=[tool],
        model_client=model_client,
        system_message="Use the `df` variable to access the dataset.",
    )
    await Console(
        agent.on_messages_stream(
            [TextMessage(content="What's the average age of the passengers?", source="user")], CancellationToken()
        )
    )


asyncio.run(main())

运行结果

---------- assistant ----------
[FunctionCall(id='call_BEYRkf53nBS1G2uG60wHP0zf', arguments='{\n  "query": "df[\'Age\'].mean()"\n}', name='python_repl_ast')]
---------- assistant ----------
[FunctionExecutionResult(content='29.69911764705882', call_id='call_BEYRkf53nBS1G2uG60wHP0zf')]
---------- assistant ----------
29.69911764705882

进程已结束,退出代码为 0

并行工具调用

某些模型支持并行工具调用,这对于需要同时调用多个工具的任务非常有用。默认情况下,如果模型客户端产生多个工具调用,AssistantAgent则会并行调用这些工具。

当工具具有可能相互干扰的副作用时,或者当智能体行为需要在不同模型之间保持一致时,我们可能需要禁用并行工具调用。这应该在模型客户端级别完成。

对于OpenAIChatCompletionClientAzureOpenAIChatCompletionClient,设置parallel_tool_calls=False为禁用并行工具调用。

完整代码

import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClient

# 定义一种用于在网络上搜索信息的工具。
async def web_search(query: str) -> str:
    """在网上查找信息"""
    return "AutoGen is a programming framework for building multi-agent applications."


model_client_no_parallel_tool_call = OpenAIChatCompletionClient(
    model="gpt-3.5-turbo",
    parallel_tool_calls=False,  # 类型: 忽略
)

agent_no_parallel_tool_call = AssistantAgent(
    name="assistant",
    model_client=model_client_no_parallel_tool_call,
    tools=[web_search],
    system_message="Use tools to solve tasks.",
)


async def assistant_run() -> None:
    response = await agent_no_parallel_tool_call.on_messages(
        [TextMessage(content="Find information on AutoGen", source="user")],
        cancellation_token=CancellationToken(),
    )
    print(response.inner_messages)
    print(response.chat_message)


asyncio.run(assistant_run())

运行结果

[ToolCallRequestEvent(source='assistant', models_usage=RequestUsage(prompt_tokens=65, completion_tokens=15), content=[FunctionCall(id='call_hqVC7UJUPhKaiJwgVKkg66ak', arguments='{"query":"AutoGen"}', name='web_search')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='assistant', models_usage=None, content=[FunctionExecutionResult(content='AutoGen is a programming framework for building multi-agent applications.', call_id='call_hqVC7UJUPhKaiJwgVKkg66ak')], type='ToolCallExecutionEvent')]
source='assistant' models_usage=None content='AutoGen is a programming framework for building multi-agent applications.' type='ToolCallSummaryMessage'

进程已结束,退出代码为 0

结构化输出

结构化输出允许模型返回具有应用程序提供的预定义架构的结构化JSON文本。与JSON模式不同,该架构可以作为Pydantic BaseModel类提供,该类也可用于验证输出。

结构化输出对于将思维链推理融入智能体的响应中也很有用。请大家看下面的示例代码,了解如何将结构化输出与AssistantAgent一起使用。

完整代码

import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.ui import Console
from typing import Literal
from pydantic import BaseModel


# 智能体的响应格式采用Pydantic基础模型 。
class AgentResponse(BaseModel):
    thoughts: str
    response: Literal["happy", "sad", "neutral"]


# 创建一个使用OpenAI GPT-4o模型且具有自定义响应格式的智能体。
model_client = OpenAIChatCompletionClient(
    model="gpt-4o",
    response_format=AgentResponse  # 类型:忽略
)

agent = AssistantAgent(
    "assistant",
    model_client=model_client,
    system_message="Categorize the input as happy, sad, or neutral following the JSON format.",
)


async def main() -> None:
    await Console(agent.run_stream(task="I am happy."))


asyncio.run(main())

运行结果

---------- user ----------
I am happy.
---------- assistant ----------
{"response":"happy","thoughts":"The user explicitly states they are happy, making this a clear categorization."}

进程已结束,退出代码为 0

流式传输令牌

我们可以通过设置model_client_stream=True来对流传输由模型客户端生成的令牌。这将使智能体在on_messages_stream()run_stream()中生成ModelClientStreamingChunkEvent消息。

要使此功能正常工作,底层模型应用程序编程接口(API)必须支持流式传输令牌。请大家向自己使用的大模型提供商核实这一功能是否受支持。

完整代码

import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.messages import TextMessage

model_client = OpenAIChatCompletionClient(model="gpt-3.5-turbo")

streaming_assistant = AssistantAgent(
    name="assistant",
    model_client=model_client,
    system_message="You are a helpful assistant.",
    model_client_stream=True,  # 启用流式传输令牌。
)


async def main() -> None:
    async for message in streaming_assistant.on_messages_stream(  # 类型: 忽略
            [TextMessage(content="Name two cities in South America", source="user")],
            cancellation_token=CancellationToken(),
    ): print(message)


asyncio.run(main())

运行结果

source='assistant' models_usage=None content='Two' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' cities' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' in' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' South' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' America' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' are' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' Rio' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' de' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' Janeiro' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' in' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' Brazil' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' and' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' Buenos' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' Aires' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' in' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' Argentina' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content='.' type='ModelClientStreamingChunkEvent'
Response(chat_message=TextMessage(source='assistant', models_usage=RequestUsage(prompt_tokens=0, completion_tokens=0), content='Two cities in South America are Rio de Janeiro in Brazil and Buenos Aires in Argentina.', type='TextMessage'), inner_messages=[])

进程已结束,退出代码为 0

我们可以在上面的输出中看到流式块。这些块由模型客户端生成,并在智能体收到后产生。最终响应(所有块的串联)在最后一个块之后立即产生。

类似地,run_stream()也会产生相同的流块,然后在最后一块之后紧接着一条完整的文本消息。

使用run_stream完整代码

import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient

model_client = OpenAIChatCompletionClient(model="gpt-3.5-turbo")

streaming_assistant = AssistantAgent(
    name="assistant",
    model_client=model_client,
    system_message="You are a helpful assistant.",
    model_client_stream=True,  # 启用流式传输令牌。
)


async def main() -> None:
    async for message in streaming_assistant.run_stream(task="Name two cities in North America."):  # 类型: 忽略
        print(message)

asyncio.run(main())

使用run_stream运行结果

source='user' models_usage=None content='Name two cities in North America.' type='TextMessage'
source='assistant' models_usage=None content='Two' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' cities' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' in' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' North' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' America' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' are' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' New' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' York' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' City' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' and' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' Los' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content=' Angeles' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=None content='.\n\n' type='ModelClientStreamingChunkEvent'
source='assistant' models_usage=RequestUsage(prompt_tokens=0, completion_tokens=0) content='Two cities in North America are New York City and Los Angeles.\n\n' type='TextMessage'
TaskResult(messages=[TextMessage(source='user', models_usage=None, content='Name two cities in North America.', type='TextMessage'), TextMessage(source='assistant', models_usage=RequestUsage(prompt_tokens=0, completion_tokens=0), content='Two cities in North America are New York City and Los Angeles.\n\n', type='TextMessage')], stop_reason=None)

进程已结束,退出代码为 0

使用模型上下文

AssistantAgent有一个model_context参数可用于传入ChatCompletionContext对象。这允许智能体使用不同的模型上下文,例如BufferedChatCompletionContext限制发送到模型的上下文。

默认情况下,AssistantAgent使用UnboundedChatCompletionContext将完整的对话历史记录发送到模型。要将上下文限制为最后一条n消息,我们可以使用BufferedChatCompletionContext

完整代码

import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_core.model_context import BufferedChatCompletionContext


# 定义一种用于在网络上搜索信息的工具。
async def web_search(query: str) -> str:
    """在网上查找信息"""
    return "AutoGen is a programming framework for building multi-agent applications."


# 创建一个使用OpenAI的GPT-3.5-Turbo模型的智能体。
model_client = OpenAIChatCompletionClient(
    model="gpt-3.5-turbo",
    # api_key="你的OPENAI_API_KEY",
)

# 创建一个智能体,该智能体仅使用上下文中的最后5条消息来生成回复。
agent = AssistantAgent(
    name="assistant",
    model_client=model_client,
    tools=[web_search],
    system_message="Use tools to solve tasks.",
    model_context=BufferedChatCompletionContext(buffer_size=5),  # 仅使用上下文中的最后5条消息。
)


async def assistant_run() -> None:
    response = await agent.on_messages(
        [TextMessage(content="Find information on AutoGen", source="user")],
        cancellation_token=CancellationToken(),
    )
    print(response.inner_messages)
    print(response.chat_message)


asyncio.run(assistant_run())

运行结果

[ToolCallRequestEvent(source='assistant', models_usage=RequestUsage(prompt_tokens=61, completion_tokens=16), content=[FunctionCall(id='call_hqVC7UJUPhKaiJwgVKkg66ak', arguments='{\n  "query": "AutoGen"\n}', name='web_search')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='assistant', models_usage=None, content=[FunctionExecutionResult(content='AutoGen is a programming framework for building multi-agent applications.', call_id='call_hqVC7UJUPhKaiJwgVKkg66ak')], type='ToolCallExecutionEvent')]
source='assistant' models_usage=None content='AutoGen is a programming framework for building multi-agent applications.' type='ToolCallSummaryMessage'

进程已结束,退出代码为 0

其他预设智能体

可以使用以下预设智能体

  • UserProxyAgent:接受用户输入的智能体将其作为响应返回。
  • CodeExecutorAgent:可以执行代码的智能体
  • OpenAIAssistantAgent:OpenAI Assistant支持的智能体,具有使用自定义工具的能力。
  • MultimodalWebSurfer:可以搜索网络并访问网页以获取信息的多模式智能体
  • FileSurfer:可以搜索和浏览本地文件以获取信息的智能体
  • VideoSurfer:可以通过观看视频来获取信息的智能体

说明

如果大家在运行上述代码的时候有AutoGen相关的提示或报错(例如:该参数不存在,没有此类方法等),请尝试更新一下AutoGen,博主在分享这篇博文的时候AutoGen的版本是0.4.5稳定版

安装或更新命令

pip install -U "autogen-agentchat" "autogen-ext[openai,azure]"

结束

好了,以上就是本次分享的全部内容,今天的内容有点多,请大家慢慢消化,日积月累才能厚积薄发。希望本次分享能对大家有所帮助。如果大家对博主分享的内容感兴趣或有帮助,请点赞和关注,博主会持续更新关于微软AutoGen更多和更有趣的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老赵爱学习

您的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值