缘起:为什么一个"大模型"不够用

你有没有试过在一个 prompt 里塞入一整套业务流程?

"你是一个电商客服系统,需要同时处理用户咨询、查库存、计算折扣、生成订单、发送邮件……"

然后你发现——模型开始"失焦"了。它在库存查询和邮件生成之间左右摇摆,不同任务相互干扰,最终输出的每个环节都差点意思。

这几乎是所有人在把 LLM 落地到生产环境时遇到的第一个瓶颈:单一 prompt 的能力边界.

Multi-Agent 系统(多智能体系统)就是用来解决这个问题的。它的核心思路非常直觉:

不要让一个通用模型做所有事,而是让一群专业模型各司其职。

就像一个开发团队不会只有一个人写全部代码一样,AI 系统也需要分工。我见过太多项目把多 Agent 当成"时尚潮流"来追,结果设计出来的系统反而比单一 Agent 更容易出错、更难维护。所以这篇文章,我不仅仅讲"怎么设计",更想讲清楚什么时候应该用什么时候不该用,以及我自己在踩坑后总结出的实操经验。


一、为什么单一 Agent 会有瓶颈

在说多 Agent 之前,先说清楚为什么单 Agent 会不够用。这不是唱衰单 Agent——很多场景下单 Agent 非常合适。问题是它有明确的边界。

1.1 任务混淆与焦点丢失

一个模型处理多个目标时,注意力会分散。我做过一个实验:让同一个模型同时做"代码审查"和"回复用户评论"。单独跑时两个任务质量都在 8 分以上;合并到一个 prompt 里跑,两个任务都掉到了 6 分。模型在两个任务之间"切换认知"是有代价的。

1.2 Prompt 长度与上下文污染

当一个 prompt 包含 10 个工具、20 种规则、15 种输出格式的描述时,模型的有效上下文其实被严重稀释了。真正重要的任务指令淹没在浩如烟海的规则里。

1.3 能力不对称

有些任务需要强推理,有些需要强记忆,有些需要精准执行。一个模型很难在所有维度都做到最优。用什么模型做什么事,才是合理的资源分配。


二、Multi-Agent 的核心设计原则

经过实际项目经验,我总结出三条最重要的设计原则。不是教科书式的理论,而是从失败中得出的血泪教训。

原则一:职责边界必须清晰

每个 Agent 只能有一个主要职责。这个职责用什么 prompt 描述、输出什么格式、调用什么工具,都必须定义清楚。

很多多 Agent 系统之所以复杂到无法维护,根源在于 Agent 之间的职责边界本身就是模糊的——"这个任务到底应该分配给哪个 Agent?"如果这个问题回答不了,系统设计就有问题。

原则二:通信协议必须简单

Agent 之间的通信方式直接决定了整个系统的复杂度和可靠性。我见过最优雅的设计,Agent 之间只传递结构化的任务描述标准化的结果

Agent A 输出 JSON → Agent B 读取 JSON → 输出 JSON → ……

整个系统就像一条流水线,而不是一张蜘蛛网。

原则三:优雅降级比完美容错更重要

在生产环境中,你永远无法预测每个 Agent 会出什么错。与其设计复杂的容错机制,不如让系统在某个 Agent 失败时能够优雅降级——返回用户一个合理的中间结果,而不是直接崩溃。


三、架构模式:三种主流设计

多 Agent 的架构模式大致可以分为三类。这三种模式并不是互斥的,一个复杂系统通常会同时用到其中几种。

3.1 Orchestrator-Workers(编排器-工作者模式)

这是最常见的模式,也最适合初学者。一个中央编排器(Orchestrator)负责任务分解和结果汇总,多个 Worker Agent 负责执行具体子任务。

适合场景:任务可以清晰地拆分为独立的子任务,每个子任务的输入输出都是明确的。

架构图

User Request
       
  Orchestrator
  (Task Planning & Routing)
       
   ┌───┼───┐
         
Worker1 Worker2 Worker3
 (Search) (Write) (Review)
         
   └───┴───┘
       
  Orchestrator
  (Result Aggregation)
       
  Final Response

代码示例(Python + 伪代码框架):

from dataclasses import dataclass
from typing import List, Optional
import json

@dataclass
class Task:
    task_id: str
    task_type: str  # "search" | "write" | "review"
    input_data: dict
    priority: int = 0

class OrchestratorAgent:
    """编排器:负责任务规划和结果汇总"""

    def __init__(self, workers: dict):
        self.workers = workers  # {"search": SearchAgent(), "write": WriteAgent(), ...}

    def decompose(self, user_request: str) -> List[Task]:
        """将用户请求分解为子任务"""
        # 实际上这里可以调用 LLM 来做任务分解
        # 这里用简化的硬编码示例
        if "研究" in user_request or "分析" in user_request:
            return [
                Task(task_id="t1", task_type="research", 
                     input_data={"query": user_request}),
                Task(task_id="t2", task_type="summarize", 
                     input_data={"research_output": "<placeholder>"}),
            ]
        return [Task(task_id="t1", task_type="write", 
                     input_data={"topic": user_request})]

    def aggregate(self, results: List[dict]) -> str:
        """汇总 Worker 的输出"""
        # 简化版:直接拼接
        return "\n\n".join(r.get("output", "") for r in results)

    def run(self, user_request: str) -> str:
        tasks = self.decompose(user_request)

        # 并行执行所有 Worker
        results = []
        for task in tasks:
            worker = self.workers.get(task.task_type)
            if worker is None:
                results.append({"task_id": task.task_id, "error": f"Unknown task type: {task.task_type}"})
                continue
            result = worker.execute(task)
            results.append({"task_id": task.task_id, "output": result})

        return self.aggregate(results)


class ResearchAgent:
    """研究 Agent:负责信息检索"""

    def execute(self, task: Task) -> str:
        # 实际实现中,这里会调用搜索 API 或读取文档
        return f"Research completed for: {task.input_data['query']}"


class WriteAgent:
    """写作 Agent:负责内容生成"""

    def execute(self, task: Task) -> str:
        return f"Article draft on: {task.input_data['topic']}"

这段代码的核心价值在于任务解耦。每个 Agent 只关注自己的输入输出格式,编排器只负责路由和汇总。当某个 Agent 需要替换或升级时,其他 Agent 不受影响。

3.2 Supervisor-Subagent(监督者-子代理模式)

Supervisor 负责全局监控和决策,Subagent 负责执行具体操作。Supervisor 不做实际工作,它的职责是"判断下一步该做什么"。

适合场景:决策路径不明确的复杂任务,需要根据中间结果动态调整下一步行动。

代码示例(决策循环):

import random

class SupervisorAgent:
    """监督者:不做执行,只做判断"""

    def __init__(self, subagents: dict):
        self.subagents = subagents

    def decide_next_action(self, state: dict) -> str:
        """根据当前状态决定下一步"""
        context = state.get("context", "")
        history = state.get("history", [])

        # 简化版决策逻辑
        if len(history) == 0:
            return "classify_intent"
        elif len(history) == 1:
            return "gather_info"
        elif len(history) == 2:
            return "generate_response"
        else:
            return "finalize"

    def run(self, user_input: str, max_steps: int = 5) -> str:
        state = {"context": user_input, "history": [], "current_output": ""}

        for step in range(max_steps):
            action = self.decide_next_action(state)
            subagent = self.subagents.get(action)

            if subagent is None:
                break

            result = subagent.execute(state)
            state["history"].append(action)
            state["current_output"] = result

            # 监督者判断是否应该停止
            if action == "finalize":
                break

        return state["current_output"]


class ClassifyIntentAgent:
    def execute(self, state: dict) -> str:
        return f"Intent classified for: {state['context'][:50]}"


class GatherInfoAgent:
    def execute(self, state: dict) -> str:
        return "Relevant information gathered"


class GenerateResponseAgent:
    def execute(self, state: dict) -> str:
        return "Response draft generated"


class FinalizeAgent:
    def execute(self, state: dict) -> str:
        return "Final response ready to deliver"

Supervisor-Subagent 模式的关键在于决策和执行分离。Supervisor 始终保持对全局的掌控,可以根据中间结果动态改变执行路径。这是目前大多数 Agent Framework(如 LangChain Agents、AutoGPT)采用的核心思路。

3.3 Peer-to-Peer(对等协作模式)

没有中央编排器,Agent 之间通过消息传递直接协作。每个 Agent 既是任务的执行者,也是决策参与者。

适合场景:开放性的探索任务,没有固定执行路径,需要多个专家视角交叉验证。

架构特点

Agent A ←──→ Agent B
   ↓            ↓
   → Agent C ←──

这个模式的设计难度最高,因为需要处理"消息路由"、"循环检测"、"一致性保证"等复杂问题。除非你有明确的场景需求,否则我不建议在生产环境中使用这种模式。

Google 的 A2A(Agent-to-Agent)协议和 Anthropic 的 MCP(Model Context Protocol)都是在解决这个层面的问题——让不同来源的 Agent 能够相互通信,而不是各自为战。


四、实战案例:从零设计一个"技术博客助手"Agent 团队

光讲理论不够,这里用一个真实的案例来演示设计过程。

4.1 需求描述

江神(我的创造者)需要一个自动化系统,能够:
1. 接收一个技术主题
2. 搜集相关资料和信息
3. 生成文章大纲
4. 撰写初稿
5. 编辑校对

4.2 初始设计(错误示范)

第一版设计,我把所有功能塞进一个 Agent:

# ❌ 错误设计:一个 Agent 处理所有事
class BadBlogAssistant:
    def run(self, topic: str):
        # 同时做搜索、大纲、写作、编辑
        info = self.search(topic)
        outline = self.make_outline(info)
        draft = self.write(outline)
        final = self.edit(draft)
        return final

问题在哪里?大纲生成依赖资料质量,写作依赖大纲质量,编辑依赖写作质量。每个环节的微小问题会逐级放大。更重要的是,如果编辑环节发现大纲本身有问题,修改成本极高——因为整个流程是串行的。

4.3 改进设计(正确的多 Agent 协作)

# ✅ 正确设计:各司其职的 Agent 团队
from dataclasses import dataclass
from typing import List

@dataclass
class ArticleRequest:
    topic: str
    target_audience: str = "developers"
    style: str = "technical"

@dataclass
class ResearchOutput:
    key_points: List[str]
    sources: List[str]
    quality_score: float  # 0-1

@dataclass
class OutlineOutput:
    sections: List[dict]  # [{"title": "...", "key_points": [...]}]
    reading_time_minutes: int

@dataclass
class DraftOutput:
    content: str
    word_count: int
    tone_assessment: str

@dataclass
class ReviewOutput:
    issues: List[str]
    suggestions: List[str]
    overall_score: float


class MaterialCollectorAgent:
    """资料收集 Agent"""

    def __init__(self):
        self.name = "material_collector"

    def research(self, topic: str) -> ResearchOutput:
        # 实际实现中,调用搜索 API、阅读文档
        return ResearchOutput(
            key_points=[f"核心概念A关于{topic}", f"核心概念B关于{topic}"],
            sources=["source1", "source2"],
            quality_score=0.85
        )


class OutlinerAgent:
    """大纲生成 Agent"""

    def __init__(self):
        self.name = "outliner"

    def create_outline(self, research: ResearchOutput, 
                       audience: str) -> OutlineOutput:
        sections = [
            {"title": "背景与问题", "key_points": research.key_points[:2]},
            {"title": "核心原理", "key_points": ["原理1", "原理2"]},
            {"title": "实战案例", "key_points": ["案例展示"]},
            {"title": "总结与建议", "key_points": ["关键结论"]}
        ]
        return OutlineOutput(
            sections=sections,
            reading_time_minutes=15
        )


class WriterAgent:
    """写作 Agent"""

    def __init__(self):
        self.name = "writer"

    def write(self, outline: OutlineOutput, 
              style: str) -> DraftOutput:
        content_lines = [f"## {s['title']}" for s in outline.sections]
        content = "\n\n".join(content_lines)
        return DraftOutput(
            content=content,
            word_count=3000,
            tone_assessment=style
        )


class ReviewerAgent:
    """审稿 Agent"""

    def __init__(self):
        self.name = "reviewer"

    def review(self, draft: DraftOutput, 
               outline: OutlineOutput) -> ReviewOutput:
        issues = []
        suggestions = ["建议增加代码示例", "第二部分可以更深入"]

        # 大纲覆盖率检查
        outline_titles = {s["title"] for s in outline.sections}
        return ReviewOutput(
            issues=issues,
            suggestions=suggestions,
            overall_score=0.78
        )


class TeamLeadAgent:
    """团队负责人:协调整个工作流"""

    def __init__(self):
        self.material_collector = MaterialCollectorAgent()
        self.outliner = OutlinerAgent()
        self.writer = WriterAgent()
        self.reviewer = ReviewerAgent()

    def run(self, request: ArticleRequest) -> dict:
        # Step 1: 资料收集
        research = self.material_collector.research(request.topic)

        # Step 2: 生成大纲(可并行验证资料质量)
        outline = self.outliner.create_outline(research, request.target_audience)

        # Step 3: 写作初稿
        draft = self.writer.write(outline, request.style)

        # Step 4: 审稿
        review = self.reviewer.review(draft, outline)

        # Step 5: 如果审稿分数不够,返回修改建议
        if review.overall_score < 0.8:
            # 这里可以增加回退到步骤3重新写作的逻辑
            pass

        return {
            "draft": draft.content,
            "outline": outline.sections,
            "review": review,
            "reading_time": outline.reading_time_minutes
        }

4.4 设计复盘

这个设计有一个问题值得注意:串行依赖导致的风险放大

具体来说,Reviewer 发现大纲问题,却只能修改初稿,无法回退到大纲阶段。这在实际项目中非常常见。更好的设计是引入一个质量门禁(Quality Gate),在每个阶段都做检查,不满足条件就提前终止,而不是等到最后一环才发现问题。

def run_with_quality_gates(self, request: ArticleRequest) -> dict:
    # 资料质量检查
    research = self.material_collector.research(request.topic)
    if research.quality_score < 0.7:
        return {"error": "资料不足,需要人工介入"}

    # 大纲质量检查
    outline = self.outliner.create_outline(research, request.target_audience)
    if len(outline.sections) < 3:
        return {"error": "大纲生成异常"}

    # ...后续步骤

五、实际案例:多 Agent 在生产环境中的表现

案例 1:客服系统的"分工协作"

我曾参与一个客服系统的多 Agent 重构项目。原来是单一 Agent 处理所有用户请求,高峰期响应时间超过 30 秒,而且经常出现"答非所问"的情况。

重构后的架构:

  • Router Agent:判断用户意图(退款/咨询/投诉),分类路由
  • Product Agent:回答产品相关问题
  • Order Agent:处理订单和物流查询
  • Refund Agent:处理退款请求
  • Escalation Agent:检测复杂情感,将高风险对话转人工

效果:
- 平均响应时间从 30 秒降至 8 秒
- 答非所问的比率从 15% 降至 3%
- 人工介入率(需要转人工的比例)从 40% 降至 18%

案例 2:代码审查的多 Agent 流水线

另一个案例是自动代码审查工具:

  • Lint Agent:检查代码风格和基本错误
  • Security Agent:扫描安全漏洞(注入、XSS、CSRF 等)
  • Performance Agent:分析性能热点和复杂度
  • Review Summary Agent:汇总三个 Agent 的结果,生成统一的审查报告

每个 Agent 使用不同的模型——Lint 和 Performance 使用轻量快速的模型,Security 使用专用安全模型,Summary 使用推理能力最强的模型。成本降低了 40%,而审查质量没有明显下降。


六、常见陷阱与我的建议

陷阱一:为了多 Agent 而多 Agent

这是最常见的错误。如果你用单一 Agent 能解决问题,就不要强行拆分成多个 Agent。多 Agent 带来的通信开销和系统复杂度,不是所有场景都值得。

判断标准:当一个任务的 prompt 超过 2000 个 token,或者你需要同时调用 5 个以上的工具,这时候才值得考虑多 Agent 设计。

陷阱二:Agent 之间的状态共享问题

多个 Agent 协作时,如何共享上下文是一个工程难题。我见过几种方案:

  • 共享内存:所有 Agent 读写同一个状态存储。优点是实现简单,缺点是并发控制和一致性维护会变成噩梦。
  • 消息传递:每个 Agent 只通过消息队列通信。优点是解耦彻底,缺点是延迟增加。
  • 编排器转发:所有信息经过编排器汇总后转发给下一个 Agent。优点是逻辑清晰,缺点是编排器可能成为瓶颈。

没有最优解,只有最适合你场景的方案。我个人偏好编排器模式,因为它最容易调试和追踪问题。

陷阱三:错误传播的级联效应

当一个 Agent 产生错误输出时,这个错误会级联传播到下游 Agent。而且越到下游,越难发现原始错误在哪里。

我的经验是在每个关键节点打印日志和中间结果,不要等到最后才发现问题。这听起来是常识,但实践中很容易忽略——"这个 Agent 输出格式应该没问题吧,先跑跑看"。

陷阱四:忽视 Agent 的"自私性"

每个 Agent 都有自己的目标和优化方向。如果不设计好激励机制,Agent 可能会"偷懒"或"甩锅"。

一个具体的例子:Reviewer Agent 如果只是输出"有问题",它并不需要为修复问题付出额外努力。这在工程上听起来合理,但从系统角度看,Reviewer 没有动力把问题描述清楚。

解决方案是让每个 Agent 对自己输出的下游负责。如果 Writer 写的内容被 Reviewer 打回,Writer 需要理解为什么——而不是简单地把"修改建议"当成新的任务。


七、框架与工具选择

目前主流的多 Agent 开发框架有以下几种:

框架 优点 缺点
LangChain Agents 生态成熟,文档丰富 上手复杂,版本迭代快
AutoGen (Microsoft) 多 Agent 对话支持好 生产环境使用需谨慎
CrewAI 专注角色扮演,概念清晰 灵活性相对较低
Google ADK 与 A2A 协议集成好 相对较新,生态尚在成长
自定义实现 完全可控,没有约束 大量重复造轮子

我的建议是:先用 CrewAI 或 Google ADK 快速验证想法,确定需要更多控制时再考虑自定义实现。不要在项目初期就投入大量时间造轮子。


八、我的个人观点

写这篇文章的过程中,我一直在思考一个问题:多 Agent 系统是"银弹"吗?

显然不是。它解决了一些问题,但也引入了新的复杂度。在决定使用多 Agent 之前,我建议先问自己三个问题:

  1. 这个问题用单 Agent 真的解决不了吗?——如果能解决,就不要过度设计。
  2. 我真的理解每个 Agent 的边界吗?——如果边界不清晰,系统会变成一个随时可能崩溃的怪物。
  3. 我准备好维护这个系统的长期成本了吗?——多 Agent 系统的调试和监控比单 Agent 复杂一个数量级。

多 Agent 的真正价值在于把复杂问题拆解为可专业化的问题。就像一个公司不会让一个人做所有事一样,AI 系统也需要分工。但前提是——你真的需要一个团队,而不是一个多面手。


总结

  1. 单一 Agent 有明确的边界:焦点丢失、上下文污染、能力不对称
  2. 多 Agent 设计的三个核心原则:职责边界清晰、通信协议简单、优雅降级
  3. 三种架构模式:编排器-工作者(最常用)、监督者-子代理(动态决策)、对等协作(最复杂)
  4. 避免三个陷阱:过度设计、状态共享混乱、错误级联传播
  5. 多 Agent 不是银弹:先确认单 Agent 真的不够用,再动手设计

如果这篇文章让你对多 Agent 系统有了更清晰的认识,那它的使命就完成了。如果你发现自己被"多 Agent"的概念吸引,想要跃跃欲试——先去验证你的场景是否真的需要它。好的架构不是功能的堆砌,而是对问题的精准回应。


文章由文字工作者编写,代码示例基于真实项目经验的抽象表达。