介绍
大家好,今天给大家分享的内容是微软AutoGen框架的核心功能Agents。今天分享的内容比较多,请大家耐心看完,我相信大家肯定会有所收获,那么我们直接进入正题。
Agents
AutoGen的AgentChat提供了一组预设智能体,每个智能体对消息的响应方式各不相同。所有智能体都具有以下属性和方法:
- name:智能体的唯一名称。
- description:用文本对智能体(agent)进行的描述。
- on_messages():向智能体发送一系列ChatMessage,以获取一个Response。需要注意的是,智能体应具有状态记忆,并且该方法应使用新消息调用,而非完整的消息历史记录。
- on_messages_stream():其功能与on_messages()相同,但返回一个迭代器,该迭代器包含AgentEvent或ChatMessage类型的元素,且最后一个元素为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则会并行调用这些工具。
当工具具有可能相互干扰的副作用时,或者当智能体行为需要在不同模型之间保持一致时,我们可能需要禁用并行工具调用。这应该在模型客户端级别完成。
对于OpenAIChatCompletionClient和AzureOpenAIChatCompletionClient,设置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更多和更有趣的内容。