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.py(Agent/AgentBasedataclass、as_tool()、get_system_prompt、get_prompt、get_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在:681;run.py的非流式路径与之镜像)。每一轮产出一个SingleStepResult,其next_step是四种之一:NextStepFinalOutput/NextStepHandoff/NextStepRunAgain/NextStepInterruption(定义在run_internal/run_steps.py)。 - “final output” 判定规则:产出了目标
output_type的文本且没有 tool calls → final。决策代码在turn_resolution.py的process_model_response(:1633),final-output 分支在:832-924。若设了结构化output_type,会把 message JSON 校验到该类型(turn_resolution.py:848-904);校验失败抛ModelBehaviorError,除非invalid_final_outputerror handler 挽回。 - 工具驱动的提前停止:
Agent.tool_use_behavior(agent.py:345-365)控制工具结果是否回灌给 LLM——"run_llm_again"(默认)/"stop_on_first_tool"/StopAtTools名单 / 自定义ToolsToFinalOutputFunction。在turn_resolution.py的check_for_final_output_from_tools(:632-664)解析。 reset_tool_choice=True(agent.py:367)在一次工具调用后重置tool_choice,避免无限工具循环(tool_execution.py:maybe_reset_tool_choice)。- Runner 级有模型重试 +
conversation_locked退避重试(run_internal/model_retry.py,running_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组合。 - Sessions(
docs/sessions/index.md,src/agents/memory/session.py):一个协议(get_items/add_items/pop_item/clear_session)。Runner 在每次 run 前自动 prepend 历史、run 后存回新 item(sessions/index.md:62-70)。内建实现:SQLiteSession(默认)、OpenAIConversationsSession、OpenAIResponsesCompactionSession;扩展另有 Async-SQLite、Redis、SQLAlchemy、MongoDB、Dapr、Encrypted、AdvancedSQLite(分支/分析)。 - 真正的上下文压缩:
OpenAIResponsesCompactionSession(memory/openai_responses_compaction_session.py,521 LOC)包一个 session,每轮后一旦触发阈值(should_trigger_compaction)就调 Responses API 的responses.compact;模式previous_response_id/input/auto(sessions/index.md:256-306)。另有 sandbox 侧的Compactioncapability(sandbox/capabilities/compaction.py)。 - 历史检索上限用
SessionSettings(limit=N);合并定制走RunConfig.session_input_callback,喂模型前的最终改写走RunConfig.call_model_input_filter(running_agents.md:429-460)。 - 注意:这套会话记忆与 sandbox 的 learning memory(见”自进化”章)是两码事。
工具体系(定义/调用协议/注册/权限)
- 工具分类在
tool.py:FunctionTool(本地 Python),加一组托管工具 dataclass——FileSearchTool、WebSearchTool、ComputerTool、HostedMCPTool、CodeInterpreterTool、ImageGenerationTool、LocalShellTool、ShellTool、ApplyPatchTool。文档层面分为 hosted / local-runtime / function / agents-as-tools 四类(docs/tools.md:11-24)。 FunctionTool字段(tool.py:380-495):name、description、params_json_schema、on_invoke_tool(ctx, json_str)->output、strict_json_schema(默认 True)、is_enabled(bool 或 callable,可动态隐藏)、needs_approval、tool_input_guardrails/tool_output_guardrails、timeout_seconds+timeout_behavior、defer_loading(Responses “tool search”——搜到才暴露)。- 定义人体工学:
@function_tool装饰器从签名 + docstring 自动推导 JSON schema(function_schema.py;docs/tools.md:430-448),可用 PydanticField加约束。输出可以是str、ToolOutputText/Image/FileContent,或任何可str()的对象(tool.py:395-406)。 - 注册:工具挂在每个
Agent上(Agent.tools);MCP 工具在运行时从Agent.mcp_servers经get_all_tools/get_mcp_tools拉取(agent.py:224-266)。禁用的工具按轮过滤。 - 派发:模型产出的 tool call 在
run_internal/tool_execution.py执行(execute_function_tool_calls、execute_computer_actions、execute_shell_calls、execute_apply_patch_calls、execute_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.instructions(agent.py:283-297):一个 str 或 callable(ctx, agent)->str(同步/异步皆可),在agent.py:get_system_prompt(:938-965)解析。这是主要的动态组装钩子。 - 服务端 prompt:
Agent.prompt(agent.py:299-303)= 一个 Responses-API 的Prompt对象/函数(仅 OpenAI),经get_prompt→PromptUtil.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.py(RECOMMENDED_PROMPT_PREFIX)。
Router / 编排(任务分解、多 agent、子 agent)
两个一等模式(docs/multi_agent.md:20-31):
- Handoffs——
Agent.handoffs是子 agent /Handoff对象的列表(agent.py:305-309,handoffs/__init__.py)。一个 handoff 以工具形式暴露给 LLM;被调用时目标 agent 接管对话(NextStepHandoff在循环里换掉current_agent)。喂给新 agent 的输入可过滤(Handoff.input_filter,全局RunConfig.handoff_input_filter),并有一个 opt-in beta 把此前 transcript 折叠成单条 assistant 消息(nest_handoff_history,running_agents.md:142-143;handoffs/history.py)。 - Agents-as-tools——
Agent.as_tool()(agent.py:508-936)把一整个 agent run 包成一个 FunctionTool;manager 保持控制权、拿到嵌套结果。支持结构化parameters、custom_output_extractor、经on_stream流式、嵌套审批传播、needs_approval。 - 另有”用代码编排”:结构化输出、链式、evaluator 循环、
asyncio.gather并行(multi_agent.md:43-52)。新 beta 是托管多 agent(extensions/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_skillFunctionTool(skills.py:263-291),按需把单个 skill 物化进 sandbox。 - 普通(非 sandbox)
Agent除 tools/MCP/handoffs 外没有插件系统。
自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)
- 有——一套真正的 learning-memory 子系统,服务于 sandbox agent(
docs/sandbox/memory.md,src/agents/sandbox/memory/)。它区别于会话式 Session 记忆:把过往 run 的经验”蒸馏成 sandbox 工作区里的文件”,让未来的 run 从过去的 run 学习(memory.md:1-14)。 - 两阶段生成(
memory.md:56-98,sandbox/memory/phase_one.py、phase_two.py、rollouts.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.5(sandbox/config.py:52)。
- Phase 1(抽取):一个 memory 模型对单个累积会话文件(剥掉 system/developer/reasoning、截断保头尾)做总结,产出原始 memory notes。默认模型
- 遗忘机制:
max_raw_memories_for_consolidation(默认 256)只保留最新的会话,按 recency 排名(memory.md:98,config.py:41)。 - 读侧 / 自纠:run 开始时把小小的
memory_summary.md注入 developer prompt(渐进披露);agent 相关时搜MEMORY.md、打开rollout_summaries/;live_update=True允许 agent 在 run 中途重写过时的MEMORY.md(memory.md:47-53,MemoryReadConfig)。Memory(read=None)/Memory(generate=None)分别关掉读/写两侧。布局隔离用MemoryLayoutConfig。 - 把用户纠正/偏好、失败恢复信号当作一等的 memory 目标(
memory.md:9-13,extra_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.md,src/agents/tracing/)。模型 = Traces(workflow 级)由 Spans 组成(start/end、trace_id、parent_id、typedspan_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_span(run_loop.py:489,1015)。span 载荷类型在tracing/span_data.py(AgentSpanData/GenerationSpanData/…)。 - 导出:全局
TraceProvider→BatchTraceProcessor→BackendSpanExporter(OpenAI 后端),后台批量 + 退出时 flush;flush_traces()立即导出(tracing.md:47-88,tracing/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。普通logginglogger 在src/agents/logger.py。
安全与权限(审批门、密钥管理)
- Guardrails(
src/agents/guardrail.py,docs/guardrails.md):InputGuardrail(在首个 agent 前/处并行跑)、OutputGuardrail(对 final output)、加 per-tool 的ToolInputGuardrail/ToolOutputGuardrail(tool.py:420-424)。guardrail 返回tripwire_triggered=True会抛InputGuardrailTripwireTriggered/OutputGuardrailTripwireTriggered并中止 run(run_loop.py:707-722,980-995)。 - 人在环审批门(
docs/human_in_the_loop.md,run_internal/approvals.py):needs_approval(bool 或 callable)可加在function_tool、Agent.as_tool、ShellTool、ApplyPatchTool上;本地 MCP server 用require_approval;HostedMCPTool用tool_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_guardrails(running_agents.md:190)。 - 密钥管理:内建极少/几乎没有。文档警告序列化的
RunState会嵌入 context/approvals/usage——不要把密钥放进RunContextWrapper.context,除非你想让它被持久化(human_in_the_loop.md:193)。Sandbox shell 容器网络策略支持域名 secret/allowlist(tool.py的ShellToolContainerNetworkPolicy*,:1072-1088)。API key 走环境变量(OPENAI_API_KEY),tracing key 可 per-run 覆盖。
沙箱与执行隔离
- beta “Sandbox Agents”(
docs/sandbox_agents.md,src/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)。 - Capabilities(
sandbox/capabilities/):Filesystem、Shell、Skills、Memory、Compaction——每个 gate 一批 sandbox 原生工具。run_as设定 sandbox 用户身份。 - 隔离/生命周期:sessions、
snapshot/session_state恢复(sandbox/snapshot.py,runtime_session_manager.py972 LOC)、remote_mount_policy.py、path-grant 校验防..逃逸(sandbox/capabilities/skills.py:294-341,workspace_paths.py)。 - 审批集成:sandbox prompt 暴露审批模式 never / on-failure / on-request / untrusted(
sandbox/instructions/prompt.md:88-90)。 - 对普通
Agent,隔离仅限于托管工具(CodeInterpreter、托管容器 shell)和 MCP 进程边界;通用的执行隔离故事在 sandbox track。
与模型的协同设计
- 默认模型
gpt-5.4-mini(agent.py:315,models/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_policy(preserve/omit)绕开 Responses-API 的 reasoning-item 不变量(running_agents.md:250-267)。 - Sandbox agent 实际上是 Codex 耦合的:内建系统提示就是 Codex CLI 的 prompt(
apply_patch工具契约、AGENTS.md),示例模型是gpt-5.6-sol(docs/sandbox_agents.md:80)。有专门的 Codex 工具(_is_codex_tool,extensions/experimental/codex)。 - 非 OpenAI 模型经
multi_provider.py+ LiteLLM 扩展 + ChatCompletions 转换器支持,但托管工具 / 服务端 prompt / compaction / tracing 都是 OpenAI-Responses 专属。 - 可选 Responses WebSocket 传输做连接复用(
responses_websocket_session.py,running_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_usage、create_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 条)
- 内建一等 tracing(默认开):Traces/Spans 数据模型 + 批量导出 OpenAI 后端 + 约 30 个第三方集成,可观测性是框架原生能力而非贴片——这在同规模框架(smolagents / langgraph)里较少见。
- run 级 HITL + 可序列化
RunState断点续跑:审批门覆盖 handoff 与嵌套 agent-as-tool,暂停后可把整个 run 状态序列化、异地/异时approve()/reject()后接着跑,把人审做成了持久化的一等流程。 - 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_prompt、get_prompt、get_all_toolssrc/agents/run.py— 公开 Runnersrc/agents/run_internal/run_loop.py— 流式循环start_streaming、run_single_turn_streamedsrc/agents/run_internal/turn_resolution.py—process_model_response、execute_tools_and_side_effects、check_for_final_output_from_toolssrc/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 schemasrc/agents/guardrail.py— Input/Output/Tool guardrailssrc/agents/handoffs/__init__.py、handoffs/history.py— handoff 原语src/agents/memory/(含openai_responses_compaction_session.py、session.py)— Session 协议、SQLite、OpenAI Conversations、Responses 压缩src/agents/sandbox/(capabilities/、memory/、config.py、snapshot.py、runtime_session_manager.py)— beta sandbox agentsrc/agents/sandbox/instructions/prompt.md— 内建 sandbox 系统提示(逐字 Codex prompt)src/agents/tracing/(span_data.py、processors.py)— TraceProvider、spans、BatchTraceProcessorsrc/agents/models/default_models.py— 默认模型 + reasoning-effort 表- docs:
docs/running_agents.md、agents.md、tools.md、handoffs.md、multi_agent.md、sandbox_agents.md、docs/sandbox/memory.md、human_in_the_loop.md、tracing.md、sessions/index.md、guardrails.md、mcp.md
一手源存档(sources/)
存于 /Users/zhao/projects/self-wiki/ai-research/sources/harness/openai-agents-sdk/:
NOTES.md— Stage-1 源码级研究笔记(逐条 file+line 可溯源)src/(16 个精选源文件,扁平重命名,592KB):agent.py、run.py、run_loop.py、turn_resolution.py、tool_execution.py、approvals.pytool.py、guardrail.pymemory_session.py、memory_compaction_session.pysandbox_config.py、sandbox_skills.py、sandbox_memory_capability.py、sandbox_prompt.mddefault_models.py、tracing_span_data.py