云沙箱活跃时,文件怎么进出云沙箱

前言

前面两篇我写的是云沙箱本身。 第一篇讨论执行该放在哪:Agent 会自己跑命令、装依赖、改文件,这些动作不适合直接发生在开发机或业务机器上,所以需要一台用完就回收的临时 Runtime。 第二篇接着把文件从这条链路里拆出来。命令能跑,只覆盖工作流中间那一段;一次性任务可以在创建前导入归档、结束后导出归档,会话会活一段时间,中间还要在同一棵目录上继续改。那一篇把文件能力分成三块:创建时导入,会话中途按路径读写单个文件,销毁时导出。

这篇我们来聊聊沙箱激活存活时的文件传输

阿里云 FC Agent Sandbox、腾讯云 Agent 沙箱和百智云云沙箱,都能在沙箱还活着的时候把文件写进去、再读出来。接口看起来都是「上传 / 下载」,背后的路径、鉴权和请求打到哪里,并不一样。百智云把这三件事收在一起:请求仍打到原来的 API,身份沿用这个会话,路径只进 /workspace。如果搞混这几件事,后面的安全边界和调用方式都会容易出错。


一. 会话中途的文件,和任务两端的归档不是一回事

一个会活几分钟到几小时的沙箱,典型过程不是「跑完一条命令就销毁」,而是:

text 复制代码
创建环境
  → 放进用户刚给的材料
  → 执行命令
  → 读回某一个结果,决定下一步
  → 人又补了一份附件
  → 再执行
  → 结束时再把整个工作区带走

例如解析一份简历。第一次跑完发现缺项目经历,人补了一页。如果补材料的办法是重新打包、重新创建,第一次装上的依赖和写下的中间文件就没了。会话退回到一次性任务。

所以会话里需要一条「世界还活着时,碰其中一个文件」的通道。它不替代另外两扇门:

通道 解决的问题 典型时机
导入归档 把一个已有项目或目录树搬进去 创建时
单文件读写 放进或取出一个文件 会话还在
导出归档 把工作区打包带走 销毁或到期

一份简历、一张图、一个 summary.json,走单文件。一整个代码仓库,走创建时的归档。整棵目录树要留档,走结束时的导出。命令结束本身通常不该自动打包,否则会话和一次性任务就没有差别了。

没有这条通道时,调用方会自己发明三种办法:把文件打进 zip 重建环境,把内容 base64 塞进命令,或者丢一个 URL 让沙箱自己下载。短演示都能过。一到真实文件,这些办法会同时暴露问题:二进制和命令输出上限、路径校验,以及 URL 带来的出网和 SSRF。


二. 阿里云:文件系统 SDK,另加一对上传下载地址

阿里云 FC Agent Sandbox 的数据面走 E2B 兼容接口。官方把 Filesystem 定义成管理沙箱内文件的对象,常见流程就是先写入输入或代码,再执行命令,最后读取结果。

读写本身是 SDK 方法,不是再套一层业务查询:

python 复制代码
sandbox.files.write("/tmp/hello.txt", "hello from fc sandbox\n")
content = sandbox.files.read("/tmp/hello.txt")

围绕这个对象,公开能力比「传一个文件」宽得多:list、exists、read、write、makeDir、remove、rename,还有监听变化。写入已有文件会覆盖,缺的父目录会创建。除了文本,还可以写字节和流。TypeScript SDK 还可以一次写入多个文件。

官方示例把临时输入放在 /tmp,或者业务自己定的工作目录。文档没有把 HTTP 文件接口收成「只能碰某一个固定根」。路径校验被写成业务侧建议:写入用户上传的文件前,检查类型、大小和路径。

另一条路不由 SDK 直接搬运字节,而是发地址。uploadUrl(path) 和 downloadUrl(path) 交给浏览器、没有 SDK 凭证的环境,或后续系统。上传地址收到的是 multipart/form-data。文档写得很明确:要把这对地址交给没有鉴权信息的调用方直接访问,创建 Sandbox 时要设 secure=false;否则请求仍要带 X-Access-Token。secure=false 会降低暴露端点的保护强度,所以还要求控制沙箱寿命、路径和数据敏感程度,也不要把这种地址写进日志。

小文件、二进制、流和 Agent 生成的代码,官方建议优先 files.read() / files.write()。地址留给「调用方手里没有 SDK 凭证」的场合。文件只在当前 Sandbox 生命周期内有效,要长期留下,得写到外部存储。

这是一套完整的沙箱文件系统,再加一条可选的直传地址。它假设调用方会操作沙箱里的路径,也接受文件请求走这台 Sandbox 自己的访问方式。

文档:


三. 腾讯云:同一件事有 SDK、CLI 和实例域名上的 HTTP

腾讯云 Agent 沙箱里,文件至少有两条公开入口:文件系统 SDK,以及对一台还在运行的实例做单文件传输。

一条是 E2B 兼容 SDK。files.read 可以把沙箱文件读成文本,或按字节下载到本地;files.write / write_files 负责写入和批量写入。旁边还有 exists、rename、make_dir,以及 watch_dir 监听目录变化。文档里的路径就是调用方给出的 your-file-path,没有收成某一个固定工作区根。

另一条不经过这套 SDK 对象,而是直接对实例做上传和下载。CLI 是:

text 复制代码
agr instance file upload  <instance-id> <local-path> <remote-path>
agr instance file download <instance-id> <remote-path> <local-path>

实例必须处于 RUNNING。本地路径可以用 - 走 stdin / stdout,方便接管道。可以指定沙箱内操作文件的用户。公开说明里的限制是:只传单个文件,不做目录递归,多个文件要逐个传,或者先打成 tar;列目录和目录监听不在这个 CLI 里,看目录要另执行 shell。

同一能力也可以打到实例自己的域名上:

bash 复制代码
curl -X POST "https://{instance-id}.{domain}/files?username=user&path=/home/user/config.yaml" \
  -H "X-Access-Token: {token}" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @./config.yaml

下载是同一个 host 上的 GET,鉴权同样是 X-Access-Token。示例里的 path 是 /home/user/config.yaml 这种沙箱内路径,host 也不是平台统一的 API 域名。

所以腾讯云这里把「文件系统对象」和「把字节搬进搬出这台实例」拆开了。SDK 更像在沙箱里管文件;CLI 和实例 HTTP 更像传输通道。列目录、重命名、监听留在前者,后者明确只做单文件。

另外还有一种不该和上传下载混在一起的能力:把 CFS 挂进沙箱。那是存储卷,用来跨实例保留或共享数据,不是这次把一个本地文件送进某个活会话。卷解决的是「沙箱死了以后字节还在不在」,单文件通道解决的是「这个会话还活着,我现在要放进或取出一个路径」。

文档:


四. 对照时值得看的,不是谁有上传按钮

阿里云、腾讯云和百智云云沙箱都能在会话还活着时放入和取出文件。差异在接口把边界画在哪。

阿里云 FC Agent Sandbox 腾讯云 Agent 沙箱 百智云云沙箱
会话中途读写 files.read / files.write SDK,以及 CLI / 实例 HTTP 统一 API 上的单个 path
请求打到哪 Sandbox 数据面,SDK 封装 {instance-id}.{domain},或 CLI 再转到它 创建会话、执行命令用的同一个 API 域名
鉴权 API Key / X-Access-Token;直传 URL 要处理 secure=false 实例上的 X-Access-Token 与会话相同的 Token 或网关身份,不单独发文件地址
路径 沙箱路径,示例多为 /tmp 或自定义目录 沙箱路径,示例可见 /home/user/... 只允许工作区,例如 resume.pdf 即 /workspace/resume.pdf
目录能力 list、mkdir、rename、remove、watch SDK 有;这条 CLI 只做单文件 文件口不做列表和监听,看目录走命令
浏览器直传 uploadUrl / downloadUrl 文档主路径是持有凭证的调用 不提供可转发的上传地址
生命周期 文件随 Sandbox 在,长期保存靠外部存储 单文件同样随实例;持久化要另挂 CFS 中途文件在会话里;结束时导出 /workspace

表里没有单独一行能决定选型。要看调用方是否接受对应的用法和边界。

路径开放到整台沙箱,还是只开放工作区。

阿里云和腾讯云的公开示例都把路径交给调用方,文件系统因此更像一台真的 Linux:可以列目录、改名、监听,也能把文件放进 /tmp 或 home。灵活的代价是,平台很难替调用方保证「最终落点仍是任务目录」。符号链接、.. 和绝对路径会变成每个业务自己的校验题。官方文档把类型、大小和路径检查放在业务侧。接口本身没把可写根收死,检查落在业务侧就说得通。

百智云云沙箱只开放 /workspace。调用方给出的 resume.pdf 就是 /workspace/resume.pdf,不用自己再处理符号链接、.. 和绝对路径。Agent 要看目录,就执行 ls;要搬走整棵树,就等销毁导出。文件接口不承担对象存储,也不承担 shell。

字节请求打在统一入口,还是打在沙箱自己的域名上。

腾讯云的 HTTP 示例,和 E2B 这一路的数据面,都是把文件请求送到这台实例:host 里带实例 ID,鉴权用实例访问令牌。好处是传输和这台机器绑在一起,也方便浏览器或脚本直接对这台沙箱说话。代价是调用方要同时理解控制面和沙箱地址,令牌的传递范围也要单独设计。阿里云把这件事写进了 uploadUrl 的注意事项:地址一旦脱离 SDK 凭证,就要用 secure=false 换可访问性,并自己约束谁能拿到这个地址。

百智云云沙箱的文件请求不离开原来的 API。会话 ID 就是路径参数,身份沿用创建会话的 Token 或网关身份。沙箱不必为了收文件再暴露一个文件服务,也没有一张可以转发给别人的上传链接。谁能写,只取决于谁还能操作这个会话,调用方也不用同时管理控制面域名、实例域名和另一张文件令牌。

直传地址和文件 API 不该当成同一个功能。

uploadUrl 解决的是「对方没有 SDK 凭证」。它很适合浏览器替用户把大文件送进某个路径。它也把写权限从「持有 API 凭证的调用方」放宽成「持有这个 URL 的人」。会话还活着、里面可能已经有别的任务文件时,这个放宽要很小心。

Agent 自己生成或改写的小文件,更适合由持有凭证的一侧直接 read / write,不必为每一份中间结果再签一次地址。阿里云把这个建议写进了文档。腾讯云 SDK 和百智云云沙箱走的也是直接读写。百智云不提供可转发的上传地址,写权限就不会从「还能操作这个会话的人」扩到「拿到链接的人」。

目录操作是另一层产品,不是上传下载的附赠。

阿里云 Filesystem 和腾讯云 SDK 把 list、rename、watch 放进了同一组文件能力。腾讯云的 agr instance file 则不收这些,只留 upload 和 download。传输通道一旦加上列目录和监听,就从「搬一个已知路径」变成「观察甚至跟随整棵树」。Agent 会很快把监听当成新的工具循环。百智云云沙箱这一期只做单文件,看树仍走命令,树的搬走仍走归档。传文件、看目录、搬走整棵树各走各的入口,失败也不会混成一次「文件接口坏了」。

还有一个公开材料里写得少、但实现时躲不开的问题:命令正在跑,能不能同时写同一个文件。文件系统接口如果和命令完全并行,Agent 会撞上正在生成的 output.json。忙的时候直接拒绝,把顺序交回调用方,通常比静默排队更可解释。这不是哪家文档里的对比项,而是会话文件通道一旦存在就必须回答的时序问题。

单次传输上限也一样。它保护的是同步 API 和模型上下文,不是沙箱磁盘。沙箱里用命令生成的大文件,可以比一次 HTTP 读取得大;装不下的结果应改走分块或结束时的归档,而不是退回 cat 和 base64。阿里云、腾讯云那几篇文件文档没有把这个数字写成同一条产品边界,集成时仍要自己量网关、SDK 和上下文各能装下多少。


五. 百智云云沙箱把文件留在原来的 API 上

我更倾向百智云云沙箱这一档。文件是会话上的一个动作,不是沙箱另外开的站,也不是一张可分享的地址。它接在原来的 API 和 MCP 上,不给每个沙箱单独的文件域名。会话还在时上传、下载,和创建、执行、销毁使用同一套身份。

路径只相对 /workspace,一次一个普通文件,落点由工作区根限制。命令正在跑就拒绝这次读写,避免撞上正在生成的文件。读成功直接给字节,写成功只告诉你落在哪。没有可以转发出去的上传链接,会话里已经有别的任务文件时,写权限也不会跟着链接扩散。

接口约定在控制台的开发者文档里:Huskbox API 集成文档。产品形态见 百智云云沙箱。

这是对照前面两家的一种切法,不是替换关系。

已经在用 E2B SDK、希望 files.list 和 files.write 直接迁过来的,阿里云 FC Agent Sandbox 和腾讯云的 E2B 兼容层更贴这个习惯。要把文件交给没有凭证的浏览器,阿里云的 uploadUrl / downloadUrl 把这个场景写成了正式能力,记得一起看 secure=false 的说明。要在脚本里对已知实例做管道上传,腾讯云的 agr instance file 更直接。要让数据在实例销毁后还按目录留在云盘上,那是 CFS 挂载,不要用单文件上传去模拟。

反过来,如果调用方只想在一个还活着的会话里放进一份材料和取出一个结果,并不想管理沙箱域名、实例令牌和整盘路径,百智云云沙箱就是按这个范围做的。大项目仍在创建时导入,整棵树仍在销毁时导出。


六. 总结

会话沙箱的上传和下载,解决的是环境还开着时的一个路径,不是网盘,也不是把归档再做一遍。

阿里云把它做成 Sandbox 上的文件系统,并用一对 URL 覆盖没有 SDK 凭证的直传。腾讯云把 SDK 文件操作和实例上的单文件传输分开,持久化则另走挂载。百智云云沙箱只做「一个 path 进、一个 path 出」:同一个 API、同一套身份、只写 /workspace。

路径开放到整台机器,调用方就得自己守住最终落点;请求打到沙箱域名,就得单独对待那张令牌或直传地址。百智云把这两件事留在平台侧:工作区根拦住落点,会话身份代替单独的文件地址。目录和整棵树仍走命令和归档。

上一篇的判断可以继续用在这次对比上:归档负责把世界搬进搬出,单文件负责世界还活着的时候,命令负责改变这个世界。选产品之前,先看自己要的是哪一层。


参考阅读

阿里云 FC Agent Sandbox

产品概述 · 读写文件 · 上传和下载文件

腾讯云 Agent 沙箱服务 AGSX

产品页 · 文件系统 SDK · 实例文件传输

百智云云沙箱

Isolated Agent Runtime,API 与 MCP。会话文件与创建、执行走同一入口,只读写 /workspace。

产品页 · API 集成文档

本系列前两篇

让 Agent 从执行代码升级到拥有一个临时 Runtime

云沙箱的文件通道:Agent 真正操作的是 Workspace

相关推荐
沛东的认知和实践3 小时前
Agentic RAG检索侧设计:从模式选型到工具、循环与提示词
agent
武子康3 小时前
150毫秒和2400毫秒:同一 Agent 任务的两种延迟
人工智能·后端·agent
Behavior3 小时前
某餐饮品牌开放 MCP 接口被玩成消费级 Agent:WorkBuddy 搭出会算营养、比价格、能下单的减脂私教
aigc·agent·mcp
轻松西西莱尔4 小时前
降低成本少花钱,模型调用量砍掉90%:缓存、分级、精简、批处理、流式,5个坑我全踩了一遍
llm·agent
玩泥巴的4 小时前
MAF + 飞书:让大模型干活,但别让它乱干
ai·c#·.net·飞书·agent
武子康4 小时前
Agent 偏好记忆怎样确认写入:范围、版本与撤销的一个最小例
人工智能·后端·agent
王中阳Go5 小时前
质保期第 90 天我翻了一遍日志目录:交付后真正会坏的 3 处
人工智能·后端·agent
sbjdhjd7 小时前
从签名重放到 Agent Harness:一堂安全课程如何把前端逆向、MCP 与工程约束串起来
网络安全·ai·github·agent·webshell·mcp·harness
Points7 小时前
我用 Codex 从零做了一个 Agent:让大模型的运行过程看得见、查得清
agent