AI Agentic Design Patterns with AutoGen(下):工具使用、代码编写、多代理群聊

news2025/1/19 11:22:09

文章目录

    • 四、工具使用: 国际象棋游戏
      • 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 Annotated

llm_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_move
    made_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_whiteplayer_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_move
    if made_move:
        made_move = False
        return True
    else:
        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_movesmake_move注册到玩家代理,其中caller为调用方,executor为执行方。注册后,棋手代理可以调用这两个工具,而棋盘代理将执行工具调用的结果。

from autogen import register_function

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.",
    )

我们可以检查黑方玩家现在所配置的工具,这些工具遵循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.",
    )

设置silentTrue,可以隐去代理内部的工具调用过程,只显示代理之间的外部对话过程。

# 创建对话流程
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 LocalCommandLineCodeExecutor

executor = LocalCommandLineCodeExecutor(
    timeout=60,
    work_dir="coding",
)

AutoGen有多种类型的代码执行器,包括基于Docker的代理执行器和基于jupyter notebook的代码执行器。

5.2 创建 代码执行/编写 代理

  接下来,创建一个代码执行代理code_executor_agent,这个代理不需要使用大模型进行回复,而只是执行代码。同时,设置人类输入模式为always,即在执行代码前总是请求人类确认。如果此代理找不到任何可执行的代码,它将回复”请继续,如果一切完成,回复终止“。

from autogen import ConversibleAgent, AssistantAgent

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'.",
)

创建一个能够使用LLM编写代码的代理code_writer_agent,设置人类输入模式为nevercode_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 datetime

today = 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 Image

Image(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 between
    the start and end dates.

    Args:
        stock_symbols (str or list): The stock symbols to get the
        prices 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 stock
        symbols 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 plt

    plt.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 between
        the start and end dates.

        Args:
            stock_symbols (str or list): The stock symbols to get the
            prices 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 stock
            symbols 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 总结

  本章介绍了两种创建代理实现代码编写并执行的方式: 基于默认助手代理的代码编写方式
和基于用户提供的函数的代码编写方式(工具调用)。下面总结这两种方式的区别以及它们的适用场景:

  1. 基于大模型的代码编写能力

    • 优点
      • 高度灵活:能够根据自然语言描述动态生成所需的代码(依赖大模型的代码编写和生成能力)。
      • 适合复杂任务:可以处理多种复杂任务,尤其是那些需要生成新代码的场景。
      • 减少初始工作量:无需预定义函数或工具,可以直接生成代码。
    • 缺点
      • 模型依赖:需要底层模型具备强大的代码编写能力,对于某些模型可能不够稳定或准确。
      • 安全性、确定性、可维护性差:生成的代码可能不在预期范围内,存在执行未知代码的风险,可能不易维护和调试。
  2. 基于用户提供的函数(工具调用)

    • 优点
      • 普遍性:不依赖于大模型的代码编写能力,只需要模型能够调用预定义函数,故适用于任何具备函数调用能力的模型,更加通用。
      • 适合标准化任务:更适合重复性、标准化的任务。
      • 安全性、确定性、维护性高:只执行预定义的、经过验证的函数,减少风险。代码结构化,易于理解和维护。
    • 缺点
      • 初始工作量大:需要预先定义和测试函数。
      • 灵活性较低:只能执行预定义的功能,无法动态生成新代码。

  总结: 基于大模型的代码编写方式适用于需要动态生成代码、处理复杂和多样化任务的场景。 基于用户提供的函数方式适用于重复性、高安全性和标准化的任务。两种方式可以互相结合,确保任务顺利完成。

  本课展示了如何为代理添加编程能力,完成财务分析任务。我们还讨论了代码执行和工具调用的区别,以及不同方法的优缺点。下一课中,我们将学习使用编码代理、规划代理和执行代理,通过群聊模式完成一个更复杂的任务。

六、多代理群聊:库存报告生成

课程主题:多代理群聊和股票表现报告生成

在本课中,我们将深入探讨多代理群聊,构建一个自定义的群聊系统,以协作生成股票过去一个月表现的详细报告。这一复杂任务涉及规划,通过在群聊中引入一个规划代理来实现。此外,我们还将学习如何自定义群聊中的发言人切换。

6.1 任务定义和代理配置

目标:

  • 使用GPT-4 Turbo模型完成股票表现报告生成任务。

步骤:

  1. 引入所需库: 导入Autogen。
  2. 定义初始代理:
    • Admin代理:发送任务并指示Writer改进博客文章。
      • 配置:不开启代码执行,使用大模型,设置为始终需要人类输入。
    • 规划代理(Planner):分解任务为更小的子任务,监督任务进度。
      • 系统消息:指导如何获取信息和检查任务进度。
      • 描述:帮助其他代理理解其角色。
    • 工程师代理(Engineer):编写Python代码。
      • 使用Autogen的默认助手代理类。
    • 执行代理(Executor):执行代码。
      • 配置:代码执行配置,使用本地命令行环境。
    • 编写代理(Writer):编写博客文章。
      • 系统消息:编写Markdown格式的博客,并根据Admin的反馈进行修改。

6.2 群聊管理和任务执行

群聊设置:

  • 创建群聊,包含上述代理。
  • 初始化消息列表,设置下一轮为10。

群聊管理器:

  • 用于管理群聊的特殊代理。
  • 使用大模型配置。
  • 启动群聊对话,从用户代理和群聊管理器之间开始。

对话流程:

  1. 任务发送: Admin发送任务到群聊管理器。
  2. 任务广播: 管理器将任务广播给所有代理。
  3. 代理响应:
    • 规划代理(Planner)首先响应,建议任务分解步骤。
    • 工程师(Engineer)编写代码。
    • 执行代理(Executor)执行代码。
    • Writer开始编写博客文章。
  4. 用户反馈: Admin代理询问用户反馈。
  5. 文章修改: Writer根据反馈改进文章。

6.3 自定义发言人顺序

问题:

  • 默认的发言人顺序有时不符合预期。

解决方案:

  • 定义允许和不允许的发言人切换。
  • 例如,限制在工程师(Engineer)之后的发言人只能是用户代理或执行代理。

实现方法:

  • 添加允许的发言人切换的字典。
  • 重新定义群聊并添加这些约束。

结果:

  • 确保规划代理在执行代理之后回顾计划,改进任务流程。

6.4 高级功能和总结

高级功能:

  • 任务分解和规划代理的使用。
  • 群聊提供了更动态的多代理协作方式。
  • 可通过自然语言指令或编程语言精确控制发言人顺序。

总结:

  • 群聊方式让多个代理协作解决任务,无需人类设计详细执行计划。
  • 规划代理帮助任务分解和规划。
  • Autogen还支持许多高级功能,如多模态、视觉能力、OpenAI助手后端、代理评估工具等。

通过以上课程内容,我们学习了如何使用多代理群聊来解决复杂任务,并了解了如何自定义代理间的交互顺序。希望这些知识能帮助我们在实际应用中更加灵活和高效地使用Autogen。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1801895.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Golang】探索进程资源监控的精妙细节:利用Gopsutil/Process实现高级进程性能和资源信息监控

【Golang】探索进程资源监控的精妙细节&#xff1a;利用Gopsutil/Process实现高级进程性能和资源信息监控 大家好 我是寸铁&#x1f44a; 总结了一篇【Golang】探索进程资源监控的精妙细节&#xff1a;利用Gopsutil/Process实现高级进程性能和资源信息监控的文章✨ 喜欢的小伙伴…

dp+矩阵快速幂,CF551D. GukiZ and Binary Operations

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 551D - Codeforces 二、解题报告 1、思路分析 今天LATEX怎么不好用了 数据量很大&#xff0c;应该要用O(log) 或者 O(1)的的算法 按位考虑进行dp&#xff0c;计算k每位的方案数累乘即可&#x…

全光网络与传统网络架构的对比分析

随着信息技术的飞速发展&#xff0c;网络已经成为我们日常生活中不可或缺的一部分。在这个信息爆炸的时代&#xff0c;全光网络和传统网络架构作为两种主流的网络技术&#xff0c;各有其特点和适用范围。本文将对这两种网络架构进行详细的对比分析&#xff0c;帮助读者更好地了…

【sklearn】【逻辑回归1】

学习笔记来自&#xff1a; 所用的库和版本大家参考&#xff1a; Python 3.7.1Scikit-learn 0.20.1 Numpy 1.15.4, Pandas 0.23.4, Matplotlib 3.0.2, SciPy 1.1.0 1 概述 1.1 名为“回归”的分类器 在过去的四周中&#xff0c;我们接触了不少带“回归”二字的算法&#xf…

K-BAT01,K-CU01和利时卡件

K-BAT01,K-CU01和利时卡件。现场控制站下装与在线调试。9二、组态流程&#xff1a;操作站组态控制站组态新建工程控制站用户组态历史站组态下装现场控制站下装历史站下装操作员站10三、组态详解&#xff1a;1、K-BAT01,K-CU01和利时卡件。新建工程&#xff1a;打开工程总控&…

深度学习Week16——数据增强

文章目录 深度学习Week16——数据增强 一、前言 二、我的环境 三、前期工作 1、配置环境 2、导入数据 2.1 加载数据 2.2 配置数据集 2.3 数据可视化 四、数据增强 五、增强方式 1、将其嵌入model中 2、在Dataset数据集中进行数据增强 六、训练模型 七、自定义增强函数 一、前言…

什么时候用C而不用C++?

做接口只用C&#xff0c;千万别要C。C是编译器敏感的&#xff0c;一旦导出的接口里有 std::string这些东西&#xff0c;以及类&#xff0c;注定了要为各个编译器的各个版本准备独立的库。 刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C的资料从专业入门…

[AIGC] SpringBoot的自动配置解析

下面是一篇关于SpringBoot自动配置的文章&#xff0c;里面包含了一个简单的示例来解释自动配置的原理。 SpringBoot的自动配置解析 Spring Boot是Spring的一个子项目&#xff0c;用于快速开发应用程序。它主要是简化新Spring应用的初始建立以及开发过程。其中&#xff0c;自动…

传统工科硕士想转嵌入式,时间够吗?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 零基础开始学&#xff0…

帕友饮食改善的小建议!

一、增加膳食纤维的摄入 帕金森病患者应增加膳食纤维的摄入量&#xff0c;以帮助调节肠道功能&#xff0c;预防便秘。膳食纤维丰富的食物包括蔬菜、水果、全谷类食物等。患者应确保每天摄入足够的膳食纤维&#xff0c;以保持肠道通畅&#xff0c;缓解帕金森病可能带来的消化不…

Huawei 大型 WLAN 组网 AC 间漫游

AC1配置命令 <AC6005>display current-configuration # vlan batch 100 # interface Vlanif100description to_S3_CAPWAPip address 10.0.100.254 255.255.255.0 # interface GigabitEthernet0/0/1port link-type trunkport trunk allow-pass vlan 100# ip route-stati…

Python 机器学习 基础 之 【实战案例】轮船人员获救预测实战

Python 机器学习 基础 之 【实战案例】轮船人员获救预测实战 目录 Python 机器学习 基础 之 【实战案例】轮船人员获救预测实战 一、简单介绍 二、轮船人员获救预测实战 三、数据处理 1、导入数据 2、对缺失数据的列进行填充 3、属性转换&#xff0c;把某些列的字符串值…

基于统一二维电子气密度表达式的通用MIS-HEMT紧凑模型

来源&#xff1a;A Compact Model for Generic MIS-HEMTs Based on the Unified 2DEG Density Expression&#xff08;TED 14年&#xff09; 摘要 本文提出了一种针对二维电子气&#xff08;ns&#xff09;密度和费米能级&#xff08;E_f&#xff09;的解析表达式&#xff0c…

c++使用_beginthreadex创建线程

记录使用_beginthreadex()&#xff0c;来创建线程。方便后期的使用。 创建一个线程 相关函数介绍 unsigned long _beginthreadex( void *security, // 安全属性&#xff0c; 为NULL时表示默认安全性 unsigned stack_size, // 线程的堆栈大小&#xff0c; 一般默认为0 u…

大型语言模型智能体(LLM Agent)在实际使用的五大问题

在这篇文章中&#xff0c;我将讨论人们在将代理系统投入生产过程中经常遇到的五个主要问题。我将尽量保持框架中立&#xff0c;尽管某些问题在特定框架中更加常见。 1. 可靠性问题 可靠性是所有代理系统面临的最大问题。很多公司对代理系统的复杂任务持谨慎态度&#xff0c;因…

SMS-GSM

SMS-GSM 短信模块&#xff0c;不想通过第三方的接口&#xff0c;自己搭建短信模块&#xff0c;提高信息安全。 /**/ package sms;import com.diagcn.smslib.CMessage; import com.diagcn.smslib.COutgoingMessage; import com.diagcn.smslib.SZHTOCService;/*** 短信模块** au…

用于认知负荷评估的集成时空深度聚类(ISTDC)

Integrated Spatio-Temporal Deep Clustering (ISTDC) for cognitive workload assessment 摘要&#xff1a; 本文提出了一种新型的集成时空深度聚类&#xff08;ISTDC&#xff09;模型&#xff0c;用于评估认知负荷。该模型首先利用深度表示学习&#xff08;DRL&#xff09;…

css3 都有哪些新属性

1. css3 都有哪些新属性 1.1. 圆角边框 (border-radius)1.2. 盒子阴影 (box-shadow)1.3. 文本阴影 (text-shadow)1.4. 响应式设计相关属性1.5. 渐变背景 (gradient backgrounds)1.6. 透明度 (opacity 和 rgba/hsla)1.7. 多列布局 (column-count, column-gap, etc.)1.8. 变换 (t…

设置电脑定时关机

1.使用快捷键winR 打开运行界面 2.输入cmd &#xff0c;点击确认&#xff0c;打开命令行窗口&#xff0c;输入 shutdown -s -t 100&#xff0c;回车执行命令&#xff0c;自动关机设置成功 shutdown: 这是主命令&#xff0c;用于执行关闭或重启操作。-s: 这个参数用于指定执行关…

超详解——识别None——小白篇

目录 1. 内建类型的布尔值 2. 对象身份的比较 3. 对象类型比较 4. 类型工厂函数 5. Python不支持的类型 总结&#xff1a; 1. 内建类型的布尔值 在Python中&#xff0c;布尔值的计算遵循如下规则&#xff1a; None、False、空序列&#xff08;如空列表 []&#xff0c;空…