AREX Feed Article
OpenRouter 推出 openrouter:shell:任意模型可在托管 Linux 容器中运行代码,沙箱按活跃秒计费 0.0001 美元
OpenRouter 官方 X 账号 在 UTC 时间 9 月 16 日 17:03(北京时间 9 月 17 日凌晨 1:03)发帖宣布,OpenRouter 上的任意模型现在都可以在托管的 Linux 容器里运行代码:在 Responses API 请求的 tools 数组里加一项 openrouter:shell,模型自己写脚本、执行、读回结果,调用方不用安装也不用自托管任何东西。帖文给出的起步写法是 {"type": "openrouter:shell", "parameters": {"engine": "openrouter"}},沙箱时间按活跃秒计费,每秒 0.0001 美元,推理费用另计。
这条帖文之外,OpenRouter 在 9 月 8 日发布的把 shell 工具与 Files API 一起介绍,称两者当天起以 beta 形式提供,并提到在 chatroom 打开 shell 开关就能试用;shell、Containers、Files API 三份文档给出了更细的机制、限制和价格口径。帖文称,自上月末的软启动以来,开发者已经启动了超过 18,000 个沙箱。下面的具体细节,均出自 OpenRouter 自己的帖文、博客和文档。
一个工具调用,容器按需启动
按 OpenRouter 的 ,在 Responses 或 Messages API 请求的 tools 数组里带上 {"type": "openrouter:shell"},模型就会在需要终端时发出 shell 调用,把一批命令交给 OpenRouter。容器按需启动,命令在隔离的 Linux 容器里逐条执行,每条返回标准输出(stdout)、标准错误(stderr),以及退出码或超时标记。文档说,失败命令的报错写在 stderr 上回到模型,模型因此能在给出最终回答前改脚本、再跑一轮;同一个请求里可以继续发新的命令批次。
文档把 shell 描述为 OpenAI 托管 shell 工具的沙箱版克隆,博客给出的适用范围是可以配任意支持工具调用(tool calling)的模型使用。shell 工具没有「在客户端执行」的模式,命令要么跑在 OpenAI 自己的托管 shell 上,要么跑在 OpenRouter 的沙箱里;在 Responses API 上直接使用 OpenAI 原生的 shell 工具形状时,非 OpenAI 模型的调用会被转到 OpenRouter 沙箱。容器按账号和工作区隔离,文档写明不会跨租户共享。
文档还列出几条硬性限制:单次调用超过 100 条命令会被拒绝;单条命令的执行时间由 timeout_ms 限制,最多钳制到 5 分钟;stdout 和 stderr 各受 max_output_length 限制,最多 65,536 个字符。工具只在 openrouter.ai 全球端点可用,走 eu.、us. 区域端点的请求会被拒绝。
只有 /workspace/home 会被保存,容器文件保留 30 天
命令运行在 /workspace/home,也就是容器的家目录。按 ,每条命令执行后,家目录下发生变化的文件会被写入存储;被删除的文件保持删除状态,家目录以外的文件不会被保存。每次 shell 结果都会列出本次命令创建或改动的文件,每个文件带 cfile_ 前缀的 id,可以通过容器文件接口列出清单、读取元数据或下载内容。
容器文件的保留期是 30 天,起点是容器最后一次被使用的时间。想把产物长期留下,可以调用提升接口把它复制到工作区,换回一个 or_file_ 前缀的文件 id,之后再像上传的文件一样挂到新的运行上。提升有大小限制,超过 100 MiB 的文件返回 413,提升后的文档保留容器里的路径作为文件名。
里还有一条规则:自己上传的文件不能被下载,对这类文件请求内容接口会返回 400,官方建议自己保留原件;只有模型在沙箱里生成、再提升到工作区的文件才可下载。另外,每个请求最多挂 20 个文件,它们会以可写副本的形式出现在家目录,文件名由文件 id 的后 8 个字符加原始文件名组成,容器内的改动不影响工作区里的原件。
黏性容器、默认关闭的出站网络,和一份改不了的策略
复用容器有两种写法:把上一次的 shell 结果带回下一个请求,或者在工具的环境字段里用 container_reference 指定 container_id。容器 id 限 1~40 个字符,只能用字母、数字、下划线和连字符;同一个 id 的每个请求都落到同一个容器、看到同一批文件,不同工作区可以用相同的 id 而互相看不到对方的文件。
容器的生命周期有几条固定规则:空闲 5 分钟后进入休眠,这段时间不可配置;休眠不删除家目录里的文件,再有同 id 的请求进来时,平台会启动新的沙箱并先加载已保存的文件。文档说明,打开的进程、环境变量和已安装的系统状态不会被恢复,重新唤醒的容器里不能指望上一次装好的依赖还在。
出站网络默认关闭。要跑 pip install 这类任务,需要按运行把 network_policy 设成允许列表,例如 pypi.org 加 files.pythonhosted.org;只有 80 和 443 端口可达,条目只能是小写主机名或通配模式,写 example.com 不会覆盖 api.example.com。策略在容器启动时就固定下来,向一个热容器发送不同的策略会以 409 失败。访问允许列表之外的域名会返回 HTTP 520,模型可以从 stderr 上读到这个状态码。
计费从第一条沙箱命令起算,冷容器最低 30 秒
文档把计费口径写得更细:计时从一次请求里第一条沙箱命令开始执行时启动,到该响应结束为止,请求之间的空闲时间不收费。如果一次请求启动的是新容器或已休眠的容器,会按最低 30 秒计费,折合 0.003 美元;随后复用同一个热容器的请求只按实际计量的时间付费。持续活跃一小时的沙箱时间对应 0.36 美元。
一次请求的总成本是 token 成本加上沙箱时间,沙箱那一行会单独出现在 Logs 页面该请求的时间线上。OpenRouter 在博客里放了一张截图:一次请求被拆成模型轮次、工具调用、shell 运行和后续模型轮次几行,各自标注耗时与费用。
chatroom 里的 shell 开关,与 bash 的默认行为差异
帖文给出的试用入口包括 chatroom 里的 shell 开关。博客列出的一个组合用法是把 web search 与 shell 一起用:搜索在容器外执行,模型把检索到的内容传进命令,容器因此可以保持默认的无网络策略。
针对 Anthropic 的 Messages API,OpenRouter 提供了对等的 openrouter:bash。两者的差别在默认行为上:博客的对照表显示,openrouter:bash 默认要求由调用方在自己的应用里执行命令,只有显式指定 engine: "openrouter" 才保证命令跑在 OpenRouter 沙箱里;shell 工具没有本地执行模式。文档还提到,同一个 container id 之下,shell 与 bash 使用各自的计算环境,但共享已保存的文件。
帖文下面有几条回复指向审计和运维边界。 要求在 stdout 之外提供可复用的「运行凭据」:镜像 id、命令、网络策略、被触碰的文件、退出码、输出哈希和清理状态; 的说法类似,认为「无需安装」不应该让运维方失去完整的审计轨迹; 直接问容器什么时候被清理,答案在 Containers 文档的容器生命周期一节。
帖文说「最多上传 10 GiB」,文档写单文件 100 MiB
帖文里关于 Files API 的一句是「最多上传 10 GiB」,然后按 id 把文件挂到运行的 environment.file_ids 上,模型拿到的是可写副本。文档给出的数字不一样:单个文件最大 100 MiB(104,857,600 字节),超出返回 413;每个工作区合计最多存 10 GiB,写满后上传返回 403。按文档的口径,10 GiB 指的是工作区总配额。
文档还列了其他几条限制:文件类型由内容推断,只接受 PDF、PNG/JPEG/GIF/WebP、DOCX/XLSX/PPTX、MP3/WAV/FLAC/OGG 和 UTF-8 文本(按结构识别为 JSON、NDJSON、CSV、Markdown 或纯文本),其他内容返回 400;空文件也返回 400;Files API 只在全球端点可用,区域端点返回 403;它不单独收费,工作区文件不过期。
管理入口在工作区的文件页面,可以上传文件、建文件夹,但不能在这里下载文件。按博客的说法,server tools 默认开启,工作区管理员可以在 Server Tools 页面把任意一个工具设为 Blocked,包括 Files API,这个设置对该工作区通过 API key、chatroom 或预设发出的每一个请求生效。
OpenRouter 把 shell 与 Files API 都标为 beta,并写明 API 与行为可能变化。帖文里那句「最多上传 10 GiB」与文档中分列的单文件上限、工作区总量两条口径并不一致。