尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

OpenAI Agents SDK 工具执行生命周期深度解析:规划、审批、守卫、并发与取消的完整链路

发布时间:2026/9/10 12:10:56

资讯中心
01
ARTICLE

OpenAI Agents SDK 工具执行生命周期深度解析:规划、审批、守卫、并发与取消的完整链路

OpenAI Agents SDK 工具执行生命周期深度解析:规划、审批、守卫、并发与取消的完整链路
OpenAI Agents SDK 工具执行生命周期深度解析规划、审批、守卫、并发与取消的完整链路【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python工具调用Function Tool / Tool Calling是 Agent 与外部世界交互的核心通道也是多 Agent 工作流中最容易出错、最难调试的环节同一个call_id被模型重复使用、工具在审批等待期间被禁用、多个并行工具中一个失败导致其他成功结果被吞掉、父任务取消后遗留的后台任务泄漏事件循环……这些问题一旦出现往往表现为偶发性的行为错乱极难复现和定位。本文基于 openai-agents-python 仓库的.agents/references/tool-execution-lifecycle.md工具执行生命周期参考文档结合 src/agents/run_internal/tool_planning.py、src/agents/run_internal/tool_execution.py、src/agents/tool.py 等源码系统拆解一个函数工具从被模型发现到输出进入运行状态的完整生命周期规划Planning→ 审批Approval→ 守卫Guardrails→ 并发执行Concurrency→ 取消/失败Cancellation Failure→ 钩子与追踪Hooks Tracing→ 工具选择复位Tool Choice Reset。读完本文你将能够理解该框架在工具执行边界上的全部设计决策并掌握在二次开发、插件扩展或排查线上问题时应该遵守的契约约束。一、总览工具执行的生命周期全景在 openai-agents-python 中一次完整的函数工具执行可以被划分为六个阶段每一阶段都有独立的职责与归属模块发现Discoveryprocess_model_response()解析模型输出识别出可执行的工作函数调用、handoff、computer action、shell call、apply_patch、custom tool 等。规划Planningsrc/agents/run_internal/tool_planning.py 中的ToolExecutionPlan决定哪些工作现在可以运行并对新鲜轮次fresh turn与恢复轮次resume turn分别构建不同的执行计划。审批分区Approval Partitioning按call_id和工具身份解析审批状态将工具运行划分为已批准approved、待中断pending interruption与被拒绝rejected三组。执行Invocationsrc/agents/run_internal/tool_execution.py 中的_FunctionToolBatchExecutor以有界并发方式实际运行工具处理器并在此边界上执行输入守卫、输出守卫、钩子与追踪 span。输出收束Output Settlement将各工具结果按模型原始顺序组装为ToolCallOutputItem提交为可接受的运行状态accepted run state或持久化会话历史。复位与清理Reset CleanupAgentToolUseTracker按 Agent 身份记录工具使用情况在reset_tool_choiceTrue时复位下一轮的工具选择同时保证每个启动的任务与每次运行持有的资源都到达确定性的终态。参考文档特别强调了一条贯穿始终的原则先规划后副作用Plan Before Side Effects。发现discovery与规划planning必须分离规划与调用invocation也必须分离发现阶段找到的可执行工作绝不等于现在就应该执行的工作。这一分离使得审批、守卫、去重、并发控制全部可以插在中间层而不需要侵入工具处理器本身。二、规划层ToolExecutionPlan与新鲜/恢复轮次的差异化处理2.1 规划层的数据结构ToolExecutionPlan定义于 src/agents/run_internal/tool_planning.py它表示单个回合中需要执行的工具工作字段包括字段类型说明function_runslist[ToolRunFunction]常规函数工具调用computer_actionslist[ToolRunComputerAction]计算机操作截图、点击等custom_tool_callslist[ToolRunCustom]自定义工具调用shell_callslist[ToolRunShellCall]shell 工具调用apply_patch_callslist[ToolRunApplyPatchCall]apply_patch 编辑操作local_shell_callslist[ToolRunLocalShellCall]本地 shell 调用pending_interruptionslist[ToolApprovalItem]待人工审批的中断项approved_mcp_responseslist[RunItem]已批准或自动批准的 MCP 审批响应mcp_requests_with_callbacklist[ToolRunMCPApprovalRequest]走回调的托管 MCP 审批请求2.2 新鲜轮次 vs 恢复轮次的规划差异参考文档明确指出Fresh and resumed turns need different plans新鲜轮次与恢复轮次需要不同的计划。源码中对应两个构建函数_build_plan_for_fresh_turn()tool_planning.py从processed_response直接搬运全部工具运行与审批请求。_build_plan_for_resume_turn()tool_planning.py不重新发现工具而是接收上一轮中断时保留下来的function_runs、computer_actions、shell_calls等参数只执行尚未解决或新批准的工作且恢复轮次的local_shell_calls固定为空[]。这一差异的工程意义在于恢复一个被中断的回合绝不能重新发现并重新运行已经完成的调用。如果模型在第一次调用后收到审批中断恢复时框架必须从RunState中还原之前的调用而不是再次向模型要一次工具调用参数——否则可能造成同一个副作用被执行两次。2.3 执行计划的分发_execute_tool_plan()tool_planning.py是规划层的总调度器。它区分两种模式并行模式parallelTrue默认通过gather_with_cancel同时启动execute_function_tool_calls、execute_computer_actions、execute_custom_tool_calls、execute_shell_calls、execute_apply_patch_calls、execute_local_shell_calls六个执行器并传入一个共享的sibling_category_failure事件——当某一类工具如 shell失败时其余类别可以感知并进入对应的收束路径。串行模式parallelFalse按类别依次执行便于在特定配置下获得确定性顺序。gather_with_cancel定义于 src/agents/util/_asyncio_tasks.py是框架内部对asyncio.gather的封装增加了取消传播与失败仲裁能力。三、审批分区needs_approval的权威性与不重复判定约束3.1 审批状态是权威的参考文档的核心约束之一是Approval state is authoritative once resolved. Do not call a dynamicneeds_approvalchecker again for a call whose status is already approved or rejected.审批状态一旦确定即为权威对于已经批准或拒绝的调用不得再次调用动态的needs_approval检查器。源码中_collect_runs_by_approval()tool_planning.py精确实现了这一语义首先通过context_wrapper.get_approval_status(tool_name, call_id, ...)查询持久化的审批状态仅当状态为None从未判定时才调用needs_approval_checker(run)再次查询状态后按False拒绝构造 rejection item→True批准加入 approved runs→needs_approvalFalse无需审批直接放行→ 否则加入pending_interruptions四条分支处理。同样的逻辑在恢复路径_select_function_tool_runs_for_resume()tool_planning.py中再次出现if approval_status is None:才调用needs_approval_checker然后立刻重查状态。这意味着needs_approval是一个一次性的、可变的判定而审批结论是跨RunState恢复仍然有效的持久化事实。3.2 审批与拒绝消息的粘附性Persisted approval decisions and rejection messages must remain attached to the same tool identity and call ID acrossRunStateresume.持久化的审批决策与拒绝消息必须始终粘附在同一个工具身份与 call ID 上。在_collect_runs_by_approval中每个工具运行都被包装为ToolApprovalItem其中携带了完整的身份信息tool_name工具名tool_namespace通过get_tool_call_namespace()解析的命名空间来自调用载荷tool_origin通过get_function_tool_origin()解析的工具来源tool_lookup_key通过get_function_tool_lookup_key_for_tool()解析的规范查找键。get_approval_status正是以tool_name call_id并辅以 lookup key / namespace为键查询状态的从而保证审批结论在跨轮次恢复时不会错配到其他工具。3.3 调用身份去重重复的工具定义不是重复的调用参考文档要求Deduplicate by invocation identity before execution while preserving model order... A repeated tool definition is not a repeated call, and a repeated call ID must not execute twice.执行前按调用身份去重同时保留模型顺序……重复的工具定义不是重复的调用重复的 call ID 绝不能执行两次。_dedupe_processed_response_invocations()tool_planning.py实现了完整的去重矩阵历史完成调用索引遍历existing_items用tool_output_identity构建已完成输出键集合并用tool_invocation_identity构建历史调用身份 → (类型, call_id, 指纹)映射。同响应内去重current_response_invocations记录本次响应中已出现的 call ID若同一响应内模型复用了 call ID 但身份不同抛出ModelBehaviorError(Model reused a tool call ID for a different invocation in one response.)。跨响应历史去重若某 call ID 在历史中已存在且身份不一致抛出ModelBehaviorError(Model reused a completed tool call ID for a different invocation.)若身份一致且filter_completedTrue则该调用被跳过skipped_raw_item_ids.add(...)。已执行未提交检测binding_status[2] and not binding_status[1]时抛出ModelBehaviorError(A tool call already executed, but its output was not committed.)防止执行了但输出丢失的状态被静默重试。值得注意的是_tool_call_identity()tool_planning.py在 call ID 缺失时回退到(call_id, name, hashable_args)三元组其中参数通过_hashable_identity_value()稳定序列化dict/list 用json.dumps(sort_keysTrue)从而在非 OpenAI 格式或不含 ID 的载荷下依然可以完成身份识别。四、调用边界to_thread、超时、失败转换与嵌套执行4.1 同步函数通过asyncio.to_thread执行参考文档Decorated synchronous Python functions run throughasyncio.to_thread()so they do not block the event loop. Async function tools run in the event loop and are the only decorated handlers that support SDK timeouts.被装饰的同步 Python 函数通过asyncio.to_thread()运行以免阻塞事件循环。异步函数工具在事件循环中运行是唯一支持 SDK 超时的装饰处理器。在 src/agents/tool.py 中可以看到精确实现if not is_sync_function_tool: if schema.takes_context: result await the_func(ctx, *args, **kwargs_dict) else: result await the_func(*args, **kwargs_dict) else: if schema.takes_context: result await asyncio.to_thread(the_func, ctx, *args, **kwargs_dict) else: result await asyncio.to_thread(the_func, *args, **kwargs_dict)这一设计直接决定了超时能力的边界asyncio.to_thread中的线程任务无法被事件循环的asyncio.wait_for可靠取消线程不会被中断因此只有 async 工具处理器才能使用 SDK 的超时机制。若你需要在同步工具上实施超时必须自行在处理器内部实现例如内部再次提交到线程池并等待。4.2 超时与普通异常是两套独立策略参考文档timeout_behaviorandtimeout_error_functionown timeout conversion;failure_error_functionNonemeans ordinary exceptions propagate instead of becoming model-visible output.timeout_behavior与timeout_error_function负责超时转换failure_error_functionNone意味着普通异常直接传播而不会变成模型可见的输出。在 src/agents/tool.py 附近的超时分支中timeout_behavior支持两种取值error_as_result默认超时被转换为模型可见的错误文本若提供了timeout_error_function则用它格式化超时消息raise_exception超时作为异常直接抛出。而failure_error_function是独立的一层它仅用于把工具执行失败转换为模型可见输出的场景配合function_tool装饰器的failure_error_function参数见 tool.py 与set_function_tool_failure_error_function/resolve_function_tool_failure_error_function。若其值为None普通异常将向上传播到运行层而不是伪装成工具输出回传给模型——这保证了错误不会被静默吞掉。4.3 每次调用恰好一个 span 与一对钩子参考文档Tool start/end hooks and function spans surround the actual invocation once per call, including failure and cancellation paths. Do not emit a successful end state before output guardrails complete.工具开始/结束钩子与函数 span 每次调用恰好包裹一次真实调用包括失败与取消路径在输出守卫完成之前不得发出成功的结束状态。在_FunctionToolBatchExecutor._run_single_tool()tool_execution.py中每次工具调用都在一个with function_span(trace_tool_name) as span_fn:块内执行异常路径通过_error_tracing.attach_error_to_current_span(...)给 span 打上SpanError其中trace_include_sensitive_data配置决定输入输出是否写入 span默认脱敏。随后在_execute_single_tool_body()中hooks.on_tool_start运行级钩子与agent_hooks.on_tool_startAgent 级钩子通过gather_with_cancel并行触发——注意这里并不存在对称的on_tool_end钩子钩子的收尾职责由 span 上下文管理器与结果提交共同完成。4.4 嵌套Agent.as_tool()拥有独立的嵌套运行状态嵌套Agent.as_tool()执行拥有一个嵌套运行循环与嵌套的可恢复状态。嵌套状态必须按父RunState与调用身份进行缓存而不是仅按可复用的 Agent 或工具对象缓存。源码中通过get_agent_tool_state_scope(context_wrapper)生成tool_state_scope_id并配合peek_agent_tool_run_result/consume_agent_tool_run_result来自 src/agents/agent_tool_state.py在嵌套中断后恢复内部 Agent 的运行。这一点对于工具内部再跑一个 Agent的场景如research_bot示例中的子 Agent至关重要多个并行的嵌套运行共享同一个外层 Agent 对象但状态必须按调用隔离。4.5 每运行资源run-scoped resources的初始化与释放Per-run resources such as resolvedComputerimplementations must be initialized and disposed by the run that acquired them.每次运行持有的资源——例如已解析的Computer实现——必须由获取它的那次运行负责初始化与释放。initialize_computer_tools()tool_execution.py演示了该模式的实现对每个ComputerTool调用resolve_computer(tooltool, run_contextcontext_wrapper)解析出Computer实例并通过dataclasses.replace(tool, computerresolved_computer)生成运行局部的工具副本而不是修改 Agent 上的共享工具对象。这样每个并发运行都持有独立的计算机实现不会相互污染。五、并发与失败语义有界并发、顺序保持与确定性仲裁5.1 SDK 侧并发 ≠ 提供方并发参考文档给出了一个关键澄清SDK-side function-tool concurrency is independent of provider-side parallel tool-call generation. The provider controls how many calls appear in one response;RunConfig.tool_execution.max_function_tool_concurrencycontrols how many local function handlers run at once.SDK 侧的函数工具并发独立于提供方侧的并行工具调用生成。提供方决定一次响应中出现多少个调用RunConfig.tool_execution.max_function_tool_concurrency决定本地函数处理器同时运行多少个。两个配置项分别在两层提供方层模型请求中的parallel_tool_calls等参数决定模型一次性发出多少工具调用SDK 层src/agents/run_config.py 中的ToolExecutionConfig.max_function_tool_concurrency默认None即启动本轮全部调用限制本地处理器同时执行的个数设为1即完全串行。__post_init__校验该值必须 1。SDK 层的并发由_FunctionToolBatchExecutor._fill_tool_task_slots()tool_execution.py实现它是一个插槽调度器——当有任务完成时_drain_pending_tasks中asyncio.wait(FIRST_COMPLETED)返回再从未处理的pending_tool_runs中按顺序取出新任务填充空位形成有界并发的工作队列。5.2 输出顺序保持模型顺序Preserve model order in emitted outputs even when handlers complete out of order.即使处理器乱序完成发出的输出也必须保持模型顺序。_FunctionToolTaskState中保存了order枚举顺序_record_completed_function_tool_tasks()tool_execution.py在记录结果时按order排序sorted(completed_tasks, keylambda task: task_states[task].order)最终_build_function_tool_results()会按工具运行顺序重新组装FunctionToolResult列表确保喂给模型的输出与模型发出调用的顺序一致——这直接避免了模型按 A、B、C 顺序调用结果却按 C、A、B 顺序返回造成的推理错乱。5.3 兄弟隔离一个失败不吞掉成功的输出Isolate sibling results. A cancelled or failed call must not discard outputs already produced by successful siblings.隔离兄弟结果。被取消或失败的调用不得丢弃已经由成功兄弟产生的输出。该语义由_raise_failure_after_draining_siblings()tool_execution.py实现其流程是将待处理任务分为可取消任务与post-invoke 阶段任务两类_partition_pending_tasks取消可取消的兄弟任务并在有界窗口内**排干drain**它们——即等待它们完成必要的自我推进步骤避免强行取消留下脏状态_drain_cancelled_function_tool_tasks超时_FUNCTION_TOOL_CANCELLED_DRAIN_SECONDS 0.25秒立即推进步数上限_FUNCTION_TOOL_CANCELLED_IMMEDIATE_STEP_LIMIT 64等待 post-invoke 任务短暂收尾_wait_pending_function_tool_tasks_for_timeout_FUNCTION_TOOL_POST_INVOKE_WAIT_SECONDS 0.1秒通过_merge_late_function_tool_failure把迟到的失败合并进主失败但不掩盖根因对仍然存活的取消任务与 post-invoke 任务附加add_done_callback报告器_attach_function_tool_task_result_callbacks把迟到的异常交给事件循环异常处理器而不是无限等待。重要语义isolate_parallel_failures的取值决定失败是否隔离。在_execute_tool_plan中当函数工具多于一个、或并行执行且存在其他类别工具时isolate_function_tool_failuresTrue——即兄弟失败不再中断已成功的调用而是走上述排干路径。这保证了多工具并行场景下部分成功的输出能够保留。5.4 工具本地取消 vs 父运行取消Distinguish cancellation of one tool handler from cancellation of the parent run. Tool-local cancellation can follow the configured tool failure policy; parent cancellation must propagate promptly.区分单个工具处理器的取消与父运行的取消。工具本地取消可以遵循配置的工具失败策略父运行取消必须立即传播。在execute()的except asyncio.CancelledError分支tool_execution.py中若取消来自兄弟类别失败sibling_category_failure.is_set()走_drain_pending_tasks_for_sibling_category_failure()——温和排干否则视为父取消走_cancel_pending_tasks_for_parent_cancellation()——立即取消所有剩余任务并附加报告回调绝不让工具输出冒充父取消的结果。而在单任务内部_invoke_tool_and_run_post_invoketool_execution.py捕获到asyncio.CancelledError后若该任务不在teardown_cancelled_tasks集合中说明是工具自身被取消而非父取消的清理阶段会尝试调用maybe_invoke_function_tool_failure_error_function将取消转换为模型可见的失败输出转换失败才重新抛出。5.5 确定性失败仲裁Select and raise failures deterministically when several tasks fail, while still observing secondary failures.当多个任务失败时确定性地选择并抛出失败同时仍然观察次要失败。_get_function_tool_failure_priority()tool_execution.py定义了失败优先级asyncio.CancelledError→ 优先级 0最低普通Exception→ 优先级 1其他BaseException如KeyboardInterrupt、SystemExit→ 优先级 2最高。_select_function_tool_failure()tool_execution.py在优先级相同时按order打破平局——取调用顺序更靠前的失败。由于order来自模型调用顺序而非任务完成顺序因此无论任务集合的迭代顺序如何、任务是否被急于执行最终抛出的失败都是确定性的。六、守卫Guardrails的执行时机与顺序6.1 输入守卫的两次运行设计参考文档的核心点Pre-approval input guardrails are an early rejection optimization. They may run before an approval interruption, but input guardrails must run again immediately before invocation because state, policy, or arguments may have changed while approval was pending.审批前输入守卫是一种早期拒绝优化。它们可以在审批中断之前运行但输入守卫必须在调用之前再次运行因为审批等待期间状态、策略或参数可能已经改变。这对应ToolExecutionConfig.pre_approval_tool_input_guardrails默认False见 run_config.py开关。当开启时_maybe_execute_tool_approval()tool_execution.py会在审批状态为None且需要审批时先跑一次输入守卫做早期拒绝但无论是否提前跑过_execute_single_tool_body()在真实调用前都会再次执行_execute_tool_input_guardrails()——这就是Rechecking guardrails does not mean rechecking approval重查守卫不意味着重查审批的含义。6.2 输入/输出守卫的完成顺序工具输入守卫_execute_tool_input_guardrailstool_execution.py在本地副作用之前完成。守卫输出支持三种行为raise_exception→ 抛ToolInputGuardrailTripwireTriggeredreject_content→ 返回拒绝消息由调用方转为FunctionToolResult拒绝项allow→ 放行。工具输出守卫_execute_tool_output_guardrailstool_execution.py在输出成为可接受的运行状态、模型输入或持久化会话历史之前完成拒绝时以is_rejectionTrue标记替换输出为拒绝消息。FunctionTool通过tool_input_guardrails与tool_output_guardrails属性挂载守卫测试覆盖见 tests/test_tool_guardrails.py输入/输出、同步/异步、三种行为、装饰器形式、tripwire 保留已完成回合结果等。6.3 守卫管道的适用范围边界Tool guardrail pipeline applies toFunctionToolinvocation. Handoffs, hosted tools, built-in provider tools, and nestedAgent.as_tool()runs have separate execution boundaries unless they explicitly opt into equivalent checks.工具守卫管道仅适用于FunctionTool调用。Handoff、托管工具、内置提供方工具与嵌套的Agent.as_tool()运行拥有独立的执行边界除非它们显式选择加入等效检查。这意味着如果你的安全策略依赖工具守卫必须明确它只保护本地的FunctionTool调用handoff 与嵌套 Agent 的安全边界需要通过各自机制如 handoff 过滤、子 Agent 自己的守卫另行配置。七、MCP 审批请求的特殊生命周期参考文档没有展开 MCP 细节但规划层对 MCP 审批请求有完整的处理路径这是理解托管工具执行边界的重要补充_partition_mcp_approval_requests()tool_planning.py将 MCP 审批请求分为两类带on_approval_request回调的回调处理与需要人工审批的manual bucket。_preflight_mcp_approval_requests()tool_planning.py对同 ID 的兄弟请求做变化检测若同一 call ID 被用于不同调用抛出ModelBehaviorError完全重复的请求则合并。execute_mcp_approval_requests()tool_planning.py执行回调先查询持久化审批状态未判定时标记_mark_tool_invocation_executed防止重复回调然后调用on_approval_request最后将结果写入approve/reject状态并构造MCPApprovalResponseItem。若回调已运行但响应未提交会抛出ModelBehaviorError(A Hosted MCP approval callback already ran, but its response was not committed.)。八、工具选择复位Tool Choice Reset与AgentToolUseTracker参考文档AgentToolUseTrackerrecords tool use per agent identity. Whenreset_tool_choiceTrue, reset the effective next-turn tool choice after that agent uses a tool sorequiredor a named choice cannot force an accidental loop.AgentToolUseTracker按 Agent 身份记录工具使用。当reset_tool_choiceTrue时在该 Agent 使用工具后复位下一轮的有效工具选择避免required或具名选择强制造成意外循环。maybe_reset_tool_choice()tool_execution.py实现如下def maybe_reset_tool_choice(agent, tool_use_tracker, model_settings): if agent.reset_tool_choice is True and tool_use_tracker.has_used_tools(agent): return dataclasses.replace(model_settings, tool_choiceNone) return model_settings即仅当agent.reset_tool_choice is True且该 Agent 已使用过工具时才将下一轮的tool_choice复位为None否则原样返回。注意它通过dataclasses.replace生成新的ModelSettings不会修改 Agent 声明的配置——do not mutate the agents declared settings across independent runs。AgentToolUseTrackersrc/agents/run_internal/tool_use_tracker.py按 Agent 身份通过_build_agent_identity_keys_by_id等工具处理重复 Agent 名记录HandoffCallItem、ToolCallItem、ToolCallOutputItem等工具事件并支持serialize_tool_use_tracker/hydrate_tool_use_tracker序列化——这正是参考文档要求的跨中断与沙箱恢复时持久化并恢复工具使用追踪器包括存在重复 Agent 名的图。测试见 tests/test_tool_choice_reset.py覆盖tool_choicerequired单工具/多工具、具名工具foo_bar、多轮运行不陷入无限循环等场景maybe_reset_tool_choice仅在 has_used_tools 且 reset 开关开启时复位。九、恢复路径Resume的契约已批准工具的再执行execute_approved_tools()tool_execution.py是 HITLHuman-in-the-loop恢复路径的核心当审批中断被用户批准后它根据中断项集合重新构造ToolRunFunction并执行。其健壮性校验包括缺少工具名 → 追加错误输出缺少 call ID → 追加错误输出并尽力解析工具来源用于追踪审批状态为False→ 追加拒绝消息resolve_approval_rejection_message或默认REJECTION_MESSAGE审批状态不为True→ Tool approval status unclear工具未找到、非函数工具、raw_item 类型非法 → 分别追加错误输出。最终构造出的tool_runs再次交给execute_function_tool_calls()走完整执行管道含守卫、钩子、span。这一路径印证了审批一旦批准执行仍要走完整生命周期的设计——批准只解决能不能执行的问题不跳过执行期校验。十、审查清单修改工具执行行为前必须验证的五个维度参考文档最后给出了变更审查清单Review Checklist任何涉及工具规划、审批、守卫、并发、取消、超时、钩子、错误转换或恢复执行的行为变更都应逐项验证路径追踪分别追踪新鲜执行、审批中断、审批拒绝、序列化恢复四条路径顺序验证验证守卫、审批、钩子、追踪 span、调用、输出、持久化之间的先后顺序并发与取消路径测试覆盖顺序执行、有界并发、兄弟失败、工具本地取消、父取消五类路径失败转换测试覆盖默认、自定义、禁用三种失败转换以及适用的超时行为终态确定性确认每个启动的任务与每次运行持有的资源都到达确定性终态无泄漏、无悬挂任务。对应源码中的测试锚点包括 tests/test_agent_runner.py、tests/test_agent_runner_streamed.py、tests/test_function_tool.py、tests/test_tool_guardrails.py、tests/test_tool_choice_reset.py、tests/test_tool_use_tracker.py 与 tests/test_run_state.py。十一、实践建议汇总基于以上生命周期分析针对二次开发与问题排查给出以下可操作建议编写新的工具执行路径时始终把发现discovery与规划planning分离不要让模型输出直接驱动副作用先经过ToolExecutionPlan的审批分区与去重。使用审批HITL时不要在needs_approval回调中依赖审批前的状态快照做最终决策审批恢复后输入守卫会重新执行参数与策略可能已变化应把输入守卫当作最终防线。使用并发工具时RunConfig(tool_executionToolExecutionConfig(max_function_tool_concurrencyN))控制 SDK 侧并发若要强顺序副作用设置为1。注意pre_approval_tool_input_guardrailsTrue只是早期拒绝优化不减少审批后的最终校验。为同步工具实现超时SDK 超时仅适用于 async 工具同步工具请自行在处理器内部实现超时控制。避免 call ID 复用自定义模型或提供方接入时务必保证每个工具调用使用唯一 call ID否则将触发ModelBehaviorError去重保护。多 Agent 图 工具选择启用reset_tool_choiceTrue防止required循环跨会话恢复时依赖 tracker 的序列化能力保持工具选择行为一致。参考资料仓库内生命周期参考.agents/references/tool-execution-lifecycle.md规划实现src/agents/run_internal/tool_planning.py执行实现src/agents/run_internal/tool_execution.py执行配置src/agents/run_config.py工具定义与调用封装src/agents/tool.py工具使用追踪src/agents/run_internal/tool_use_tracker.py官方文档docs/running_agents.md、docs/tools.md、docs/guardrails.md、docs/human_in_the_loop.md测试锚点tests/test_agent_runner.py、tests/test_function_tool.py、tests/test_tool_guardrails.py、tests/test_tool_choice_reset.py、tests/test_tool_use_tracker.py、tests/test_run_state.py【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。