OpenAI Agents SDK

一句话定位

OpenAI 官方的轻量多 agent 编排框架(Swarm 的正式继任者,pip 包 openai-agents / import agents,约 95k LOC)。核心抽象只有 Agent(配置 dataclass)+ Runner(运行循环),默认走 OpenAI Responses API;差异化亮点是内建的 Traces/Spans 可观测、run 级 HITL 审批 + 可序列化 RunState 断点续跑,以及一整套 beta 的 sandbox + skills + learning-memory 栈。

核心架构总览(目录结构关键路径 + 引用的 commit)

分析基于 commit 0354f482a8e76d33c50a6a3e462c814eefde1e6b(2026-07-10,feat: add hosted multi-agent beta support (#3788))。

  • 公开面src/agents/agent.pyAgent/AgentBase dataclass、as_tool()get_system_promptget_promptget_all_tools)+ src/agents/run.py(1882 LOC,公开 Runner.run / run_sync / run_streamed)。
  • 真正的循环:旧的单体 run loop 已重构进 src/agents/run_internal/(24 个模块、约 12.8k LOC)。循环编排在 run_internal/run_loop.py(1929 LOC),单轮解析在 run_internal/turn_resolution.py(2139 LOC),工具派发在 run_internal/tool_execution.py(2429 LOC)。
  • 模型 I/O:默认 Responses API(models/openai_responses.py),另有 Chat Completions 转换器(models/chatcmpl_converter.py)和 LiteLLM 扩展用于非 OpenAI 模型。
  • 文档即一手源:仓库内 docs/*.md(mkdocs 站点),本 dossier 引用的 docs/… 路径均为仓库内文件。
  • 注:留档 src/ 下的文件是从上述路径拷贝后扁平重命名(如 run_loop.py 对应 src/agents/run_internal/run_loop.py)。

Agent Loop(主循环 / 何时继续何时停)

  • 规范描述见 docs/running_agents.md:34-45:调 LLM → 若产出 final output 则结束;若 handoff 则换 agent 重跑;若有 tool calls 则执行、把结果 append 回去、重跑。max_turns 超限抛 MaxTurnsExceeded(设 max_turns=None 关闭上限)。
  • 实现是 run_internal/run_loop.py 里的 while True(streaming 路径 start_streaming:681run.py 的非流式路径与之镜像)。每一轮产出一个 SingleStepResult,其 next_step 是四种之一:NextStepFinalOutput / NextStepHandoff / NextStepRunAgain / NextStepInterruption(定义在 run_internal/run_steps.py)。
  • “final output” 判定规则:产出了目标 output_type 的文本且没有 tool calls → final。决策代码在 turn_resolution.pyprocess_model_response:1633),final-output 分支在 :832-924。若设了结构化 output_type,会把 message JSON 校验到该类型(turn_resolution.py:848-904);校验失败抛 ModelBehaviorError,除非 invalid_final_output error handler 挽回。
  • 工具驱动的提前停止Agent.tool_use_behavioragent.py:345-365)控制工具结果是否回灌给 LLM——"run_llm_again"(默认)/ "stop_on_first_tool" / StopAtTools 名单 / 自定义 ToolsToFinalOutputFunction。在 turn_resolution.pycheck_for_final_output_from_tools:632-664)解析。
  • reset_tool_choice=Trueagent.py:367)在一次工具调用后重置 tool_choice,避免无限工具循环(tool_execution.py:maybe_reset_tool_choice)。
  • Runner 级有模型重试 + conversation_locked 退避重试(run_internal/model_retry.pyrunning_agents.md:416-427)。

记忆与上下文管理(压缩、长期记忆、会话持久化)

  • 四种策略docs/running_agents.md:269-289):(a) 手动 result.to_input_list();(b) 客户端 Session;(c) OpenAI 托管 conversation_id(Conversations API);(d) OpenAI 托管 previous_response_id(response 链)。(c)/(d) 不能在同一 run 里和 Session 组合。
  • Sessionsdocs/sessions/index.mdsrc/agents/memory/session.py):一个协议(get_items/add_items/pop_item/clear_session)。Runner 在每次 run 前自动 prepend 历史、run 后存回新 item(sessions/index.md:62-70)。内建实现:SQLiteSession(默认)、OpenAIConversationsSessionOpenAIResponsesCompactionSession;扩展另有 Async-SQLite、Redis、SQLAlchemy、MongoDB、Dapr、Encrypted、AdvancedSQLite(分支/分析)。
  • 真正的上下文压缩OpenAIResponsesCompactionSessionmemory/openai_responses_compaction_session.py,521 LOC)包一个 session,每轮后一旦触发阈值(should_trigger_compaction)就调 Responses API 的 responses.compact;模式 previous_response_id / input / autosessions/index.md:256-306)。另有 sandbox 侧的 Compaction capability(sandbox/capabilities/compaction.py)。
  • 历史检索上限用 SessionSettings(limit=N);合并定制走 RunConfig.session_input_callback,喂模型前的最终改写走 RunConfig.call_model_input_filterrunning_agents.md:429-460)。
  • 注意:这套会话记忆与 sandbox 的 learning memory(见”自进化”章)是两码事。

工具体系(定义/调用协议/注册/权限)

  • 工具分类在 tool.pyFunctionTool(本地 Python),加一组托管工具 dataclass——FileSearchToolWebSearchToolComputerToolHostedMCPToolCodeInterpreterToolImageGenerationToolLocalShellToolShellToolApplyPatchTool。文档层面分为 hosted / local-runtime / function / agents-as-tools 四类(docs/tools.md:11-24)。
  • FunctionTool 字段tool.py:380-495):namedescriptionparams_json_schemaon_invoke_tool(ctx, json_str)->outputstrict_json_schema(默认 True)、is_enabled(bool 或 callable,可动态隐藏)、needs_approvaltool_input_guardrails/tool_output_guardrailstimeout_seconds+timeout_behaviordefer_loading(Responses “tool search”——搜到才暴露)。
  • 定义人体工学@function_tool 装饰器从签名 + docstring 自动推导 JSON schema(function_schema.pydocs/tools.md:430-448),可用 Pydantic Field 加约束。输出可以是 strToolOutputText/Image/FileContent,或任何可 str() 的对象(tool.py:395-406)。
  • 注册:工具挂在每个 Agent 上(Agent.tools);MCP 工具在运行时从 Agent.mcp_serversget_all_tools / get_mcp_tools 拉取(agent.py:224-266)。禁用的工具按轮过滤。
  • 派发:模型产出的 tool call 在 run_internal/tool_execution.py 执行(execute_function_tool_callsexecute_computer_actionsexecute_shell_callsexecute_apply_patch_callsexecute_local_shell_calls)。本地函数工具并发由 ToolExecutionConfig.max_function_tool_concurrency 封顶(running_agents.md:165-188),与 provider 侧的 parallel_tool_calls 分开。
  • 未解析的 tool call 处理RunConfig.tool_not_found_behavior(默认抛 ModelBehaviorError,可选 return_error_to_model);对模型可见的报错文本用 RunConfig.tool_error_formatter 定制(running_agents.md:192-248)。
  • MCP:完整的 Model Context Protocol 客户端(src/agents/mcp/docs/mcp.md)——Stdio/SSE/StreamableHttp server + HostedMCPTool,权限经 require_approval 把控。

Prompt 设计(系统提示结构、动态组装)

  • Agent 的”系统提示”= Agent.instructionsagent.py:283-297):一个 str 或 callable (ctx, agent)->str(同步/异步皆可),在 agent.py:get_system_prompt:938-965)解析。这是主要的动态组装钩子。
  • 服务端 prompt:Agent.promptagent.py:299-303)= 一个 Responses-API 的 Prompt 对象/函数(仅 OpenAI),经 get_promptPromptUtil.to_model_input 解析。
  • 喂模型前的最终改写:RunConfig.call_model_input_filter 返回新的 ModelInputData(instructions, input)running_agents.md:429-460)。
  • SDK 对普通 Agent 不带任何精致的默认系统提示——用户的 instructions 字符串本身就是系统提示。唯一的大块内建 prompt 是 sandbox agent 的(sandbox/instructions/prompt.md,192 行),它是 OpenAI Codex CLI 的逐字 prompt:AGENTS.md 规范、preamble-message 规则、审批模式、apply_patch 工具契约。Sandbox 的各 capability 会各自贡献一段 prompt(如 Skills 渲染出 ## Skills 段——sandbox/capabilities/skills.py:764-800)。
  • Handoff prompt 辅助:extensions/handoff_prompt.pyRECOMMENDED_PROMPT_PREFIX)。

Router / 编排(任务分解、多 agent、子 agent)

两个一等模式(docs/multi_agent.md:20-31):

  • Handoffs——Agent.handoffs 是子 agent / Handoff 对象的列表(agent.py:305-309handoffs/__init__.py)。一个 handoff 以工具形式暴露给 LLM;被调用时目标 agent 接管对话(NextStepHandoff 在循环里换掉 current_agent)。喂给新 agent 的输入可过滤(Handoff.input_filter,全局 RunConfig.handoff_input_filter),并有一个 opt-in beta 把此前 transcript 折叠成单条 assistant 消息(nest_handoff_historyrunning_agents.md:142-143handoffs/history.py)。
  • Agents-as-tools——Agent.as_tool()agent.py:508-936)把一整个 agent run 包成一个 FunctionTool;manager 保持控制权、拿到嵌套结果。支持结构化 parameterscustom_output_extractor、经 on_stream 流式、嵌套审批传播、needs_approval
  • 另有”用代码编排”:结构化输出、链式、evaluator 循环、asyncio.gather 并行(multi_agent.md:43-52)。新 beta 是托管多 agentextensions/experimental/hosted_multi_agent,即 HEAD commit 引入的特性)。

Skill / 插件体系

  • 有——一套完整的 Claude 风格 Skills 系统,但只在 beta 的 sandbox track 里:sandbox/capabilities/skills.py。一个 Skill = SKILL.md + 可选的 scripts/references/assets/skills.py:401-493)。Skills 挂进一个 “Codex auto-discovery root”(skills_path 默认 .agents:503)。
  • 渐进式披露在生成的 prompt 里是显式的(skills.py:33-104):先注入索引(name+description+path),触发时才打开 SKILL.md,只按需加载 references/,优先跑 scripts/,另有”context hygiene”规则。frontmatter 从 SKILL.md 解析(_parse_frontmatter:357)。
  • 懒加载LocalDirLazySkillSource + 一个 load_skill FunctionTool(skills.py:263-291),按需把单个 skill 物化进 sandbox。
  • 普通(非 sandbox)Agent 除 tools/MCP/handoffs 外没有插件系统。

自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)

  • 有——一套真正的 learning-memory 子系统,服务于 sandbox agent(docs/sandbox/memory.mdsrc/agents/sandbox/memory/)。它区别于会话式 Session 记忆:把过往 run 的经验”蒸馏成 sandbox 工作区里的文件”,让未来的 run 从过去的 run 学习memory.md:1-14)。
  • 两阶段生成memory.md:56-98sandbox/memory/phase_one.pyphase_two.pyrollouts.py):
    • Phase 1(抽取):一个 memory 模型对单个累积会话文件(剥掉 system/developer/reasoning、截断保头尾)做总结,产出原始 memory notes。默认模型 gpt-5.4-mini,medium reasoning(sandbox/config.py:43-49)。
    • Phase 2(巩固):一个 consolidation agent 读原始 memory + 会话摘要,写出 MEMORY.md + memory_summary.md。默认模型 gpt-5.5sandbox/config.py:52)。
  • 遗忘机制max_raw_memories_for_consolidation(默认 256)只保留最新的会话,按 recency 排名(memory.md:98config.py:41)。
  • 读侧 / 自纠:run 开始时把小小的 memory_summary.md 注入 developer prompt(渐进披露);agent 相关时搜 MEMORY.md、打开 rollout_summaries/live_update=True 允许 agent 在 run 中途重写过时的 MEMORY.mdmemory.md:47-53MemoryReadConfig)。Memory(read=None) / Memory(generate=None) 分别关掉读/写两侧。布局隔离用 MemoryLayoutConfig
  • 把用户纠正/偏好、失败恢复信号当作一等的 memory 目标(memory.md:9-13extra_prompt)。无 RL / 权重更新;这是基于文件的经验记忆,不是 fine-tuning。
  • Eval 钩子仅是建议性:文档推荐用 evals 迭代(multi_agent.md:37-39),但 SDK 本身除了 error_handlers(max_turns / model_refusal / invalid_final_output)外,没有内建的 eval 驱动纠错循环。

可观测性(日志 / trace 格式)

  • 一等的内建 tracing,默认开(docs/tracing.mdsrc/agents/tracing/)。模型 = Traces(workflow 级)由 Spans 组成(start/end、trace_idparent_id、typed span_data)。
  • 自动 span(tracing.md:29-42):整个 run 在 trace(),每个 agent 在 agent_span(),LLM 调用在 generation_span(),每个函数工具在 function_span(),guardrail 在 guardrail_span(),handoff 在 handoff_span(),音频在 transcription/speech span。循环内还用 task_span/turn_spanrun_loop.py:489,1015)。span 载荷类型在 tracing/span_data.py(AgentSpanData/GenerationSpanData/…)。
  • 导出:全局 TraceProviderBatchTraceProcessorBackendSpanExporter(OpenAI 后端),后台批量 + 退出时 flush;flush_traces() 立即导出(tracing.md:47-88tracing/processors.py,743 LOC)。
  • 可扩展:add_trace_processor() / set_trace_processors();文档列了约 30 个第三方集成(Langfuse、W&B、Braintrust、Logfire、Datadog…)。
  • 敏感控制:RunConfig.trace_include_sensitive_data、环境变量 OPENAI_AGENTS_DISABLE_TRACING、ZDR 组织不产生 tracing。普通 logging logger 在 src/agents/logger.py

安全与权限(审批门、密钥管理)

  • Guardrailssrc/agents/guardrail.pydocs/guardrails.md):InputGuardrail(在首个 agent 前/处并行跑)、OutputGuardrail(对 final output)、加 per-tool 的 ToolInputGuardrail/ToolOutputGuardrailtool.py:420-424)。guardrail 返回 tripwire_triggered=True 会抛 InputGuardrailTripwireTriggered/OutputGuardrailTripwireTriggered 并中止 run(run_loop.py:707-722,980-995)。
  • 人在环审批门docs/human_in_the_loop.mdrun_internal/approvals.py):needs_approval(bool 或 callable)可加在 function_toolAgent.as_toolShellToolApplyPatchTool 上;本地 MCP server 用 require_approvalHostedMCPTooltool_config={"require_approval":"always"}。触发时 run 暂停、通过 RunResult.interruptions 暴露(一组 ToolApprovalItem)。经 result.to_state()state.approve()/reject()Runner.run(agent, state) 恢复。有 sticky 决策 always_approve/always_reject。审批面是 run 级的(覆盖 handoff 和嵌套 agent-as-tool)。自动决策经 on_approval / on_approval_request 回调。
  • 审批前的工具输入 guardrail:ToolExecutionConfig.pre_approval_tool_input_guardrailsrunning_agents.md:190)。
  • 密钥管理:内建极少/几乎没有。文档警告序列化的 RunState 会嵌入 context/approvals/usage——不要把密钥放进 RunContextWrapper.context,除非你想让它被持久化(human_in_the_loop.md:193)。Sandbox shell 容器网络策略支持域名 secret/allowlist(tool.pyShellToolContainerNetworkPolicy*:1072-1088)。API key 走环境变量(OPENAI_API_KEY),tracing key 可 per-run 覆盖。

沙箱与执行隔离

  • beta “Sandbox Agents”docs/sandbox_agents.mdsrc/agents/sandbox/,约 5k LOC):一个持久工作区,模型在里面读写真实文件、跑命令、快照状态。用 SandboxAgent + Manifest(files/dirs/mounts)+ Capabilities + SandboxRunConfig
  • 后端(clients)UnixLocalSandboxClient(本地开发)、Docker(pip install openai-agents[docker],默认镜像 python:3.14-slim——sandbox/config.py:11)、以及托管 provider(docs/sandbox/clients.md)。
  • Capabilitiessandbox/capabilities/):FilesystemShellSkillsMemoryCompaction——每个 gate 一批 sandbox 原生工具。run_as 设定 sandbox 用户身份。
  • 隔离/生命周期:sessions、snapshot/session_state 恢复(sandbox/snapshot.pyruntime_session_manager.py 972 LOC)、remote_mount_policy.py、path-grant 校验防 .. 逃逸(sandbox/capabilities/skills.py:294-341workspace_paths.py)。
  • 审批集成:sandbox prompt 暴露审批模式 never / on-failure / on-request / untrustedsandbox/instructions/prompt.md:88-90)。
  • 对普通 Agent,隔离仅限于托管工具(CodeInterpreter、托管容器 shell)和 MCP 进程边界;通用的执行隔离故事在 sandbox track。

与模型的协同设计

  • 默认模型 gpt-5.4-miniagent.py:315models/default_models.py)。与 GPT-5 家族 + Responses API 深度协同:按模型名自动选 reasoning-effort 的表(default_models.py:50-72)——如 gpt-5 → low,gpt-5.1/5.2/5.4/5.5/5.6 → none,*-pro → medium,*-codex 变体特判。verbosity 默认 low。gpt-5_reasoning_settings_required 强制 reasoning 参数。
  • Reasoning item 跨轮携带;RunConfig.reasoning_item_id_policypreserve/omit)绕开 Responses-API 的 reasoning-item 不变量(running_agents.md:250-267)。
  • Sandbox agent 实际上是 Codex 耦合的:内建系统提示就是 Codex CLI 的 prompt(apply_patch 工具契约、AGENTS.md),示例模型是 gpt-5.6-soldocs/sandbox_agents.md:80)。有专门的 Codex 工具(_is_codex_toolextensions/experimental/codex)。
  • 非 OpenAI 模型经 multi_provider.py + LiteLLM 扩展 + ChatCompletions 转换器支持,但托管工具 / 服务端 prompt / compaction / tracing 都是 OpenAI-Responses 专属。
  • 可选 Responses WebSocket 传输做连接复用(responses_websocket_session.pyrunning_agents.md:51-120)。

轨迹利用(session/trajectory 是否反哺训练/评测)

  • 没有训练反馈闭环。 轨迹用于:(a) 会话记忆(Sessions / conversation_id);(b) 经可序列化 RunState 的持久暂停-恢复(human_in_the_loop.md:181-197);(c) 可观测性 traces;(d) sandbox 的 learning-memory 蒸馏(见”自进化”章),把 rollouts 变成未来 run 会读的 MEMORY.md——经验式,非梯度式。
  • AdvancedSQLiteSession 加了用量分析 + 会话分支(store_run_usagecreate_branch_from_turn——sessions/index.md:452-472),对离线 eval 有用,但没接任何 trainer。
  • Rollout JSONL 产物(sessions/<rollout-id>.jsonl)是 memory 生成的原始底料(sandbox/memory/rollouts.py),不是给 RL/SFT 的。
  • Eval 是外部且建议性的(multi_agent.md:37-39);SDK 提供 error_handlers 做受控恢复,但没有自纠的 eval 循环。

与同类 harness 的关键差异(1-3 条)

  1. 内建一等 tracing(默认开):Traces/Spans 数据模型 + 批量导出 OpenAI 后端 + 约 30 个第三方集成,可观测性是框架原生能力而非贴片——这在同规模框架(smolagents / langgraph)里较少见。
  2. run 级 HITL + 可序列化 RunState 断点续跑:审批门覆盖 handoff 与嵌套 agent-as-tool,暂停后可把整个 run 状态序列化、异地/异时 approve()/reject() 后接着跑,把人审做成了持久化的一等流程。
  3. beta 的 sandbox + skills + learning-memory 三件套:Claude 风格 SKILL.md 渐进披露 + 懒加载、两阶段(gpt-5.4-mini 抽取 / gpt-5.5 巩固)经验记忆 + recency 遗忘、Codex 耦合的执行沙箱——但整套仅在 sandbox track,普通 Agent 用不到。

原始源码定位

  • repo: https://github.com/openai/openai-agents-python
  • commit/version analyzed: 0354f482a8e76d33c50a6a3e462c814eefde1e6b(2026-07-10,feat: add hosted multi-agent beta support (#3788);克隆日 2026-07-11,--depth 1
  • 关键文件列表(相对 repo 根):
    • src/agents/agent.py — Agent/AgentBase dataclass、as_tool()get_system_promptget_promptget_all_tools
    • src/agents/run.py — 公开 Runner
    • src/agents/run_internal/run_loop.py — 流式循环 start_streamingrun_single_turn_streamed
    • src/agents/run_internal/turn_resolution.pyprocess_model_responseexecute_tools_and_side_effectscheck_for_final_output_from_tools
    • src/agents/run_internal/tool_execution.py — function/computer/shell/apply_patch 派发
    • src/agents/run_internal/approvals.py — 审批中断管线
    • src/agents/tool.py — FunctionTool + 全部托管工具 dataclass;function_tool 装饰器
    • src/agents/function_schema.py — 从签名 + docstring 自动生成 JSON schema
    • src/agents/guardrail.py — Input/Output/Tool guardrails
    • src/agents/handoffs/__init__.pyhandoffs/history.py — handoff 原语
    • src/agents/memory/(含 openai_responses_compaction_session.pysession.py)— Session 协议、SQLite、OpenAI Conversations、Responses 压缩
    • src/agents/sandbox/capabilities/memory/config.pysnapshot.pyruntime_session_manager.py)— beta sandbox agent
    • src/agents/sandbox/instructions/prompt.md — 内建 sandbox 系统提示(逐字 Codex prompt)
    • src/agents/tracing/span_data.pyprocessors.py)— TraceProvider、spans、BatchTraceProcessor
    • src/agents/models/default_models.py — 默认模型 + reasoning-effort 表
    • docs:docs/running_agents.mdagents.mdtools.mdhandoffs.mdmulti_agent.mdsandbox_agents.mddocs/sandbox/memory.mdhuman_in_the_loop.mdtracing.mdsessions/index.mdguardrails.mdmcp.md

一手源存档(sources/)

存于 /Users/zhao/projects/self-wiki/ai-research/sources/harness/openai-agents-sdk/

  • NOTES.md — Stage-1 源码级研究笔记(逐条 file+line 可溯源)
  • src/(16 个精选源文件,扁平重命名,592KB):
    • agent.pyrun.pyrun_loop.pyturn_resolution.pytool_execution.pyapprovals.py
    • tool.pyguardrail.py
    • memory_session.pymemory_compaction_session.py
    • sandbox_config.pysandbox_skills.pysandbox_memory_capability.pysandbox_prompt.md
    • default_models.pytracing_span_data.py