openai-agents-python-sdk 源码解析 | 第二篇:环境搭建与第一个文本 Agent
本篇导读上一篇我们先建立了 OpenAI Agents Python SDK 的项目地图Agent是声明对象Runner是执行入口Tools、Handoffs、Guardrails、Sessions 和 Tracing 是围绕模型调用组织起来的运行时能力。这一篇开始进入实际运行。目标很明确在当前源码仓库中跑通第一个文本 Agent并理解这几件事本地开发环境应该怎么准备。OPENAI_API_KEY在哪里生效。最小Agent Runner示例长什么样。Runner.run和Runner.run_sync有什么区别。RunResult.final_output、new_items、raw_responses和usage应该怎么看。本文仍然以源码阅读为主但会从一个可运行示例切入。先跑起来再回头看源码理解效率会高很多。当前仓库的开发环境这个项目不是单文件脚本而是一个标准 Python SDK 仓库。核心配置在pyproject.toml常用命令在Makefile。从pyproject.toml可以看到几个关键信息包名是openai-agents。源码包路径是src/agents。Python 版本要求是3.10。开发依赖包含pytest、ruff、mypy、pyright、mkdocs、coverage等。项目使用uv管理 workspace 和依赖。如果你是在当前仓库中开发或阅读源码建议从仓库根目录执行makesync这个命令会执行uvsync--all-extras --all-packages--groupdev它会安装全部 extras、workspace 包和开发依赖。后续运行示例、测试、类型检查都建议使用uv run这样可以保证使用的是当前项目环境。如果你是在一个外部业务项目里使用 SDK可以安装 PyPI 包pipinstall--timeout60--retries3openai-agents不过本系列是源码解析后续默认都在当前仓库中观察实现。配置 OPENAI_API_KEY官方 quickstart 明确要求设置OPENAI_API_KEY。在 macOS 或 Linux 终端中可以这样设置exportOPENAI_API_KEYsk-...这个环境变量只对当前终端会话生效。关闭终端后需要重新设置。在运行示例前可以先确认变量是否存在python-cimport os; print(bool(os.getenv(OPENAI_API_KEY)))输出True表示当前终端已经能读取到 API Key。注意不要把真实 API Key 写入示例代码、博客正文、测试文件或提交记录。示例中保留sk-...占位即可。运行官方最小示例当前仓库里最直接的入门示例是uv run python examples/basic/hello_world.py这个文件内容很短核心逻辑可以概括成importasynciofromagentsimportAgent,Runnerasyncdefmain():agentAgent(nameAssistant,instructionsYou only respond in haikus.,)resultawaitRunner.run(agent,Tell me about recursion in programming.)print(result.final_output)if__name____main__:asyncio.run(main())这就是 SDK 的最小使用闭环创建一个Agent。调用Runner.run。读取result.final_output。如果这段示例能成功运行说明本地依赖、API Key 和基础模型调用链路已经打通。第一个文本 Agent同步版本README 中展示的是Runner.run_sync写法。对于普通命令行脚本这种方式最容易理解fromagentsimportAgent,Runner agentAgent(nameSummaryAgent,instructions你是技术文章摘要助手用三句话概括输入内容。,)resultRunner.run_sync(agent,Agent runtime 负责协调模型、工具和状态。)print(result.final_output)这段代码适合简单脚本。本地快速验证。没有现成 asyncio event loop 的同步环境。但它不适合在已经运行事件循环的环境里直接调用比如某些 Web 框架 handler、Jupyter notebook 或异步任务内部。当前源码中run_sync会检查是否已经存在 running loop如果存在会抛出运行时错误提示不能在已有事件循环中调用同步入口。这不是 SDK 限制异步能力而是为了避免同步 API 和已有事件循环互相干扰。第一个文本 Agent异步版本官方examples/basic/hello_world.py使用的是异步版本importasynciofromagentsimportAgent,Runnerasyncdefmain()-None:agentAgent(nameSummaryAgent,instructions你是技术文章摘要助手。)resultawaitRunner.run(agent,请解释 Agent 和 Runner 的区别。)print(result.final_output)if__name____main__:asyncio.run(main())异步版本适合Web 服务。后台任务系统。需要并发运行多个 Agent 的场景。已经处在 asyncio event loop 中的代码。后续要接入 streaming、Realtime、MCP 等异步能力的场景。本系列后续文章会优先使用异步写法因为 SDK 内部运行、工具调用、MCP、Realtime 和 streaming 都天然更贴近异步模型。Agent 的最小配置现在回到Agent本身。最小示例里只传了两个字段agentAgent(nameSummaryAgent,instructions你是技术文章摘要助手。,)这两个字段分别承担不同职责name给 Agent 一个可识别名称Tracing、handoff 和调试输出中都会用到。instructions告诉模型这个 Agent 的职责和回答方式类似系统指令。instructions不只是普通 prompt。源码中它可以是字符串也可以是一个函数。函数版本会接收运行上下文和当前 Agent用于动态生成 instructions。例如examples/basic/dynamic_system_prompt.py就展示了动态 instructions 的写法。后续第三篇会专门解析Agent的字段设计这里先记住一个原则Agent用来声明“这个智能体应该如何工作”不是用来保存一次运行的临时状态。Runner.run 做了什么Runner.run是异步入口。源码中的 docstring 把运行循环总结为四步使用当前输入调用 Agent。如果模型已经产生最终输出结束循环。如果发生 handoff切换到新的 Agent 后继续循环。如果发生工具调用执行工具把结果交回模型后继续循环。可以用下面的流程理解最终输出工具调用Handoff输入文本Runner.runAgent 配置模型调用结果类型RunResult.final_output执行 Tool切换 Agent第二篇的示例没有工具也没有 handoff所以链路会比较短输入进入Runner.run模型返回文本SDK 把结果包装成RunResult。这也是入门时先跑普通文本 Agent 的原因。它能让我们先看清最短路径再逐步加入工具、handoff、guardrail 和 session。RunResult 应该看什么Runner.run和Runner.run_sync返回的都是RunResult。它不是单纯的字符串而是一次运行的结构化结果。常用字段包括字段含义final_output最后一个 Agent 的最终输出入门阶段最常用new_items本次运行中新产生的消息、工具调用、工具输出等 itemraw_responses底层模型返回的原始响应列表last_agent本次运行最后实际执行的 Agentinput_guardrail_results输入 guardrail 的执行结果output_guardrail_results输出 guardrail 的执行结果context_wrapper.usage本次运行累计的 token 和 request 使用量可以写一个很小的调试函数观察结果defprint_run_summary(result)-None:print(Final output:,result.final_output)print(Last agent:,result.last_agent.name)print(New items:,len(result.new_items))print(Raw responses:,len(result.raw_responses))print(Total tokens:,result.context_wrapper.usage.total_tokens)这里最需要关注的是new_items。当后续引入工具调用和 handoff 后它会记录更多运行过程 item。理解new_items是理解多轮 Agent loop 的基础。usage 从哪里来examples/basic/usage_tracking.py展示了 usage 的读取方式resultawaitRunner.run(agent,Whats the weather in Tokyo?)print(result.context_wrapper.usage.total_tokens)usage挂在context_wrapper上而不是直接挂在final_output上。这符合 SDK 的运行模型token 使用量属于整次 run 的上下文不属于某一段最终文本。当一次 run 中发生多次模型请求时usage会累计请求数、输入 token、输出 token 和总 token。排查成本、性能和循环次数时这个字段很有用。第二轮对话怎么继续quickstart 中提到三种延续对话的方式目标推荐方式完全手动控制历史且保持 provider-agnosticresult.to_input_list()让 SDK 自动加载和保存历史session...使用 OpenAI server-managed continuationprevious_response_id或conversation_id入门阶段可以先理解to_input_list()firstawaitRunner.run(agent,请记住我在学习 Agents SDK。)secondawaitRunner.run(agent,first.to_input_list()[{role:user,content:我在学什么}])print(second.final_output)这段代码表达的是把第一次运行产生的新上下文转换成下一次模型输入然后追加新的用户消息。真实业务中更常用的是 session。因为手动拼接历史容易出错也不利于持久化、重试和上下文裁剪。Session 会在后续单独成篇。常见问题1. 没有设置 API Key现象通常是认证失败或客户端初始化失败。先检查当前终端python-cimport os; print(os.getenv(OPENAI_API_KEY))如果输出为空说明当前终端没有读取到环境变量。2. 在 Jupyter 中调用 run_syncJupyter 通常已经运行了事件循环不适合直接调用Runner.run_sync。应改用resultawaitRunner.run(agent,你的问题)print(result.final_output)3. 示例运行很慢先区分是依赖环境问题还是模型请求问题如果uv run python -c import agents; print(agents.__version__)很慢优先检查环境和依赖。如果导入很快但 Agent run 慢通常是网络、模型响应或工具执行耗时。如果后续加入工具调用需要观察usage、new_items和 tracing。4. 不知道模型实际被调用几次入门阶段先看print(result.context_wrapper.usage.requests)print(len(result.raw_responses))如果后续加入工具一次用户请求可能对应多次模型调用因为工具结果会被送回模型继续生成最终回答。最小调试脚本可以把下面脚本保存为临时文件运行用来观察第一次 run 的核心结果importasynciofromagentsimportAgent,Runnerasyncdefmain()-None:agentAgent(nameSummaryAgent,instructions用两句话解释技术概念。)resultawaitRunner.run(agent,什么是 Agent runtime)print(输出:,result.final_output)print(Agent:,result.last_agent.name)print(Items:,len(result.new_items))print(Tokens:,result.context_wrapper.usage.total_tokens)asyncio.run(main())这段脚本只观察四个值最终输出、最后执行的 Agent、新增 item 数量和 token 使用量。后续引入工具后可以继续用这个脚本结构扩展调试字段。源码入口本篇建议重点看四个文件examples/basic/hello_world.py最小异步示例。docs/quickstart.md官方入门流程。src/agents/run.pyRunner.run和run_sync的实现入口。src/agents/result.pyRunResult字段和 continuation helper。阅读时可以带着三个问题Runner.run的输入参数如何映射到内部AgentRunner.run。run_sync为什么不能在已有 event loop 中调用。RunResult为什么要保留new_items和raw_responses而不是只返回字符串。本篇小结这一篇完成了第一个文本 Agent 的最小闭环当前源码仓库推荐使用make sync和uv run。运行真实模型前必须设置OPENAI_API_KEY。Agent(name, instructions)是最小智能体声明。Runner.run是异步主入口Runner.run_sync适合同步脚本。RunResult.final_output是最终答案但排障时还要看new_items、raw_responses、last_agent和usage。下一篇会深入Agent对象本身重点解析instructions、prompt、handoffs、model、guardrails、output_type和tool_use_behavior等字段的设计。实践任务建议按顺序完成执行make sync准备开发依赖。设置OPENAI_API_KEY。运行uv run python examples/basic/hello_world.py。改写一个自己的SummaryAgent分别用Runner.run和Runner.run_sync运行。打印result.final_output、result.last_agent.name、len(result.new_items)、len(result.raw_responses)和result.context_wrapper.usage.total_tokens。打开src/agents/run.py阅读Runner.run的 docstring。打开src/agents/result.py确认RunResult为什么能支持to_input_list()。

相关新闻

openai-agents-python-sdk 源码解析 | 第一篇:认识 OpenAI Agents Python SDK:它解决什么问题

openai-agents-python-sdk 源码解析 | 第一篇:认识 OpenAI Agents Python SDK:它解决什么问题

本篇导读 如果你已经用过 OpenAI API,通常会从一个很直接的流程开始:组织 prompt、调用模型、解析返回值。如果任务只是一问一答,这样足够。但当任务开始包含工具调用、多步骤推理、多 Agent 分工、人工审批、会话记忆、流式输出、Trace 排障…

2026/8/28 8:57:06 阅读更多 →
Fate/Grand Automata:解放双手的FGO自动化神器,告别重复刷本的终极指南

Fate/Grand Automata:解放双手的FGO自动化神器,告别重复刷本的终极指南

Fate/Grand Automata:解放双手的FGO自动化神器,告别重复刷本的终极指南 【免费下载链接】FGA Auto-battle app for F/GO Android 项目地址: https://gitcode.com/gh_mirrors/fg/FGA 你是否厌倦了每天在Fate/Grand Order中重复点击刷取素材&#x…

2026/8/26 8:34:40 阅读更多 →
从浏览器开发者工具到专业软件:网页音频流媒体下载与转换全攻略

从浏览器开发者工具到专业软件:网页音频流媒体下载与转换全攻略

1. 从“想听”到“拥有”:一个音乐爱好者的朴素需求作为一个听歌超过十年的老乐迷,我电脑里存着几个T的音乐文件,从学生时代的MP3播放器到现在的手机、电脑,这些音乐文件跟着我换了好几代设备。我相信很多朋友和我一样&#xff0c…

2026/8/27 5:37:46 阅读更多 →

最新新闻

Qt实战:从零开发串口调试助手,详解QSerialPort通信与界面设计

Qt实战:从零开发串口调试助手,详解QSerialPort通信与界面设计

简介:一份基于Qt的串口调试助手完整源码项目,面向Qt初学者与嵌入式调试人员,可帮助理解串口通信原理、Qt界面开发流程及信号槽应用。资源压缩包共31个文件,包含9个C源码文件、9个头文件、3个UI界面设计文件,以及图标、…

2026/9/2 11:49:24 阅读更多 →
HyperX暗影精灵MAX:300W功耗释放+RTX 5080满血旗舰游戏本实测

HyperX暗影精灵MAX:300W功耗释放+RTX 5080满血旗舰游戏本实测

这次我们来看一台 2026 年的旗舰游戏本:HyperX 暗影精灵 MAX。名字稍微有点绕,HyperX 目前归属惠普旗下,而暗影精灵系列本身就是惠普游戏本的招牌,MAX 后缀说明这一代把配置、散热和功耗释放全部拉满。核心卖点其实一句话就能讲完…

2026/9/2 11:49:24 阅读更多 →
单片机毕设选题推荐:基于 STM32 单片机的环境参数阈值配置与联动控制装置设计 基于 STM32 与 WIFI 模块的室内环境远程监测与设备管控系统设计(010306)

单片机毕设选题推荐:基于 STM32 单片机的环境参数阈值配置与联动控制装置设计 基于 STM32 与 WIFI 模块的室内环境远程监测与设备管控系统设计(010306)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/9/2 11:49:24 阅读更多 →
Hugging Face周增4PB数据:开发者高效访问与实战指南

Hugging Face周增4PB数据:开发者高效访问与实战指南

在AI模型开发与开源社区,数据与模型的规模增长一直是衡量生态活力的关键指标。最近,Hugging Face平台单周新增数据量接近4PB的消息,无疑在开发者圈内投下了一颗“重磅炸弹”。这个数字不仅刷新了平台自身的记录,更深刻地反映了当前…

2026/9/2 11:49:24 阅读更多 →
Awesome Agent Skills:快速把 1500+ 个 AI Agent Skills 装进你的 AI 编程助手

Awesome Agent Skills:快速把 1500+ 个 AI Agent Skills 装进你的 AI 编程助手

Awesome Agent Skills:快速把 1500 个 AI Agent Skills 装进你的 AI 编程助手 【免费下载链接】awesome-agent-skills A curated collection of 1000 agent skills from official dev teams and the community, compatible with Claude Code, Codex, Gemini CLI, Cu…

2026/9/2 11:49:24 阅读更多 →
《Obey the Voice™》声音指令操控:AI驱动的沉浸式恐怖游戏设计解析

《Obey the Voice™》声音指令操控:AI驱动的沉浸式恐怖游戏设计解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/2 11:48:24 阅读更多 →

日新闻

QEMU为什么能模拟不同CPU?从ISA、CPU模型到指令翻译讲起

QEMU为什么能模拟不同CPU?从ISA、CPU模型到指令翻译讲起

1. 引言:一个软件为何能“伪装”成不同CPUQEMU 是一款广为人知的开源模拟器,它既能在一台 x86 电脑上运行 ARM 系统,也能在 ARM 开发板上启动 x86 的 Linux 发行版。很多人第一次接触 QEMU 时都会好奇:一个纯软件程序,…

2026/9/2 0:00:30 阅读更多 →
单片机计算机毕设之基于 STM32 或 51 单片机的感知式智能垃圾桶硬件控制系统设计 基于 STM32 或 51 单片机的安全防护型智能垃圾桶装置设计(025005)

单片机计算机毕设之基于 STM32 或 51 单片机的感知式智能垃圾桶硬件控制系统设计 基于 STM32 或 51 单片机的安全防护型智能垃圾桶装置设计(025005)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/9/2 0:00:30 阅读更多 →
单片机计算机毕设之基于 ESP8266 的智能垃圾分类桶 APP 监控系统设计与实现 基于单片机的超声波满溢检测垃圾分类装置设计(025105)

单片机计算机毕设之基于 ESP8266 的智能垃圾分类桶 APP 监控系统设计与实现 基于单片机的超声波满溢检测垃圾分类装置设计(025105)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/9/2 0:00:30 阅读更多 →

周新闻

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

2026/9/1 19:44:48 阅读更多 →
数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

2026/9/1 18:13:19 阅读更多 →
蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

2026/9/2 1:01:37 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/2 1:06:24 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/2 1:01:13 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/2 2:01:56 阅读更多 →