Execute code in isolated environments with sandbox backends
Agents generate code, interact with filesystems, and run shell commands. Because we can’t predict what an agent might do, it’s important that its environment is isolated so it can’t access credentials, files, or the network. Sandboxes provide this isolation by creating a boundary between the agent’s execution environment and your host system.In Deep Agents, sandboxes are backends that define the environment where the agent operates. Unlike other backends (State, Filesystem, Store) which only expose file operations, sandbox backends also give the agent an execute tool for running shell commands. When you configure a sandbox backend, the agent gets:
All standard filesystem tools (ls, read_file, write_file, edit_file, delete, glob, grep)
The execute tool for running arbitrary shell commands in the sandbox
Sandboxes are used for security.
They let agents execute arbitrary code, access files, and use the network without compromising your credentials, local files, or host system.
This isolation is essential when agents run autonomously.Sandboxes are especially useful for:
Coding agents: Agents that run autonomously can use shell, git, clone repositories (many providers offer native git APIs, e.g., Daytona’s git operations), and run Docker-in-Docker for build and test pipelines
Data analysis agents—Load files, install data analysis libraries (pandas, numpy, etc.), run statistical calculations, and create outputs like PowerPoint presentations in a safe, isolated environment
Using Deep Agents Code? Deep Agents Code has built-in sandbox support via the --sandbox flag. See Use remote sandboxes for Deep Agents Code-specific setup, flags (--sandbox-id, --sandbox-setup), and examples.
If you’re looking for LangSmith sandboxes: LangSmith provides first-party managed sandboxes you can use directly from the LangSmith UI or SDK without a third-party account required. For managed sandbox resources, snapshots, service URLs, and the auth proxy, refer to LangSmith Sandboxes.
These examples assume you have already created a sandbox/devbox using the provider’s SDK and have credentials set up. For signup, authentication, and provider-specific lifecycle details, see Available providers.
LangSmith
Daytona
E2B
Modal
Runloop
Vercel
pip install "langsmith[sandbox]"
uv add "langsmith[sandbox]"
client = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="google_genai:gemini-3.5-flash"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: client.delete_sandbox(ls_sandbox.name)
client = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="openai:gpt-5.5"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: client.delete_sandbox(ls_sandbox.name)
client = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="anthropic:claude-sonnet-4-6"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: client.delete_sandbox(ls_sandbox.name)
client = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="openrouter:z-ai/glm-5.2"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: client.delete_sandbox(ls_sandbox.name)
client = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="fireworks:accounts/fireworks/models/glm-5p2"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: client.delete_sandbox(ls_sandbox.name)
client = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="baseten:zai-org/GLM-5.2"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: client.delete_sandbox(ls_sandbox.name)
client = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="ollama:north-mini-code-1.0"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: client.delete_sandbox(ls_sandbox.name)
pip install langchain-daytona
uv add langchain-daytona
sandbox = Daytona().create()backend = DaytonaSandbox(sandbox=sandbox)agent = create_deep_agent( model=ChatAnthropic(model="google_genai:gemini-3.5-flash"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: sandbox.stop()
sandbox = Daytona().create()backend = DaytonaSandbox(sandbox=sandbox)agent = create_deep_agent( model=ChatAnthropic(model="openai:gpt-5.5"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: sandbox.stop()
sandbox = Daytona().create()backend = DaytonaSandbox(sandbox=sandbox)agent = create_deep_agent( model=ChatAnthropic(model="anthropic:claude-sonnet-4-6"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: sandbox.stop()
sandbox = Daytona().create()backend = DaytonaSandbox(sandbox=sandbox)agent = create_deep_agent( model=ChatAnthropic(model="openrouter:z-ai/glm-5.2"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: sandbox.stop()
sandbox = Daytona().create()backend = DaytonaSandbox(sandbox=sandbox)agent = create_deep_agent( model=ChatAnthropic(model="fireworks:accounts/fireworks/models/glm-5p2"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: sandbox.stop()
sandbox = Daytona().create()backend = DaytonaSandbox(sandbox=sandbox)agent = create_deep_agent( model=ChatAnthropic(model="baseten:zai-org/GLM-5.2"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: sandbox.stop()
sandbox = Daytona().create()backend = DaytonaSandbox(sandbox=sandbox)agent = create_deep_agent( model=ChatAnthropic(model="ollama:north-mini-code-1.0"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: sandbox.stop()
pip install langchain-e2b
uv add langchain-e2b
from e2b import Sandboxfrom deepagents import create_deep_agentfrom langchain_anthropic import ChatAnthropicfrom langchain_e2b import E2BSandboxe2b_sandbox = Sandbox.create()backend = E2BSandbox(sandbox=e2b_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="claude-sonnet-4-6"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: e2b_sandbox.kill()
pip install langchain-modal
uv add langchain-modal
import modalfrom deepagents import create_deep_agentfrom langchain_anthropic import ChatAnthropicfrom langchain_modal import ModalSandboxapp = modal.App.lookup("your-app")modal_sandbox = modal.Sandbox.create(app=app)backend = ModalSandbox(sandbox=modal_sandbox)agent = create_deep_agent( model=ChatAnthropic(model="claude-sonnet-4-6"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: modal_sandbox.terminate()
pip install langchain-runloop
uv add langchain-runloop
import osfrom deepagents import create_deep_agentfrom langchain_anthropic import ChatAnthropicfrom langchain_runloop import RunloopSandboxfrom runloop_api_client import RunloopSDKclient = RunloopSDK(bearer_token=os.environ["RUNLOOP_API_KEY"])devbox = client.devbox.create()backend = RunloopSandbox(devbox=devbox)agent = create_deep_agent( model=ChatAnthropic(model="claude-sonnet-4-6"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: devbox.shutdown()
pip install langchain-vercel-sandbox
uv add langchain-vercel-sandbox
from deepagents import create_deep_agentfrom langchain_anthropic import ChatAnthropicfrom langchain_vercel_sandbox import VercelSandboxfrom vercel.sandbox import Sandboxsandbox = Sandbox.create()backend = VercelSandbox(sandbox=sandbox)agent = create_deep_agent( model=ChatAnthropic(model="claude-sonnet-4-6"), system_prompt="You are a Python coding assistant with sandbox access.", backend=backend,)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a small Python package and run pytest", } ] } )finally: sandbox.stop()
LangSmith traces show which shell commands ran inside a sandbox and how the agent used filesystem tools. Follow the observability quickstart to get set up. For managed sandbox hosting, see LangSmith Sandboxes.We recommend you also set up LangSmith Engine, which monitors your traces, detects issues, and proposes fixes.
Most applications choose either one sandbox per thread (thread-scoped) or one shared sandbox for every thread on the same assistant (assistant-scoped).Sandboxes consume resources and cost money until they are shut down. Make sure you shut sandboxes down once they are no longer in use.For the full lifecycle table, async graph factory notes, TTL behavior, LangGraph Deployment wiring, and client-side examples, see Sandbox lifecycle in Going to production.
Each conversation gets its own sandbox. The first run creates it; follow-up turns on the same thread reuse it. When the thread ends or the sandbox TTL expires, the environment goes away. Store the mapping with sandbox names or metadata as in the following example so each run resolves to the same sandbox.
When users can return after idle time, configure a TTL on the sandbox so the provider deletes or archives idle environments automatically.
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langchain_core.runnables import RunnableConfigfrom langsmith.sandbox import SandboxClientclient = 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 ] if existing: ls_sandbox = existing[0] else: ls_sandbox = client.create_sandbox( name=sandbox_name, idle_ttl_seconds=3600, # TTL: clean up when idle ) return create_deep_agent( model="google_genai:gemini-3.5-flash", backend=LangSmithSandbox(sandbox=ls_sandbox), )
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langchain_core.runnables import RunnableConfigfrom langsmith.sandbox import SandboxClientclient = 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 ] if existing: ls_sandbox = existing[0] else: ls_sandbox = client.create_sandbox( name=sandbox_name, idle_ttl_seconds=3600, # TTL: clean up when idle ) return create_deep_agent( model="openai:gpt-5.5", backend=LangSmithSandbox(sandbox=ls_sandbox), )
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langchain_core.runnables import RunnableConfigfrom langsmith.sandbox import SandboxClientclient = 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 ] if existing: ls_sandbox = existing[0] else: ls_sandbox = client.create_sandbox( name=sandbox_name, idle_ttl_seconds=3600, # TTL: clean up when idle ) return create_deep_agent( model="anthropic:claude-sonnet-4-6", backend=LangSmithSandbox(sandbox=ls_sandbox), )
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langchain_core.runnables import RunnableConfigfrom langsmith.sandbox import SandboxClientclient = 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 ] if existing: ls_sandbox = existing[0] else: ls_sandbox = client.create_sandbox( name=sandbox_name, idle_ttl_seconds=3600, # TTL: clean up when idle ) return create_deep_agent( model="openrouter:z-ai/glm-5.2", backend=LangSmithSandbox(sandbox=ls_sandbox), )
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langchain_core.runnables import RunnableConfigfrom langsmith.sandbox import SandboxClientclient = 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 ] if existing: ls_sandbox = existing[0] else: ls_sandbox = client.create_sandbox( name=sandbox_name, idle_ttl_seconds=3600, # TTL: clean up when idle ) return create_deep_agent( model="fireworks:accounts/fireworks/models/glm-5p2", backend=LangSmithSandbox(sandbox=ls_sandbox), )
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langchain_core.runnables import RunnableConfigfrom langsmith.sandbox import SandboxClientclient = 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 ] if existing: ls_sandbox = existing[0] else: ls_sandbox = client.create_sandbox( name=sandbox_name, idle_ttl_seconds=3600, # TTL: clean up when idle ) return create_deep_agent( model="baseten:zai-org/GLM-5.2", backend=LangSmithSandbox(sandbox=ls_sandbox), )
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langchain_core.runnables import RunnableConfigfrom langsmith.sandbox import SandboxClientclient = 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 ] if existing: ls_sandbox = existing[0] else: ls_sandbox = client.create_sandbox( name=sandbox_name, idle_ttl_seconds=3600, # TTL: clean up when idle ) return create_deep_agent( model="ollama:north-mini-code-1.0", backend=LangSmithSandbox(sandbox=ls_sandbox), )
Every thread on the same assistant reuses one sandbox. Files, installed packages, and cloned repositories persist across conversations.
Assistant-scoped sandboxes accumulate in-sandbox state over time. Configure a TTL with your sandbox provider, use snapshots to reset periodically, or implement cleanup logic so disk and memory do not grow without bound.
The agent runs inside the sandbox and you communicate with it over the network. You build a Docker or VM image with your agent framework pre-installed, run it inside the sandbox, and connect from outside to send messages.Benefits:
✅ Mirrors local development closely.
✅ Tight coupling between agent and environment.
Trade-offs:
🔴 API keys must live inside the sandbox (security risk).
🔴 Updates require rebuilding images.
🔴 Requires infrastructure for communication (WebSocket or HTTP layer).
To run an agent in a sandbox, build an image and install deepagents on it.
FROM python:3.11RUN pip install deepagents-code
Then run the agent inside the sandbox.
To use the agent inside the sandbox you have to add additional infrastructure to handle communication between your application and the agent inside the sandbox.
The agent runs on your machine or server. When it needs to execute code, it calls sandbox tools (such as execute, read_file, or write_file) which invoke the provider’s APIs to run operations in a remote sandbox.Benefits:
✅ Update agent code instantly without rebuilding images.
✅ Cleaner separation between agent state and execution.
API keys stay outside the sandbox.
Sandbox failures don’t lose agent state.
Option to run tasks in multiple sandboxes in parallel.
✅ Pay only for execution time.
Trade-offs:
🔴 Network latency on each execution call.
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langsmith.sandbox import SandboxClientclient = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model="google_genai:gemini-3.5-flash", backend=backend, system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a hello world Python script and run it", } ] } ) print(result["messages"][-1].content)finally: client.delete_sandbox(ls_sandbox.name)
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langsmith.sandbox import SandboxClientclient = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model="openai:gpt-5.5", backend=backend, system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a hello world Python script and run it", } ] } ) print(result["messages"][-1].content)finally: client.delete_sandbox(ls_sandbox.name)
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langsmith.sandbox import SandboxClientclient = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model="anthropic:claude-sonnet-4-6", backend=backend, system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a hello world Python script and run it", } ] } ) print(result["messages"][-1].content)finally: client.delete_sandbox(ls_sandbox.name)
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langsmith.sandbox import SandboxClientclient = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model="openrouter:z-ai/glm-5.2", backend=backend, system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a hello world Python script and run it", } ] } ) print(result["messages"][-1].content)finally: client.delete_sandbox(ls_sandbox.name)
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langsmith.sandbox import SandboxClientclient = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model="fireworks:accounts/fireworks/models/glm-5p2", backend=backend, system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a hello world Python script and run it", } ] } ) print(result["messages"][-1].content)finally: client.delete_sandbox(ls_sandbox.name)
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langsmith.sandbox import SandboxClientclient = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model="baseten:zai-org/GLM-5.2", backend=backend, system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a hello world Python script and run it", } ] } ) print(result["messages"][-1].content)finally: client.delete_sandbox(ls_sandbox.name)
from deepagents import create_deep_agentfrom deepagents.backends.langsmith import LangSmithSandboxfrom langsmith.sandbox import SandboxClientclient = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)agent = create_deep_agent( model="ollama:north-mini-code-1.0", backend=backend, system_prompt="You are a coding assistant with sandbox access. You can create and run code in the sandbox.",)try: result = agent.invoke( { "messages": [ { "role": "user", "content": "Create a hello world Python script and run it", } ] } ) print(result["messages"][-1].content)finally: client.delete_sandbox(ls_sandbox.name)
The examples in this doc use the sandbox as a tool pattern.
Choose the agent in sandbox pattern when your provider’s SDK handles the communication layer and you want production to mirror local development.
Choose the sandbox as tool pattern when you need to iterate quickly on agent logic, keep API keys outside the sandbox, or prefer cleaner separation of concerns.
All sandbox providers protect your host system from the agent’s filesystem and shell operations. The agent cannot read your local files, access environment variables on your machine, or interfere with other processes. However, sandboxes alone do not protect against:
Context injection: An attacker who controls part of the agent’s input can instruct it to run arbitrary commands inside the sandbox. The sandbox is isolated, but the agent has full control within it.
Network exfiltration: Unless network access is blocked, a context-injected agent can send data out of the sandbox over HTTP or DNS. Some providers support blocking network access (e.g., blockNetwork: true on Modal).
Sandbox backends have a simple architecture: the only method a provider must implement is execute(), which runs a shell command and returns its output.Every other filesystem operation (read, write, edit, delete, ls, glob, grep) is built on top of execute() by the BaseSandbox base class, which constructs scripts and runs them inside the sandbox via execute().This design means:
Adding a new provider is straightforward. Implement execute()—the base class handles everything else.
The execute tool is conditionally available. On every model call, the harness checks whether the backend implements SandboxBackendProtocol. If not, the tool is filtered out and the agent never sees it.
When the agent calls the execute tool, it provides a command string and gets back the combined stdout/stderr, exit code, and a truncation notice if the output was too large.You can also call the backend execute() method directly in your application code.
from vercel.sandbox import Sandboxfrom langchain_vercel_sandbox import VercelSandboxsandbox = Sandbox.create()backend = VercelSandbox(sandbox=sandbox)try: result = backend.execute("python --version") print(result.output)finally: sandbox.stop()
For example:
4[Command succeeded with exit code 0]
bash: foobar: command not found[Command failed with exit code 127]
If a command produces very large output, the result is automatically saved to a file and the agent is instructed to use read_file to access it incrementally. This prevents context window overflow.
There are two distinct ways files move in and out of a sandbox, and it’s important to understand when to use each:Agent filesystem tools: read_file, write_file, edit_file, delete, ls, glob, grep, execute are the tools the LLM calls during its execution. These go through execute() inside the sandbox. The agent uses them to read code, write files, and run commands as part of its task.File transfer APIs: the uploadFiles() and downloadFiles() methods that your application code calls. These use the provider’s native file transfer APIs (not shell commands) and are designed for moving files between your host environment and the sandbox. Use these to:
Seed the sandbox with source code, configuration, or data before the agent runs
Retrieve artifacts (generated code, build outputs, reports) after the agent finishes
Pre-populate dependencies that the agent will need
Use download_files() to retrieve files from the sandbox after the agent finishes:
LangSmith
AgentCore
Daytona
E2B
Modal
Runloop
Vercel
from deepagents.backends.langsmith import LangSmithSandboxfrom langsmith.sandbox import SandboxClientclient = SandboxClient()ls_sandbox = client.create_sandbox()backend = LangSmithSandbox(sandbox=ls_sandbox)results = backend.download_files(["/src/index.py", "/output.txt"])for result in results: if result.content is not None: print(f"{result.path}: {result.content.decode()}") else: print(f"Failed to download {result.path}: {result.error}")
pip install langchain-agentcore-codeinterpreter
uv add langchain-agentcore-codeinterpreter
from bedrock_agentcore.tools.code_interpreter_client import CodeInterpreterfrom langchain_agentcore_codeinterpreter import AgentCoreSandboxinterpreter = CodeInterpreter(region="us-west-2")interpreter.start()backend = AgentCoreSandbox(interpreter=interpreter)results = backend.download_files(["hello.py"])for result in results: if result.content is not None: print(f"{result.path}: {result.content.decode()}") else: print(f"Failed to download {result.path}: {result.error}")interpreter.stop()
pip install langchain-daytona
uv add langchain-daytona
from daytona import Daytonafrom langchain_daytona import DaytonaSandboxsandbox = Daytona().create()backend = DaytonaSandbox(sandbox=sandbox)results = backend.download_files(["/src/index.py", "/output.txt"])for result in results: if result.content is not None: print(f"{result.path}: {result.content.decode()}") else: print(f"Failed to download {result.path}: {result.error}")
pip install langchain-e2b
uv add langchain-e2b
from e2b import Sandboxfrom langchain_e2b import E2BSandboxe2b_sandbox = Sandbox.create()sandbox = E2BSandbox(sandbox=e2b_sandbox)try: results = sandbox.download_files(["/src/index.py", "/output.txt"]) for result in results: if result.content is not None: print(f"{result.path}: {result.content.decode()}") else: print(f"Failed to download {result.path}: {result.error}")finally: e2b_sandbox.kill()
import modalfrom langchain_modal import ModalSandboxapp = modal.App.lookup("your-app")modal_sandbox = modal.Sandbox.create(app=app)backend = ModalSandbox(sandbox=modal_sandbox)results = backend.download_files(["/src/index.py", "/output.txt"])for result in results: if result.content is not None: print(f"{result.path}: {result.content.decode()}") else: print(f"Failed to download {result.path}: {result.error}")
pip install langchain-runloop
uv add langchain-runloop
from runloop_api_client import RunloopSDKfrom langchain_runloop import RunloopSandboxapi_key = "..."client = RunloopSDK(bearer_token=api_key)devbox = client.devbox.create()backend = RunloopSandbox(devbox=devbox)results = backend.download_files(["/src/index.py", "/output.txt"])for result in results: if result.content is not None: print(f"{result.path}: {result.content.decode()}") else: print(f"Failed to download {result.path}: {result.error}")
pip install langchain-vercel-sandbox
uv add langchain-vercel-sandbox
from vercel.sandbox import Sandboxfrom langchain_vercel_sandbox import VercelSandboxsandbox = Sandbox.create()backend = VercelSandbox(sandbox=sandbox)results = backend.download_files(["/src/index.py", "/output.txt"])for result in results: if result.content is not None: print(f"{result.path}: {result.content.decode()}") else: print(f"Failed to download {result.path}: {result.error}")
Inside the sandbox, the agent uses filesystem tools (read_file, write_file). The upload_files and download_files methods are for your application code to move files across the boundary between your host and the sandbox.
Sandboxes isolate code execution from your host system, but they don’t protect against context injection. An attacker who controls part of the agent’s input can instruct it to read files, run commands, or exfiltrate data from within the sandbox. This makes credentials inside the sandbox especially dangerous.
Never put secrets inside a sandbox. API keys, tokens, database credentials, and other secrets injected into a sandbox (via environment variables, mounted files, or the secrets option) can be read and exfiltrated by a context-injected agent. This applies even to short-lived or scoped credentials—if an agent can access them, so can an attacker.
If your agent needs to call authenticated APIs or access protected resources, you have two options:
Keep secrets in tools outside the sandbox. Define tools that run in your host environment (not inside the sandbox) and handle authentication there. The agent calls these tools by name, but never sees the credentials. This is the recommended approach.
Use a network proxy that injects credentials. Some sandbox providers support proxies that intercept outgoing HTTP requests from the sandbox and attach credentials (e.g., Authorization headers) before forwarding them. The agent never sees the secret—it just makes plain requests to a URL. This approach is not yet widely available across providers.
If you must inject secrets into a sandbox (not recommended), take these precautions:
Enable human-in-the-loop approval for all tool calls, not just sensitive ones
Block or restrict network access from the sandbox to limit exfiltration paths
Use the narrowest possible credential scope and shortest possible lifetime
Monitor sandbox network traffic for unexpected outbound requests
Even with these safeguards, this remains an unsafe workaround. A sufficiently creative enough context injection attack can bypass output filtering and HITL review.