Agent来了0x0a:AutoGen 进阶

前言

前面学习了 AutoGen 基础,今天通过几个简单的应用场景来理解 MAS 的应用。

Agent 协同方式

上节讲了几个多 Agent 的通讯机制,但具体 AutoGen 内部多个 Agent 之间是怎么协调的?谁先谁后的顺序是由谁决定的?

RoundRobinGroupChat

RoundRobinGroupChat ,轮询群聊,是 MAS 系统中最简单的协同调度器。传入一个智能体列表 [A, B, C],系统会严格按照 A→B→C→A→B→C...的顺序循环执行,每个智能体在轮到自己时向全体广播消息。

  • max_turns:最大轮次
  • termination_condition:终止条件,如关键词触发。作用是防止无限循环。

SelectorGroupChat

SelectorGroupChat ,选择器群聊,是基于 LLM 的智能调度器。每轮对话后,系统会将完整的对话历史、各个智能体的角色描述(name, description)提交给一个LLM(即selector),由这个LLM根据当前上下文判断"下一步谁最合适发言"。

  • allow_repeated_speaker:默认Flase,防止同一智能体霸占对话
  • selector_func:支持自定义选择逻辑,实现类似状态机的复杂流转

Swarm

Swarm ,蜂群模式。智能体通过发送特殊的 HandoffMessage来主动将任务"移交"给另一个智能体。系统不依赖中央调度器,而是根据最新的移交信号来决定下一个发言者。去中心化自主性 设计的典型案例。

GraphFlow

GraphFlow ,工作流模式,是一种基于有向图的显式流程编排模式 。开发者使用 DiGraphBuilder等API,像画流程图一样,用节点(智能体)和边(执行顺序与条件)来定义精确的工作流。中心化控制确定性 设计的典型案例。

  • 支持顺序、并行、条件分支和循环等复杂逻辑。消息传递路径是预先定义且确定的,控制力极强。

MagenticOneGroupChat

MagenticOneGroupChat ,M1编排器群聊,Magentic-One 通用多智能体系统的 "大脑"或"总指挥" 。它是一个高层抽象,将复杂的任务规划、工具调用(如网页浏览、文件操作)逻辑封装了起来。你提供一组智能体,它来负责指挥。

MagenticOne

MagenticOne ,M1辅助类。他是 MagenticOneGroupCha t的一个便捷封装。它会自动为你创建并集成一整套预定义的专家智能体 ,如 MultimodalWebSurfer(网页浏览)、FileSurfer(文件操作)、Coder(代码编写)和 Executor(代码执行)等。M1 相关的设计模式都是模型驱动的智能调度

  • "开箱即用"

该有哪个?

协同方式 应用场景
RoundRobinGroupChat 固定流程的流水线作业,如"反思模式"(写手与评论家轮流迭代)。
SelectorGroupChat 复杂、非固定流程的专家会诊,如根据症状动态选择专科医生。
Swarm 灵活的客服转接、跨领域问题会诊等需要智能体自主协商移交任务的场景。
GraphFlow 严格的业务流程、审批流水线、数据处理管道等需要精确编排的确定性工作流。
MagenticOneGroupChat 解决跨领域的开放式复杂任务,特别是涉及网页搜索、文件处理、代码编写与执行的综合性研究或自动化。
MagenticOne 快速搭建具备多模态感知和复杂任务执行能力的智能体团队,用于概念验证或快速开发。

🌰论文搜集

需求背景

使⽤autoGen通过多agent群聊搜集LLM⽂献实例。从arxiv上找到最新的5篇关于 Agent 的论文,保存到markdown表。并在同目录生成一个md格式的文件,用于存储该表格。

任务拆解

  • 编写脚本搜集资料
  • 仔细审查搜集资料,判断有效性。并针对性分类

角色定义

  • Planner (AssistantAgent):规划师,负责整个任务规划、管理和分配
ini 复制代码
# 创建一个计划员assistant
planner = AssistantAgent(
    name="Planner",
    system_message="""规划师。提出计划。根据管理员和评论员的反馈修改计划,直到管理员批准。
    该计划可能涉及会写代码的工程师Engineer和不会写代码的科学家Scientist。
    首先解释一下计划。明确哪一步由工程师执行,哪一步由科学家执行。
    """,
    model_client=model_client,
)
  • Admin (UserProxyAgent):人类管理员,规划师互动,讨论计划。授权其他角色行动
ini 复制代码
# 创建一个管理员Proxy
user_proxy = UserProxyAgent(
    name="Admin",
    description="人类管理员. 与规划师互动,讨论计划。计划执行需要得到该管理员的批准。",
)
  • Engineer(AssistantAgent):工程师,负责写代码来解决对应问题
ini 复制代码
# 创建一个工程师assistant
engineer = AssistantAgent(
    name="Engineer",
    model_client=model_client,
    system_message="""工程师。您遵循已批准的计划。您编写 python/shell 代码来解决任务。
    将代码包装在指定脚本类型的代码块中。用户无法修改您的代码。因此,不要建议需要其他人修改的不完整代码。
    如果代码块不打算由执行器执行,请不要使用它。
    不要在一个响应中包含多个代码块。不要要求其他人复制和粘贴结果。检查执行器返回的执行结果。
    如果结果表明存在错误,请修复错误并再次输出代码。建议使用完整代码而不是部分代码或代码更改。
    如果错误无法修复,或者即使代码成功执行后任务仍未解决,请分析问题,重新审视您的假设,
    收集您需要的其他信息,并考虑尝试其他方法。
    """,
)
  • Critic (AssistantAgent):审核员,检查其他代理商的计划、声明和代码并提供反馈,同时决定是否需要 Admin 干预
ini 复制代码
# 创建一个评论家assistant
critic = AssistantAgent(
    name="Critic",
    system_message="批评家。仔细检查其他代理商的计划、声明和代码并提供反馈。检查计划是否包括添加可验证信息,例如源 URL。"
                   "你的工作完成后请以'人类管理员'的称呼明确告知管理员是否需要干预",
    model_client=model_client,
)
  • Executor(CodeExecutorAgent):代码执行器,执行代码并返回结果。
ini 复制代码
code_executor = DockerCommandLineCodeExecutor(work_dir="../paper")
await code_executor.start()

# 创建一个执行者Proxy
executor = CodeExecutorAgent(
    name="Executor",
    description="执行器。执行工程师编写的代码并报告结果。",
    model_client= model_client,
    code_executor=code_executor
)
  • Scientist(CodeExecutorAgent):科学家。可以对论文进行鉴别、分类。以及进一步专业处理。
ini 复制代码
# 创建一个科学家assistant
scientist = AssistantAgent(
    name="Scientist",
    model_client=model_client,
    system_message="""科学家。你遵循一个已批准的计划。你可以在看到论文摘要后对论文进行分类。你不写代码。""",
)

协作方式

这里是用 RoundRobinGroupChat,还是 SelectorGroupChat 呢?其实从程序执行上都可以,都是可以得出最终结果的。但是前者往往更适合固定流程的 case ,但是本场景中几个角色发言可能是不固定的,所以这里选择 SelectorGroupChat 更好一些。

scss 复制代码
agent_team = SelectorGroupChat(
    [user_proxy, engineer, scientist, planner, executor, critic],
    model_client = model_client
)

print("\033[1;31m本程序因为要访问arxiv需要科学上网!请先检查人类管理员检查是否开启了科学上网!\033[0m")

stream = agent_team.run_stream(task="从arxiv上找到最新的5篇关于 Agent 的论文,保存到markdown表。并在同目录生成一个md格式的文件,用于存储该表格。"
                                    "请问人类管理员对该计划是否有调整?如有,请告知我")
await Console(stream)

运行分析

  1. Selecter(LLM)选择 Engineer 开始写相关查询代码
  1. Selecter(LLM)选择 Executor 来执行和验证 Engineer 写的代码
  1. 代码执行报错后,Selecter(LLM)选择 Critic 进行审查,对代码给出了修改建议
  1. 基于 3 的变动,Admin 询问 人类管理员是否需要干预

  2. Executor 继续执行 -> Critic审查 -> 人类干预 循环直到代码完全可靠

    • 这里可能执行多轮
  1. Executor 终于生成了我们要的 md 格式的论文汇总表格
  1. 最后还给出了一些建议
  1. paper 目录下是 LLM 不断自我修正中产生的py中间代码最后一个完整且正确的代码,我们自己执行也会生成对应的 md 表格。

🌰数据分析

使⽤ autoGen 分析数据并绘制对应图标。

Coder

ini 复制代码
coder = AssistantAgent(
    name="Coder",
    model_client=model_client,
)

Executor

ini 复制代码
code_executor = DockerCommandLineCodeExecutor(work_dir="workspace/dataanalysis")
await code_executor.start()
executor = CodeExecutorAgent(
    name="Executor",
    code_executor=code_executor
)

Critic

ini 复制代码
critic = AssistantAgent(
    name="Critic",
    system_message="""
    评论家。您是一位乐于助人的助手,能够通过提供 1(差)- 10(好)的分数来评估给定可视化代码的质量,同时提供明确的理由。您必须为每次评估考虑可视化最佳实践。具体来说,您可以从以下维度仔细评估代码
    - 错误(bug):是否存在错误、逻辑错误、语法错误或拼写错误?代码编译失败的原因是什么?应该如何修复?如果存在任何错误,错误分数必须小于 5。
    - 目标合规性(合规性):代码与指定可视化目标的符合程度如何?
    
    您必须为上述每个维度提供分数。
    {bug:0,合规性:0}
    不建议代码。
    最后,根据上述批评,建议程序员应采取的具体行动清单,以改进代码。
    """,
    model_client=model_client,
)

测试代码

ini 复制代码
team = RoundRobinGroupChat([coder, executor, critic], max_turns=20)
stream = team.run_stream(task="从 https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv 下载数据并告诉我每种天气的数量。将图保存到文件中。在可视化数据集之前打印数据集中的字段。接受评论者的反馈以改进代码。")
await Console(stream)

运行

过程就不做过多分析,直接上结果。

🌰查看股价

查看估价信息。

Coder

ini 复制代码
# 创建助手代理
assistant = AssistantAgent(
    name="Coder",
    system_message='''你需要编写 python/shell 代码来解决任务。将代码包装在指定脚本类型的代码块中。
    用户无法修改您的代码。因此,不要建议需要其他人修改的不完整代码。如果代码块不打算由执行器执行,请不要使用它。
    不要在一个响应中包含多个代码块。不要要求其他人复制和粘贴结果。检查执行器返回的执行结果。
    如果结果表明存在错误,请修复错误并再次输出代码。建议使用完整代码而不是部分代码或代码更改。
    如果错误无法修复,或者即使代码成功执行后任务仍未解决,请分析问题,重新审视您的假设,收集您需要的其他信息,
    并考虑尝试其他方法。''',
    model_client=model_client
)

Executor

ini 复制代码
# 创建代码执行器
code_executor = DockerCommandLineCodeExecutor(work_dir="workspace/stockprice")
await code_executor.start()

# 创建执行器代理
executor = CodeExecutorAgent(
    name="Executor",
    code_executor=code_executor
)

终止条件

ini 复制代码
max_msg_termination = MaxMessageTermination(max_messages=10)
text_termination = TextMentionTermination("TERMINATE")
combined_termination = max_msg_termination | text_termination

测试代码

ini 复制代码
# 创建团队聊天
team = RoundRobinGroupChat(
    [assistant, executor],
    termination_condition=combined_termination
)

# 运行任务
stream = team.run_stream(task="今天是几号,获取美团公司(三快科技)本月至今的股票变化信息,并且用文字对股票变化进行分析。同时获取最近一周美团的股价信息,并绘制成K线图,生成图片保存到当前目录!")
await Console(stream)

🌰数据生成可视化图

Coder

ini 复制代码
coder = AssistantAgent(
    name="Coder",
    model_client=model_client,
    system_message="务必全程使用中文进行交流和反馈!!!"
)

Executor

ini 复制代码
code_executor = DockerCommandLineCodeExecutor(work_dir="workspace/visualization")
await code_executor.start()
executor = CodeExecutorAgent(
    name="Executor",
    code_executor=code_executor,
    system_message="务必全程使用中文进行交流和反馈!!!"
)

Critic

ini 复制代码
critic = AssistantAgent(
        name="Critic",
        system_message="""
        评论家。您是一位乐于助人的助手,能够通过提供 1(差)- 10(好)的分数来评估给定可视化代码的质量,同时提供明确的理由。您必须为每次评估考虑可视化最佳实践。具体来说,您可以从以下维度仔细评估代码
- 错误(bug):是否存在错误、逻辑错误、语法错误或拼写错误?代码编译失败的原因是什么?应该如何修复?如果存在任何错误,错误分数必须小于 5。
- 数据转换(transformation):数据是否针对可视化类型进行了适当的转换?例如,数据集是否根据需要进行了适当的过滤、聚合或分组?如果使用日期字段,是否先将日期字段转换为日期对象等?
- 目标合规性(compliance):代码与指定可视化目标的匹配程度如何?
- 可视化类型 (type):考虑最佳实践,可视化类型是否适合数据和意图?是否有更有效地传达见解的可视化类型?如果其他可视化类型更合适,则分数必须小于 5。
- 数据编码 (encoding):数据是否适合可视化类型编码?
- 美学 (aestics):可视化的美学是否适合可视化类型和数据?

您必须为上述每个维度提供分数。
{错误:0,转换:0,合规性:0,类型:0,编码:0,美观性:0}
不建议代码。
最后,根据上述批评,建议程序员应采取的具体行动清单,以改进代码。
要求:务必全程使用中文进行交流和反馈!!!"
""",
        model_client=model_client,
    )

测试代码

ini 复制代码
team = RoundRobinGroupChat(
    [coder, executor, critic],
    max_turns=20,
)

stream = team.run_stream(task="从 https://raw.githubusercontent.com/uwdata/draco/master/data/cars.csv 下载数据并绘制可视化图,告诉我们重量和马力之间的关系。将图保存到文件中。在可视化之前打印数据集中的字段。")
await Console(stream)

源码

github

相关推荐
Flittly2 小时前
【SpringAIAlibaba新手村系列】(7)结构化输出与对象映射
java·spring boot·agent
无责任此方_修行中2 小时前
"JavaScript"这个名字,到底属于谁?一场价值74亿美元的法律战争
前端·javascript·程序员
宇擎智脑科技2 小时前
Claude Code 源码分析(五):分层记忆体系 —— AI Agent 的知识持久化架构
人工智能·agent·claude code
LuoQuHen2 小时前
第十一章:Agent的“雷区“与边界—— 幻觉、安全、工程化与伦理挑战
人工智能·ai·agent
SimonKing3 小时前
IntelliJ IDEA AI Assistant 携带OpenCode保姆级安装教程来了
java·后端·程序员
默 语3 小时前
Web Access:一个Skill,拉满Agent联网和浏览器能力
前端·agent·skill
iiiiii113 小时前
【LLM学习笔记】Batch Normalization vs Layer Normalization,为什么 NLP 中使用 LN 而非 BN
笔记·深度学习·学习·语言模型·大模型·llm·transformer
蜘蛛侠..3 小时前
什么是React模式?ReAct 是怎么实现的?你的项目中有实际体现React吗?
ai·llm·agent·react·reasoning·acting
云雾J视界3 小时前
2026年AI Agent框架选型指南:OpenClaw vs LangChain vs AutoGen 深度对比
大数据·人工智能·langchain·agent·open claw