序言:当你的AI助手上知天文下知地理,但写出来的代码全是Bug、做的PPT逻辑混乱,你就该考虑给它找几个"同事"了。

一、那个"全能型"AI的翻车现场

今年3月,我尝试用单个Agent做一个内容创作工具。想法很美好:一个Agent包办从选题、调研、写作到排版的全流程。

我给它配了搜索引擎、代码执行器、文档编辑器,Prompt写得老长:“你是一位全能的内容创作专家,擅长资料搜集、文案撰写、逻辑审核和格式排版……”

第一篇文章是关于"量子计算入门"的。Agent确实跑完了全流程:搜了资料、写了初稿、做了排版。但交出来的东西让我哭笑不得。

  • 资料搜集环节,它把维基百科和某营销号的文章混在了一起,引用来源真假难辨。

  • 写作环节,前半部分还在讲量子比特的物理原理,后半部分突然跳到了量子金融的应用场景,中间没有任何过渡。

  • 审核环节,它给自己打了98分,理由是"内容全面、结构清晰"——但实际上整篇文章的章节顺序是乱的。

  • 排版环节,它把二级标题和正文混在了一起,代码块没有高亮,引用格式也不统一。

我盯着屏幕看了十分钟,终于想明白问题出在哪:一个Agent什么都会,但什么都不精。

就像公司不会招一个"既当CTO又当销售总监还兼行政前台"的人,AI也不应该把所有任务塞给一个模型。术业有专攻,调研的归调研,写作的归写作,审核的归审核,排版的归排版。

这就是多Agent架构的核心思想:把复杂任务拆给多个专业Agent,让它们像团队一样协作。

二、从"一个人干"到"一个团队干":多Agent架构设计

多Agent系统不是把多个Agent简单堆在一起。它的设计关键在于职责拆分协作机制

职责拆分:给每个Agent定KPI

在内容创作场景中,我拆出了四个角色:

  • Researcher(调研员):负责搜集资料、核实来源、整理关键信息。它的KPI是"资料全面且来源可靠"。
  • Writer(撰稿人):负责根据调研结果撰写初稿。它的KPI是"逻辑连贯、表达清晰"。
  • Editor(编辑):负责审核初稿,提出修改意见。它的KPI是"找出所有逻辑漏洞和表达问题"。
  • Publisher(排版员):负责把定稿转成最终格式。它的KPI是"格式规范、排版美观"。

每个Agent只配和它职责相关的工具。调研员有搜索引擎和文献数据库,撰稿人只有文本编辑器,编辑有批注工具,排版员有Markdown转HTML工具。

Prompt也要"专精化"。 不是"你是一位全能专家",而是"你是一位资深科技编辑,你的唯一职责是审核文章质量。不要试图修改内容,只提意见"。Prompt越聚焦,Agent的行为越稳定。

协作机制:谁指挥谁?

多Agent协作有两种主流模式,选择哪种取决于你的业务场景。

模式一:主管调度(Supervisor Pattern)

这是LangGraph最推荐的模式,适合90%的生产场景。它像一个星型拓扑:中间一个主管Agent,周围一圈专业Agent。主管负责接收用户任务、拆解子任务、分配给对应的Agent、收集结果、决定下一步或结束 。

用户 → 主管 → Researcher → 返回结果 
     → 主管 → Writer → 返回结果 
     → 主管 → Editor → 返回结果 
     → 主管 → Publisher → 返回结果 
     → 主管 → 最终答案

主管不干活,只调度。它的Prompt核心是:“你是团队主管,负责拆解任务并分配给专业Agent。不要自己做专业工作。每次只分配给一个Agent。”

这种模式的优势是可控性强。所有路由决策集中在一个点,调试时只需要看主管的日志。缺点是主管可能成为瓶颈,如果任务需要频繁切换Agent,主管的LLM调用次数会很多 [220^]。

模式二:去中心化协商(Swarm Pattern)

这种模式没有主管,Agent之间直接移交控制权。每个Agent配有一组"Handoff工具",当它觉得自己搞不定时,调用工具把任务转给另一个Agent。

用户 → Researcher → "这个话题需要写作专家" 
     → handoff → Writer → "写完了,需要编辑审核" 
     → handoff → Editor → "审核通过,可以排版" 
     → handoff → Publisher → 最终答案

Swarm的优势是灵活性高,Agent之间的协作更自然,像真人团队一样自发交接。缺点是调试困难——AgentA为什么把任务转给AgentB,而不是AgentC?这个决策藏在模型的"内心独白"里,不像主管模式那样集中可控。

我的建议:生产环境先用Supervisor模式,跑稳定后再考虑Swarm。

三、实战:搭建一个"内容创作团队"

下面我们用LangGraph的Supervisor模式,搭建一个完整的内容创作多Agent系统。

第一步:定义共享状态

所有Agent共享同一个State,这是它们协作的"公共白板"。

from typing import TypedDict, Annotated, List
from operator import add
from langgraph.graph import MessagesState

class ContentTeamState(MessagesState):
    """内容创作团队的共享状态"""
    topic: str                    # 文章主题
    research_notes: str           # 调研笔记
    draft: str                    # 初稿
    edit_feedback: str            # 编辑意见
    final_article: str            # 终稿
    citations: Annotated[List[str], add]  # 引用来源(自动追加)
    status: str                   # 当前状态:researching/writing/editing/publishing/done

Annotated[List[str], add]意味着多个Agent都可以往citations里追加引用,不会互相覆盖。这是多Agent共享状态的关键技巧。

第二步:创建专业Agent

create_react_agent创建每个专业Agent,给它们配专属工具和Prompt。

from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
from langchain.tools import tool

llm = ChatOpenAI(model="gpt-4o", temperature=0)

# ===== Researcher Agent =====
@tool
def web_search(query: str) -> str:
    """搜索互联网获取最新信息"""
    return f"搜索结果:关于'{query}'的最新资料……"

researcher = create_react_agent(
    model=llm,
    tools=[web_search],
    name="researcher",
    prompt=(
        "你是一位资深调研员。你的职责是搜集与主题相关的权威资料,"
        "整理关键信息,并列出所有引用来源。"
        "不要写文章,只输出结构化的调研笔记。"
        "如果任务涉及写作、编辑或排版,请拒绝并建议主管分配给对应专家。"
    ),
)

# ===== Writer Agent =====
writer = create_react_agent(
    model=llm,
    tools=[],  # 撰稿人只需要文本能力
    name="writer",
    prompt=(
        "你是一位资深科技撰稿人。根据提供的调研笔记撰写初稿。"
        "要求:逻辑清晰、段落过渡自然、语言通俗易懂。"
        "不要添加未经调研笔记证实的信息。"
        "如果调研资料不足,请明确标注'此处需要补充资料'。"
    ),
)

# ===== Editor Agent =====
@tool
def grammar_check(text: str) -> str:
    """检查语法和表达问题"""
    return "语法检查结果:……"

editor = create_react_agent(
    model=llm,
    tools=[grammar_check],
    name="editor",
    prompt=(
        "你是一位资深编辑。你的职责是审核文章质量,提出具体修改意见。"
        "检查维度:逻辑连贯性、事实准确性、表达清晰度、结构合理性。"
        "输出格式:逐条列出问题+修改建议。"
        "不要直接修改文章,只提意见。"
    ),
)

# ===== Publisher Agent =====
@tool
def format_markdown(text: str) -> str:
    """将文本转为规范Markdown格式"""
    return f"排版结果:\n\n{text}"

publisher = create_react_agent(
    model=llm,
    tools=[format_markdown],
    name="publisher",
    prompt=(
        "你是一位排版专家。将定稿转为规范的Markdown格式。"
        "要求:标题层级正确、代码块带语言标识、引用格式规范、列表对齐。"
        "不要修改文章内容,只做格式处理。"
    ),
)

每个Agent的Prompt都包含"职责边界"声明:“不要干别人的活”。这是防止Agent"越权"的关键——调研员不要试图写文章,编辑不要试图排版。

第三步:创建主管Agent

主管是系统的"大脑",负责调度所有专业Agent。

from langgraph_supervisor import create_supervisor

# 主管Prompt:明确职责是调度,不是执行
supervisor = create_supervisor(
    agents=[researcher, writer, editor, publisher],
    model=llm,
    prompt=(
        "你是一位内容创作团队的主管。你的职责是:"
        "1. 接收用户的创作需求,拆解成子任务"
        "2. 每次只分配一个子任务给一个专业Agent"
        "3. 收集Agent的返回结果,决定下一步行动"
        "4. 当所有子任务完成,整合输出最终答案"
        "分配规则:"
        "- 需要搜集资料 → researcher"
        "- 需要撰写文章 → writer"
        "- 需要审核质量 → editor"
        "- 需要排版输出 → publisher"
        "禁止:不要自己做专业工作,不要同时分配给多个Agent。"
    ),
    output_mode="last_message",  # 控制上下文窗口
).compile(name="content_team")

output_mode="last_message"是一个生产级优化。它只把最新的消息传给主管,而不是完整的历史对话,防止上下文窗口爆炸 [220^]。

第四步:运行完整流程

from langchain_core.messages import HumanMessage

result = supervisor.invoke({
    "messages": [
        HumanMessage(content="写一篇关于'AI智能体在企业办公中的应用'的公众号文章,1500字左右")
    ]
}, config={"recursion_limit": 25})

print(result["messages"][-1].content)

运行后,你会在控制台看到主管的调度过程:

> 主管:分配任务给 researcher —— 搜集AI智能体在企业办公中的资料
> researcher 返回调研笔记
> 主管:分配任务给 writer —— 根据调研笔记撰写初稿
> writer 返回初稿
> 主管:分配任务给 editor —— 审核初稿质量
> editor 返回修改意见
> 主管:分配任务给 writer —— 根据编辑意见修改初稿
> writer 返回修改稿
> 主管:分配任务给 publisher —— 排版输出
> publisher 返回终稿
> 主管:所有任务完成,输出最终答案

整个流程像一条流水线,但每一步的"下一站"由主管动态决定。如果编辑提出了重大修改意见,主管会让撰稿人返工;如果调研资料不足,主管会让调研员补充。这种动态调度是单Agent无法实现的。

四、Command和Goto:Agent间的任务移交

上面的Supervisor模式虽然好用,但有一个限制:主管必须参与每一次任务切换。如果Agent之间需要频繁协作,主管会成为瓶颈。

LangGraph提供了更灵活的机制——Commandgoto,让Agent可以直接把任务移交给另一个Agent,不需要主管中转 [226][227]。

Swarm模式下的Handoff

from langchain_core.tools import tool
from langgraph.types import Command

# 创建handoff工具工厂
def make_handoff_tool(target_agent: str, description: str):
    @tool(f"transfer_to_{target_agent}")
    def handoff(reason: str) -> Command:
        """移交任务给另一个Agent"""
        return Command(
            goto=target_agent,
            update={"current_agent": target_agent},
            graph=Command.PARENT,
        )
    handoff.__doc__ = description
    return handoff

# 为每个Agent创建handoff工具
transfer_to_writer = make_handoff_tool(
    "writer",
    "当调研完成,需要撰写文章时,移交给撰稿人。"
)
transfer_to_editor = make_handoff_tool(
    "editor",
    "当文章初稿完成,需要审核时,移交给编辑。"
)
transfer_to_publisher = make_handoff_tool(
    "publisher",
    "当文章审核通过,需要排版时,移交给排版员。"
)

# 给Researcher配handoff工具
researcher_with_handoff = create_react_agent(
    model=llm,
    tools=[web_search, transfer_to_writer],
    name="researcher",
    prompt="你是一位调研员。调研完成后,调用transfer_to_writer移交任务。",
)

Command对象同时做两件事:更新状态(把current_agent改成目标Agent)和跳转节点goto=writer)。这两件事是原子操作,保证状态一致性和执行连续性 [227^]。

主管模式 vs Swarm模式对比

维度 Supervisor(主管调度) Swarm(去中心化协商)
控制权 集中,主管决定一切 分散,Agent自主协商
调试难度 低,看主管日志即可 高,需追踪每个Agent的决策
适用场景 任务类型明确、流程可控 任务模糊、需要频繁协作
延迟 较高(每次切换都经主管) 较低(Agent直接移交)
成本 较高(主管额外LLM调用) 较低(无主管开销)
可靠性 高(规则硬编码) 中(依赖模型判断)

我的生产经验:先用Supervisor跑通流程,积累足够的数据和日志后,再逐步把高频协作路径改成Swarm的handoff。比如"调研→写作"这条路径稳定后,可以让调研员直接移交撰稿人,不需要主管中转 [221^]。

五、共享State:团队的"公共白板"

多Agent协作的核心难题是信息传递。调研员找到了资料,撰稿人怎么知道?编辑提了意见,撰稿人怎么看到?

LangGraph的解决方案是共享State。所有Agent读写同一个State对象,像团队共用一块白板。

状态更新的三种模式

模式一:追加模式(Annotated + add)

class TeamState(MessagesState):
    citations: Annotated[List[str], add]

多个Agent都可以往citations里append,不会覆盖。适合引用来源、日志记录等场景 [220^]。

模式二:覆盖模式(普通字段)

class TeamState(MessagesState):
    draft: str  # 普通字段,后写入的覆盖先写入的

draft字段每次被写入都会覆盖旧值。适合"当前版本"类数据,比如初稿、修改稿、终稿。

模式三:合并模式(Annotated + operator.or_)

from operator import or_

class TeamState(MessagesState):
    collected_info: Annotated[dict, or_]

字典类型的字段,新值和旧值自动合并。适合信息收集场景,比如调研员先写入"关键词",撰稿人后写入"大纲",两者都保留。

避免状态冲突

生产环境中,两个Agent同时写入同一个字段会导致竞争条件。LangGraph的解决方案是:串行执行。Supervisor每次只激活一个Agent,不存在真正的并发写入。Swarm模式下,handoff是原子操作,移交完成后原Agent才释放控制权 [220^]。

六、生产级优化:从Demo到上线

上面的代码能跑通,但距离生产环境还有几步。

优化一:递归限制防死循环

result = supervisor.invoke(
    {"messages": [HumanMessage(content="...")]},
    config={"recursion_limit": 25}  # 最多25轮,超限强制终止
)

多Agent系统最容易出现的bug是"踢皮球":AgentA说"这个给AgentB",AgentB说"这个给AgentA",无限循环。recursion_limit是保险丝,25轮后强制结束 [220^]。

优化二:分层模型策略降低成本

主管需要推理能力,用GPT-4o。专业Agent只需要执行能力,用gpt-4o-mini。这种分层策略可以降低成本60-70%,且不影响调度可靠性 [221^]。

supervisor_llm = ChatOpenAI(model="gpt-4o", temperature=0)  # 主管用大脑
worker_llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)  # 工人用眼睛

优化三:评估Pipeline

多Agent系统比单Agent更容易出错,需要更完善的评估:

  • 路由准确率:主管每次分配是否正确?
  • 工具调用效率:完成任务用了多少次工具调用?
  • 端到端成功率:最终输出是否满足用户需求?

建议用LangSmith追踪每次运行的完整链路,定位是哪个Agent出了问题 [220^]。

七、写在最后:从"超级个体"到"超级团队"

做完这个项目,我对AI应用开发最大的认知转变是:未来的AI系统不是"一个超级聪明的个体",而是"一个协作高效的团队"。

单个Agent的能力边界是模型的能力边界。它再聪明,也不可能同时精通调研、写作、编辑、排版。而且Prompt越长、职责越杂,行为越不可控。

多Agent系统的价值不在于每个Agent有多强,而在于它们之间的协作有多顺畅。就像一支篮球队,五个普通球员配合默契,能打赢五个全明星各自为战。

LangGraph的Supervisor和Swarm模式,给了我们搭建这种"AI团队"的基础设施。主管调度保证可控性,Handoff机制保证灵活性,共享State保证信息流通。

如果你今天还在用一个Prompt试图让AI包办所有事,不妨试着把它拆成几个Agent。当你看到调研员找到资料、撰稿人写出初稿、编辑提出意见、排版员输出终稿,整个流程像一支配合默契的团队一样运转——你会明白:AI的未来不是更聪明的个体,而是更聪明的协作。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐