多 Agent 协作实战:CrewAI / AutoGen 框架对比与生产级架构设计

多 Agent 协作实战:CrewAI / AutoGen 框架对比与生产级架构设计

前言: 上篇文章讲了单 Agent 的三大范式(ReAct / Plan-and-Execute / Reflexion),这篇聊聊更复杂的场景------多 Agent 协作。当单个 Agent 的能力不够用的时候,怎么让多个 Agent 配合工作?这篇文章对比主流框架,给出生产级架构设计的思路。


先说清楚:什么时候需要多 Agent?

多 Agent 不是银弹。能用单 Agent 解决的,不要用多 Agent。

多 Agent 的适用场景:

复制代码
✅ 适合多 Agent 的场景:
├── 任务需要多种专业能力(写代码 + 搜索 + 发邮件)
├── 需要多人协作的工作流程(写稿 + 审核 + 发布)
├── 信息需要从多个来源汇总(多平台搜索 → 整合)
└── 需要相互校验的任务(生成 + 审查 + 修订)

❌ 不适合多 Agent 的场景:
├── 简单问答(直接问就行)
├── 单一步骤任务(不需要协作)
└── 实时性要求极高(多 Agent 有通信开销)

1. 多 Agent 协作模式

1.1 四种基本模式

python 复制代码
"""
多 Agent 协作的四种基本模式
"""

# 模式1:层次式(Hierarchical)
# ┌─────────────┐
# │  Manager    │  ← 负责任务分配、结果汇总
# └──────┬──────┘
#    ┌───┴───┐
# ┌──┴──┐ ┌──┴──┐
# │Worker│ │Worker│  ← 负责执行具体任务
# └─────┘ └─────┘
HIERARCHICAL_PATTERN = """
特点:有一个中心协调者(Manager),分解任务给下属 Worker
优点:清晰、易理解
缺点:Manager 可能成为瓶颈
适用:任务明确、可分解的场景
"""


# 模式2:并行式(Parallel)
# ┌────────────────────┐
# │       Task         │
# └─────────┬──────────┘
#      ┌────┴────┐
#   ┌──┴──┐  ┌──┴──┐
#   │Agent│  │Agent│  ← 同时处理
#   └──┬──┘  └──┬──┘
#      └────┬────┘
#      ┌────┴────┐
#   ┌──┴──┐  ┌──┴──┐
#   │Agent│  │Agent│  ← 结果汇总
#   └─────┘  └─────┘
PARALLEL_PATTERN = """
特点:多个 Agent 同时工作,结果汇总
优点:速度快、并行度高
缺点:结果可能冲突,需要裁决机制
适用:信息收集、多方案生成
"""


# 模式3:环形协作(Round-robin)
# ┌──────────────────────────────────────┐
# │                                       │
# │  Agent-A → Agent-B → Agent-C → Agent-A│
# │                                       │
# │  每一轮的输出是下一轮的输入           │
# └──────────────────────────────────────┘
ROUND_ROBIN_PATTERN = """
特点:Agent 轮流处理,每一轮的输出影响下一轮
优点:可以逐步完善、相互补充
缺点:速度慢,可能陷入循环
适用:创意生成、写作修订
"""


# 模式4:网状式(Mesh)
#     ┌──────┐
#     │Agent │
#     │  A   │◄──────►┌──────┐
#     └───┬───┘        │Agent │
#         │            │  B   │
#     ┌───┴───┐        └───┬───┘
#     │Agent  │◄──────►───┘
#     │  C   │
#     └───────┘
MESH_PATTERN = """
特点:Agent 之间可以直接通信,没有固定顺序
优点:灵活、适应性强
缺点:通信复杂、难以追踪
适用:复杂、需要多领域知识融合的任务
"""

1.2 选择建议

模式 适用场景 框架选择
层次式 任务分解、流程明确 CrewAI (默认) / LangGraph
并行式 信息收集、投票决策 CrewAI + parallel
环形 迭代优化、内容创作 LangGraph / Custom
网状式 复杂协作、需要对话 AutoGen

2. CrewAI 框架实战

2.1 为什么选 CrewAI

CrewAI 是我目前用下来最顺手的多 Agent 框架:

ini 复制代码
优点:
✅ 概念清晰:Agent = 角色 + 目标 + 工具
✅ 配置简单:YAML 或代码都能定义
✅ 内置多种进程:Sequential / Parallel / Hierarchical
✅ 支持任务依赖:写清楚谁依赖谁
✅ 社区活跃:文档和示例比较全

缺点:
⚠️ 定制化有限(复杂逻辑可能不够用)
⚠️ 生产级监控/追踪要自己加
⚠️ 国内生态相对弱

2.2 完整代码示例

python 复制代码
# crewai_demo.py

"""
CrewAI 完整示例:技术博客创作流程

流程:
1. Researcher:搜索最新 AI 技术动态
2. Writer:基于研究结果撰写文章
3. Editor:审核文章质量,给出修改意见
4. Publisher:发布到平台(模拟)
"""

from crewai import Agent, Task, Crew, Process
from crewai.tools import SerpDevTool, FileReadTool, FileWriteTool


def create_blog_crew(topic: str):
    """创建博客创作团队"""
    
    # 定义工具
    search_tool = SerpDevTool()
    file_read = FileReadTool()
    file_write = FileWriteTool()
    
    # ========== Agent 定义 ==========
    
    # 1. 研究员
    researcher = Agent(
        role="高级研究员",
        goal=f"收集关于「{topic}」的全面、有价值的信息",
        backstory="""
        你是一位经验丰富的技术研究员,擅长:
        - 从多个渠道收集一手信息
        - 识别信息的可靠性和时效性
        - 提炼关键观点和趋势
        
        你搜索的资料会成为文章的基础,所以要尽量全面准确。
        """,
        tools=[search_tool],
        verbose=True,  # 打印详细日志
        allow_delegation=False  # 不需要委托给其他人
    )
    
    # 2. 写手
    writer = Agent(
        role="技术内容创作者",
        goal="将研究成果转化为通俗易懂、有价值的文章",
        backstory="""
        你是一位专业的内容创作者,擅长:
        - 用简洁清晰的语言解释复杂技术
        - 结构化组织文章(开篇 / 正文 / 总结)
        - 在专业性和可读性之间找到平衡
        
        你的文章要:
        - 有干货、有深度
        - 语言生动、不枯燥
        - 给读者带来实际收获
        """,
        tools=[file_read, file_write],
        verbose=True,
        allow_delegation=False
    )
    
    # 3. 编辑
    editor = Agent(
        role="资深编辑",
        goal="确保文章质量达到发布标准",
        backstory="""
        你是一位严格的编辑,职责是:
        - 检查文章逻辑是否清晰
        - 指出需要补充或修改的地方
        - 给出具体、可操作的修改建议
        
        你要对读者负责,不要放过任何问题。
        """,
        verbose=True,
        allow_delegation=False
    )
    
    # ========== Task 定义 ==========
    
    # 任务1:研究
    research_task = Task(
        description=f"""
        深入研究「{topic}」相关的内容:
        1. 搜索最新进展和趋势
        2. 找到3-5个有代表性的案例或应用
        3. 整理关键信息点和技术要点
        4. 评估信息的可靠性和时效性
        
        输出:一份结构化的研究报告
        """,
        agent=researcher,
        expected_output="包含最新动态、案例、技术要点的研究报告"
    )
    
    # 任务2:写作
    writing_task = Task(
        description="""
        基于研究报告,撰写一篇完整的文章:
        1. 标题要吸引人
        2. 开篇引入要抓人
        3. 正文结构清晰,有逻辑
        4. 结尾有总结和行动指引
        
        目标读者:有一定技术基础的学习者
        字数:2000-3000字
        """,
        agent=writer,
        expected_output="一篇完整的文章草稿",
        context=[research_task]  # 依赖研究任务的结果
    )
    
    # 任务3:编辑审核
    editing_task = Task(
        description="""
        审核文章草稿:
        1. 检查文章结构和逻辑
        2. 指出需要改进的地方
        3. 给出具体的修改建议
        
        如果发现问题,标注出来让写手修改。
        """,
        agent=editor,
        expected_output="包含修改建议的审核报告",
        context=[writing_task]  # 依赖写作任务的结果
    )
    
    # 任务4:修订(如果需要)
    revision_task = Task(
        description="""
        根据编辑的反馈修订文章。
        确保所有提到的问题都得到解决。
        """,
        agent=writer,
        expected_output="修订后的最终文章",
        context=[editing_task],
        async_execution=False  # 同步执行,等待编辑完成
    )
    
    # ========== Crew 定义 ==========
    
    crew = Crew(
        agents=[researcher, writer, editor],
        tasks=[research_task, writing_task, editing_task, revision_task],
        process=Process.sequential,  # 顺序执行
        verbose=True
    )
    
    return crew


def run_blog_creation(topic: str):
    """执行博客创作流程"""
    
    print(f"🚀 开始创作:「{topic}」\n")
    
    crew = create_blog_crew(topic)
    result = crew.kickoff()
    
    print("\n" + "="*60)
    print("✅ 创作完成!")
    print("="*60)
    
    return result


if __name__ == "__main__":
    result = run_blog_creation("AI Agent 开发实战")
    
    # result 包含:
    # - raw: 原始输出
    # - tasks_output: 每个任务的输出
    print(result.raw)

2.3 并行执行示例

python 复制代码
# parallel_crew.py

"""
并行执行:多源信息收集

场景:同时从多个来源收集信息,然后汇总
"""

from crewai import Agent, Task, Crew, Process


def create_research_crew(topic: str):
    """创建并行研究团队"""
    
    # 三个研究员,分别负责不同来源
    researcher_news = Agent(
        role="新闻研究员",
        goal=f"收集「{topic}」的最新新闻动态",
        backstory="你专注于追踪最新的新闻和事件..."
    )
    
    researcher_tech = Agent(
        role="技术研究员",
        goal=f"深入研究「{topic}」的技术原理和实现",
        backstory="你专注于技术细节和实现方案..."
    )
    
    researcher_cases = Agent(
        role="案例研究员",
        goal=f"收集「{topic}」的真实应用案例",
        backstory="你专注于寻找有代表性的实践案例..."
    )
    
    # 三个独立的研究任务
    task_news = Task(
        description=f"搜索「{topic}」的最新新闻",
        agent=researcher_news,
        expected_output="最新动态汇总"
    )
    
    task_tech = Task(
        description=f"分析「{topic}」的技术原理",
        agent=researcher_tech,
        expected_output="技术原理说明"
    )
    
    task_cases = Task(
        description=f"收集「{topic}」的应用案例",
        agent=researcher_cases,
        expected_output="案例列表"
    )
    
    # 汇总任务
    synthesizer = Agent(
        role="内容整合师",
        goal="整合三个研究员的结果,生成完整报告",
        backstory="你擅长将不同来源的信息整合成连贯的报告..."
    )
    
    task_synthesize = Task(
        description="整合研究结果,生成完整报告",
        agent=synthesizer,
        expected_output="结构完整的综合报告",
        context=[task_news, task_tech, task_cases]
    )
    
    # 并行执行前三个任务
    research_crew = Crew(
        agents=[researcher_news, researcher_tech, researcher_cases],
        tasks=[task_news, task_tech, task_cases],
        process=Process.parallel
    )
    
    # 再执行汇总
    final_crew = Crew(
        agents=[synthesizer],
        tasks=[task_synthesize],
        process=Process.sequential
    )
    
    return research_crew, final_crew


def run_parallel_research(topic: str):
    """执行并行研究流程"""
    
    print(f"🔍 开始并行研究:「{topic}」\n")
    
    research_crew, final_crew = create_research_crew(topic)
    
    # 第一步:并行研究
    print("📡 三个研究员同时工作...\n")
    research_result = research_crew.kickoff()
    
    # 第二步:汇总
    print("📝 整合师正在汇总...\n")
    final_result = final_crew.kickoff(
        inputs={"previous_output": research_result.raw}
    )
    
    return final_result

3. AutoGen 框架实战

3.1 AutoGen 的特点

AutoGen(微软开源)和 CrewAI 的定位不太一样:

ini 复制代码
AutoGen 特点:
✅ 更灵活:Agent 之间可以真正「对话」
✅ 对话式:适合需要来回讨论的场景
✅ 微软背书:质量和持续性有保障
✅ 多种模式:对话 / 群聊 / 层级

CrewAI 特点:
✅ 配置更简单
✅ 概念更直观
✅ 任务管理更强

简单理解:
- CrewAI = 任务管理框架
- AutoGen = 对话框架

3.2 AutoGen 代码示例

python 复制代码
# autogen_demo.py

"""
AutoGen 示例:代码生成 + 审查对话

流程:
1. User 发起请求
2. Assistant 生成代码
3. Critic 审查代码
4. Assistant 根据反馈修改
5. 循环直到 Critic 满意
"""

from autogen import AssistantAgent, UserProxyAgent, GroupChat, GroupChatManager


def create_code_review_system():
    """创建代码审查系统"""
    
    # 1. 助手 Agent(生成代码)
    assistant = AssistantAgent(
        name="Coder",
        system_message="""
        你是一位经验丰富的 Python 开发者。
        根据用户需求编写高质量的代码。
        
        职责:
        - 编写清晰、规范的代码
        - 添加必要的注释
        - 考虑边界情况
        
        如果审查员提出问题,要积极修改。
        """,
        llm_config={
            "model": "gpt-4o",
            "api_type": "openai"
        }
    )
    
    # 2. 审查员 Agent
    critic = AssistantAgent(
        name="Critic",
        system_message="""
        你是一位严格的代码审查员。
        
        审查要点:
        1. 代码正确性:逻辑是否正确?
        2. 代码规范:是否符合 PEP8?
        3. 安全性:是否有潜在风险?
        4. 性能:是否有优化空间?
        5. 可读性:是否易于理解?
        
        审查方式:
        - 如果代码有问题,明确指出问题所在
        - 如果代码OK,说 "代码审查通过"
        - 必要时给出修改建议
        """,
        llm_config={
            "model": "gpt-4o",
            "api_type": "openai"
        }
    )
    
    # 3. 用户代理(模拟用户)
    user_proxy = UserProxyAgent(
        name="User",
        human_input_mode="NEVER"  # 不需要人工输入
    )
    
    return assistant, critic, user_proxy


def code_review_workflow(requirement: str):
    """执行代码审查工作流"""
    
    assistant, critic, user_proxy = create_code_review_system()
    
    # 初始化群聊
    group_chat = GroupChat(
        agents=[user_proxy, assistant, critic],
        max_round=10,  # 最多对话10轮
        speaker_selection_method="round_robin"  # 轮流发言
    )
    
    manager = GroupChatManager(groupchat=group_chat)
    
    # 开始对话
    user_proxy.initiate_chat(
        manager,
        message=f"""
请帮我实现以下功能:

{requirement}

完成后,等待审查员的反馈并根据需要修改代码。
"""
    )
    
    # 获取对话历史
    chat_history = user_proxy.chat_messages.get(manager, [])
    
    return chat_history


# ===== 更简单的两人对话示例 =====

def simple_conversation():
    """简单的两 Agent 对话"""
    
    coder = AssistantAgent(
        name="Coder",
        system_message="你是一位 Python 开发者,简洁高效。"
    )
    
    tester = AssistantAgent(
        name="Tester",
        system_message="你是一位测试工程师,负责验证代码的正确性。"
    )
    
    # 测试场景:写一个排序函数
    tester.initiate_chat(
        coder,
        message="""
写一个 Python 函数,对列表进行排序并返回结果。
然后测试它是否能正确排序 [3, 1, 4, 1, 5, 9, 2, 6]
"""
    )

4. 生产级架构设计

4.1 整体架构

python 复制代码
"""
多 Agent 系统的生产级架构

┌─────────────────────────────────────────────────────────────┐
│                      API Layer                               │
│              (FastAPI / Flask / 各种 API)                   │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│                   Router / Orchestrator                     │
│         任务路由、负载均衡、异常处理                         │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│                    Agent Runtime                            │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐            │
│  │  Agent-A   │  │  Agent-B   │  │  Agent-C   │            │
│  │  (专用)    │  │  (通用)    │  │  (专用)    │            │
│  └─────┬──────┘  └─────┬──────┘  └─────┬──────┘            │
│        │                │                │                   │
│  ┌─────▼────────────────▼────────────────▼─────┐            │
│  │              Tool Execution Layer           │            │
│  │   (搜索引擎 / 数据库 / API / 文件系统)       │            │
│  └─────────────────────────────────────────────┘            │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│                   Memory Layer                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                 │
│  │ 短期记忆  │  │ 长期记忆  │  │ 情节记忆  │                 │
│  │(上下文)   │  │(向量DB)   │  │(任务日志) │                 │
│  └──────────┘  └──────────┘  └──────────┘                 │
└─────────────────────────────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│                   Monitoring                               │
│          (日志 / 指标 / 追踪 / 告警)                        │
└─────────────────────────────────────────────────────────────┘
"""

# ===== 核心组件 =====

class AgentRuntime:
    """
    Agent 运行时
    管理 Agent 的生命周期
    """
    
    def __init__(self):
        self.agents: dict[str, Agent] = {}
        self.tools: dict[str, Callable] = {}
        self.memory = AgentMemory()
        self.monitor = Monitor()
    
    def register_agent(self, name: str, agent: Agent):
        """注册 Agent"""
        self.agents[name] = agent
    
    def register_tool(self, name: str, tool: Callable):
        """注册工具"""
        self.tools[name] = tool
    
    def execute_task(self, task: Task) -> Result:
        """执行任务"""
        
        # 1. 选择合适的 Agent
        agent = self._select_agent(task)
        
        # 2. 获取相关记忆
        context = self.memory.recall(task.description)
        
        # 3. 执行
        with self.monitor.track(agent.name, task.id):
            result = agent.execute(task, context)
        
        # 4. 存储结果到记忆
        self.memory.remember(task.description, result)
        
        return result
    
    def _select_agent(self, task: Task) -> Agent:
        """根据任务类型选择 Agent"""
        # 简单路由:按标签匹配
        for agent in self.agents.values():
            if any(tag in agent.capabilities for tag in task.tags):
                return agent
        
        # 默认返回通用 Agent
        return self.agents.get("general")

4.2 记忆系统

python 复制代码
# memory_system.py

"""
Agent 记忆系统

多层记忆:
1. Working Memory:当前任务的上下文
2. Short-term Memory:当前会话的历史
3. Long-term Memory:持久化的知识(向量数据库)
"""

from dataclasses import dataclass
from typing import Optional
import time


@dataclass
class MemoryItem:
    """记忆条目"""
    content: str
    memory_type: str  # "working" | "short_term" | "long_term"
    importance: float  # 重要程度 0-1
    timestamp: float
    tags: list[str]


class AgentMemory:
    """
    Agent 记忆系统
    
    设计原则:
    - 重要信息 → 强化存储
    - 不重要信息 → 定期清理
    - 失败经验 → 长期记住
    """
    
    def __init__(self, vector_db=None):
        self.working_memory: list[str] = []  # 当前上下文
        self.short_term: list[MemoryItem] = []  # 短期记忆
        self.long_term: list[MemoryItem] = []  # 长期记忆(简化版,生产用向量数据库)
        self.vector_db = vector_db
    
    def remember(
        self,
        content: str,
        memory_type: str = "working",
        importance: float = 0.5,
        tags: list[str] = None
    ):
        """存储记忆"""
        
        item = MemoryItem(
            content=content,
            memory_type=memory_type,
            importance=importance,
            timestamp=time.time(),
            tags=tags or []
        )
        
        if memory_type == "working":
            self.working_memory.append(content)
            # 限制大小
            if len(self.working_memory) > 20:
                self.working_memory = self.working_memory[-20:]
        
        elif memory_type == "short_term":
            self.short_term.append(item)
            if len(self.short_term) > 100:
                self._compress_short_term()
        
        elif memory_type == "long_term":
            self.long_term.append(item)
            if self.vector_db:
                # 存入向量数据库
                pass
    
    def recall(self, query: str, limit: int = 5) -> list[str]:
        """检索记忆"""
        results = []
        
        # 工作记忆(直接返回)
        results.extend(self.working_memory[-limit:])
        
        # 短期记忆(关键词匹配)
        for item in self.short_term[-20:]:
            if query.lower() in item.content.lower():
                results.append(item.content)
        
        # 长期记忆(向量搜索)
        if self.vector_db:
            vector_results = self.vector_db.search(query, limit=limit)
            results.extend([r["content"] for r in vector_results])
        
        return results[:limit]
    
    def remember_episode(
        self,
        task: str,
        actions: list[str],
        result: str,
        success: bool,
        lesson: str = ""
    ):
        """记录情节记忆(任务执行记录)"""
        
        # 失败经验很重要,必须记住
        if not success:
            self.remember(
                content=f"任务「{task}」失败的教训:{lesson}",
                memory_type="long_term",
                importance=0.9  # 失败经验重要度高
            )
        
        # 成功经验也记住
        if success and lesson:
            self.remember(
                content=f"任务「{task}」成功的经验:{lesson}",
                memory_type="long_term",
                importance=0.7
            )
    
    def _compress_short_term(self):
        """压缩短期记忆,保留重要的"""
        # 按重要性排序
        sorted_memory = sorted(
            self.short_term,
            key=lambda x: x.importance,
            reverse=True
        )
        # 保留最重要的 50 条
        self.short_term = sorted_memory[:50]

5. 框架对比总结

特性 CrewAI AutoGen LangGraph
定位 任务导向 对话导向 状态机
上手难度 ⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
灵活性 最高
多 Agent 协作
监控/追踪 一般 一般 需自己加
适合场景 任务流水线 对话协作 复杂工作流

我的选择建议:

复制代码
快速原型、业务流程 → CrewAI
多 Agent 对话、讨论 → AutoGen
复杂状态机、精确控制 → LangGraph
生产级、需要定制 → 组合使用 + 自定义

6. 踩坑和经验

坑1:Agent 之间通信要清晰

多个 Agent 协作时,最容易出问题是信息传递不清

python 复制代码
# ❌ 容易出问题
task_b = Task(
    description="处理上一步的结果",
    context=[task_a]
)

# ✅ 明确说明需要什么
task_b = Task(
    description=f"""
    基于以下研究结果,撰写文章:
    
    {task_a.expected_output}
    
    注意:重点关注XX方面,忽略YY方面
    """,
    context=[task_a]
)

坑2:不要让 Agent 产生过多对话

多 Agent 对话很灵活,但也很容易陷入无限循环

解决:设置 max_round,并且设计好终止条件。

坑3:监控和日志必须做好

多 Agent 出问题很难排查,因为涉及多个 Agent 的交互。

必备:

  • 每个 Agent 的输入输出日志
  • 任务执行时间
  • 错误追踪

结语

多 Agent 协作是 Agent 发展的下一个重点方向。从单 Agent 到多 Agent,不只是数量上的变化,而是从「一个聪明的工具」到「一个协作团队」的质变。

框架只是工具,核心还是理解什么场景需要协作、怎么协作

希望这篇文章对你有帮助。下次聊点别的方向~


相关阅读:

相关推荐
DO_Community1 小时前
RAG 的 Embedding 模型需要微调吗?什么时候值得自己训练?
人工智能·llm·aigc·agent·ai编程
俊男无期2 小时前
【openJiuwen】大模型流式输出的格式控制探索及实现方案
ai编程
小虎AI生活2 小时前
别再花两万找广告公司了,你的下一条宣传片,AI一个下午能出
ai编程
HjhIron2 小时前
从零构建 AI Agent 的 Memory 记忆系统(上篇)—— 核心概念与上下文管理
ai编程
HjhIron2 小时前
从零构建 AI Agent 的 Memory 记忆系统(下篇)—— 基于 Milvus 的长期记忆与 RAG 检索
ai编程
_codeOH2 小时前
MCP Server 开发实战:从 0 到 1 构建自己的工具服务
人工智能·ai编程
VIP_CQCRE4 小时前
Visual Studio 接入 Ace Data Cloud:让 LMLocal 直接调用统一 AI 模型能力
ai编程·visual studio·openai兼容·ace data cloud·lmlocal