---
type: study
created: 2026-08-11
updated: 2026-08-11
sensitivity: standard
status: verified
tags:
  - study
  - langchain
  - langsmith
  - smith-api
  - sandbox
  - streaming
topic: LangSmith Smith API Sandbox 命令执行、SSE/WebSocket、文件检索与传输
sources:
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/download-a-sandbox-file
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/execute-a-sandbox-command
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/execute-a-sandbox-command-over-websocket
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/glob-a-sandbox-filesystem
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/grep-a-sandbox-filesystem
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/open-a-sandbox-tcp-tunnel
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/resume-a-streamed-sandbox-command
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/start-a-streamed-sandbox-command
  - https://docs.langchain.com/langsmith/smith-api/sandboxes/upload-a-sandbox-file
last_verified: 2026-08-11
---

# Smith API：Sandbox 命令流、文件检索与隧道传输

Sandbox 数据面提供同步命令、SSE 可恢复命令流、WebSocket 交互、文件上传下载、服务器端 glob/grep 和 TCP tunnel。它们都能触达运行时内部数据，应使用 `sandboxes:exec` 等最小权限、隔离的 sandbox 身份和严格输入边界，不能因为运行环境“是临时的”就省略安全控制。

## 同步命令执行

`POST /api/v2/sandboxes/{sandbox_id}/execute` 接收 command、cwd、env、shell、timeout_seconds，返回 stdout、stderr 与 exit_code。页面描述说 command 可为 shell 字符串或 argv 数组，但当前 OpenAPI schema 将它定义为 `array<string>`。这是文档文字与机器契约的差异：生成客户端应以 argv 数组为稳定基线；只有在目标环境实测并固定兼容性后才发送 string。

同步接口适合输出有明确上限的短命令。HTTP 200 只表示执行请求成功，业务成功仍要检查 exit_code；stderr 非空也不一定表示失败。timeout、进程退出和网络断开是三类状态，调用方要分别记录，避免把超时解释为命令必定没有产生副作用。

`shell` 模式会引入 shell expansion 与注入面。来自用户或模型的参数优先作为 argv 元素传递，不拼接成一条命令；cwd 限制在工作目录；env 采用 allowlist，禁止继承控制面 secret。标准输出也可能包含 secret 或个人数据，进入 trace 前应截断与脱敏。

## 可恢复 SSE 命令流

`POST .../execute/stream/start` 要求 v2 runtime，响应是 `text/event-stream`。stdout/stderr payload 以 base64 传输，调用方需要按 event type 分流并在 decode 后按字节处理，不能假设每个 chunk 都是完整 UTF-8 行。

请求字段：

- command、cwd、env、shell；
- `command_id`：幂等键；已知 ID 会 attach 到正在运行的 command，而不是再启动一份；
- `stdin`：整段 base64 一次写入，然后 stdin 关闭并让进程看到 EOF，不支持持续 stdin streaming；
- `timeout_seconds=0` 表示无总超时；
- `idle_timeout_seconds=0` 使用默认值，`-1` 永不因空闲终止；
- `ttl_seconds=0` 使用默认值，`-1` 永久保留 command 状态。

调用方应始终生成并持久化一个业务请求到 command_id 的映射。SSE 连接断开时，用同一 command_id/offset 恢复；换新 ID 会重复执行可能有副作用的命令。`-1` 会产生无界运行或状态保留风险，只应对受控运维任务开放，并有平台外 watchdog。

当 sandbox 输出 buffer 需要确认时，start/resume 流以 `ack_required` 结束并给出 stdout/stderr offsets。`POST .../stream/resume` 的 offsets 同时表示：

1. 从该字节位置继续发送；
2. 确认此前字节已被调用方持久处理；
3. 允许 sandbox 释放对应 buffer 并唤醒因 buffer 满而暂停的命令。

offset=0 会从头 replay，适合连接在任何输出前断开。消费方必须按 `(command_id, stream, byte_offset)` 去重，先持久化输出再推进 ack；否则 crash 后可能丢日志。Resume 只 attach，不会把 sandbox 已丢失的 command 重跑，找不到返回 404；状态冲突可返回 409。

## WebSocket 执行与 TCP Tunnel

`GET .../execute/ws` 以 101 升级到 WebSocket，适合需要双向实时交互的命令。OpenAPI 页面只承诺升级，没有形式化 frame schema；客户端必须固定与目标运行时版本匹配的协议实现，设置最大 frame/消息、心跳、总时限和关闭码处理。

`GET .../tunnel` 同样用 WebSocket 建立到 sandbox TCP port 的隧道，目标端口放在 `X-Sandbox-Port` header。它是认证隧道，不是把端口公开到互联网。要限制可访问 port、连接时长、并发与字节数；禁止借 tunnel 扫描内部控制面、metadata service 或挂载网络。

长任务选择：

| 需求 | 接口 | 特征 |
|---|---|---|
| 短命令、有限输出 | sync execute | 一次 JSON 响应，无恢复协议 |
| 长命令、单次 stdin、可恢复输出 | SSE start/resume | command_id 幂等，offset ack/backpressure |
| 持续双向交互 | execute WebSocket | 协议需客户端与 runtime 配套 |
| 任意内部 TCP 协议 | tunnel WebSocket | 端口在 header，需更严格网络策略 |

## 文件上传与下载

Upload 使用 `multipart/form-data`，文件字段名为 `file`，目标 path 是必填 query 参数；返回实际 path 与写入字节数。Download 把文件 path 放在 query 并直接返回文件内容，不是 JSON。

这些页面没有给出最大文件、覆盖/原子替换、symlink 或 path traversal 的完整保证。客户端侧仍要：

- 规范化 path 并限制在工作根目录，拒绝 `..`、NUL 与意外绝对路径；
- 对上传设置本地大小、类型与压缩包展开限制；
- 大文件用流式 I/O、校验长度/哈希，不将内容整体放入 trace；
- 如业务要求原子替换，先上传临时文件并在 sandbox 内做受控 rename；
- 下载响应按二进制处理，不根据文件名猜测安全 MIME 并在浏览器内联执行。

网络超时后，upload 是否已完整落盘未知，应查询文件/hash 后再决定重传。Download、glob、grep 是读取，可有界重试；upload 与 command 可能有副作用，必须先核对状态或使用业务幂等设计。

## Glob 与 Grep

`POST .../glob` 在给定 path 下按 pattern 查找，支持 `**`，结果按 path 字典序返回。每项包含 path、是否目录、size 与 modified_at；达到 limit 时 `truncated=true`，没有 cursor，因此完整扫描需要缩小 root/pattern 分片，而不是反复发送同一请求。

`POST .../grep` 搜索的是 literal text，不是正则表达式；可用 glob 限定文件，返回 path、line、text，并同样用 truncated 指示截断。不要把用户输入当 regex 转义后再推断服务端行为。对于二进制、大文件、生成目录和 secret 目录，先用 glob 限定集合，避免无界扫描和敏感内容进入结果。

## 执行可靠性与审计

```text
command accepted
  → process spawned
  → output streamed / buffered
  → exit event observed
  → output persisted
  → business result committed
```

只有最后一步完成才算业务成功。断线可能发生在任意阶段；同步执行没有 command_id，因此副作用命令应在 command 自身实现幂等键。SSE 模式把 command_id 与 offset checkpoint 一起持久化。

审计记录 sandbox ID、command_id、调用者、经过规范化的可执行程序名、cwd、开始/结束时间、exit/timeout/close 状态和输出字节数。不要记录 raw stdin、env secrets、service tokens 或未脱敏 stdout/stderr。400/403/404 通常是请求、权限或资源状态问题；500 只能对明确幂等读取/attach 做退避重试，不能据此自动重跑未知状态的命令。

