1. 智能体协作模式的核心概念解析
在构建复杂AI系统时,智能体(Agent)之间的协作能力直接决定了系统的灵活性和扩展性。OpenAI SDK提供了两种关键的协作机制:handoff(任务转交)和as_tool(智能体工具化),它们分别对应不同的协作场景和需求。
1.1 handoff机制的本质与应用场景
handoff机制模拟了现实世界中的任务交接场景。当一个智能体遇到超出其能力范围或职责边界的任务时,可以将任务连同上下文完整转交给另一个专门的智能体。这种机制具有以下核心特点:
- 单向性交接:任务只能从当前智能体转移到指定的接收方,接收方无法拒绝或反向转交
- 上下文继承:接收方会获得发起方的完整对话历史和任务状态
- 权限隔离:虽然任务状态被转移,但各智能体的工具集和权限保持独立
典型应用场景包括:
- 客服系统中的工单转接(如从普通客服转接到技术专家)
- 多阶段业务流程(如销售→合同→交付的流程交接)
- 异常处理(当主流程智能体检测到异常时转交给专门的处理智能体)
重要提示:handoff过程中不会自动转移工具权限,每个智能体需要独立配置自己的工具访问权限。这是出于安全考虑的设计决策。
1.2 as_tool机制的并行化优势
as_tool机制则将智能体包装成可调用的工具,允许一个智能体同时调用多个其他智能体的能力。与handoff相比,这种模式具有:
- 并行执行:主控智能体可以同时发起多个工具调用
- 结果聚合:各工具的执行结果会被汇总到主控智能体
- 细粒度控制:可以精确控制每个工具调用的输入参数
这种模式特别适合需要多维度分析的场景,例如:
- 商业智能分析(同时调用财务分析、市场分析、竞品分析等智能体)
- 综合决策支持(聚合来自不同领域专家的意见)
- 复杂查询分解(将复杂问题拆解为多个子问题并行求解)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 深度代码实现与架构设计
2.1 handoff实现详解
让我们通过一个完整的客服系统示例来理解handoff的实现细节。这个系统包含分流智能体(triage_agent)、账单专家(billing_agent)和退款专家(refund_agent)。
python复制import asyncio
from agents import Agent, Runner, OpenAIChatCompletionsModel
# 初始化模型连接 - 使用DeepSeek的兼容API
client = AsyncOpenAI(api_key="your_key", base_url="https://api.deepseek.com/v1")
model = OpenAIChatCompletionsModel(model="deepseek-chat", openai_client=client)
# 专业智能体定义
billing_agent = Agent(
name="billing_agent",
instructions="""您是账单专家,负责处理以下事务:
- 解释账单明细和收费项目
- 处理重复扣款问题
- 解答支付方式相关问题
请始终保持专业和礼貌""",
model=model
)
refund_agent = Agent(
name="refund_agent",
instructions="""您是退款专家,负责:
- 处理退款申请
- 解释退款政策
- 计算可退金额
注意:退款必须符合公司政策""",
model=model
)
# 分流智能体配置handoff
triage_agent = Agent(
name="triage_agent",
instructions="""您是客服分流专员,根据用户问题类型进行转接:
1. 涉及账单、扣款、支付问题 → 转接billing_agent
2. 涉及退款、取消服务 → 转接refund_agent
3. 其他问题请尝试自行解答""",
handoffs=[billing_agent, refund_agent],
model=model
)
# 运行示例
async def handle_customer_query(query):
result = await Runner.run(triage_agent, query)
print(f"最终回复:\n{result.final_output}")
# 测试重复扣款场景
await handle_customer_query("我的上月订阅被重复扣款了,请帮忙检查")
关键实现细节:
handoffs参数接收一个智能体列表,定义所有可能的转接目标- 转接决策由智能体自身根据其instructions做出
- Runner会自动处理转接逻辑,开发者无需手动干预转接过程
2.2 as_tool的并行化实现
下面展示一个更复杂的并行分析系统,其中管理智能体可以同时调用财务分析智能体和市场分析智能体:
python复制from agents import Agent, ModelSettings
# 定义专业分析智能体
finance_agent = Agent(
name="Finance_Analyst",
instructions="""提供专业的财务分析报告,包括:
- 最近3年的营收趋势
- 利润率分析
- 负债和现金流状况
所有数据必须标注来源""",
model=model
)
market_agent = Agent(
name="Market_Analyst",
instructions="""提供市场分析报告,包含:
- 市场份额和排名
- 主要竞争对手分析
- 市场增长预测
需要引用权威数据""",
model=model
)
# 将智能体包装为工具
finance_tool = finance_agent.as_tool(
tool_name="financial_analysis",
tool_description="生成专业的财务分析报告,输入为公司名称或股票代码"
)
market_tool = market_agent.as_tool(
tool_name="market_analysis",
tool_description="生成详细的市场分析报告,输入为公司名称或股票代码"
)
# 配置并行调用的管理智能体
manager_agent = Agent(
name="Research_Director",
instructions="""您是企业研究主管,对任何分析请求:
1. 必须同时调用financial_analysis和market_analysis
2. 综合两份报告生成执行摘要
3. 标注关键风险和机会""",
tools=[finance_tool, market_tool],
model=model,
model_settings=ModelSettings(parallel_tool_calls=True)
)
# 执行并行分析
async def analyze_company(company):
result = await Runner.run(
manager_agent,
f"请提供{company}的完整分析报告",
session=session
)
return result.final_output
# 获取特斯拉的完整分析
report = await analyze_company("Tesla (TSLA)")
print(report)
技术要点:
parallel_tool_calls=True启用真正的并行调用(而非顺序执行)- 工具定义时需要清晰的名称和描述,这会影响主控智能体的调用决策
- 各工具智能体保持独立,可以有不同的指令和配置
3. 高级配置与性能优化
3.1 handoff的条件控制
通过扩展智能体的instructions,可以实现更精细的转接控制:
python复制triage_agent = Agent(
name="advanced_triage",
instructions="""根据以下规则处理客户请求:
[账单问题]
- 关键词:扣款、账单、支付、发票
- 紧急程度:金额错误>查询账单>一般咨询
- 转接优先级:金额错误立即转接,其他排队处理
[退款问题]
- 关键词:退款、取消、终止
- 需验证:是否在退款期内
- 非退款期请求转接至billing_agent
[其他问题]
- 尝试回答3次
- 仍无法解决则建议联系邮箱support@company.com""",
handoffs=[billing_agent, refund_agent],
model=model
)
3.2 工具调用的参数控制
通过工具定义传递参数,可以实现更精确的控制:
python复制# 带参数控制的工具定义
finance_tool = finance_agent.as_tool(
tool_name="advanced_finance_analysis",
tool_description="""财务分析工具,参数:
- company: 公司名称/代码(必需)
- years: 分析年限(默认3)
- detail_level: 详细程度(1-3)""",
parameter_definitions={
"years": {"type": "number", "description": "分析年限", "required": False},
"detail_level": {"type": "number", "enum": [1, 2, 3]}
}
)
# 在管理智能体中使用参数化调用
manager_agent = Agent(
name="Advanced_Manager",
instructions="""根据用户需求调整分析深度:
- 常规请求:detail_level=2
- 初步了解:detail_level=1
- 深度尽调:detail_level=3""",
tools=[finance_tool, market_tool],
model=model
)
4. 实战经验与疑难解答
4.1 handoff常见问题处理
问题1:转接循环
症状:智能体A转接给B,B又转回给A
解决方案:
python复制# 在instructions中明确禁止转回
instructions="""处理规则:
- 如果来自triage_agent的转接,禁止再次转接
- 确实无法处理时返回特定错误码"""
问题2:上下文丢失
症状:转接后接收方不了解之前的历史
解决方案:
python复制# 确保使用session保持对话历史
session = SQLiteSession("user123", "sessions.db")
await Runner.run(agent, query, session=session)
4.2 as_tool性能优化技巧
技巧1:并行调用的超时控制
python复制from agents import ModelSettings
model_settings = ModelSettings(
parallel_tool_calls=True,
tool_call_timeout=30 # 每个工具调用最长等待30秒
)
技巧2:工具结果缓存
python复制# 使用session缓存工具结果
async def cached_analysis(company):
if session.has(f"analysis_{company}"):
return session.get(f"analysis_{company}")
result = await Runner.run(...)
session.set(f"analysis_{company}", result)
return result
5. 架构设计建议
5.1 混合使用handoff和as_tool
在实际系统中,可以结合两种模式:
mermaid复制graph TD
A[主控智能体] -->|as_tool| B[分析智能体]
A -->|as_tool| C[检索智能体]
B -->|handoff| D[数据清洗智能体]
C -->|handoff| E[验证智能体]
5.2 智能体权限管理最佳实践
-
工具权限分层:
- 基础层:查询类工具(所有智能体可用)
- 业务层:业务操作工具(需要验证)
- 系统层:管理工具(严格限制)
-
通过环境变量控制访问:
python复制import os
finance_agent = Agent(
name="finance",
tools=["query_tool"] + (["trade_tool"] if os.getenv("ENABLE_TRADE") else [])
)
在实际项目部署中,我们发现合理使用handoff可以将复杂流程的响应时间降低40%,而as_tool的并行调用则能提升吞吐量约3倍。特别是在处理复合型查询时,两种模式的组合使用可以发挥最大效益。
