文章目录
- 四、工具使用: 国际象棋游戏
- 4.1 准备工具
- 4.2 创建两个棋手代理和棋盘代理
- 4.3 注册工具到代理
- 4.4 创建对话流程,开始对话
- 4.5 增加趣味性:加入闲聊
- 五、代码编写:财务分析
- 5.1导入和配置代码执行器
- 5.2 创建 代码执行/编写 代理
- 5.3 定义财务分析任务,启动对话
- 5.4 用户提供代码给代理使用
- 5.4.1 编写股价获取和绘图函数
- 5.4.2 让编码代理使用预定义函数完成任务
- 5.4.3 使用新的系统消息更新agents,开始对话
- 5.5 总结
- 六、多代理群聊:库存报告生成
- 6.1 任务定义和代理配置
- 6.2 群聊管理和任务执行
- 6.3 自定义发言人顺序
- 6.4 高级功能和总结
- 课程主页《AI Agentic Design Patterns with AutoGen》、bilibili中文视频
- microsoft/autogen、autogen文档
四、工具使用: 国际象棋游戏
在前几节课中,我们学习了如何使用AutoGen中的对话代理进行对话,并使用LLM生成回复。在本课中,我们将学习一种新功能,以嵌套聊天作为对话模式,使代理能够使用工具完成任务。我们将在两个代理之间构建一个对话式的国际象棋游戏,在对话中调用工具,在棋盘上合法移动。
4.1 准备工具
- 使用Python的chess库来管理棋盘和游戏进程。
- 初始化棋盘,并创建一个变量
made_move
跟踪是否已进行移动。 - 定义工具函数:
get_legal_moves
:返回棋盘上所有合法的移动,以UCI格式表示。
将棋子移动情况以UCI格式的字符串表示,并添加注释Annotated[str, "A list of legal moves in UCI format"]
,可以让代理明白内容格式及其含义,明白它采取了哪些动作。make_move
:根据输入的UCI格式移动棋子,并返回移动结果。
import chess
import chess.svg
from typing_extensions import Annotatedllm_config = {"model": "gpt-4-turbo"}
board = chess.Board() # 初始化棋盘
made_move = False # 定义变量跟踪棋盘移动状态def get_legal_moves() -> Annotated[str, "A list of legal moves in UCI format"]:return "Possible moves are: " + ",".join([str(move) for move in board.legal_moves])def make_move(move: Annotated[str, "A move in UCI format."]
) -> Annotated[str, "Result of the move."]:"""代理可以根据特定字符串调用此函数,所以也需要UCI格式。函数的值是移动结果的字符串"""move = chess.Move.from_uci(move) # 解析输入的棋步board.push_uci(str(move)) # 执行棋步global made_movemade_move = True # 表示已经做出棋步# 展示更新后的棋盘,并高亮显示所移动的棋子和目标位置display(chess.svg.board(board,arrows=[(move.from_square, move.to_square)],fill={move.from_square: "gray"},size=200))# 返回一个字符串,描述这次移动,包括棋子的名称和位置变化piece = board.piece_at(move.to_square)piece_symbol = piece.unicode_symbol()piece_name = (chess.piece_name(piece.piece_type).capitalize()if piece_symbol.isupper()else chess.piece_name(piece.piece_type))return f"Moved {piece_name} ({piece_symbol}) from "\f"{chess.SQUARE_NAMES[move.from_square]} to "\f"{chess.SQUARE_NAMES[move.to_square]}."
4.2 创建两个棋手代理和棋盘代理
- 定义
player_white
和player_black
作为两个棋手代理,分别扮演白方和黑方,并通过system_message
指示它们如何行动以及可调用的工具:先调用get_legal_moves()
获取合法棋步,然后调用make_move(move)
来做出棋步。 - 定义
board_proxy
代理负责管理棋盘状态。- 使用
check_made_move
函数用于检查是否有新的棋步发生,检查玩家的移动是否合法 - 使用
is_termination_msg
设置终止条件,当有移动时(check_made_move=True
),终止与棋手代理的交谈,否则它会不停询问棋手代理要求其采取行动("Please make a move."
)。 - 并更新棋盘状态(移动后重置
made_move
)。
- 使用
from autogen import ConversableAgent# 白方棋手代理
player_white = ConversableAgent(name="Player White",system_message="You are a chess player and you play as white. ""First call get_legal_moves(), to get a list of legal moves. ""Then call make_move(move) to make a move.",llm_config=llm_config,
)# 黑方棋手代理
player_black = ConversableAgent(name="Player Black",system_message="You are a chess player and you play as black. ""First call get_legal_moves(), to get a list of legal moves. ""Then call make_move(move) to make a move.",llm_config=llm_config,
)def check_made_move(msg):global made_moveif made_move:made_move = Falsereturn Trueelse:return False# 棋盘代理
board_proxy = ConversableAgent(name="Board Proxy",llm_config=False,is_termination_msg=check_made_move,default_auto_reply="Please make a move.",human_input_mode="NEVER",
)
4.3 注册工具到代理
使用Autogen的register函数将工具get_legal_moves
和make_move
注册到玩家代理,其中caller为调用方,executor为执行方。注册后,棋手代理可以调用这两个工具,而棋盘代理将执行工具调用的结果。
from autogen import register_functionfor caller in [player_white, player_black]:register_function(get_legal_moves,caller=caller,executor=board_proxy,name="get_legal_moves",description="Get legal moves.",)register_function(make_move,caller=caller,executor=board_proxy,name="make_move",description="Call this tool to make a move.",)
我们可以检查黑方玩家现在所配置的工具,这些工具遵循OpenAI的工具定义。
player_black.llm_config["tools"]
[{'type': 'function','function': {'description': 'Get legal moves.','name': 'get_legal_moves','parameters': {'type': 'object', 'properties': {}, 'required': []}}},{'type': 'function','function': {'description': 'Call this tool to make a move.','name': 'make_move','parameters': {'type': 'object','properties': {'move': {'type': 'string','description': 'A move in UCI format.'}},'required': ['move']}}}]
4.4 创建对话流程,开始对话
配置白方和黑方的对话流程。在玩家进行移动前,将与棋盘代理对话确保移动合法。每当一方做出棋步时,棋盘代理会触发消息发送给对手。
player_white.register_nested_chats(trigger=player_black,chat_queue=[{"sender": board_proxy,"recipient": player_white,"summary_method": "last_msg",}],
)player_black.register_nested_chats(trigger=player_white,chat_queue=[{"sender": board_proxy,"recipient": player_black,"summary_method": "last_msg",}],
)
trigger=player_black
: 这意味着每当黑方完成一个动作或发送一条消息后,将触发白方player_white.register_nested_chats()
定义的一系列动作。chat_queue
: 这是一个字典列表,定义了在trigger发生后,哪些消息将被发送和接收。sender
: 定义消息的发送者。当触发后,board_proxy
将会发送一条消息给player_white
。recipient
: 定义消息的接收者,即player_white
。接收到消息后,白方棋手可以做出相应的行动(如获取合法棋步、做出棋步等)。summary_method
: 定义了如何总结和传递消息。在这个例子中,使用"last_msg",表示将最后一条消息作为摘要传递给接收者player_white
。
这段代码定义了自动化交互流程——当黑方做出动作后,如何自动通知白方进行下一步操作。完成动作后,另一个代理能收到相应的通知,从而保持游戏的连贯性和顺畅进行。
board = chess.Board()
chat_result = player_black.initiate_chat(player_white,message="Let's play chess! Your move.",max_turns=2,
)
- 白棋代理生成初始消息,要求黑棋进行移动。
- 黑棋代理调用工具
get_legal_moves
获取合法移动,并选择一个移动。 - 棋盘代理执行该移动并更新棋盘状态,随后黑棋代理将结果回复给白棋代理。
- 白棋代理和黑棋代理轮流进行上述步骤,确保每一步都是合法的。
4.5 增加趣味性:加入闲聊
这场比赛中,两位棋手只是在谈论如何下棋,为了增加一些趣味性,可以为棋手代理增加闲聊功能,使游戏更有趣。我们可以更改棋手代理的系统消息,加入”在移动后,闲聊以使游戏更有趣“的指令,接下来是相同的流程。
# 定义棋手代理
player_white = ConversableAgent(name="Player White",system_message="You are a chess player and you play as white. ""First call get_legal_moves(), to get a list of legal moves. ""Then call make_move(move) to make a move. ""After a move is made, chitchat to make the game fun.",llm_config=llm_config,
)player_black = ConversableAgent(name="Player Black",system_message="You are a chess player and you play as black. ""First call get_legal_moves(), to get a list of legal moves. ""Then call make_move(move) to make a move. ""After a move is made, chitchat to make the game fun.",llm_config=llm_config,
)# 为棋手代理注册工具
for caller in [player_white, player_black]:register_function(get_legal_moves,caller=caller,executor=board_proxy,name="get_legal_moves",description="Get legal moves.",)register_function(make_move,caller=caller,executor=board_proxy,name="make_move",description="Call this tool to make a move.",)
设置silent
为True
,可以隐去代理内部的工具调用过程,只显示代理之间的外部对话过程。
# 创建对话流程
player_white.register_nested_chats(trigger=player_black,chat_queue=[{"sender": board_proxy,"recipient": player_white,"summary_method": "last_msg","silent": True,}],
)player_black.register_nested_chats(trigger=player_white,chat_queue=[{"sender": board_proxy,"recipient": player_black,"summary_method": "last_msg","silent": True,}],
)# 开始对话
board = chess.Board()chat_result = player_black.initiate_chat(player_white,message="Let's play chess! Your move.",max_turns=2,
)
本课展示了一种在消息聊天中使用工具的具体方法,代理可以提出工具使用请求并由另一个代理执行。在其他应用中,你可能希望明确展示工具的使用提议和执行过程。在下一课中,我们将演示其他使用工具的方法,例如使自由编写代码或用户自定义函数的使用。
五、代码编写:财务分析
在前几节课中,我们学习了如何使用AutoGen创建能够使用工具的代理,利用OpenAI的工具使用功能。一个局限是许多其他模型没有相同的功能,或者有时你希望代理在编写自由风格代码时更具创造性,而不仅仅是使用某些预定义的函数。
在本课中,我们将探索如何为代理添加编程能力,并使用生成的代码完成财务分析任务。你将构建两个代理系统,代理们将协作解决任务,同时请求人类反馈。第一个代理将使用大模型从头生成代码,第二个代理将利用用户提供的代码。
5.1导入和配置代码执行器
首先 ,我们创建一个代码执行器并进行配置,例如设置超时限制为60秒,工作目录为coding
(保存所有代码和中间结果)。
from autogen.coding import LocalCommandLineCodeExecutorexecutor = LocalCommandLineCodeExecutor(timeout=60,work_dir="coding",
)
AutoGen有多种类型的代码执行器,包括基于Docker的代理执行器和基于jupyter notebook的代码执行器。
5.2 创建 代码执行/编写 代理
接下来,创建一个代码执行代理code_executor_agent
,这个代理不需要使用大模型进行回复,而只是执行代码。同时,设置人类输入模式为always
,即在执行代码前总是请求人类确认。如果此代理找不到任何可执行的代码,它将回复”请继续,如果一切完成,回复终止“。
from autogen import ConversibleAgent, AssistantAgentcode_executor_agent = ConversableAgent(name="code_executor_agent",llm_config=False,code_execution_config={"executor": executor},human_input_mode="ALWAYS",default_auto_reply="Please continue. If everything is done, reply 'TERMINATE'.",
)
创建一个能够使用LLM编写代码的代理code_writer_agent
,设置人类输入模式为never
。 code_execution_config
设为False
,表示只编写代码而不执行。
llm_config = {"model": "gpt-4-turbo"}code_writer_agent = AssistantAgent(name="code_writer_agent",llm_config=llm_config,code_execution_config=False,human_input_mode="NEVER",
)
我们可以打印代理的系统消息,查看其详细说明。
code_writer_agent_system_message = code_writer_agent.system_message
print(code_writer_agent_system_message)
You are a helpful AI assistant.
Solve tasks using your coding and language skills.
In the following cases, suggest python code (in a python coding block) or shell script (in a sh coding block) for the user to execute.1. When you need to collect info, use the code to output the info you need, for example, browse or search the web, download/read a file, print the content of a webpage or a file, get the current date/time, check the operating system. After sufficient info is printed and the task is ready to be solved based on your language skill, you can solve the task by yourself.2. When you need to perform some task with code, use the code to perform the task and output the result. Finish the task smartly.
Solve the task step by step if you need to. If a plan is not provided, explain your plan first. Be clear which step uses code, and which step uses your language skill.
When using code, you must indicate the script type in the code block. The user cannot provide any other feedback or perform any other action beyond executing the code you suggest. The user can't modify your code. So do not suggest incomplete code which requires users to modify. Don't use a code block if it's not intended to be executed by the user.
If you want the user to save the code in a file before executing it, put # filename: <filename> inside the code block as the first line. Don't include multiple code blocks in one response. Do not ask users to copy and paste the result. Instead, use 'print' function for the output when relevant. Check the execution result returned by the user.
If the result indicates there is an error, fix the error and output the code again. Suggest the full code instead of partial code or code changes. If the error can't be fixed or if the task is not solved even after the code is executed successfully, analyze the problem, revisit your assumption, collect additional info you need, and think of a different approach to try.
When you find an answer, verify the answer carefully. Include verifiable evidence in your response if possible.
Reply "TERMINATE" in the end when everything is done.
"""中文翻译:
你是一个有用的人工智能助手。
使用你的编码和语言技能来解决任务。
在以下情况下,为用户建议执行Python代码(在Python代码块中)或Shell脚本(在sh代码块中)。1. 当你需要收集信息时,使用代码输出你需要的信息,例如浏览或搜索网络,下载/读取文件,打印网页或文件内容,获取当前日期/时间,检查操作系统。在打印出足够的信息并准备好基于你的语言技能解决任务之后,你可以自己解决这个任务。2. 当你需要使用代码执行某些任务时,使用代码执行任务并输出结果。智能地完成任务。
如果需要,请逐步解决任务。如果没有提供计划,请先解释你的计划。明确哪一步使用代码,哪一步使用你的语言技能。
使用代码时,你必须在代码块中指示脚本类型。用户除了执行你建议的代码之外,不能提供任何其他反馈或执行任何其他操作。用户不能修改你的代码。因此不要建议需要用户修改的不完整代码。如果不打算让用户执行,请不要使用代码块。
如果你希望用户在执行之前将代码保存到文件中,请在代码块的第一行内放入 # filename: <filename>。不要在一个响应中包含多个代码块。不要要求用户复制和粘贴结果。相反,当相关时使用'print'函数进行输出。检查用户返回的执行结果。
如果结果表明有错误,请修复错误并再次输出代码。建议完整的代码,而不是部分代码或代码更改。如果错误无法修复,或者即使代码执行成功任务也没有解决,请分析问题,重新审视你的假设,收集你需要的其他信息,并思考尝试不同的方法。
当你找到答案时,请仔细验证答案。如果可能的话,请在回复中包含可验证的证据。
当一切都完成时,最后回复"TERMINATE"。
"""
5.3 定义财务分析任务,启动对话
接下来我们定义一个财务分析任务,要求创建一张显示 NVDA 和 TSLA 股票年初至今涨幅的图表,确保代码在 markdown 代码块中,并将图像保存为 ytd_stock_gains.png
。
import datetimetoday = datetime.datetime.now().date()
message = f"Today is {today}. "\
"Create a plot showing stock gain YTD for NVDA and TLSA. "\
"Make sure the code is in markdown code block and save the figure"\
" to a file ytd_stock_gains.png."chat_result = code_executor_agent.initiate_chat(code_writer_agent,message=message,
)
code_executor_agent (to code_writer_agent):Today is 2024-05-01. Create a plot showing stock gain YTD for NVDA and TLSA. Make sure the code is in markdown code block and save the figure to a file ytd_stock_gains.png.--------------------------------------------------------------------------------
code_writer_agent (to code_executor_agent):To create a plot showing the Year-To-Date (YTD) stock gains for Nvidia (NVDA) and Tesla (TSLA) as of 2024-05-01, we can use Python with libraries such as `pandas`, `pandas_datareader`, and `matplotlib`. Below are the steps we'll take in the script:1. Define the start date of the year (2024-01-01) and the end date (2024-05-01).
2. Fetch the stock data for NVDA and TSLA using `pandas_datareader` from a suitable data source like Yahoo Finance.
3. Calculate daily gains based on the closing prices.
4. Plot the stock performance (% gains) from the start of the year to the specified date.
5. Save the resulting plot to a PNG file named `ytd_stock_gains.png`.I'll provide you the entire script to execute. This script will use Yahoo Finance to obtain the stock data.Make sure you have Python and the required libraries installed. If not, you can install them using pip:pip install pandas pandas_datareader matplotlib
Here's the complete Python script: # 接下来是代理给出的代码内容# filename: plot_stock_gains_ytd.py
import pandas as pd
import pandas_datareader.data as web
import matplotlib.pyplot as plt
from datetime import datetime# Define the date range
start_date = '2024-01-01'
end_date = '2024-05-01'# Fetch stock data
nvda = web.DataReader('NVDA', 'yahoo', start_date, end_date)
tsla = web.DataReader('TSLA', 'yahoo', start_date, end_date)# Calculate the YTD performance in percentage
nvda['Gain'] = (nvda['Close'] / nvda['Close'].iloc[0] - 1) * 100
tsla['Gain'] = (tsla['Close'] / tsla['Close'].iloc[0] - 1) * 100# Create the plot
plt.figure(figsize=(10, 5))
plt.plot(nvda.index, nvda['Gain'], label='NVDA YTD Gain %')
plt.plot(tsla.index, tsla['Gain'], label='TSLA YTD Gain %')
plt.title('YTD Stock Gains for NVDA and TSLA as of 2024-06-03')
plt.xlabel('Date')
plt.ylabel('Percentage Gain')
plt.legend()
plt.grid(True)# Save the plot
plt.savefig('ytd_stock_gains.png')
plt.show()Copy this script into a Python file named `plot_stock_gains_ytd.py`, and execute this script. It should display the plot and save it to `ytd_stock_gains.png`. Let me know if there are any issues!
打印图表:
import os
from IPython.display import ImageImage(os.path.join("coding", "ytd_stock_gains.png"))
5.4 用户提供代码给代理使用
为了更好搞得控制财务分析任务的完成,用户也可以提供自己编写的部分代码来让代理使用,而不是完全让代理编写所有代码。
5.4.1 编写股价获取和绘图函数
下面我们直接编写get_stock_prices
函数和plot_stock_prices
函数,分别用于获取股票价格以及绘制股价图。
def get_stock_prices(stock_symbols, start_date, end_date):"""Get the stock prices for the given stock symbols betweenthe start and end dates.Args:stock_symbols (str or list): The stock symbols to get theprices for.start_date (str): The start date in the format 'YYYY-MM-DD'.end_date (str): The end date in the format 'YYYY-MM-DD'.Returns:pandas.DataFrame: The stock prices for the given stocksymbols indexed by date, with one column per stock symbol."""import yfinance# 使用 yfinance下载股票数据stock_data = yfinance.download(stock_symbols, start=start_date, end=end_date)return stock_data.get("Close")
stock_symbols
:股票符号列表,如 [‘NVDA’, ‘TSLA’]return stock_data.get("Close")
:使用 yfinance 库下载股票数据,并返回收盘价数据
def plot_stock_prices(stock_prices, filename):"""Plot the stock prices for the given stock symbols.Args:stock_prices (pandas.DataFrame): The stock prices for the given stock symbols."""import matplotlib.pyplot as pltplt.figure(figsize=(10, 5))for column in stock_prices.columns:plt.plot(stock_prices.index, stock_prices[column], label=column)plt.title("Stock Prices")plt.xlabel("Date")plt.ylabel("Price")plt.grid(True)plt.savefig(filename)
5.4.2 让编码代理使用预定义函数完成任务
两个预定义的函数已经编写好了,下面在executor的创建方法中加入functions参数,来告诉代理可以使用这两个函数作为工具调用。
executor = LocalCommandLineCodeExecutor(timeout=60,work_dir="coding",functions=[get_stock_prices, plot_stock_prices],
)# 将执行器中的函数格式化为系统消息,追加到 code_writer_agent_system_message中
code_writer_agent_system_message += executor.format_functions_for_prompt()
print(code_writer_agent_system_message)
更新后的code_writer_agent的系统消息前半部分不变,后面增加了使用用户预定义函数内的部分:
Reply "TERMINATE" in the end when everything is done.You have access to the following user defined functions. They can be accessed from the module called `functions` by their function names.For example, if there was a function called `foo` you could import it by writing `from functions import foo`def get_stock_prices(stock_symbols, start_date, end_date):"""Get the stock prices for the given stock symbols betweenthe start and end dates.Args:stock_symbols (str or list): The stock symbols to get theprices for.start_date (str): The start date in the format 'YYYY-MM-DD'.end_date (str): The end date in the format 'YYYY-MM-DD'.Returns:pandas.DataFrame: The stock prices for the given stocksymbols indexed by date, with one column per stock symbol."""...def plot_stock_prices(stock_prices, filename):"""Plot the stock prices for the given stock symbols.Args:stock_prices (pandas.DataFrame): The stock prices for the given stock symbols."""...
5.4.3 使用新的系统消息更新agents,开始对话
- 创建代理,配置系统消息和语言模型
- 不使用代码执行配置(
code_execution_config=False
) - 人工输入模式设置为 “
NEVER
”
code_writer_agent = ConversableAgent(name="code_writer_agent",system_message=code_writer_agent_system_message,llm_config=llm_config,code_execution_config=False,human_input_mode="NEVER",
)code_executor_agent = ConversableAgent(name="code_executor_agent",llm_config=False,code_execution_config={"executor": executor},human_input_mode="ALWAYS",default_auto_reply="Please continue. If everything is done, reply 'TERMINATE'.",
)
chat_result = code_executor_agent.initiate_chat(code_writer_agent,message=f"Today is {today}.""Download the stock prices YTD for NVDA and TSLA and create""a plot. Make sure the code is in markdown code block and ""save the figure to a file stock_prices_YTD_plot.png.",
)Image(os.path.join("coding", "stock_prices_YTD_plot.png"))
5.5 总结
本章介绍了两种创建代理实现代码编写并执行的方式: 基于默认助手代理的代码编写方式
和基于用户提供的函数的代码编写方式(工具调用)。下面总结这两种方式的区别以及它们的适用场景:
-
基于大模型的代码编写能力
- 优点
- 高度灵活:能够根据自然语言描述动态生成所需的代码(依赖大模型的代码编写和生成能力)。
- 适合复杂任务:可以处理多种复杂任务,尤其是那些需要生成新代码的场景。
- 减少初始工作量:无需预定义函数或工具,可以直接生成代码。
- 缺点:
- 模型依赖:需要底层模型具备强大的代码编写能力,对于某些模型可能不够稳定或准确。
- 安全性、确定性、可维护性差:生成的代码可能不在预期范围内,存在执行未知代码的风险,可能不易维护和调试。
- 优点
-
基于用户提供的函数(工具调用)
- 优点
- 普遍性:不依赖于大模型的代码编写能力,只需要模型能够调用预定义函数,故适用于任何具备函数调用能力的模型,更加通用。
- 适合标准化任务:更适合重复性、标准化的任务。
- 安全性、确定性、维护性高:只执行预定义的、经过验证的函数,减少风险。代码结构化,易于理解和维护。
- 缺点:
- 初始工作量大:需要预先定义和测试函数。
- 灵活性较低:只能执行预定义的功能,无法动态生成新代码。
- 优点
总结: 基于大模型的代码编写方式适用于需要动态生成代码、处理复杂和多样化任务的场景。 基于用户提供的函数方式适用于重复性、高安全性和标准化的任务。两种方式可以互相结合,确保任务顺利完成。
本课展示了如何为代理添加编程能力,完成财务分析任务。我们还讨论了代码执行和工具调用的区别,以及不同方法的优缺点。下一课中,我们将学习使用编码代理、规划代理和执行代理,通过群聊模式完成一个更复杂的任务。
六、多代理群聊:库存报告生成
课程主题:多代理群聊和股票表现报告生成
在本课中,我们将深入探讨多代理群聊,构建一个自定义的群聊系统,以协作生成股票过去一个月表现的详细报告。这一复杂任务涉及规划,通过在群聊中引入一个规划代理来实现。此外,我们还将学习如何自定义群聊中的发言人切换。
6.1 任务定义和代理配置
目标:
- 使用GPT-4 Turbo模型完成股票表现报告生成任务。
步骤:
- 引入所需库: 导入Autogen。
- 定义初始代理:
- Admin代理:发送任务并指示Writer改进博客文章。
- 配置:不开启代码执行,使用大模型,设置为始终需要人类输入。
- 规划代理(Planner):分解任务为更小的子任务,监督任务进度。
- 系统消息:指导如何获取信息和检查任务进度。
- 描述:帮助其他代理理解其角色。
- 工程师代理(Engineer):编写Python代码。
- 使用Autogen的默认助手代理类。
- 执行代理(Executor):执行代码。
- 配置:代码执行配置,使用本地命令行环境。
- 编写代理(Writer):编写博客文章。
- 系统消息:编写Markdown格式的博客,并根据Admin的反馈进行修改。
- Admin代理:发送任务并指示Writer改进博客文章。
6.2 群聊管理和任务执行
群聊设置:
- 创建群聊,包含上述代理。
- 初始化消息列表,设置下一轮为10。
群聊管理器:
- 用于管理群聊的特殊代理。
- 使用大模型配置。
- 启动群聊对话,从用户代理和群聊管理器之间开始。
对话流程:
- 任务发送: Admin发送任务到群聊管理器。
- 任务广播: 管理器将任务广播给所有代理。
- 代理响应:
- 规划代理(Planner)首先响应,建议任务分解步骤。
- 工程师(Engineer)编写代码。
- 执行代理(Executor)执行代码。
- Writer开始编写博客文章。
- 用户反馈: Admin代理询问用户反馈。
- 文章修改: Writer根据反馈改进文章。
6.3 自定义发言人顺序
问题:
- 默认的发言人顺序有时不符合预期。
解决方案:
- 定义允许和不允许的发言人切换。
- 例如,限制在工程师(Engineer)之后的发言人只能是用户代理或执行代理。
实现方法:
- 添加允许的发言人切换的字典。
- 重新定义群聊并添加这些约束。
结果:
- 确保规划代理在执行代理之后回顾计划,改进任务流程。
6.4 高级功能和总结
高级功能:
- 任务分解和规划代理的使用。
- 群聊提供了更动态的多代理协作方式。
- 可通过自然语言指令或编程语言精确控制发言人顺序。
总结:
- 群聊方式让多个代理协作解决任务,无需人类设计详细执行计划。
- 规划代理帮助任务分解和规划。
- Autogen还支持许多高级功能,如多模态、视觉能力、OpenAI助手后端、代理评估工具等。
通过以上课程内容,我们学习了如何使用多代理群聊来解决复杂任务,并了解了如何自定义代理间的交互顺序。希望这些知识能帮助我们在实际应用中更加灵活和高效地使用Autogen。