hello-agents学习笔记--AutoGen框架

AutoGen

AutoGen 是一个面向多智能体协作的开发框架。它的核心不是让一个大模型单独完成所有事情,而是把任务拆给多个具有不同职责的智能体,让它们通过对话协作完成任务。

在软件开发场景中,可以把不同智能体看作一个虚拟开发团队:产品经理负责分析需求,工程师负责写代码,代码审查员负责检查质量,用户代理负责反馈或验收。整个任务的推进过程,本质上就是这些角色之间的一轮轮消息传递。


6.2.1 AutoGen 的核心机制

AutoGen 的核心思想可以概括为:用对话组织协作,用角色拆分任务

在新版本架构中,AutoGen 更强调模块化和异步执行。底层能力主要由 autogen-core 提供,上层对话式智能体开发主要由 autogen-agentchat 提供。这样设计的好处是职责更清晰:底层负责模型交互、消息传递等基础能力,上层负责更方便地搭建多智能体应用。

AutoGen 中最常用的智能体是 AssistantAgent。它由大语言模型驱动,可以根据系统提示词自动生成回复。产品经理、工程师、代码审查员这类角色一般都适合用它来实现。

python 复制代码
AssistantAgent(
    name="Engineer",
    model_client=model_client,
    system_message="你是一位资深 Python 工程师,负责根据需求编写完整代码。"
)

这里真正重要的是 system_message。它决定了智能体的角色边界、任务目标和输出方式。多智能体系统能不能稳定协作,很大程度上取决于这些角色提示词是否清楚。

另一个重要组件是 UserProxyAgent。它和 AssistantAgent 不同,并不是普通的自动回复智能体,而是用于引入真实用户反馈。流程走到它时,通常会等待用户输入。因此,如果程序运行到"请用户代理测试"后不继续输出,往往不是卡死,而是轮到 UserProxyAgent 等待人工输入。

多个智能体需要通过团队机制组织起来。案例中使用的是 RoundRobinGroupChat,也就是轮询群聊。它会按照 participants 中的顺序让智能体依次发言。

python 复制代码
team_chat = RoundRobinGroupChat(
    participants=[product_manager, engineer, code_reviewer, user_proxy],
    termination_condition=TextMentionTermination("TERMINATE"),
    max_turns=20,
)

这个流程可以理解为:

text 复制代码
产品经理 → 工程师 → 代码审查员 → 用户代理 → 再循环

为了避免对话无限进行,需要设置终止条件。TextMentionTermination("TERMINATE") 表示:只要某条消息中出现 TERMINATE,团队协作就结束。max_turns 则是保险机制,防止智能体忘记输出终止词。


6.2.2 软件开发团队

这一节用 AutoGen 构建了一个模拟软件开发团队,任务是开发一个比特币价格显示应用。这个案例虽然不复杂,但完整包含了需求分析、代码实现、代码审查和用户测试几个典型环节,所以很适合用来展示 AutoGen 的多智能体协作流程。

这个团队主要包含四个角色。

ProductManager 负责把用户需求转化成清晰的开发计划。它需要分析功能需求、划分模块、提出技术建议,并给出验收标准。它的输出重点不是代码,而是让后续工程师知道要做什么、怎么做、做到什么程度算完成。

Engineer 负责根据产品经理的分析编写具体代码。在案例中,它需要使用 Streamlit 实现一个比特币价格显示应用,包括当前价格、24 小时涨跌情况、刷新功能、错误处理和加载状态。

CodeReviewer 负责检查工程师提交的代码。它关注的是代码质量、可读性、安全性、异常处理和是否符合需求。这个角色相当于开发流程中的质量关卡。

UserProxy 代表用户参与最终反馈。它可以用于人工验收,也可以在任务完成后输入 TERMINATE 结束流程。不过需要注意,UserProxyAgent 通常不会自动完成测试,它更像是等待用户输入的接口。

这个案例的重点不是"生成一个比特币应用",而是展示如何把一个开发任务拆成多个角色,并让它们按照固定流程协作。


6.2.3 核心代码实现

代码实现可以分成四个关键部分:模型客户端、智能体定义、团队编排、任务运行。

首先是模型客户端配置。所有基于 LLM 的智能体都需要通过模型客户端调用大模型。AutoGen 使用 OpenAIChatCompletionClient 来连接 OpenAI 或兼容 OpenAI API 的模型服务。

python 复制代码
def create_openai_model_client():
    return OpenAIChatCompletionClient(
        model=os.getenv("LLM_MODEL_ID"),
        api_key=os.getenv("LLM_API_KEY"),
        base_url=os.getenv("LLM_BASE_URL")
    )

实际开发中,API Key 不应该写死在代码里,而应该放到 .env 文件中。这样更安全,也方便切换不同模型。

如果使用 DeepSeek、通义千问等非 OpenAI 官方模型,通常还需要补充 model_info,告诉 AutoGen 这个模型支持哪些能力,例如函数调用、JSON 输出、上下文长度等。

python 复制代码
model_info={
    "function_calling": True,
    "max_tokens": 4096,
    "context_length": 32768,
    "vision": False,
    "json_output": True,
    "family": "deepseek",
    "structured_output": True,
}

第二步是定义不同智能体。以产品经理为例,本质上就是用 AssistantAgent 加一段明确的系统提示词。

python 复制代码
product_manager = AssistantAgent(
    name="ProductManager",
    model_client=model_client,
    system_message="你是产品经理,负责需求分析和项目规划,完成后请工程师开始实现。"
)

工程师和代码审查员也是类似的方式,只是 system_message 不同。工程师要被要求输出完整代码,代码审查员要被要求检查质量并给出审查意见。

第三步是定义团队协作流程。RoundRobinGroupChatparticipants 顺序决定了发言顺序。

python 复制代码
team_chat = RoundRobinGroupChat(
    participants=[
        product_manager,
        engineer,
        code_reviewer,
        user_proxy
    ],
    termination_condition=TextMentionTermination("TERMINATE"),
    max_turns=20,
)

这里最容易出问题的是 user_proxy。如果它是 UserProxyAgent,流程走到它时会等待用户输入。所以当输出停在:

text 复制代码
代码审查完成,请用户代理测试

后面没有继续,很可能是因为系统正在等待你手动输入,而不是模型没有响应。

如果想让流程自动结束,可以不要使用 UserProxyAgent,而是改成一个普通的测试智能体:

python 复制代码
tester = AssistantAgent(
    name="Tester",
    model_client=model_client,
    system_message="你是测试工程师,负责检查代码是否满足需求。如果可以接受,最后输出 TERMINATE。"
)

然后团队顺序改为:

python 复制代码
participants=[
    product_manager,
    engineer,
    code_reviewer,
    tester
]

这样流程就可以自动走完。

最后是运行任务。由于 AutoGen 新版本大量使用异步接口,所以运行时通常写成:

python 复制代码
result = await Console(team_chat.run_stream(task=task))

主程序中用:

python 复制代码
asyncio.run(run_software_development_team())

启动整个协作流程。


  • 运行结果(删减后便于展示):
text 复制代码
PS C:\Users\27807\Desktop\研究生\Agent\Framework\AutoGen>
& D:\yyq\Anaconda\python.exe autogen_software_team.py

🔧 正在初始化模型客户端...
👥 正在创建智能体团队...
🚀 启动 AutoGen 软件开发团队协作...
============================================================

---------- TextMessage (user) ----------
开发一个比特币价格显示应用:
- 实时显示比特币当前价格(USD)
- 显示 24 小时价格变化趋势
- 提供价格刷新功能
- 使用 Streamlit 创建 Web 应用
- 添加错误处理和加载状态

---------- TextMessage (ProductManager) ----------
需求分析完成:

该应用属于典型的金融信息看板场景,核心目标是让用户快速、直观地查看 BTC/USD 当前价格及 24 小时涨跌情况。

功能模块划分:
1. 数据获取模块:调用 CoinGecko API 获取 BTC 价格数据
2. 核心展示模块:突出显示当前价格、涨跌额和涨跌幅
3. 交互控制模块:提供手动刷新和自动刷新能力

技术建议:
- 使用 Streamlit 快速构建数据应用
- 使用 CoinGecko 免费 API 作为数据源
- 使用 st.metric 展示价格和涨跌信息
- 使用 try...except 和 st.error 处理异常

请工程师开始实现。

---------- TextMessage (Engineer) ----------
代码实现完成:

实现方案:
- 使用 CoinGecko /coins/markets 接口获取当前价格、24h 涨跌额和涨跌幅
- 使用 Streamlit 构建页面
- 使用 st.spinner 提供加载状态
- 使用 st.session_state 保存上次更新时间和价格数据
- 使用 st.button 实现手动刷新
- 通过自定义 CSS 美化价格展示卡片
- 对网络超时、连接错误、HTTP 错误和数据解析异常进行处理

请代码审查员检查。

---------- TextMessage (CodeReviewer) ----------
代码审查结论:

整体代码结构清晰,功能完整,基本满足产品需求。工程化思路较好,包含模块划分、状态管理、错误处理和界面优化。

主要审查建议:
1. 删除未完成且未使用的 get_bitcoin_price() 函数
2. 避免使用 while True + time.sleep 实现自动刷新,否则可能阻塞 Streamlit 应用
3. 建议使用 st.cache_data(ttl=60) 管理 API 缓存和刷新周期
4. 清理与最终实现不一致的过时注释
5. 对 API 返回数据做更严格的字段校验

代码审查完成,请用户代理测试。

TERMINATE

---------- TextMessage (UserProxy) ----------
TERMINATE

============================================================
✅ 团队协作完成!

📋 协作结果摘要:
- 参与智能体数量:4 个
- 任务完成状态:成功

6.2.4 AutoGen 的优势与局限性分析

AutoGen 的优势在于它把复杂任务变成了多个角色之间的协作。开发者不需要一开始就设计复杂的状态机,只需要先想清楚:有哪些角色、每个角色负责什么、它们按什么顺序交流、什么时候结束。

这种方式特别适合流程比较明确的任务,比如软件开发、代码审查、文档生成、方案讨论和多角色评审。RoundRobinGroupChat 可以让流程变得清晰可控,UserProxyAgent 又可以在关键节点引入人工反馈,避免系统完全无人监督。

但 AutoGen 也有明显局限。首先,LLM 输出本身有不确定性。即使写了系统提示词,智能体也可能没有严格按照预期输出,比如忘记说 TERMINATE、重复讨论、偏离自己的角色,或者把别人的任务也做了。

其次,多智能体系统的调试比普通程序更麻烦。普通代码出错会有异常栈,而 AutoGen 出问题时,往往要回看整段对话历史,判断到底是哪个智能体的提示词不清楚、哪个环节的终止条件没设计好,还是发言顺序不合理。

最后,UserProxyAgent 很容易被初学者误用。它不是自动测试员,而是用户代理。需要人工参与时用它是合适的;如果想让流程自动执行,就应该用 AssistantAgent 模拟测试员。

总结来说,AutoGen 的价值不在于"让一个模型自动完成所有任务",而在于提供了一套多智能体协作机制。它适合把复杂任务拆成多个角色,通过对话一步步推进。使用时最关键的是三点:角色定义要清楚,协作顺序要合理,终止条件要明确。