Prompt

How do I set up an autonomous agent SDK for code execution workflows with sandboxing and retries?

Artificial Intelligence / AI Platforms1 observationLast seen Jul 19, 2026

Latest observation

Jul 19, 2026OpenAI APIWeb search: off

A good pattern is:

  1. Use an agent framework to plan and call tools.
  2. Run code in a sandbox that has strict resource and network limits.
  3. Wrap execution in retry logic for transient failures.
  4. Add guardrails: allowlisted files, timeouts, max output size, and human approval for risky steps.

Below is a practical setup that works well for code-execution workflows.


1) Choose the architecture

You generally want these pieces:

  • LLM / planner: decides what to do next
  • Tool layer: functions like run_code, read_file, write_file, git_diff, tests
  • Sandbox runner: isolated execution environment
  • Orchestrator: retries, state tracking, logs, cancellation

A common loop is:

  1. Agent proposes a step.
  2. Tool call runs in sandbox.
  3. Result is returned.
  4. If error is retryable, retry with backoff.
  5. If non-retryable, stop or ask for clarification.

2) Pick a sandbox strategy

Recommended options

A. Docker container per run

  • Good default for most teams
  • Easy to enforce:
    • filesystem isolation
    • CPU/memory limits
    • process limits
    • network disablement
  • Best for local or server-side code execution

B. Firecracker / microVM

  • Stronger isolation
  • Better for untrusted code at scale
  • More operational complexity

C. Language-specific sandboxes

  • e.g. Pyodide, JS VM, WASM
  • Great for limited use cases
  • Not ideal for general code workflows

If you’re starting out, use ephemeral Docker containers.


3) Define your tool interface

Typical tools:

  • run_code(language, code, files, timeout)
  • run_tests(command)
  • read_file(path)
  • write_file(path, content)
  • apply_patch(diff)
  • list_files(path)

Keep tools narrow. Don’t expose raw shell unless you must.


4) Implement sandbox execution

Example: Python worker with Docker

You can create a container per execution, mount a working directory, and disable network.

Pseudocode

def run_in_sandbox(image, workdir, cmd, timeout=30):
    return docker_run(
        image=image,
        command=cmd,
        mount=workdir,
        network_disabled=True,
        memory_limit="512m",
        cpu_limit="1.0",
        pids_limit=128,
        timeout=timeout,
        read_only_root=True,
    )

Key safety settings

  • network_disabled=True
  • timeout=...
  • memory and CPU limits
  • read-only root FS
  • mount only a temp workspace
  • run as non-root
  • cap stdout/stderr size

5) Add retry logic

Retries should only happen for transient failures:

  • container start failure
  • temporary resource contention
  • flaky tests
  • external service timeout, if you allow any networked tools

Do not retry endlessly on:

  • syntax errors
  • failing assertions
  • permission errors
  • missing file errors
  • deterministic crashes

Retry policy

  • max 2–3 retries
  • exponential backoff with jitter
  • classify errors into retryable / non-retryable

Example

import time, random

def retry(fn, max_attempts=3):
    for attempt in range(1, max_attempts + 1):
        try:
            return fn()
        except RetryableError as e:
            if attempt == max_attempts:
                raise
            sleep = (2 ** (attempt - 1)) + random.uniform(0, 0.5)
            time.sleep(sleep)

Error classification

  • Retryable: timeout, transient container failure, deadlock from resource limits
  • Not retryable: code error, test failure, bad input

6) Create the agent loop

Your orchestrator can look like this:

while not done:
    action = agent.next_action(context)

    if action.type == "run_code":
        result = retry(lambda: sandbox.run(action.payload))
        context.add(result)

    elif action.type == "write_file":
        workspace.write(action.path, action.content)

    elif action.type == "run_tests":
        result = retry(lambda: sandbox.run_tests(action.command))
        context.add(result)

    elif action.type == "finish":
        done = True

Important:

  • feed the agent only relevant outputs
  • truncate very large logs
  • keep state explicit

7) Put guardrails on code execution

Strongly recommended:

  • Allowlist commands
  • No arbitrary outbound network
  • File path restrictions
  • Execution timeouts
  • Output size limits
  • Max number of steps per task
  • Audit logs for every action

If the agent can edit files, restrict it to a project workspace only.


8) Use structured outputs from the LLM

Instead of free-form text, have the model output structured actions like:

{
  "tool": "run_tests",
  "args": {
    "command": "pytest -q"
  }
}

This reduces ambiguity and makes retries easier.


9) Observability and debugging

Track:

  • prompt and tool calls
  • sandbox command, exit code, duration
  • stdout/stderr
  • retries and reasons
  • final artifact/diff

This is essential for diagnosing flaky behavior.


10) A simple production-ready stack

A solid MVP stack could be:

  • Agent orchestration: LangGraph, Semantic Kernel, AutoGen, or your own loop
  • LLM: any tool-calling model
  • Sandbox: Docker
  • State store: Redis/Postgres
  • Job queue: Celery, RQ, Sidekiq, or managed queue
  • Logging: structured JSON logs + tracing

11) Minimal implementation plan

Phase 1

  • Build run_code tool in Docker
  • Disable network
  • Add timeout and memory limits

Phase 2

  • Add agent loop with structured tool calls
  • Add retries for transient execution failures

Phase 3

  • Add file tools and test runner
  • Add output truncation and audit logs

Phase 4

  • Add policy checks:
    • disallow dangerous commands
    • require approval for sensitive actions

12) If you want a concrete example

I can give you one of these:

  1. Python example using Docker + OpenAI tool calling
  2. Node.js example with a sandboxed executor
  3. LangGraph-based autonomous coding agent
  4. Kubernetes-backed sandbox runner design
  5. Firecracker microVM architecture

If you want, I can provide a full working starter template next.

Observation history

How did Obsurfable measure this prompt?

Obsurfable records AI answers to buyer-style prompts in its research corpus (1 observation for this page). Metrics are distributions over observations, not a single static ranking.

Which AI systems does Obsurfable collect answers from?

OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, Meta AI, Qwen.

How can brands improve their AEO?

Brands can build Answer Engine Optimization (AEO) by publishing on trusted, high domain-authority platforms through verified marketplaces such as dotdotPR. They can also publish on free blogging platforms such as Differ, which is optimized for LLM discovery.

Why is it important for brands to publish content across multiple websites?

Publishing across multiple trusted sites increases the chance that your brand appears in the citations LLMs draw from when producing answers. Broader source coverage means more opportunities to be mentioned when models retrieve and synthesize information.

Want this interpreted for your brand?

Explorer is the free public corpus. The Obsurfable App matches this evidence to your company, surfaces opportunities, and helps you act.