使用 AutoGen 构建下一代 LLM 应用
LLM 所展现出的推理、规划、指令遵循、上下文学习和工具使用等多项能力,使得它们成为目前开发强大 AI 智能体 (AI Agent)的首选。一些基于这样的智能体构建的 AI 应用已经出现,例如 ChatGPT + Wolfram Alpha 插件可以解答数学问题,AutoGPT 可以自主达成用户给定的目标,等等。最近公开的 AutoGen 框架引入了多智能体对话(multi-agent conversation)机制,为构建 AI 应用提供了高效实现和高度可扩展性。
本教程演示几个基于 AutoGen 框架构建的简单应用。这些应用分别采用了 OpenAI 的 GPT 系列模型以及开源的 LLM 作为智能体的后端,前者通过调用 OpenAI 的官方 API 实现,后者则是接入使用 SimpleMLService 部署的 LLM 推理服务。
应用的代码被放置在 https://github.com/t9k/examples/tree/v20240206/applications/autogen,用户可参照 README 自行尝试。这里推荐用户在 Notebook 中运行应用示例的 .ipynb
文件;如要使用开源模型作为智能体后端,请参阅部署 LLM 聊天机器人进行本地部署。
AutoGen 框架
我们希望基于 LLM 的智能体能够帮助人类完成现实世界中的复杂任务,但即便是当下最强大的 GPT-4 模型,也在许多场景下表现不佳。为了提升智能体解决问题的能力,除了提升单个智能体的表现,另一种直观的思路是使用多个智能体进行分工合作,分解复杂任务并各自承担一个专业的子任务。现有研究表明,多个智能体有助于鼓励不同的思考方式,提高推理能力,提供验证以提高正确性。就像人类一样,团队合作能够实现许多个人难以独立达成的成就。
论文 《AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation》提出了多智能体对话框架 AutoGen,其基本原理如下:
- 提供通用的可对话智能体抽象,智能体有统一的对话接口,由 LLM、人类、(由 Python 代码实现的)外部工具或它们的组合驱动,可自定义和扩展行为,可重用。
- LLM 应用的工作流被统一为多智能体的对话流,开发应用的过程即为:(1) 定义一组各自有特定能力和角色的可对话智能体;(2) 通过程序语言(Python 代码)和自然语言(LLM 的系统信息(system message)、指令等)控制智能体自身的计算以及智能体之间的对话流。
AutoGen 框架提供的灵活性超越了目前其他框架或系统(如 AutoGPT、LangChain Agent、CAMEL 等),适用于构建各种形式、领域和复杂度的应用。
应用一:解数学题
在第一个应用中,我们使用 MathChat 框架解答数学问题。
为该应用编写的部分 AutoGen 代码如下,其中定义了智能体 user_proxy 和 assistant。前者负责初始化对话(MathUserProxyAgent 封装了解答数学问题的 prompt,见下面的日志),以及执行 Python 代码并返回结果(所有 UserProxyAgent 均有执行 Python 代码的功能);后者负责解答问题(使用了默认的系统信息):
user_proxy = MathUserProxyAgent(
name="user_proxy",
human_input_mode="NEVER",
)
assistant = autogen.AssistantAgent(
name="assistant",
system_message="你是一个提供帮助的助手。",
llm_config={
"request_timeout": 600,
"seed": 42,
"config_list": config_list,
}
)
math_problem = "[数学问题]"
user_proxy.initiate_chat(assistant, problem=math_problem)
通过修改 config,智能体可以使用由 OpenAI 提供的 gpt-4、gpt-3.5-turbo 等 API,或者由 FastChat 本地部署的开源模型作为 LLM 后端。数学问题如下:
- 任务 1:找到满足不等式 的所有 ,并以区间表示答案。
- 任务 2:当 取何负值时,以下方程组存在恰好一个解?
使用 gpt-4 后端执行任务 1,整个过程的日志如下,最终回答正确:
日志
user_proxy (to assistant):
让我们使用 Python 来解决一个数学问题。
查询要求:
- 对于输出,应始终使用 ‘print’ 函数,并使用分数 / 根式形式而不是小数。
- 您可以使用诸如 sympy 之类的包来帮助您。
- 您必须遵循以下格式来编写您的代码:
# your code
首先陈述解决问题的关键思想。您可以选择以下三种方式来解决问题: 情况 1:如果问题可以直接用 Python 代码解决,请编写一个程序来解决它。如果需要,您可以枚举所有可能的排列。 情况 2:如果问题主要是基于推理,您可以直接解决它。 情况 3:如果问题不能用以上两种方式处理,请按照以下过程进行:
- 逐步解决问题(不要过于细分步骤)。
- 挑选出可以通过 Python 询问的任何查询(例如,可以计算的任何计算或方程式)。
- 等待我提供结果。
- 如果您认为结果正确,请继续。如果结果无效或不符合预期,请更正您的查询或推理。
在运行所有查询并获得答案后,将答案放入 \boxed {} 中。
问题: 找到满足不等式 (2x+10)(x+3)<(3x+9)(x+8) 的所有 x,并以区间表示答案。
assistant (to user_proxy):
解决这个问题的关键思想是首先简化不等式。然后,通过将其化为零来找到简化表达式的临界点。一旦我们有了临界点,我们将在由这些点确定的每个区间中评估原始不等式。不等式成立的区间将是我们的解集。
具体的步骤如下:
- 展开不等式两侧并将其简化为 的形式。
- 解方程 以找到临界点。
- 确定由临界点确定的区间中不等式 成立的区间。
我们可以使用 Python 执行所有这些步骤。让我们编写程序来执行这些操作。我们将使用 sympy 库来进行符号计算。
from sympy import *
x = symbols('x')
# 定义不等式
inequality = (2*x + 10)*(x + 3) - (3*x + 9)*(x + 8)
# 展开和简化不等式
simplified_inequality = simplify(inequality)
# 通过解方程f(x) = 0来找到临界点
critical_points = solve(simplified_inequality, x)
# 对临界点进行排序,然后添加 -oo 和 +oo 形成实线上的区间
intervals = [-oo, *sorted(critical_points), oo]
# 在每个区间中评估简化的不等式,
# 如果成立,该区间是解的一部分
solution_set = [] # 采用了复杂的解法
for i in range(len(intervals) - 1):
mid_point = (intervals[i] + intervals[i+1]) / 2
if simplified_inequality.subs(x, mid_point) < 0:
solution_set.append((intervals[i], intervals[i+1]))
print(solution_set)
运行这段代码,输出将是给定不等式中 的解集,以区间表示。
user_proxy (to assistant):
[(-oo, -14), (-3, oo)]
assistant (to user_proxy):
不等式 的解是 。
换用其他 LLM 作为 Assistant 的后端能否解决这些数学问题?这里实验了 gpt-3.5-turbo、meta-llama/Llama-2-70b-chat-hf、meta-llama/Llama-2-13b-chat-hf、Qwen/Qwen-14B-Chat,结果汇总如下:
模型 | 任务 1 | 任务 2 | 失败原因 |
---|---|---|---|
gpt-4 | ✅ | ✅ | |
gpt-3.5-turbo | ❌ | ✅ | 代数计算出错 |
meta-llama/Llama-2-70b-chat-hf | ❌ | ❌ | 代数计算出错,代码编写出错(不会使用 sympy 包) |
meta-llama/Llama-2-13b-chat-hf | ❌ | ❌ | 代数计算出错,指令遵循存在问题 |
Qwen/Qwen-14B-Chat | ❌ | ✅ | 代数计算出错 |
由此可见,gpt-4 的数学能力相较于这些有代表性的开源模型遥遥领先。
应用二:文档问答
在第二个应用中,LLM 需要根据从向量数据库检索得到的上下文回答用户提出的问题。
为该应用编写的 AutoGen 代码如下,其中定义了智能体 user_proxy 和 assistant,前者在对话之外负责构建和检索向量数据库(定义中包含一些相关配置),在对话当中负责提供 prompt、问题和上下文,后者回答问题:
user_proxy = RetrieveUserProxyAgent(
name="user_proxy",
human_input_mode="NEVER",
max_consecutive_auto_reply=10,
retrieve_config={
"task": "qa",
"docs_path": "local_path_or_url_of_docs",
"chunk_token_size": 2000,
"model": config_list[0]["model"],
"client": chromadb.PersistentClient(path="./tmp/chromadb"),
"collection_name": "natural-questions",
"chunk_mode": "one_line",
"embedding_model": "all-MiniLM-L6-v2",
},
)
assistant = RetrieveAssistantAgent(
name="assistant",
system_message="你是一个提供帮助的助手。",
llm_config={
"request_timeout": 600,
"seed": 42,
"config_list": config_list,
},
)
question = "[提出的问题]"
user_proxy.initiate_chat(assistant, problem=question, n_results=30)
这里准备了两个任务:
任务 1:根据 NaturalQuestionsQA 语料库,回答下列问题:
No. | 问题 | 正确答案 |
---|---|---|
1 | what is non controlling interest on balance sheet | the portion of a subsidiary corporation’s stock that is not owned by the parent corporation |
2 | how many episodes are in chicago fire season 4 | 23 |
3 | what are bulls used for on a farm | breeding, as work oxen, slaughtered for meat |
4 | who has been honoured with the wisden leading cricketer in the world award for 2016 | Virat Kohli |
5 | who carried the usa flag in opening ceremony | Erin Hamlin |
任务 2:根据比亚迪 2023 年上半年财报,回答下列问题:
No. | 问题 | 正确答案 |
---|---|---|
1 | 公司是否计划派发现金红利? | 公司计划不派发现金红利。 |
2 | 集团在八月达成的里程碑是什么? | 本集团第500万辆新能源汽车下线,成为全球首家达成这一里程碑的车企。 |
3 | 公司的主管会计工作负责人是谁? | 周亚琳 |
4 | 公司的 2023 年上半年的归母净利润为多少元? | 10,954,145,000元 |
5 | 王传福的持股比例是多少? | 17.64% |
使用 gpt-4 后端执行任务 2 的问题 1,整个过程的日志如下,最终回答正确:
日志
doc_ids: [[‘doc_460’, ‘doc_1461’, ‘doc_4853’, ‘doc_4871’, ‘doc_1582’, ‘doc_1439’, ‘doc_1374’, ‘doc_2312’, ‘doc_1584’, ‘doc_512’, ‘doc_6188’, ‘doc_2324’, ‘doc_1577’, ‘doc_2314’, ‘doc_1444’, ‘doc_14’, ‘doc_3357’, ‘doc_1336’, ‘doc_6106’, ‘doc_1948’, ‘doc_1588’, ‘doc_1587’, ‘doc_4898’, ‘doc_439’, ‘doc_1448’, ‘doc_2308’, ‘doc_5452’, ‘doc_6186’, ‘doc_6166’, ‘doc_536’]] Adding doc_id doc_460 to context. Adding doc_id doc_1461 to context. Adding doc_id doc_4853 to context. Adding doc_id doc_4871 to context. Adding doc_id doc_1582 to context. Adding doc_id doc_1439 to context. Adding doc_id doc_1374 to context. Adding doc_id doc_2312 to context. Adding doc_id doc_1584 to context. Adding doc_id doc_512 to context. Adding doc_id doc_6188 to context. Adding doc_id doc_2324 to context. Adding doc_id doc_1577 to context. Adding doc_id doc_2314 to context. Adding doc_id doc_1444 to context. Adding doc_id doc_14 to context. Adding doc_id doc_3357 to context. Adding doc_id doc_1336 to context. Adding doc_id doc_6106 to context. Adding doc_id doc_1948 to context. Adding doc_id doc_1588 to context. Adding doc_id doc_1587 to context. Adding doc_id doc_4898 to context. Adding doc_id doc_439 to context. Adding doc_id doc_1448 to context. Adding doc_id doc_2308 to context. Adding doc_id doc_5452 to context. Adding doc_id doc_6186 to context. Adding doc_id doc_6166 to context. Adding doc_id doc_536 to context. ragproxyagent (to assistant):
You’re a retrieve augmented chatbot. You answer user’s questions based on your own knowledge and the
context provided by the user.
If you can’t answer the question with or without the current context, you should reply exactly UPDATE CONTEXT
.
You must give as short an answer as possible.
User’s question is: 公司是否计划派发现金红利?
Context is: 公司报告期无募集资金使用情况。
限 公 司 各 项 经 济 损 失
母公司股东 归属于
母公司股东 归属于
公司控股的财务公司与关联方之间不存在存款、贷款、授信或其他金融业务。
公司报告期不存在控股股东及其 他关联方对上市公司的非经营性占用资金。
沙分公司 废气 氮氧化
公司报告期控股股东未发生变更。
公司报告期无其他重大关联交易。
公司计划半年度不派发现金红利,不送红股,不以公积金转增股本。
限公司 房屋
公司半年度财务报告未经审计。
公司报告期不存在关联债权债务往来。
公司报告期实际控制人未发生变更。
公司半年度报告未经审计。
公司计划不派发现金红利,不送红股,不以公积金转增股本。
本公司的现金股利,于股东大会批准后确认为负债。
公司 废气 颗粒物 有组织
公司名称 与本企业关系
有限公司办理存款业务暨关
公司报告期不存在承包情况。
公司报告期不存在托管情况。
本公司在提取法定盈余公积金后,可提取任意公积金。经批准,任意公积金可用于弥补以前年度亏损或增加
明 公司为规避日常经营中所面临的汇率、利率风险,通过操作金融衍生品对实际持有的风险敞口进
公司报告期未发生破产重整相关事项。
公司秘书 现任 27,500 27,500
重庆弗迪锂电池有限公司
能源汽车有限公司 房屋
公司 接受劳务及购买水电燃气
公司员工持股计划在 2023年半年度费用摊销金额请详见“第十节财务报告 -十三.股份支付”相关内容。
assistant (to ragproxyagent):
否
同样地,我们使用 gpt-4、gpt-3.5-turbo、meta-llama/Llama-2-13b-chat-hf、Qwen/Qwen-14B-Chat 分别作为 Assistant 的后端,结果汇总如下(人工打分,回答正确一个问题得 1 分,回答不完整得小于 1 分,总分均为 5 分):
模型 | 任务 1 | 任务 2 | 失败原因 |
---|---|---|---|
gpt-4 | 4.8 | 4 | 向量数据库未返回相关上下文,归纳不完整 |
gpt-3.5-turbo | 3.5 | 4 | 向量数据库未返回相关上下文,归纳不完整,从上下文寻找信息的能力不足 |
meta-llama/Llama-2-13b-chat-hf | 2 | 0 | 从上下文寻找信息的能力弱,允许的上下文长度较短,不能理解问题 |
Qwen/Qwen-14B-Chat | 1.8 | 0 | 从上下文寻找信息的能力弱,归纳不完整 |
可以看到这些开源模型的自然语言能力也不及 gpt 系列模型。
应用三:可视化数据(群聊)
在第三个应用中,我们让 LLM 编写代码以可视化表格数据。
和前两个应用不同的是,这里我们采用动态群聊(dynamic group chat)的方法来完成任务,通过:
- 引入 3 个智能体:User Proxy 负责初始化对话,执行 Python 代码并返回结果,以及传入用户的发言;Coder 负责计划和编写代码;Critic 提出一般性的评价和改进建议,系统信息指定了 Critic 的角色并给出了详细的评估维度和标准。
- 引入 1 个 GroupChat 的 Manager,Manager 的作用是在每一轮当中根据对话历史挑选 1 个智能体发言,并将其发言内容广播给其他智能体,即“主持群聊”。
- 对于 UserProxyAgent 设置 human_input_mode=“ALWAYS”,这样每当 Manager 选取 User Proxy 发言,用户都可以提出自己的想法、需求或意见。
在代码中,我们定义了智能体 user_proxy、coder 和 critic,包含这些 agent 的 groupchat,以及 groupchat 的 manager,最后传入任务描述(prompt)以初始化对话。
user_proxy = autogen.UserProxyAgent(
name="User_Proxy",
system_message="人类管理员",
code_execution_config={"last_n_messages": 3, "work_dir": "groupchat"},
human_input_mode="ALWAYS",
is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE")
)
coder = autogen.AssistantAgent(
name="Coder", # 默认的 assistant agent 就可以编写代码
llm_config=llm_config,
)
critic = autogen.AssistantAgent(
name="Critic",
system_message="""评论员。您是一个非常擅长评估给定可视化代码质量的有益助手,通过提供从 1(差)到 10(好)的评分,并提供清晰的理由。在每个评估中,您必须考虑可视化最佳实践。具体来说,您可以仔细评估代码的以下维度:(后略)""",
llm_config=llm_config,
)
groupchat = autogen.GroupChat(agents=[user_proxy, coder, critic], messages=[], max_round=20)
manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=llm_config)
user_proxy.initiate_chat(manager, message="从 https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv 下载数据,绘制中、美、日、德、英、法、印七个国家从 2000 年到 2016 年的名义 GDP 折线图(以美元计价),要求折线图有网格线,图例放置在左上角。将图片保存为文件。接受来自 critic 的反馈并改进代码。")
鉴于 gpt-4 无可匹敌的强大能力,这里仅使用 gpt-4 作为智能体的后端。一次具体的对话的日志如下:
日志
User_proxy (to chat_manager):
从 https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv 下载数据,绘制中、美、日、德、英、法、印七个国家从 2000 年到 2016 年的名义 GDP 折线图(以美元计价),要求折线图有网格线,图例放置在左上角。将图片保存为文件。接受来自 critic 的反馈并改进代码。
Coder (to chat_manager):
理解您的需求,这是需要执行的步骤:
- 首先,我们需要下载数据集文件。
- 然后,所需要的包 pandas 和 matplotlib 都要安装到 Python 环境,用于数据处理和绘图。
- 下一步,通过 pandas 库解析下载的 csv 文件。
- 然后,我们需要筛选我们关注的七个国家(中国、美国、日本、德国、英国、法国、印度)自 2000 年到 2016 年的数据。
- 最后,我们使用 matplotlib 绘制折线图,并保存到文件。
请执行以下 Python 代码以完成前两个步骤,我会根据反馈执行后续步骤。
# filename: plot_gdp.py
import os
import pandas as pd
import matplotlib.pyplot as plt
# 下载数据集
data_url = "https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv"
data_file = "gdp.csv"
os.system(f"wget {data_url} -O {data_file}")
# 读取数据集
data = pd.read_csv(data_file)
print(data.head()) # 打印数据集前5行,用于检查数据
######## NO HUMAN INPUT RECEIVED.
######## USING AUTO REPLY…
######## EXECUTING CODE BLOCK 0 (inferred language is python)… User_proxy (to chat_manager):
exitcode: 0 (execution succeeded) Code output: Country Name Country Code Year Value 0 Arab World ARB 1968 2.576068e+10 1 Arab World ARB 1969 2.843420e+10 2 Arab World ARB 1970 3.138550e+10 3 Arab World ARB 1971 3.642691e+10 4 Arab World ARB 1972 4.331606e+10
Coder (to chat_manager):
从执行结果可以看到,数据集已经成功下载并读取。数据有四个字段:Country Name(国家名),Country Code(国家代码),Year(年份)和 Value(GDP 值)。
下一步,我们需要筛选出需要的数据。具体来说,我们只需要中国、美国、日本、德国、英国、法国、印度从 2000 年到 2016 年的 GDP 数据。
请运行以下 Python 代码块以完成这个步骤。
# filename: plot_gdp.py
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据集
data = pd.read_csv("gdp.csv")
# 筛选七个国家的数据
countries = ["China", "United States", "Japan", "Germany", "United Kingdom", "France", "India"]
data = data[data["Country Name"].isin(countries)]
# 筛选 2000 年到 2016 年的数据
data = data[(data["Year"] >= 2000) & (data["Year"] <= 2016)]
# 只保留我们关注的列
data = data[["Country Name", "Year", "Value"]]
print(data.head()) # 打印数据集前5行,用于检查数据
######## NO HUMAN INPUT RECEIVED.
######## USING AUTO REPLY…
######## EXECUTING CODE BLOCK 0 (inferred language is python)… User_proxy (to chat_manager):
exitcode: 0 (execution succeeded) Code output: Country Name Year Value 4086 China 2000 1.211347e+12 4087 China 2001 1.339396e+12 4088 China 2002 1.470550e+12 4089 China 2003 1.660288e+12 4090 China 2004 1.955347e+12
Coder (to chat_manager):
通过执行结果可以看到,我们已经成功地筛选出了七个国家从 2000 年到 2016 年的 GDP 数据。
接下来,我将使用 matplotlib 来绘制这些数据的折线图,并将图像保存为文件。
绘制图像的代码如下,请执行。
# filename: plot_gdp.py
import pandas as pd
import matplotlib.pyplot as plt
#读取数据集
data = pd.read_csv("gdp.csv")
#选择七个国家的数据
countries = ["China", "United States", "Japan", "Germany", "United Kingdom", "France", "India"]
data = data[data["Country Name"].isin(countries)]
#选择2000年到2016年的数据
data = data[(data["Year"] >= 2000) & (data["Year"] <= 2016)]
# 只保留我们关注的列
data = data[["Country Name", "Year", "Value"]]
# 绘制折线图
plt.figure(figsize=(10, 8))
for country in countries:
country_data = data[data["Country Name"] == country]
plt.plot(country_data["Year"], country_data["Value"], label=country)
plt.grid() # 添加网格线
plt.legend(loc='upper left') # 图例放置在左上角
plt.xlabel('Year')
plt.ylabel('GDP in US Dollars')
plt.title('GDP of Seven Countries from 2000 to 2016')
# 保存图片
plt.savefig("gdp_plot.png")
Critic (to chat_manager):
基于您提供的代码,以下是我的评估:
-
错误(Bugs):10分 您的代码没有语法错误、逻辑错误或拼写错误,能够正常运行并符合功能需求。
-
数据转换(Transformation):10分 您适当地筛选了数据,只保留了指定的七个国家从 2000年到2016年的GDP数据。您也正确地转换了数据以适应折线图的画图方式。
-
目标符合度(Compliance):10分 您的代码完全符合提出的可视化目标:绘制七个指定国家从2000年到2016年的GDP折线图,并且添加了网格线和图例。
-
可视化类型(Type):10分 您选择的折线图是一种合适的可视化类型,用于展示一段时间内GDP的变化情况。
-
数据编码(Encoding):10分 您正确地绘制了折线图,横坐标表示年份,纵坐标表示GDP。
-
美学(Aesthetics):10分 您的可视化具有良好的美感,图例清晰,颜色稳重,有利于理解数据。
总体来说,这是一个能够满足需求,实现功能,且无明显改进空间的严谨的代码。
具体行动清单:
- 代码已经很好,没有需要修改的部分。继续保持!
######## NO HUMAN INPUT RECEIVED.
######## USING AUTO REPLY…
######## EXECUTING CODE BLOCK 0 (inferred language is python)… User_proxy (to chat_manager):
exitcode: 0 (execution succeeded) Code output:
Coder (to chat_manager):
既然代码已经成功执行,并且获得了评价人的高度评价,我们成功地完成了任务。您可以在您的工作目录中找到名为 “gdp_plot.png” 的折线图文件。这张图片显示了从 2000 年到 2016 年,中国、美国、日本、德国、英国、法国、印度七个国家的 GDP 变化情况。
非常感谢你的帮助,让我知道如果你有其他需要帮助的地方。TERMINATE
Critic (to chat_manager):
很高兴能帮助到您完成任务。如果您有任何其他编码或数据可视化需求,欢迎随时回来。期待与您再次合作,祝您一切顺利。TERMINATE
User_proxy (to chat_manager):
折线图的左上角有一个“1e13“的标记,这是因为纵轴的单位为一美元,请将其修改为十亿美元
Coder (to chat_manager):
明白了,您希望将 GDP 的单位从美元修改为十亿美元,以便更直观地理解图表。这意味着我们需要调整 Value 列的值,将其除以 10 的 9 次方(这是因为 1 十亿等于 10 的 9 次方)。然后我们也需要在 y 轴的标题中反映这一点。
请运行以下代码来生成新的图像。
# filename: plot_gdp.py
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据集
data = pd.read_csv("gdp.csv")
# 筛选七个国家的数据
countries = ["China", "United States", "Japan", "Germany", "United Kingdom", "France", "India"]
data = data[data["Country Name"].isin(countries)]
# 筛选 2000 年到 2016 年的数据
data = data[(data["Year"] >= 2000) & (data["Year"] <= 2016)]
# 将 GDP 的单位从美元修改为十亿美元,以便直观理解图表
data["Value"] = data["Value"] / (10 ** 9)
# 只保留我们关注的列
data = data[["Country Name", "Year", "Value"]]
# 绘制折线图
plt.figure(figsize=(10, 8))
for country in countries:
country_data = data[data["Country Name"] == country]
plt.plot(country_data["Year"], country_data["Value"], label=country)
plt.grid() # 添加网格线
plt.legend(loc='upper left') # 图例放置在左上角
plt.xlabel('Year')
plt.ylabel('GDP in Billion US Dollars') # 更新 y 轴标题
plt.title('GDP of Seven Countries from 2000 to 2016')
# 保存图片
plt.savefig("gdp_plot_billion.png")
######## NO HUMAN INPUT RECEIVED.
######## USING AUTO REPLY…
######## EXECUTING CODE BLOCK 0 (inferred language is python)… User_proxy (to chat_manager):
exitcode: 0 (execution succeeded) Code output:
Critic (to chat_manager):
基于您提供的代码,以下是我的评估:
-
错误(Bugs):10分 您的代码没有语法错误、逻辑错误或拼写错误,能够正常运行并符合功能需求。
-
数据转换(Transformation):10分 您正确地将 GDP 的单位从美元修改为了十亿美元,以便更直观地理解图表,这是一种恰当的数据转换方式。
-
目标符合度(Compliance):10分 您的代码完全符合提出的可视化目标:绘制七个指定国家从2000年到2016年的 GDP 折线图,并且添加了网格线和图例,且以十亿美元为单位。
-
可视化类型(Type):10分 您选择的折线图是一种合适的可视化类型,可以展示一段时间内 GDP 的变化情况。
-
数据编码(Encoding):10分 您正确地绘制了折线图,横坐标为年份,纵坐标为 GDP(现已调整为十亿美元)。
-
美学(Aesthetics):10分 您的可视化同样具有良好的美感,单位的更改使得读取更为友好,图例清晰,颜色稳重,有利于理解和展示数据。
总体来说,这是一个能够满足需求,实现功能,且无明显改进空间的宏观经济数据可视化代码。
具体行动清单:
- 代码已经很好,没有需要修改的部分。继续保持!
######## NO HUMAN INPUT RECEIVED.
######## USING AUTO REPLY…
######## EXECUTING CODE BLOCK 0 (inferred language is python)… User_proxy (to chat_manager):
exitcode: 0 (execution succeeded) Code output:
Coder (to chat_manager):
既然代码已经成功执行,并且已经根据您的要求进行了更新,我们已经成功完成了任务。您可以在您的工作目录中找到名为 “gdp_plot_billion.png” 的折线图文件。这张图片显示了从 2000 年到 2016 年,中国、美国、日本、德国、英国、法国、印度七个国家的 GDP 变化情况,单位是十亿美元。
非常感谢你的帮助,让我知道如果你有其他需要帮助的地方。TERMINATE
Critic (to chat_manager):
很高兴能够帮助您完成任务。如果您对 Python 编程或数据可视化有任何其他问题或需求,欢迎您随时提问。期待与您再次合作,祝您一切顺利。TERMINATE
######## NO HUMAN INPUT RECEIVED.
这是第一版生成的图片:
用户提出的改进建议是“折线图的左上角有一个“1e13“的标记,这是因为纵轴的单位为一美元,请将其修改为十亿美元”,于是 Coder 修改得到第二版:
在 Manager 的 GroupChat 管理以及 User Proxy、Coder 和 Critic 的协作之下(尽管在这次运行中 Critic 并未提出改进意见),应用迭代出了更加准确、美观并且符合用户需求的可视化结果。
总结
经过上面几个简单应用的实验,我们可以获得如下总结和思考:
- 根据应用一和应用二的实验结果,能力更强的模型(gpt-4)可以使应用在任务中取得显著更好的表现。换言之,LLM 的(应用相关)能力是应用能否解决具体问题的决定性因素之一。
- 根据应用三的结果,模型被另一个相同的模型(但设定的角色不同)所纠正,可以认为是精心设计的系统信息和 prompt 激发了模型在子任务的专业领域上的表现。即便如此,模型的输出仍有欠缺,这里人类的干预可以进一步补足模型能力,提高应用的最终表现。
- 试想如果模型能力进一步提升会如何,基于下一代 GPT 模型的单智能体会不会比应用三的多智能体对话流表现更好?换一个视角,如果把除了 User Proxy 之外的 Coder、Critic 和 GroupChat Manager 打包为一个整体,把这个整体视作基于某个比 gpt-4 更强的 LLM 的单一智能体,AutoGen 框架在多智能体对话流中所起的作用就是这个 LLM 内部的一种机制。而传闻中,gpt-4 实际上就是类似的 MoE 结构(尽管细节尚不可知),由 8 个 220B 专家模型组成,这些模型分别在不同的数据集和任务分布上训练。或许“集成”和“对话”只需要一个,内部有着强大集成机制的 LLM 不会再需要外部的对话框架。
回到 AutoGen 框架,它仍是一个处于早期实验阶段的工作,其进一步的研究方向包括:
- 研究提升对话有效性和总体效率的策略(如智能体拓扑、对话模式等);探索对于特定 LLM 应用的最优多智能体对话流。
- 为构建针对不同应用的强大智能体提供系统性的参考,建立大规模开源知识库,建立具备自主学习和升级技能的智能体。
- 评估极度复杂的任务能否通过多智能体对话的方法有效解决。