Vercel Sandbox支持stdin:为AI Agent打通交互式命令通道

Vercel Sandbox 支持向运行中命令写入 stdin,实现与长驻进程双向交互。
Vercel Sandbox 新增了运行中命令的标准输入支持,使沙箱从只能一次性执行脚本的"跑批容器"升级为可与长驻进程双向对话的会话环境。文章介绍了 TypeScript SDK 中通过 stdin: true 与 detached: true 配合 writeStdin()、closeStdin()、wait() 的用法,以及 Python SDK 中基于 subprocess.PIPE 与 server.stdin.send()、communicate() 的实现路径,并指出 stdin 还可直接绑定 Node.js 可读流或通过 input 参数一次性传入。典型场景是 stdio MCP 服务器、LSP 进程和交互式 CLI,让 Agent 能维持多轮会话而非每步重启进程。文章同时提醒进程生命周期管理与消息边界等注意事项。
Vercel Sandbox 近期补上了一块关键短板:运行中的命令现在可以通过标准输入(stdin)接收数据。这意味着沙箱不再只是执行一次性脚本的"跑批容器",而开始具备与长驻进程双向对话的能力。

从单向执行到双向交互
过去的沙箱模型大多围绕"执行命令—返回结果"设计,输入在启动时一次性给定,运行中无法再注入数据。Vercel 这次把 stdin 开放给运行中的命令,直接改变了可支持的场景边界:任何依赖交互输入的 CLI 程序,都能在沙箱里跑完整流程。
官方点名的典型用例是 stdio MCP 服务器,例如 agent-browser。MCP 服务器通常以子进程形式存在,通过标准输入输出与宿主交换 JSON-RPC 消息。缺少 stdin 支持时,这类服务器只能启动却无法真正对话;现在 Agent 可以在沙箱内向其持续发送请求并读取响应。
stdio MCP 服务器中的 MCP 指 Model Context Protocol,是 Anthropic 提出的一套开放协议,用于让 AI 应用(宿主)以标准化方式调用外部工具、数据源与提示模板。
采用 stdio 传输时,MCP 服务器作为宿主启动的子进程运行,双方在 stdin/stdout 上交换 JSON-RPC 2.0 格式的消息:宿主向子进程写入请求,子进程在标准输出上回写结果或通知。这种传输方式部署简单、无需网络端口,但强依赖宿主能向运行中的进程持续写入数据——这正是沙箱此前缺失 stdin 时无法真正驱动 MCP 服务器的原因。
TypeScript SDK 的用法
在 TypeScript SDK 中,需要在 runCommand() 里同时设置 stdin: true 和 detached: true——前者开启输入通道,后者让命令在后台运行,避免阻塞后续操作。之后通过 writeStdin() 写入数据,用 closeStdin() 结束输入,再 wait() 等待进程退出并读取 stdout。
官方示例用 cat 演示了完整闭环:写入 hello、关闭 stdin、等待结束,最终 stdout 输出同样是 hello。这个例子虽小,却覆盖了写入、关闭、回收输出三个关键动作。
除了布尔值,stdin 还可以直接绑定一个 Node.js 可读流(例如 process.stdin)。SDK 会转发流中的数据,并在流结束时自动关闭命令的标准输入。对于需要把本地输入管道进沙箱的场景,这省去了手写中转逻辑。
detached: true 的作用是让命令以分离模式在沙箱后台运行:调用 runCommand() 后立即返回一个进程句柄,而不是阻塞到命令结束。对交互式场景来说这一步几乎是必需的,因为进程往往要等外部输入才会产生输出,若采用同步等待,调用方会陷入"等它退出"与"给它发数据"相互卡死的僵局。分离运行后,开发者可以持有句柄,在任意时刻调用 writeStdin()、读取 stdout,最后再用 wait() 统一回收退出状态与剩余输出。
Python SDK 的用法
Python 侧走的是更贴近 subprocess 的路径:create_process() 时传入 stdin=subprocess.PIPE,随后调用 server.stdin.send() 发送字节数据。示例中向 cat 写入 ping\n 并读取一行输出,最后调用 communicate() 关闭 stdin、收集剩余输出并等待进程退出。
如果命令不需要分多次交互、而是一次性吃下全部输入,可以直接把 input 传给 run_process(),不必走 PIPE 那套流程。两种方式并存,照顾了交互式与批处理两类需求。
subprocess.PIPE 是 Python 标准库 subprocess 中表示"创建管道"的特殊常量。传入 stdin=subprocess.PIPE 后,子进程的标准输入不再继承父进程,而是连接到一条由父进程掌控的管道,父进程可通过返回对象的 stdin 属性写入字节;同理 stdout=PIPE 让父进程能读取子进程输出。Vercel Python SDK 沿用这一约定,使沙箱内进程的交互方式与本地 subprocess 编程习惯保持一致,降低迁移成本。
对 Agent 工具链的意义
这项能力的价值不止于"多了一个参数"。Agent 在沙箱中运行工具时,常见需求包括与语言服务器协议(LSP)进程通信、驱动需要逐步确认的交互式 CLI、以及维持 MCP 会话。这些场景的共同点是进程生命周期长于单次请求,必须依赖 stdin/stdout 维持会话。
stdin 支持让沙箱从"执行环境"向"会话环境"靠拢。配合 detached 运行模式,Agent 可以并行维持多个交互进程,按需写入、按需读取,而不必为每一步交互重启进程。
使用时的注意点
交互式进程会带来生命周期管理问题:忘记调用 closeStdin() 或 communicate() 可能导致进程悬挂,占用沙箱资源。另外,基于流的输入需要处理好结束信号,否则命令可能一直等待输入而永不退出。对需要严格时序的协议(如 JSON-RPC),写入方还需自行保证消息边界,SDK 只负责字节转发。
这些约束并不复杂,但意味着开发者要把"进程编排"纳入设计,而不再只是拼一条命令。对构建 Agent 应用的团队来说,这是必要的心智转变。
closeStdin() 与 communicate() 之所以关键,是因为管道具有"读到 EOF 才结束"的语义:许多 CLI 程序会在标准输入关闭前持续等待更多数据,若父进程既不写入也不关闭,子进程就会一直挂起。而 JSON-RPC 等基于消息的协议本身并不携带分帧信息,管道只保证字节顺序、不保证消息边界,因此写入方必须自行约定分隔方式(如按行分隔或长度前缀),否则接收端可能把两条消息粘在一起解析失败。
相关推荐

MCP 是什么?让 AI 接入所有工具的开放标准
MCP(Model Context Protocol)是让 AI 应用统一接入各类工具的开放标准。本文解析 MCP 的 Host、Server、Client 三角色,Tools、Resources、Prompts 三构建块,一次工具调用的完整链路,以及在 n8n 中的双向用法与安全风险。
MCP图解:AI Agent如何连接你的应用
MCP图解:AI Agent如何连接你的应用
从电商客服机器人场景出发,图解MCP(Model Context Protocol)如何解决AI应用与外部工具的M×N集成困境,对比REST API直连的缺陷,解析Tools/Resources/Prompts三大原语、Host-Client-Server三层架构、stdio与streamable HTTP传输,以及认证授权、凭证管理与prompt injection防护要点。

CodeMode:让AI代理写代码代替调用工具,token成本直降90%
探索CodeMode如何让AI代理通过编写代码在沙箱中执行,替代传统逐个调用工具的方式,从而减少token消耗高达90%,并分析其实现要点与适用场景。