十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PraisonAI Agent Handoffs 完全指南:多智能体任务委派、结构化交接与安全边界实战

PraisonAI Agent Handoffs 完全指南:多智能体任务委派、结构化交接与安全边界实战 PraisonAI Agent Handoffs 完全指南多智能体任务委派、结构化交接与安全边界实战【免费下载链接】PraisonAIPraisonAI — Hire a 24/7 AI Workforce. Stop writing boilerplate and start shipping autonomous self-improving agents that research, plan, code, and execute tasks. Deployed in 5 lines of code with built-in memory, RAG, and support for 100 LLMs.项目地址: https://gitcode.com/GitHub_Trending/pr/PraisonAI导读Agent Handoffs智能体交接是 PraisonAI 中让不同专长的智能体相互协作的核心机制当一个 Agent 判断任务超出自身能力范围时可以自动将任务交接给更专业的 Agent并携带必要的对话上下文。本指南以官方文档 handoffs.md 为主线结合 handoff.py 与 agent.py 的源码实现带你掌握手写交接配置、结构化输入、输入过滤器、回调钩子、上下文策略与工具安全边界并最终落地一个完整的客服多智能体路由系统。一、什么是 Agent Handoffs在手写代码中Agent 之间的协作通常要靠主控脚本硬编码调度逻辑谁来做什么、什么时候切换都由外部决定。PraisonAI 的 Handoffs 机制把这种决策权交给 Agent 自己交接被自动转换成 LLM 可调用的工具Tool模型根据对话上下文自主决定是否、以及向哪个 Agent 交接。从源码结构看handoff.py 的模块 docstring 明确指出这是一套Unified Handoff System同时支持LLM 驱动的交接通过工具调用tool call完成程序化交接通过 Python APIAgent.handoff_to()直接调用异步交接与并发控制支持max_concurrent并发限制环检测与深度限制防止无限循环交接可配置的上下文策略决定把多少历史上下文传给目标 Agent。在 agent.py 中Agent.__init__接受handoffs参数其类型为List[Union[Agent, Handoff]]——也就是说你既可以直接传 Agent 对象也可以传封装了高级配置的Handoff实例。基本用法最简单的交接只需两步先创建几个专职 Agent再把它们挂到主 Agent 的handoffs列表上from praisonaiagents import Agent, handoff # 创建专职 Agent billing_agent Agent(nameBilling Agent, roleBilling Specialist) refund_agent Agent(nameRefund Agent, roleRefund Specialist) # 创建带交接能力的主 Agent triage_agent Agent( nameTriage Agent, roleCustomer Service, handoffs[billing_agent, refund_agent] # 可交接给这些 Agent )交接如何工作官方文档给出了四条核心机制结合源码可以看得更细交接自动转换为工具在 agent.py 的_process_handoffs()中每个交接项都会被转换为一个可调用工具并追加到 Agent 的tools列表中。直接传入的 Agent 对象会被包装成默认Handoff而Handoff实例则调用其to_tool_function()生成工具函数见 handoff.py。Agent 根据上下文自主决策转换后的工具会出现在 LLM 的工具 schema 中模型在对话中自行决定是否调用交接工具。目标 Agent 接收会话历史Handoff会把源 Agent 的chat_history按配置策略过滤后临时播种seed到目标 Agent 的chat_history上目标 Agent 因此能看到前序对话。目标 Agent 的响应返回给用户工具函数返回Handoff successful. {target} response: {response}源 Agent 把该响应作为最终答案呈现。关于第 3 点的实现细节_seed_target_history()handoff.py采用调用级作用域——先保存目标 Agent 原有chat_history在交接期间把过滤后的上下文前插交接结束后立即恢复。这样既能让目标 Agent 感知上下文又不会污染后续普通对话也防止上下文在连续交接中无限膨胀。二、默认工具命名与描述规则每个交接在未指定覆盖参数时会生成默认的工具名称与描述handoff.py默认工具名transfer_to_agent_name其中 Agent 名称会转为小写并用下划线替换空格。例如Agent(nameRefund Agent)会生成工具transfer_to_refund_agent默认工具描述Transfer task to agent_name (role) - goal会尽量拼入 role 与 goal 信息帮助 LLM 判断何时应该交接。这也是为什么在handoff_unified_config.py示例中协调者可以直接在instructions里写使用transfer_to_research_agent——工具名是确定可预期的。三、高级特性handoff()函数与完整配置3.1 自定义交接配置当默认行为不够时使用handoff()工厂函数获得更细粒度的控制handoff.pyfrom praisonaiagents import Agent, handoff, handoff_filters agent Agent(nameTarget Agent) custom_handoff handoff( agentagent, tool_name_overrideescalate_to_specialist, tool_description_overrideEscalate complex issues to a specialist, on_handofflambda ctx: print(fHandoff from {ctx.name}), input_filterhandoff_filters.remove_all_tools ) main_agent Agent( nameMain Agent, handoffs[custom_handoff] )各参数说明参数作用默认值agent交接的目标 Agent必填无tool_name_override覆盖默认工具名transfer_to_agent_nametool_description_override覆盖默认工具描述由 name/role/goal 拼接on_handoff交接被触发时执行的回调无input_type交接所需的结构化输入类型Pydantic 模型无input_filter过滤/转换传入目标 Agent 的输入支持单函数或函数列表列表按顺序链式执行无configHandoffConfig高级配置上下文策略、超时、并发、安全默认HandoffConfig()此外handoff()还提供一组快捷参数直接映射到HandoffConfig字段context_policy、timeout_seconds、max_concurrent、detect_cycles、max_depth以及安全相关的tool_policy_mode与blocked_tools详见下文统一配置一节。3.2 交接回调Handoff Callbacks回调用于在交接发生时执行自定义逻辑最典型的是日志与监控# 创建目标 Agent target_agent Agent(nameTarget Agent, roleSpecialist) def log_handoff(source_agent): print(fHandoff initiated from {source_agent.name}) handoff_with_callback handoff( target_agent, on_handofflog_handoff )从源码看回调执行器_execute_callback()handoff.py通过inspect.signature自动适配回调的函数签名0 个必填参数callback()无参调用1 个必填参数传入source_agent若存在result则传入HandoffResult2 个及以上必填参数优先callback(source_agent, result)若配置了input_type且有工具参数则尝试构造结构化输入对象callback(source_agent, input_data)。因此你可以为同一个回调编写只关心来源或同时关心来源与数据的不同签名框架会自动适配。3.3 结构化输入Structured Input要求交接时携带特定数据可以用 Pydantic 模型定义载荷契约from pydantic import BaseModel class EscalationData(BaseModel): reason: str priority: str # 创建升级 Agent escalation_agent Agent(nameEscalation Agent, roleSenior Manager) def handle_escalation(source_agent, data: EscalationData): print(fEscalation: {data.reason} (Priority: {data.priority})) escalation_handoff handoff( escalation_agent, on_handoffhandle_escalation, input_typeEscalationData )设置input_type后to_tool_function()会把模型的字段注解转换为工具函数的签名inspect.Parameter见 handoff.pyLLM 就会按 schema 生成结构化参数回调则能收到反序列化好的模型实例。在 handoff_basic.py 中官方示例更进一步演示了多载荷契约同一个 Triage Agent 对三个不同目标分别定义BillingPayloadPydantic、RefundPayloadTypedDict、TechnicalPayloadPydantic交接时从用户请求中提取对应字段填充载荷实现带数据路由。3.4 更强的类型安全TypedHandoff如果你需要在校验失败时主动抛出结构化错误可以使用TypedHandoffhandoff.py。它要求input_schema必须是 PydanticBaseModel子类在边界处用model_validate()校验载荷失败时抛出HandoffValidationError携带validation_errors明细通过校验后载荷会被序列化为格式化 JSONmodel_dump_json(indent2)拼进提示词而不是字符串拼接从而保证结构数据可被目标 Agent 正确反序列化from pydantic import BaseModel from praisonaiagents.agent.handoff import TypedHandoff, HandoffValidationError class ResearchResult(BaseModel): summary: str citations: list[str] confidence: float typed_handoff TypedHandoff( agentwriter_agent, input_schemaResearchResult ) # 合法载荷正常执行 result ResearchResult(summaryAI research findings, citations[ref1], confidence0.92) response typed_handoff.execute_programmatic(source_agent, result) # 非法载荷抛出 HandoffValidationError bad_payload {summary: ..., citations: not-a-list} typed_handoff.execute_programmatic(source_agent, bad_payload)3.5 输入过滤器Input Filters输入过滤器控制哪些会话历史被传给目标 Agent是保护隐私、控制 token 消耗、防止工具噪声干扰目标 Agent 的关键手段。框架内置了handoff_filters静态工具类handoff.pyfrom praisonaiagents import handoff_filters # 创建目标 Agent 用于过滤示例 agent Agent(nameTarget Agent, roleSpecialist) # 移除历史中所有工具调用消息 filtered_handoff handoff( agent, input_filterhandoff_filters.remove_all_tools ) # 仅保留最后 N 条消息 limited_handoff handoff( agent, input_filterhandoff_filters.keep_last_n_messages(5) ) # 移除系统消息 clean_handoff handoff( agent, input_filterhandoff_filters.remove_system_messages )内置过滤器一览除文档列出的三种外源码还提供了第四种过滤器行为remove_all_tools剔除包含tool_calls或role tool的消息keep_last_n_messages(n)工厂函数只保留最后 n 条消息remove_system_messages删除所有系统角色消息compress_history把所有消息内容压缩成单条用户摘要消息降低 token 占用同时保留上下文要点过滤器既可以传单个函数也可以传函数列表——_prepare_context()会按顺序链式应用handoff.py。在 handoff_advanced.py 中甚至有自定义组合过滤器的范例def custom_filter(data): 只保留最后 3 条消息并移除系统消息 data handoff_filters.keep_last_n_messages(3)(data) data handoff_filters.remove_system_messages(data) return data四、上下文策略与统一配置HandoffConfigPraisonAI 将交接相关的所有设置收敛进HandoffConfig数据类handoff.py通过config参数传入handoff()或使用快捷参数。完整字段如下字段类型默认值说明context_policyContextPolicySUMMARY上下文共享策略见下表max_context_tokensint4000上下文最大 token 数max_context_messagesint10LAST_N策略下最多保留的消息数preserve_systemboolTrue是否在过滤时保留系统消息tool_policyHandoffToolPolicyintersect模式工具边界策略timeout_secondsfloat300.0交接执行超时秒0表示不限制max_concurrentint5最大并发交接数0表示不限detect_cyclesboolTrue环检测防止 A→B→A 无限循环max_depthint10交接链最大深度async_modeboolFalse是否异步执行allow_parallelboolFalse是否允许并行交接on_handoff/on_complete/on_errorCallable无交接开始/成功/失败回调ContextPolicy上下文共享策略handoff.py 定义了四种策略策略值行为FULLfull共享完整会话历史SUMMARYsummary共享摘要化上下文默认安全——保留系统消息加最后 3 条非系统消息NONEnone不共享任何上下文LAST_Nlast_n只共享最近 N 条消息由max_context_messages控制注意SUMMARY为默认策略说明框架默认安全优先不会把完整历史直接交给目标 Agent。NONE模式有一个值得注意的联动行为当没有上下文且未配置input_type时工具签名会自动暴露一个显式的task参数handoff.py让调用方必须显式给出任务指令避免空壳交接。工具边界策略HandoffToolPolicy这是交接系统的安全核心。HandoffToolPolicyhandoff.py有两个模式intersect默认安全目标 Agent 只能获得源 Agent 与目标 Agent 工具集的交集。源 Agent 没有的工具目标 Agent 在交接期间也无法使用——这从源头限制了交接后的工具权限放大passthrough传统行为需显式开启目标 Agent 保留自己的完整工具集仅剔除blocked_tools列表中的工具。blocked_tools在两种模式下都生效用于永远禁用某些危险工具如execute_code、shell_tools。使用示例from praisonaiagents import Agent, handoff, HandoffConfig, HandoffToolPolicy triage_agent Agent( nameTriage Agent, handoffs[ handoff(billing_agent, tool_policy_modeintersect, # 仅共享工具 blocked_tools[execute_code, shell_tools]), handoff(refund_agent, configHandoffConfig( tool_policyHandoffToolPolicy( modepassthrough, # 传统行为 blocked_tools[dangerous_tool] ) )) ] )_compute_effective_tools()handoff.py在每次交接时实时计算生效工具集并传给agent.chat(prompt, tools...)而不是在构造期固定保证边界策略始终生效。完整配置示例handoff_unified_config.py 给出了三种交接的差异化配置from praisonaiagents import Agent, handoff, HandoffConfig, ContextPolicy coordinator Agent( nameCoordinator, roleProject Coordinator, handoffs[ # 摘要上下文 120s 超时 深度上限 5 handoff(research_agent, context_policysummary, timeout_seconds120, max_depth5), # 完整上下文 180s 超时 handoff(writer_agent, context_policyfull, timeout_seconds180), # 自定义配置最近 5 条消息、环检测、深度 3 handoff(editor_agent, configHandoffConfig( context_policyContextPolicy.LAST_N, max_context_messages5, detect_cyclesTrue, max_depth3, )), ] )五、程序化交接与并行交接5.1Agent.handoff_to()代码直接发起交接除了让 LLM 自主调用交接工具你也可以在代码里直接决定交接。Agent.handoff_to()agent.py是统一程序化交接 API内部构造Handoff并调用execute_programmatic()返回带类型化结果的HandoffResultresult source_agent.handoff_to( target_agent, promptSummarize the key benefits of multi-agent systems, configHandoffConfig( context_policyContextPolicy.SUMMARY, timeout_seconds60, detect_cyclesTrue, ), ) print(fSuccess: {result.success}) print(fTarget: {result.target_agent}) print(fDuration: {result.duration_seconds:.2f}s) print(fResponse: {result.response})HandoffResulthandoff.py字段包括success、response、target_agent、source_agent、duration_seconds、error、handoff_depth以及类型化结果outcomeAgentRunOutcome成功/超时/失败三种状态。同步版本handoff_to()之外还有异步版本handoff_to_async()agent.py。5.2parallel_handoffs()并行任务委派当需要同时向多个 Agent 委派任务时parallel_handoffs()handoff.py用asyncio.gather并发执行多个交接并通过信号量限制并发数results await parallel_handoffs( sourcemain_agent, targets[ (research_agent, Research topic X), (analysis_agent, Analyze data Y), (summary_agent, Summarize findings Z) ], max_concurrent3 )并行交接时框架会为每个子任务复制contextvars中的交接链handoff.py避免兄弟任务互相污染环检测/深度状态同时每个目标 Agent 的历史播种通过DualLock串行化防止并发写入同一chat_history造成上下文交错。六、推荐提示词与交接指令注入让 LLM 理解何时该交接是交接成功的关键。框架提供两个配套工具handoff.py 与 handoff.pyRECOMMENDED_PROMPT_PREFIX一段建议前缀告诉 Agent 它有能力把任务转交给更专业的 Agentprompt_with_handoff_instructions(base_prompt, agent)在基础提示词上自动追加可用交接 Agent 列表名称 工具描述并拼接推荐前缀。from praisonaiagents import RECOMMENDED_PROMPT_PREFIX, prompt_with_handoff_instructions # 创建专职 Agent billing_agent Agent(nameBilling Agent, roleBilling Specialist) technical_agent Agent(nameTechnical Agent, roleTechnical Support) agent Agent( nameSupport Agent, handoffs[billing_agent, technical_agent] ) # 创建 Agent 后更新其指令 agent.instructions prompt_with_handoff_instructions( Help customers and transfer to specialists when needed., agent # 传入 Agent 以自动生成交接信息 )生成的提示词结构大致为You have the ability to transfer tasks to specialized agents when appropriate. ... Available handoff agents: - Billing Agent: Transfer task to Billing Agent (Billing Specialist) - ... - Technical Agent: Transfer task to Technical Agent (Technical Support) - ... 你的基础提示词prompt_with_handoff_instructions对Handoff实例使用其tool_description对直接传入的 Agent 对象会临时构造默认Handoff来生成描述——两种交接写法都能正确生成清单。注意在Agent.__init__中handoffs必须在调用该函数前传入或在之后手动赋值agent.instructions否则函数因检测不到agent.handoffs而直接返回原提示词。七、安全机制环检测与深度限制多 Agent 协作最怕两类事故A→B→A 无限循环以及交接链无限拉长。Handoff 系统内置了两道防线_check_safety()handoff.py环检测默认开启detect_cyclesTrue每个交接任务在contextvars中维护自己的交接链handoff_chain交接前检查目标是否已在链中命中则抛出HandoffCycleError并附上完整环路径A - B - A深度限制默认max_depth10当交接深度达到上限时抛出HandoffDepthError。这两类错误与HandoffTimeoutError、HandoffValidationError一起构成了完整的错误层级见 errors.py 的导入列表。使用contextvars.ContextVar而非threading.local()存储交接链handoff.py使得每个asyncio.Task/线程的交接链彼此隔离并发场景如服务器并行请求、parallel_handoffs不会互相污染。八、完整实战客服多智能体路由系统handoff_customer_service.py 提供了一个可直接运行的真实场景一个客服主 Agent 路由到订单、退款、FAQ、技术支持、升级五个专职 Agent其中前四个直接传 Agent 对象升级 Agent 则用handoff()定制了工具描述from praisonaiagents import Agent, handoff, RECOMMENDED_PROMPT_PREFIX # 专职 Agent 各自携带工具 order_agent Agent( nameOrder Specialist, roleOrder Management Specialist, tools[check_order_status], instructionsf{RECOMMENDED_PROMPT_PREFIX} I can help with: - Checking order status - Tracking shipments ... For refunds, Ill transfer you to our Refund Specialist. For technical issues, Ill connect you with Technical Support. ) customer_service_agent Agent( nameCustomer Service, roleCustomer Service Representative, instructionsf{RECOMMENDED_PROMPT_PREFIX} - For order tracking and status → Order Specialist - For refunds and returns → Refund Specialist - For common questions → FAQ Assistant - For technical problems → Technical Support - For complaints or special requests → Senior Manager, handoffs[ order_agent, refund_agent, faq_agent, technical_agent, handoff( escalation_agent, tool_description_overrideEscalate to senior management for complex issues or complaints ) ] ) # 调用 response customer_service_agent.chat(I want a refund for order #67890, the product was damaged)这个例子完整展示了主 Agent 用RECOMMENDED_PROMPT_PREFIX声明交接能力、在instructions中明确路由规则、混合使用直接 Agent 引用与定制handoff()两种交接写法。运行它即可观察 LLM 自主把不同类型的请求交给对应专员。另外handoff_basic.py 展示了带类型化载荷的分诊系统handoff_advanced.py 则集中演示了回调、结构化输入、自定义过滤器的组合使用——三者覆盖了从入门到进阶的完整路径。九、最佳实践官方文档给出了五条实践准则这里结合源码补充落地要点明确角色定义Clear Role Definition给每个 Agent 清晰的role与goal。它们不仅影响目标 Agent 的行为还直接参与默认交接工具描述的生成Transfer task to name (role) - goal是 LLM 判断何时交接的重要依据。在指令中写明交接时机Handoff Instructions使用prompt_with_handoff_instructions()或手动拼接RECOMMENDED_PROMPT_PREFIX明确什么情况下转给谁并像客服示例那样给出显式映射表。谨慎使用输入过滤器Context Preservation默认SUMMARY策略已相对安全需要保留关键上下文时优先选择LAST_Npreserve_systemTrue避免过度过滤导致目标 Agent 缺乏必要信息。涉及隐私场景可用remove_system_messages等过滤器脱敏。用回调跟踪交接Logging在on_handoff/on_complete/on_error中记录交接来源、目标、耗时与结果便于调试与数据分析。回调签名会自动适配简单场景只需一个参数。测试所有交接路径Testing确保每个目标 Agent 都能被正确触发、上下文能正确传递、环检测与深度限制按预期工作尤其要覆盖交接失败回退HandoffResult.successFalse的路径。十、向后兼容性官方文档明确声明 Handoff 特性完全向后兼容现有 Agent 无需任何修改即可继续工作——handoffs是Agent.__init__的可选参数agent.py不传即为空列表[]_process_handoffs()会直接返回旧的allow_delegation参数已被弃用代码会给出use handoffs[other_agent] instead的替代提示agent.py所有既有 Agent 功能工具、记忆、守卫等在交接机制下保持不变工具边界策略默认intersect提供安全优先的默认行为追求旧语义时可显式开启passthrough。所有与 Handoff 相关的符号Handoff、handoff、handoff_filters、parallel_handoffs、HandoffConfig、HandoffResult、ContextPolicy、TypedHandoff及各类错误都通过 agent/init.py 导出并支持懒加载可直接从praisonaiagents顶层导入。结语PraisonAI 的 Agent Handoffs 把任务委派从外部编排脚本中解放出来交给 Agent 自己决策通过handoffs[...]一行声明即可获得 LLM 驱动的自主交接通过handoff()、HandoffConfig与handoff_filters可以实现结构化载荷、上下文策略、超时/并发控制、环检测与工具安全边界等生产级能力。无论是构建客服路由、研究-写作流水线还是多步骤任务编排这套机制都能让多智能体协作更可靠、更可观测、更安全。建议从 handoff_basic.py 起步逐步迁移到 handoff_advanced.py 的高级用法最后参考 handoff_customer_service.py 落地真实业务。【免费下载链接】PraisonAIPraisonAI — Hire a 24/7 AI Workforce. Stop writing boilerplate and start shipping autonomous self-improving agents that research, plan, code, and execute tasks. Deployed in 5 lines of code with built-in memory, RAG, and support for 100 LLMs.项目地址: https://gitcode.com/GitHub_Trending/pr/PraisonAI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表