Jean's Blog

一个专注软件测试开发技术的个人博客

0%

多智能体协作:工具模式

为什么要用多智能体?(解决什么问题?)

1. 先抛出痛点:单个 AI “万能助理” 的 3 个天生缺陷

把单个大模型比作一个什么都要干的万能助理,任务一多就会出问题:

  1. 工具太多,选择困难

    要调用日历、计算器、搜索引擎等几十种工具,单个 AI 不知道优先用哪个,容易判断失误、执行出错。

  2. 记性不够用(上下文丢失)

    同时处理多件事时,记忆会过载,很容易遗忘之前的对话、任务上下文,逻辑断裂。

  3. 不是全才,能力有短板

    一个 AI 很难精通所有领域,比如擅长写邮件,但不擅长做数学计算,复杂任务会做不好。

2. 给出解决方案:多智能体的核心逻辑

针对上面的问题,多智能体系统的核心思路是:

不让一个 AI 干所有事,而是拆分出多个专用 AI 助手(智能体),每个只专注一件事、做细分领域专家,再让它们分工协作,一起完成复杂的大任务。

两种核心的合作模式

模式一:工具调用(Tool Calling)—“经理-下属”模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from langchain.tools import tool
from langchain.agents import create_agent

# 1. 先创建个专业下属: 邮件专家
subagent1 = create_agent(
model="...", # 比如GPT-4
tools=[...] # 邮件专家专用的工具, 比如发邮件的API
)

# 2. 把这个下属"包装"成一个工具, 让经理能调用
@tool("邮件专家", description="专门负责写邮件和发邮件的专家")
def call_subagent1(query: str):
# 经理下达指令时, 调用邮件专家
result = subagent1.invoke({
"messages": [{"role": "user", "content": query}]
})
return result["messages"][-1].content # 只返回专家的最终回复

# 3. 创建经理, 把"邮件专家"作为他的工具之一
agent = create_agent(
model="...",
tools=[call_subagent1] # 经理现在可以调用邮件专家了
)

用户给经理下达任务 → 经理判断需要写邮件 → 调用「邮件专家」工具 → 邮件专家独立完成任务 → 结果返回给经理 → 经理整理后回复用户。

详细解读

步骤 1:经理分析任务

用户输入:安排会议并通知小王

  • 主智能体(经理)接收指令,拆解任务:

    ① 安排会议;② 通知小王(需要写会议通知邮件)

  • 经理判断:自己不会写邮件,必须调用【邮件专家】这个下属工具。

步骤 2:经理调用专家工具

经理生成子指令:给小王写会议通知,调用 call_subagent1("给小王写会议通知")

  • 这里触发我们定义的工具函数 call_subagent1
  • 函数把指令转发给下属智能体 subagent1(邮件专家)。

步骤 3:下属(邮件专家)独立执行任务

1
subagent1.invoke({"messages": [{"role": "user", "content": "给小王写会议通知"}]})
  • 邮件专家是垂直领域专家,调用发邮件专用 API
  • 独立完成:撰写邮件正文、格式化会议时间 / 地点、生成完整通知内容;
  • 输出完整结果,存储在返回值的 messages 列表里。

步骤 4:结果返回给经理(核心代码行)

1
return result["messages"][-1].content
  • result["messages"]:是邮件专家完整的对话历史(包含思考、工具调用、最终回答);
  • [-1]:取最后一条消息,也就是邮件专家的最终成品;
  • .content:提取文本内容(会议通知邮件正文);
  • 把纯文本结果返回给经理主智能体。

步骤 5:经理整合结果,回复用户

经理拿到邮件正文后,整合会议安排信息 + 通知邮件,整理成完整话术,最终回复用户:

已为您安排会议,会议通知已撰写完成:

小王您好,兹定于 XX 时间召开会议,请准时参会…

核心逻辑通俗总结

  1. 分工明确:经理只管拆任务、派活、汇总结果,不做专业活;邮件专家只管写邮件,做垂直领域专家;
  2. 调用逻辑:子智能体被包装成普通工具,经理用调用工具的方式调用子 AI,实现上下级协作;
  3. 解决痛点:单个 AI 既要排会议又要写邮件,容易记不住上下文、工具混乱;拆分后各司其职,任务更精准。

技巧1:控制输入信息(给专家更相关的上下文)

有时候经理不能直接把用户原话扔给专家,需要加工一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from langchain.agents import AgentState
from langchain.tools import tool, ToolRuntime

class CustomState(AgentState):
current_task: str # 自定义状态,记录当前任务

@tool("邮件专家", description="专门负责写邮件的专家")
def call_subagent1(query: str, runtime: ToolRuntime[None, CustomState]):
# 不只是用户原话,还加上经理知道的其他信息
enhanced_input = f"""
当前整体任务: {runtime.state["current_task"]}
具体需要你做的: {query}
请用专业语气完成。
"""
result = subagent1.invoke({
"messages": [{"role": "user", "content": enhanced_input}]
})
return result["messages"][-1].content

之前的基础版代码里,经理直接把用户原指令扔给下属专家,专家只知道要干局部小事,不知道这件事属于哪个大任务,写出来的内容容易生硬、脱离整体场景。

例:用户说「安排会议并通知小王」,经理只告诉专家「写邮件」,专家不知道是会议通知,邮件会写得很通用。

优化思路

经理在调用下属前,加工输入信息,把整体任务上下文一起传给专家,让专家知道自己的工作在整个流程里的定位,输出更贴合场景。

优化前(基础版)

经理传给专家:给小王写会议通知

→ 专家只知道写邮件,不知道是会议场景,邮件很简单。

优化后(本代码版)

经理传给专家的完整指令:

1
2
3
当前整体任务: 安排会议并通知小王
具体需要你做的: 给小王写会议通知
请用专业语气完成。

→ 专家明确知道:我在完成「安排会议」这个大任务的一环,会自动调整为正式会议通知格式,内容更贴合业务场景。

主智能体(经理)不能无脑甩指令,要做信息加工,给子智能体补充全局上下文,解决子智能体 “信息孤岛” 问题,大幅提升输出质量。

技巧2:控制输出信息(让专家汇报得更清楚)

有时候专家干活很好,但不会写工作报告。我们需要教他如何汇报:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from typing import Annotated
from langchain.tools import InjectedToolCallId
from langgraph.types import Command

@tool("邮件专家", description="专门负责写邮件的专家")
def call_subagent1(query: str, tool_call_id: Annotated[str, InjectedToolCallId]) -> Command:
result = subagent1.invoke({
"messages": [{"role": "user", "content": query}]
})

# 不仅返回文本,还能返回结构化数据
return Command(
update={
"email_status": "completed", # 告诉经理邮件状态
"messages": [{
"content": f"邮件已完成: {result['messages'][-1].content}",
"tool_call_id": tool_call_id
}]
}
)

承接上一个技巧(控制输入),这是经理 - 下属多智能体的第二个工程优化

  • 旧版本:子智能体只返回纯文本,经理只能拿到结果,不知道任务状态、执行细节
  • 新版本:通过 Command 返回结构化数据,把任务状态 + 执行结果一起上报给经理,方便主智能体做后续决策

旧版输出(纯文本)

经理只收到:小王您好,兹定于XX时间召开会议...

经理不知道邮件是否发完、任务是否结束,无法判断下一步。

新版输出(结构化)

经理收到完整结构化信息:

  • 状态:email_status: completed(邮件任务已完成)
  • 结果:邮件正文
  • 标识:本次调用 ID

经理可据此判断:通知小王的任务已完成,可以继续推进后续会议流程

整体价值总结

  1. 信息完整度升级:从只返回 “干活结果”,升级为返回「任务状态 + 结果 + 唯一标识
  2. 便于主智能体决策:经理能清晰知道每个子任务的完成情况,实现复杂流程的串联
  3. 工程可落地:适配 LangGraph 状态流,可用于复杂多智能体系统的任务监控、进度追踪

一个完整的多智能体专家的示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 经理的完整工具箱
def create_supervisor():
# 创建各个专家
email_agent = create_agent(model="...", tools=[email_tools])
calendar_agent = create_agent(model="...", tools=[calendar_tools])

# 把专家包装成工具
@tool("邮件专家", description="负责写邮件和发邮件")
def call_email_expert(instruction: str):
# 可以在这里加工输入信息
enhanced_instruction = f"这是会议安排流程的一部分,请写邮件: {instruction}"
result = email_agent.invoke({"messages": [{"role": "user", "content": enhanced_instruction}]})
return result["messages"][-1].content

@tool("日历专家", description="负责检查档期和创建会议")
def call_calendar_expert(instruction: str):
result = calendar_agent.invoke({"messages": [{"role": "user", "content": instruction}]})
return result["messages"][-1].content

# 创建经理,拥有调用专家的能力
supervisor = create_agent(
model="...",
tools=[call_email_expert, call_calendar_expert]
)
return supervisor

# 使用经理
supervisor = create_supervisor()
response = supervisor.invoke(
{"messages": [{"role": "user", "content": "安排下周三下午两点的团队会议,并通知小王"}]}
)

这是经理 - 下属模式多智能体的完整落地示例,整合了你前面学的工具调用、控制输入信息两大技巧,实现一个可处理复杂任务的多 AI 协作系统。

整体架构

  • 经理(supervisor):主智能体,负责拆解任务、调度下属、整合结果
  • 邮件专家(email_agent):子智能体,专注写邮件、发邮件
  • 日历专家(calendar_agent):子智能体,专注查档期、创建会议
  • 模式:1 个经理 + 多个垂直领域专家,专家被包装成经理可调用的工具

完整执行流程(结合示例指令)

  1. 经理拆解任务:收到指令 → 拆分为「创建会议(日历专家)」+「通知小王(邮件专家)」
  2. 调用日历专家:下达指令,日历专家查询档期、创建会议
  3. 调用邮件专家:下达指令,同时补充上下文 “这是会议安排的一部分”,邮件专家生成专业会议通知
  4. 整合结果:经理汇总会议创建结果 + 邮件内容,返回给用户

核心优势总结

  1. 分工明确:日历、邮件专业分离,互不干扰
  2. 上下文精准:经理给专家补充全局信息,输出质量更高
  3. 可扩展性强:后续新增财务、文档专家,只需新增子智能体 + 工具,直接挂载给经理即可
  4. 工程化落地:基于 LangChain 原生能力,简单、稳定、易维护

代码如何体现多智能体思想

对前面经理 - 下属模式多智能体完整代码的核心思想总结,从 4 个维度解释了:我们写的代码,为什么就是多智能体(Multi‑Agent)。我结合之前的代码案例,逐个通俗拆解:

1. 分工明确

每个智能体有专门的工具和职责

  • 对应代码:
    • 邮件专家:只挂载邮件工具,只负责写邮件、发邮件
    • 日历专家:只挂载日历工具,只负责查档期、建会议
    • 经理:不做具体执行,只负责调度、汇总
  • 核心思想:一人一岗、垂直专精,解决单个 AI 工具太多、样样不精的问题。

2. 层次清晰

经理智能体协调,专家智能体执行

  • 对应代码:上下级层级架构
    1. 上层:经理(主智能体),负责拆任务、发指令、整合结果
    2. 下层:多个专家(子智能体),负责干活、输出专业结果
  • 类比企业:老板指挥,员工干活,权责边界清晰,避免混乱。

3. 信息可控

通过代码精确控制每个智能体看到什么、返回什么

  • 对应我们前面学的两个核心技巧:
    1. 控制输入:经理给专家补充整体任务上下文,不让专家只收到零散指令
    2. 控制输出:通过结构化返回,强制专家上报任务状态,经理全程掌握进度
  • 核心价值:避免信息泄露、上下文丢失、输出失控,让 AI 行为可预测、可管控。

4. 灵活组合

可以轻松添加新的专家到团队中

  • 对应代码的可扩展设计

    新增专家(如财务专家、文档专家、翻译专家),只需要:

    1. 创建新的子智能体 + 专属工具
    2. @tool包装成工具
    3. 挂载到经理的工具列表里
  • 不用改动原有代码,插拔式扩展,适配越来越复杂的业务任务。