一个智能体可以独立完成很多事情。但随着应用程序规模的增长,智能体可能需要处理不同类型的任务。此时,引入多智能体设置并划分职责可能会非常有帮助。

正如一位朋友最近想选购新能源车,使用了一个购车智能体帮他提供实用建议。这就要求这个智能体既要懂车型,又能算电费,还能合理规划路线,最后提示词写到几百行,回答反而越来越飘。

这里有个易被忽略的细节:提示词并不是越长越强。当一个智能体同时背负三种专业判断,模型每一轮都要在一堆互相冲突的约束里选边,结果就是每件事都做得浅。所以分工不是为了炫技,是为了让每一段提示词只服务一件事。

在本文中,我们将讨论如何使用 OpenAI Agents SDK 构建实用的多智能体系统。我们将重点介绍构成更复杂多智能体架构的两种模式:智能体即工具和任务交接。

拆完职责之后,先解决一件事:活怎么交出去

在多智能体应用中,给每个智能体拆分完职责,紧接着要回答一个问题:调用方是继续坐在主位,还是直接把话筒交出去。Agents SDK 给了两个答案,理解它们的分歧点,后面所有架构你都能自己推出来。

智能体即工具:把子智能体当成一个工具

主管智能体(后面简称为主管)收到用户需求,判断这件事该由哪个专家智能体(后面简称为专家)做,然后把子任务丢给该专家。专家干完活把结果返回,主管继续往下走流程,最后仍由主管交付用户最终答案。

从主管视角看,这个专家和它手里的搜索函数没有本质区别,所以这套写法叫 “智能体当工具”:

car_tool = car_agent.as_tool(
    tool_name="research_ev_models",
    tool_description="按预算、里程和座位数筛选在售电动车型",
    max_turns=5,
)

tool_name 和 tool_description 是写给主管看的说明书,写得含糊,主管就会在不该派活的时候乱派。

三个专家按同样方式各包装一遍,就有了 car_tool、plug_tool、cost_tool。其中 max_turns 限制子智能体内部的循环次数,防止它自己跟自己聊个没完。

任务交接:把控制权整体交接出去

另一种做法是把话筒直接递过去。主管只负责判断这单该那个智能体接手,智能体接完后,主管就退场,之后的追问、澄清、收尾全由新接手的智能体负责。

support_agent = Agent(
    name="EV support agent",
    instructions="回答用车问题;涉及充电、路线、保养时交给对应专家",
    model="gpt-4.1",
    handoffs=[charging_agent, route_agent, care_agent],
)

这里 handoffs 列表就是可转接对象的名单。专家身上的 handoff_description 是写给上一站看的路标,比 instructions 更容易被忽视,却直接决定路由准不准。这个过程对于用户来说是无感知的,因为对话历史会一起打包过去。

两者的真正差别,只有四条

• 控制权:工具模式跑完就把控制权还给主管;交接模式递出去就没有控制权了。

• 上下文:交接模式时,目标拿到的是完整对话历史;工具模式下的专家只看到主管传进去的那一段内容,跑在相对隔离的上下文里。

• 最终输出者:工具模式由主管输出结果;交接模式由接手的专家输出结果,result.last_agent 就是那个专家智能体的名字。

• 底层建模:交接模式本质上是一个特殊的 transfer 工具,所以它同样会被护栏和追踪记录下来,不是绕开框架的暗箱操作。

所以,要多路汇总时,用工具模式;要专人负责到底,用交接模式。

更常见的是两者混用。比如前台用交接模式把工单派给退款专家,退款专家内部再用工具模式并行调用订单查询和规则校验。前台只管分诊,专家负责决策,边界都很清楚。

场景 1:给一个上海家庭挑新能源车

先看一个 “多路调研汇成一份结论” 的例子。一家三口住在上海,每年开车约 15000 公里,预算 20 万,租的房子装不了私人充电桩,还想带上儿童座椅和行李。他们要的不是一台车的参数,而是 “这款新能源车到底适不适合我们”。

这个问题天然能拆成三块:有哪些车能买、充电到底方不方便、算下来总共花多少钱。三块互不依赖,结论却必须合在一起看,于是扇出再扇入,正好对应工具模式。

def expert(name, duty):
    return Agent(name=name, instructions=duty, model="gpt-4.1",
                 tools=[WebSearchTool(search_context_size="medium")])
car  = expert("Vehicle researcher", "研究符合用户约束的在售车型")
plug = expert("Charging researcher", "评估公共充电可行性、覆盖与电价")
cost = expert("Cost researcher", "核算购置、税费、保险与用电成本")

三个专家各带一个搜索工具,谁都不用知道另外两个在干嘛;专家智能体归属于采购顾问智能体,在主管这一层才有全局视角:

adviser = Agent(name="EV purchase adviser", model="gpt-4.1",
                instructions="需要车型、充电、成本信息时调用对应工具,最后自己汇总",
                tools=[car_tool, plug_tool, cost_tool])
result = Runner.run_sync(adviser, request, max_turns=10)
print(result.final_output, result.last_agent.name)

翻阅轨迹会发现:顾问调用了三个研究工具,最终交付仍是顾问自己。这就是工具模式最有价值的地方:调研可以外包,判断必须自己留着。因为三份报告的价值不在各自结论,而在它们互相矛盾时由谁来决策。

场景 2:老车主的充电咨询

换个场景,同一个 SDK,写法完全不同。这次是一位在上海开电动车、全靠公共充电桩的车主,他想搞清楚各家网络的订阅和计费怎么组合才不吃亏。

这类请求一旦落到某个专业领域,整段对话就归那一位专家智能体负责,中间不需要主管回来汇总,所以直接用交接模式。

跑起来,轨迹里会留下一条 EV support agent → Charging specialist 的交接记录,最后输出结果的是 Charging specialist。

前台只判断该给谁,然后交出控制权;充电专家接手给出最终答复。用户毫无感知,也不用重新讲一遍背景。

两个场景摆到一块,标准其实很朴素:你自己要不要控制权。要控制权用工具模式,不要控制权用交接模式。

该需要控制权的地方用交接模式,主管会中途失去全局掌握;该交给专人的地方用工具模式,专家每轮都得重述结论,又慢又贵。

五种架构,都是同一批 “积木”

有了这两种原语,常见架构就不需要背了。它们只是在三个维度上做了不同选择:委托方式(返回结果还是接管任务)、拓扑结构(谁连谁)、执行节奏(串行、并行还是循环)。

•扇出/扇入:协调者把互不依赖的子任务并行发下去,收齐再合并。委托用工具模式,拓扑结构采用集中式,执行方式是并行的。前面的购车顾问就是它。

•管道:不同智能体负责不同阶段,上一段产出是下一段输入。委托多用交接模式,拓扑结构采用链式,执行方式是串行的,适合 “先清洗、再分析、后成文” 的流水线业务。

•层级:专家自己也带专家,形成树形结构。常见写法是递归使用工具模式,主管调用专家,专家再调用自己的小组执行者。

•评估器-优化器:优化器负责生成,评估器负责挑刺,不过关就打回重写。委托用工具模式,拓扑结构采用集中式,执行在一个循环中进行,适合对正确率要求高的场景。

•集群/点对点:不需要中心调度,谁在线谁决定下一个交给谁。委托以交接模式为主,拓扑结构是网状的,执行是动态的,虽然操作灵活但最难维护。

这里的层级分为三层:最上面是一个总协调智能体,中间是三个领域负责智能体,各自下面再挂两三个只懂一件事的执行智能体。

请求从上往下走,结果从下往上回,每层只关心自己那一段。想加一个新领域,只需判断它该被调用还是该接管,不用重设整个系统。

工具的能力从哪来

分完各智能体的职责,还得有工具干活。工具的来源有三类:

• 实际项目通常混着用:内置的网页搜索、代码解释器开箱即用;

• 任意 Python 函数加个装饰器就能注册,名字、docstring 和参数 schema 由框架自动提取;

• 外部系统按 MCP 协议接进来,本地远程都行。

这也是它容易接进存量系统的原因:已有的函数注册一下就是工具,接内部系统只需起一个 MCP 服务器,所有智能体共用同一入口。

十分钟跑通,再谈上生产环境

环境要求 Python 3.9 以上,注意实时语音那条分支要求 3.10 以上,两者别搞混。安装包只有一条命令:

pip install openai-agents

最小的 Agent 长这样。Agent 是员工,Runner 是调度员,这个分工贯穿整个框架:

from agents import Agent, Runner
agent = Agent(name="Assistant", instructions="你是一位乐于助人的助手")
result = Runner.run_sync(agent, "用三句话解释递归")
print(result.final_output)

能跑通不等于能上线。上生产环境时,要先想清楚四件事:

• 护栏:输入护栏只对链路上第一个智能体生效,输出护栏只对最终产出结果的那个智能体生效,中间被交接的专家默认不触发。

想给每一次工具调用都设卡,得单独配工具护栏,否则中间节点等于 “裸奔”。

• 会话:不用自己拼历史,SDK 会加载和写回。单机跑用 SQLiteSession 就够,多实例部署则要把会话放到 Redis 这类外部存储里,别落在本机文件。

• 追踪:默认开启,模型调用、工具执行、交接、护栏都会记成 span,带耗时和 token 用量。出问题时,先看轨迹,再判断是提示词的问题、工具的问题,还是模型选错了。

• 最大轮数:max_turns 是防死循环的兜底。先跑通正常场景数一下实际步数,再按高 20% 到 30% 设置阈值,既不误杀也不放任。

四个新手最容易踩的坑

• 分不清工具模式和交接模式:一旦选错模式,控制权就会乱套。判断标准只有一条,最终答案由谁来写。

• 工具描述写得太随意:模型看到的是函数名、参数签名和 docstring,不是你的源码。

docstring 要写清楚做什么、参数什么意思、什么时候该用、什么时候不该用,否则它在不该调用时也会去调用。

• 密钥只在当前终端有效:换个终端就报认证错误,别怀疑代码,先检查环境变量有没有重新导出。

• 一上来就用最强模型:路由判断和简单工具调用,小模型又快又稳。

一个 Agent 内部要跑好几轮推理,token 消耗比单次问答高得多,先用轻量模型做前置分类,强模型只负责核心推理。

再往前一步:让一个团队写投研报告

把上面这些拼起来,就能做一套更像真实业务的系统。比如投资研究:一个组合管理(PM)智能体居中,宏观、基本面、量化三个专家向外发散。

用户问 “如果降息落地,我手里的某只股票表现会怎样”,问题先到 PM,由它拆解派活,三份报告回来再合成一份可交付的结论。

值得抄的不只是分工,还有两个工程细节。

1. 把三个专家打包成一个并行工具,一次调用同时触发三路分析,等待时间压到最慢的那一路;

2. 再挂载一个编辑工具,专门把三份结论拼成格式统一的报告。分析和成文分开,谁出问题换谁,不用推倒重写。

另一个小习惯:把 PM 的提示词放在独立的 Markdown 文件里,而不是写死在代码字符串中。改动可 diff、可评审,结果也更好复现。

它和单个 “全能 Agent” 的差别不在聪明程度,而在可审计。每一份子结论都能追溯到哪个专家、查了哪次搜索、拿到什么数据,这在需要签字背书的场景里是硬指标。

顺带提醒一句,并行不是万能的:子任务之间有依赖时强行并发,后面的那一路只会拿到过期信息,该串行的地方还得采用串行。

最后

多智能体应用的门槛从来不在模型,而在你愿不愿意把职责切干净。职责切得干净,两种原语能拼出任何结构;切不干净,再花哨的架构也只是把混乱摊到更多节点上。

如果你手上正好有一个提示词写到五百行、改一处崩另一处的项目,那就是最该动手的信号。先问自己一句:这个答案最后该由谁来写?想清楚这一句,代码基本就成型了。