02 Sandbox 生命周期
Sandbox 是 Deep Agents 的执行环境后端:它让 Agent 不只读写文件,还能通过 execute 跑命令。生命周期问题解决的是“这个环境什么时候创建、什么时候复用、什么时候销毁”。生产里最常见的是 threadscoped:每个 conversation 一个 sandbox,同一个 threadi
本站只展示教学文档和静态源码。不会执行示例、启动服务、访问模型、数据库或其他外部系统。
Sandbox 是 Deep Agents 的执行环境后端:它让 Agent 不只读写文件,还能通过 execute 跑命令。生命周期问题解决的是“这个环境什么时候创建、什么时候复用、什么时候销毁”。生产里最常见的是 thread-scoped:每个 conversation 一个 sandbox,同一个 thread_id 后续 run 复用它,不同 thread 彼此隔离。
最小代码
本章代码在:
deepagent_src/advanced_teach/02_sandbox_lifecycle.py
核心逻辑只有一个 registry:
@dataclass
class ThreadSandboxRegistry:
root_dir: Path
sandboxes: dict[str, LocalShellBackend] = field(default_factory=dict)
def get_or_create(self, thread_id: str) -> LocalShellBackend:
if thread_id not in self.sandboxes:
workspace = self.root_dir / f"thread-{thread_id}"
workspace.mkdir(parents=True, exist_ok=True)
self.sandboxes[thread_id] = LocalShellBackend(root_dir=workspace)
return self.sandboxes[thread_id]
同一个 thread_id 会拿回同一个 backend;不同 thread_id 会创建不同 backend 和不同工作目录。官方生产文档里的 SandboxClient.list_sandboxes() / create_sandbox(name=..., idle_ttl_seconds=...) 做的就是同一件事,只是它创建的是远端隔离容器。
运行命令
uv run python -m deepagent_src.advanced_teach.02_sandbox_lifecycle
预期现象:
- 输出两个不同 backend id,例如
local-xxxx。 alpha两次获取的是同一个 backend,写入/note.txt后后续还能读到。beta是另一个 backend,/note.txt内容和alpha不一样。execute("pwd")的输出分别落在thread-alpha和thread-beta临时目录。
生产写法
官方最新文档推荐生产中用 graph factory 读取 config["configurable"]["thread_id"],再按名字查找或创建 sandbox:
from deepagents import create_deep_agent
from deepagents.backends.langsmith import LangSmithSandbox
from langchain_core.runnables import RunnableConfig
from langsmith.sandbox import SandboxClient
client = SandboxClient()
async def agent(config: RunnableConfig):
thread_id = config["configurable"]["thread_id"]
sandbox_name = f"thread-{thread_id}"
existing = [sb for sb in client.list_sandboxes() if getattr(sb, "name", None) == sandbox_name]
ls_sandbox = existing[0] if existing else client.create_sandbox(
name=sandbox_name,
idle_ttl_seconds=3600,
)
return create_deep_agent(
model="openai:gpt-5.5",
backend=LangSmithSandbox(sandbox=ls_sandbox),
)
这里不能用静态 graph,因为 sandbox 选择依赖每次 run 的 thread_id。所以生产里导出的 agent 是 async factory,LangGraph server 每次 run 调它,拿到本次 thread 对应的 backend 后再返回 agent graph。
常见误区
别把 LocalShellBackend 当成安全 sandbox。官方文档明确警告:FilesystemBackend 和 LocalShellBackend 会直接访问 host,不要在部署环境里用。它适合本地教学和开发验证;真正面向用户的 coding agent 要用 LangSmith Sandbox、Daytona、E2B、Modal 这类隔离 provider。
另一个坑是忘记 TTL。sandbox 会占资源和成本,不设置 idle_ttl_seconds 或清理策略,assistant-scoped sandbox 会越堆越脏,磁盘和依赖状态都会膨胀。
验证
本章不触发 LLM 调用。验证重点是 sandbox backend 的真实行为:文件写入、文件读取、命令执行、同 thread 复用、不同 thread 隔离。