代理API托管沙箱测试:CSV运行器、工件检查及故障处理
测试托管在沙箱环境中的 OpenAI Agents API:通过 Python 运行程序发送 CSV 文件,获取生成的结果,并检查 JSON 摘要内容。同时会显示失败情况及相关成本。
这个实验基于一个具体问题:Agents API 会话能否接收文件,在沙箱环境中对其进行处理,并返回可验证的结果?一个简单的 Python 程序用于解答这个问题。输入是一个包含四笔销售记录、一笔退款记录以及一行无效数据的交易 CSV 文件。智能体会生成一份 JSON 摘要,而应用程序则会自行计算出预期结果,以便两者进行对比。此处所有的观点均为个人见解,来源于使用个人 OpenAI Pro 套餐账户进行的测试,以及当时可用的文档资料。
2026年9月10日,OpenAI推出了Agents API的公开测试版,提供了一个托管式的Codex框架,用于驱动模型与工具之间的交互循环。调用应用程序负责提交任务并决定命令的执行位置。接下来的内容将介绍该运行器的构建方式。所记录的五次测试来自该框架的早期版本。经过改进的运行器具备了可重复性并能保存相关证据,目前仅能在离线环境中进行测试。
01 Agents API的组成结构
有四个部分需要保持独立。代理负责承载模型、指令和工具;环境则提供可选的计算资源;会话用于在时间维度上整合各项操作;事件与项目则用于报告当前正在发生的情况以及已存储的信息。一次“轮次”即指完成该循环的一次完整过程。
本实验中的托管架构如下:Python运行程序负责启动会话并获取结果,而OpenAI则负责管理控制框架及执行沙箱。
第一个设计问题是代理循环应放置在哪里。使用Agents API时,OpenAI会托管控制框架并确保会话的持久性;而Agents SDK则会在您的应用程序中运行该循环,因此您可自行选择存储方式及集成方案。Responses API则可直接访问模型,其余工作流程由您自行处理。
Responses还可以执行托管的shell命令,因此单纯的CSV计算无需使用Agents API。运行程序会通过该API完成从会话到输出结果的整个流程。每次测试都会创建一个新的会话并执行一项任务,不会测试多轮对话的持续性或子代理功能。
02 为何选择托管沙箱
该任务只需一个地方来存放CSV文件以及代理生成的Python文件。它不需要私有网络,也不需要自定义镜像,因此运行器会选择关闭沙箱网络的openai_hosted选项。其他选项主要会影响工作空间的归属以及文件的输出方式。
none这一选项意味着没有环境文件系统,也没有内置的Bash执行功能,不过应用程序函数和远程MCP服务器仍可能在其他地方运行代码。而选择self_hosted时,OpenAI会继续运行相关工具,但执行环境由你自行管理。
输出处理也属于这一选项的范畴。在自托管环境中,即使代理将文件写入/workspace/outputs目录,这些文件也不会通过OpenAI的Artifacts API发布。你的应用程序必须自行获取并保存这些文件。
此处重要的托管设置
托管指南还涉及环境变量、技能、插件以及能力目录。此处只需设置种子文件并禁用沙箱网络访问即可。远程MCP连接是从OpenAI的服务开始的,因此沙箱出站设置不应被视为所有工具连接的通用策略。
03 CSV运行器内部结构
相关代码位于openai-agents-api/sandbox_check.py中,完整示例可在GitHub上的techforum-repo ai-agents-experimentation仓库的openai-agents-api目录中找到。该运行器会将金额以整数分的形式生成并保存其种子值。每份CSV文件都刻意包含一些复杂情况:货币符号、千位分隔符、多余的空白字符、负数退款以及N/A条目。
seed-42输入示例
amount,note
$981.96 ,sale
" $1,838.10 ",sale
$42.78 ,sale
-$100.12,refund
N/A,voided
$155.92 ,sale
本地生成器直接从这些整数数值中得出下面的参考值。这是该测试用例的预期结果,而非实时代理的响应。
{
"total_cents": 291864,
"valid_rows": 5,
"invalid_rows": 1
}
已发送的说明
系统会将 CSV 文件及书面任务交给处理人员,预期答案不会离开该应用程序。任务要点如下:创建 /workspace/outputs/calculate.py 文件并使用 Python 运行它;加载 /workspace/data.csv 文件;去除每笔金额中的空白字符、美元符号及千位分隔符;忽略非数字值,但保留负数的退款金额;使用 Decimal 类型或整数分值进行计算,严禁使用二进制浮点数;生成 /workspace/outputs/summary.json 文件,其中需包含三个名为 total_cents、valid_rows 和 invalid_rows 的整数字段;每行数据仅计数一次,且需排除表头行;同时将 calculate.py 文件作为输出结果保留。
run_trial()函数通过client.beta.agents.sessions.create()打开会话,将gpt-6-astra及相应指令作为智能体传入,并通过内联base64格式传入/workspace/data.csv数据。该环境为openai_hosted类型,且network.access设置为disabled状态。这与原始实验所使用的API路径完全相同。
哪些内容会被检查并保存
- 跟踪正确步骤。获取会话后,运行程序会轮询当前步骤状态。会话失败、需要执行特定操作、当前步骤失败、任务被取消以及轮询次数耗尽,每种情况都会产生不同的结果。
- 获取所需的两个文件。
summary.json和calculate.py会根据路径和步骤ID进行匹配,因此缺失或过时的文件绝不会被通过。
工件指南说明了文件如何与各轮次关联,而可观测性指南则介绍了如何查看命令执行情况。自动检查会确认文件存在且结构化输出准确无误。在有人声称知晓计算过程之前,仍需仔细查看已保存的脚本和各项内容。下载的代码绝不会在应用程序的服务器上执行。
04 五次记录的测试结果说明了什么
最初的测试于2026年9月15日记录了结果,每次试验都使用新随机生成的CSV文件。这些数据来自那次测试。它们是客户端在收到创建响应后的观测值,计时范围不包括会话创建和结果文件下载的时间。
代理报告的五个总计数值都与参考数值一致。该验证采用浮点运算,容差小于0.1%。计时记录的是首次轮询时会话状态发生变化的时刻,因此既不能反映服务器的确切执行时间,也无法体现端到端延迟。五次成功的试验仅描述了一次小型测试中的情况,无法说明整体的可靠性水平。
更新后的测试工具所做的改变
经过修改的测试程序会使用更严格的成功标准来重复同样的小规模实验。它会精确比对整数分值与行数,存储每个输入样本,同时保留生成的脚本及会话历史记录。计时从会话创建之前就开始,下载和验证过程也会分别计时。共有八次离线测试用于验证这些功能,而上述数据仍来自之前的实时测试。
05 错误处理
轮询循环会设置明确的HTTP超时时间,关闭自动重试功能,并在每次请求之间检查剩余的尝试次数。该尝试次数并非强制终止进程的计时器。程序会在尝试清理之前记录测试结果,即便答案正确但清理失败,也会产生非零的退出码。
会话可以有四种状态:idle、in_progress、requires_action和failed。由于CSV任务未配置任何应用程序功能工具,因此一旦需要执行操作,运行程序会保存当前状态并上报以便检查,而不会无限期等待。
直播不会重播那些错过的事件。要重新呈现应用程序的界面,需要重新连接并缓冲传入的事件,同时获取已保存的会话数据,再通过项目ID进行匹配。这样虽然可以恢复已保存内容的显示,但无法保证被中断的命令能够成功执行。
有一起相关的事件值得注意。早期的调查记录显示会话处于空闲状态且没有可见的轮次切换,而 OpenAI 在 2026 年 9 月 14 日发布的事件报告中则指出,从太平洋时间当天的 13:30 开始,轮次开始出现延迟或被阻塞,后来被标记为已解决。这些症状看似一致,但由于缺乏请求级别的证据,无法证明所有本地故障的成因。应将服务状态与保存的会话记录及轮次错误进行对比。运行程序会将失败的会话、失败的轮次、缺失的文件、无效的摘要以及错误的结果作为独立的结果记录下来,而且它不会再将未观察到的轮次视为旧有事件复发的证据。
一旦结果生成并保存,如果任务尚未完成,运行器会请求取消并尝试删除会话,遇到删除冲突时最多可尝试三次。任何清理错误都会记录在result.json中。如果在返回ID之前会话创建失败,则无法通过ID进行清理,运行器会记录这一不确定性。
若托管工作空间一小时内没有活动或保持连接的操作,将会过期;而连接的沙箱则会在各轮任务之间自动发送保持连接信号。已发布的成果可以在环境过期后仍然存在,但必要的输出结果必须在会话被删除之前保存下来。
06 何时自行提供计算资源
在更完整的架构图中,虚线仅适用于自托管计算环境,而此处的 CSV 实验仍在 OpenAI 托管的计算环境中进行。如果任务需要特定的图像、对私有网络的访问权限,或是使用您现有的计算资源,那么自托管方案就会显现出优势。在该环境中,您需要启动 codex exec-server,并传入远程 URL 与环境 ID,同时还需提供限定该环境的专用密钥,而通用的应用密钥则应保持在外部。
之后,应用程序需负责资源的配置、存储、重新连接以及资源清理工作。删除 OpenAI 会话并不会停止服务提供商的计算运行,而重复使用环境 ID 也不会将文件恢复到替代机器上。
自行托管并不意味着整个服务都在本地运行。当前的 Agents API 会保留会话状态,支持美国地区的数据存储要求,但不支持零数据保留功能。
成本是需要考虑的因素。模型令牌和托管计算资源是分开计费的,容器的费用则根据内存大小和计费周期来计算,因此请记录实际使用情况,不要仅凭经过的时间来估算试用期的费用。
07 运行实验
运行该服务需要实际支付费用,因为它需要通过积分或活跃的API计费方式单独支付API使用费用,而Pro订阅并不涵盖这些调用成本。该服务会调用GPT-6 Astra(gpt-6-astra),因此多次试用或长时间运行都会迅速消耗积分,此外托管沙箱的使用时间还会产生计算费用。在进一步使用之前,建议先进行一次试用,查看使用情况仪表板,并阅读Astra的定价页面。
在代码仓库中创建虚拟环境并安装指定的SDK。需要一个应用API密钥,该密钥必须具备读取和写入会话以及运行模型推理的权限。每次试用都会消耗实时API令牌及托管计算资源。
cd openai-agents-api
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
export OPENAI_API_KEY="your-key"
python sandbox_check.py --seed 42 # Start with one trial
# python sandbox_check.py 5 --seed 42 # Optional: five trials
第一个命令使用种子值42运行一次测试,而可选的五次测试命令则会使用42到46这五个种子值依次运行。测试结果会保存在新的runs/目录中,每个测试对应一个文件夹。SDK版本为openai==3.13.0,README文件中说明了输出文件及命令选项的相关信息。
trial-001/
data.csv # Exact input
expected.json # Local reference
request.json # Submitted configuration
session.json # Latest retrieved session
turns.json # Turn status, timestamps, usage
items.json # Saved messages and tool calls
artifacts.json # Published file metadata
summary.json # Downloaded result
calculate.py # Downloaded agent script
result.json # Checks, timing, errors, cleanup
失败运行会保留失败前已获取的所有文件。若退出码为0,则需对输出结果进行严格检查,并确认每次尝试后的会话均已删除。如需在本地测试该运行程序且不使用任何API调用:
python -m unittest discover -s . -p test_sandbox_check.py -v
在不连接网络的情况下,该测试套件能够检测参考数学计算、格式错误的模型输出、过时或缺失的生成物、失败的会话与轮次、必需的操作、请求错误、截止日期处理以及清理失败等问题。经过修改的运行程序尚未在真实服务环境中进行验证。
该项目的持久价值在于提供了一种可重复的方法,用于检查Agents API如何将文件转换为生成物。完成一轮处理只是一个信号,而下载后经过独立验证的输出才是真正的验收标准。文档已于2026年9月15日进行过检查,测试数值来自最初的实验,没有新的实时测量数据,所链接的指南描述的是当前的测试版,内容可能会发生变化。