引言:为什么多智能体需要一个框架?
当你尝试用单个LLM解决复杂的工程问题时,往往会遇到一个共同的瓶颈:上下文窗口不够用、任务太复杂、错误无法自我纠正。微软研究院给出的答案是 AutoGen —— 一个专为多智能体对话设计的开源框架,它的核心理念是:让多个AI代理相互对话、协作、甚至争辩,最终完成单个代理无法独立完成的任务。
AutoGen 于2023年底发布,迅速成为多智能体领域的标杆工具。2024年,AutoGen 0.4版本进行了彻底的架构重写,引入了事件驱动的异步消息系统。本文将从工程实践角度,深度解析AutoGen的核心设计,以及如何在生产环境中落地。
AutoGen的核心架构
基础对话单元:ConversableAgent
AutoGen的最小单位是 ConversableAgent,它可以:
- 接收消息并生成回复
- 调用工具(Tool Use)
- 与人类协作(Human-in-the-loop)
- 控制对话的终止条件
from autogen import ConversableAgent, config_list_from_json
# 配置LLM
config_list = [
{
"model": "gpt-4o",
"api_key": "YOUR_API_KEY",
}
]
llm_config = {
"config_list": config_list,
"temperature": 0.7,
"timeout": 120,
}
# 创建一个基础Agent
assistant = ConversableAgent(
name="AI助手",
system_message="你是一个专业的Python工程师,擅长代码审查和优化。",
llm_config=llm_config,
human_input_mode="NEVER", # 全自动,不需要人工输入
max_consecutive_auto_reply=10, # 最多自动回复10次
)
# 创建用户代理
user_proxy = ConversableAgent(
name="用户",
human_input_mode="TERMINATE", # 收到TERMINATE时结束对话
code_execution_config={
"work_dir": "coding", # 代码执行工作目录
"use_docker": False, # 是否在Docker中执行
},
)
双智能体对话:最基础的协作模式
# 启动对话
result = user_proxy.initiate_chat(
assistant,
message="请帮我写一个Python函数,计算斐波那契数列的第N项,要求时间复杂度O(1),并附带单元测试。",
)
print(result.summary)
这个对话中,用户代理提出需求,AI助手生成代码,用户代理执行代码,若出错则将错误信息反馈给AI助手,AI助手修复后再执行,直到代码通过测试。这个自我纠错的循环是AutoGen最核心的价值之一。
GroupChat:多智能体协作的关键
当任务需要多个专家时,GroupChat 提供了多智能体的聊天室机制:
from autogen import GroupChat, GroupChatManager
# 创建多个专家Agent
architect = ConversableAgent(
name="架构师",
system_message="""你是资深软件架构师,专注于系统设计和架构决策。
在讨论中,你负责提出架构方案,评估技术选型的合理性。
每次发言结束时,如果需要其他人发言,请明确指出下一步应该谁来处理。""",
llm_config=llm_config,
human_input_mode="NEVER",
)
developer = ConversableAgent(
name="开发工程师",
system_message="""你是高级Python开发工程师,专注于代码实现。
你负责将架构师的设计转化为具体的代码实现,
并关注代码质量、性能和可维护性。""",
llm_config=llm_config,
human_input_mode="NEVER",
code_execution_config={"work_dir": "project", "use_docker": False},
)
qa_engineer = ConversableAgent(
name="测试工程师",
system_message="""你是QA测试工程师,专注于测试策略和质量保证。
你负责审查代码,发现潜在问题,并编写测试用例。
你需要对每个功能模块提出测试方案。""",
llm_config=llm_config,
human_input_mode="NEVER",
)
pm = ConversableAgent(
name="产品经理",
system_message="""你是产品经理,负责需求澄清和验收标准。
当团队完成任务后,你来做最终的验收判断,
如果满足需求则回复TERMINATE结束对话。""",
llm_config=llm_config,
human_input_mode="NEVER",
)
# 配置GroupChat
groupchat = GroupChat(
agents=[architect, developer, qa_engineer, pm],
messages=[],
max_round=20, # 最多讨论20轮
speaker_selection_method="auto", # 自动选择下一个发言者
allow_repeat_speaker=False, # 禁止同一个人连续发言
)
# 创建GroupChatManager(协调者)
manager = GroupChatManager(
groupchat=groupchat,
llm_config=llm_config,
)
# 启动多智能体协作
user_proxy.initiate_chat(
manager,
message="""需求:设计并实现一个分布式任务队列系统,要求:
1. 支持任务优先级(高/中/低)
2. 支持任务重试机制(最多3次)
3. 支持任务超时控制
4. 使用Redis作为消息中间件
请团队协作完成设计和实现。""",
)
发言者选择策略的深度控制
AutoGen提供了几种发言者选择策略:
# 策略1:轮流发言(RoundRobin)
groupchat_rr = GroupChat(
agents=[architect, developer, qa_engineer],
speaker_selection_method="round_robin",
messages=[],
max_round=15,
)
# 策略2:随机选择
groupchat_rand = GroupChat(
agents=[architect, developer, qa_engineer],
speaker_selection_method="random",
messages=[],
max_round=15,
)
# 策略3:自定义选择函数(最灵活)
def custom_speaker_selector(last_speaker, groupchat):
"""根据最后发言者决定下一个发言者"""
messages = groupchat.messages
if last_speaker.name == "架构师":
# 架构师发言后,让开发工程师接手
return groupchat.agent_by_name("开发工程师")
elif last_speaker.name == "开发工程师":
# 开发完成后,让测试工程师审查
return groupchat.agent_by_name("测试工程师")
else:
# 默认让产品经理做最终判断
return groupchat.agent_by_name("产品经理")
groupchat_custom = GroupChat(
agents=[architect, developer, qa_engineer, pm],
speaker_selection_method=custom_speaker_selector,
messages=[],
max_round=20,
)
工具调用:让Agent具备实际执行能力
AutoGen的工具调用机制允许Agent执行真实的函数:
from autogen import register_function
from typing import Annotated
import requests
import json
# 定义工具函数
def search_docs(
query: Annotated[str, "搜索关键词"],
max_results: Annotated[int, "返回结果数量,默认5"] = 5
) -> str:
"""搜索技术文档"""
# 模拟文档搜索
results = [
{"title": f"关于{query}的文档 {i}", "url": f"https://docs.example.com/{query}/{i}"}
for i in range(max_results)
]
return json.dumps(results, ensure_ascii=False)
def run_code(
code: Annotated[str, "要执行的Python代码"],
timeout: Annotated[int, "执行超时秒数,默认30"] = 30
) -> str:
"""在沙箱中执行Python代码"""
import subprocess
try:
result = subprocess.run(
["python", "-c", code],
capture_output=True,
text=True,
timeout=timeout
)
if result.returncode == 0:
return f"执行成功:\n{result.stdout}"
else:
return f"执行失败:\n{result.stderr}"
except subprocess.TimeoutExpired:
return f"执行超时({timeout}秒)"
# 注册工具到Agent
register_function(
search_docs,
caller=assistant, # 谁调用工具
executor=user_proxy, # 谁执行工具
name="search_docs",
description="搜索技术文档,返回相关文档列表",
)
register_function(
run_code,
caller=assistant,
executor=user_proxy,
name="run_code",
description="在沙箱中执行Python代码并返回结果",
)
AutoGen 0.4:事件驱动的新架构
AutoGen 0.4引入了全新的事件驱动架构,这是一次彻底的重构:
AgentChat API(高级接口)
# AutoGen 0.4的新式写法
from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
from autogen_agentchat.teams import RoundRobinGroupChat, SelectorGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_ext.models.openai import OpenAIChatCompletionClient
import asyncio
# 配置模型客户端
model_client = OpenAIChatCompletionClient(
model="gpt-4o",
api_key="YOUR_API_KEY",
)
# 创建Agent(新API)
assistant = AssistantAgent(
name="assistant",
model_client=model_client,
system_message="你是一个专业的技术顾问,擅长解决复杂的工程问题。",
)
# 终止条件:当对话中出现"TERMINATE"时结束
termination = TextMentionTermination("TERMINATE")
# 创建团队
team = RoundRobinGroupChat(
participants=[assistant],
termination_condition=termination,
max_turns=10,
)
# 异步运行
async def main():
result = await team.run(
task="请设计一个高可用的微服务架构,支持水平扩展和故障自愈。"
)
print(result.messages[-1].content)
asyncio.run(main())
SelectorGroupChat:智能发言者选择
from autogen_agentchat.teams import SelectorGroupChat
# 创建专业团队
coder = AssistantAgent(
name="coder",
model_client=model_client,
system_message="你是Python专家,负责代码实现。只在需要编写代码时发言。",
)
reviewer = AssistantAgent(
name="reviewer",
model_client=model_client,
system_message="你是代码审查专家,在coder完成代码后进行审查。",
)
tester = AssistantAgent(
name="tester",
model_client=model_client,
system_message="你是测试专家,在reviewer审查通过后编写测试用例。",
)
# SelectorGroupChat使用LLM智能选择下一个发言者
selector_team = SelectorGroupChat(
participants=[coder, reviewer, tester],
model_client=model_client, # 用LLM来决定发言顺序
termination_condition=TextMentionTermination("完成"),
)
生产环境实践要点
1. 消息持久化与对话恢复
import pickle
from pathlib import Path
class PersistentGroupChat:
def __init__(self, chat_id: str, save_dir: str = "./chats"):
self.chat_id = chat_id
self.save_path = Path(save_dir) / f"{chat_id}.pkl"
def save(self, groupchat: GroupChat):
"""保存对话状态"""
self.save_path.parent.mkdir(parents=True, exist_ok=True)
with open(self.save_path, 'wb') as f:
pickle.dump({
'messages': groupchat.messages,
'agents': [a.name for a in groupchat.agents],
}, f)
def load(self) -> dict | None:
"""恢复对话状态"""
if self.save_path.exists():
with open(self.save_path, 'rb') as f:
return pickle.load(f)
return None
2. 成本控制与Token管理
from autogen import token_count_utils
class CostAwareAgent(ConversableAgent):
def __init__(self, *args, max_tokens_per_session=50000, **kwargs):
super().__init__(*args, **kwargs)
self.max_tokens = max_tokens_per_session
self.total_tokens = 0
def _process_received_message(self, message, sender, silent):
# 估算token消耗
tokens = len(str(message).split()) * 1.3 # 粗略估算
self.total_tokens += int(tokens)
if self.total_tokens > self.max_tokens:
return True # 返回True终止对话
return super()._process_received_message(message, sender, silent)
3. 错误处理与重试机制
import time
from functools import wraps
def with_retry(max_retries=3, delay=2.0, backoff=2.0):
"""装饰器:为Agent操作添加重试逻辑"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
last_error = None
current_delay = delay
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
last_error = e
if attempt < max_retries - 1:
print(f" 第{attempt+1}次尝试失败: {e},{current_delay}秒后重试...")
time.sleep(current_delay)
current_delay *= backoff
raise last_error
return wrapper
return decorator
@with_retry(max_retries=3)
def safe_initiate_chat(proxy, assistant, message):
return proxy.initiate_chat(assistant, message=message)
典型应用场景与最佳实践
场景1:代码生成与自动修复流水线
# 代码生成 → 执行 → 报错 → 自动修复的完整循环
coding_agent = ConversableAgent(
name="coding_agent",
system_message="""你是一个代码生成专家。
当收到代码执行错误时,分析错误原因并修复代码。
代码必须可以直接运行,不需要任何额外依赖(除标准库外)。
修复完成后,明确说明修改了什么。""",
llm_config=llm_config,
human_input_mode="NEVER",
)
executor = ConversableAgent(
name="executor",
human_input_mode="NEVER",
code_execution_config={
"work_dir": "generated_code",
"use_docker": True, # 生产环境强烈建议使用Docker隔离
"timeout": 60,
"last_n_messages": 3,
},
default_auto_reply="", # 执行完自动回复空字符串等待
is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
)
场景2:研究助手工作流
多个专家Agent协作完成技术调研报告:文献搜索 → 内容分析 → 写作 → 校对,每个环节由专门的Agent负责,确保输出质量。
场景3:持续集成中的代码审查
将AutoGen集成到CI/CD流水线,PR提交时自动触发多Agent审查:
- 安全Agent:检查安全漏洞
- 性能Agent:分析时间/空间复杂度
- 规范Agent:检查代码风格和文档
- 综合Agent:汇总所有意见生成审查报告
与其他框架的对比
| 特性 | AutoGen | LangGraph | CrewAI |
|---|---|---|---|
| 对话驱动 | ✅ 原生 | ❌ 需封装 | ✅ 支持 |
| 状态管理 | 对话历史 | 显式图状态 | 任务状态 |
| 人机协作 | ✅ 一等公民 | ⚠️ 需要实现 | ⚠️ 基础支持 |
| 代码执行 | ✅ 内置 | ❌ 需集成 | ❌ 需集成 |
| 学习曲线 | 中等 | 较高 | 较低 |
| 生产成熟度 | 高 | 高 | 中等 |
总结
AutoGen的核心价值在于将复杂任务分解为多个智能体之间的对话,通过自然语言的交互和自动的错误纠正循环,实现了超越单个模型能力的任务完成能力。
对于工程团队来说,AutoGen最适合的场景是:
- 代码生成与自动修复:充分利用其代码执行+自我纠错的能力
- 复杂技术决策:用多个专家角色模拟真实的技术评审
- 长流程自动化:将多步骤工作流转化为Agent之间的对话
随着0.4版本事件驱动架构的成熟,AutoGen正在向更大规模、更可靠的生产部署迈进。掌握AutoGen,是构建企业级多智能体系统的重要一步。