is probably one of the most useful capabilities we can give to an LLM agent. Once the agent can write and execute code, many tasks become possible. For example, the agent can inspect files or datasets, write data processing logic, or produce artifacts for downstream consumption. That opens the door to a much wider range of agentic applications. In this post, let’s build a coding agent with the OpenAI Agents SDK and Docker. We’ll first build the mental model, then walk through a small case study where we ask the agent to analyze a CSV file, and return a report with charts. In the end, we’ll also summarize the practical details that make this pattern reusable. 1. How Code-Executing Agents Work There are three important components of a code-executing agent: the model, the workspace, and the execution environment. Let’s unpack them one by one. 1.1 The Model A code-executing agent is, after all, an LLM agent. Naturally, it needs an LLM to power the agent. In this specific scenario, the common tasks of the LLM would be to inspect the available files, decide what type of analysis is needed, write the actual code, read the results, and continue with further iterations. 1.2 Workspace This is the space where the agent works, and it’s where the input files go in and the output files come out. The user may upload the data files (such as CSV, PDF, a folder of documents, etc) into the workspace, the agent can work on them, and save the artifacts back to it. 1.3 Execution Environment The LLM agent only writes the code and doesn’t execute it. So we need an execution environment where the generated code can actually run. There are multiple available options. For example, this code-execution environment can be a hosted one managed by the platform, or it can be a sandbox we control ourselves locally. If we control it ourselves, Docker is usually the default way to package the runtime and isolate the run. 1.4 Cross-Cutting Concern: Control Then, there is one practical design question: control. At the model layer, we need to decide how to build the agent system instruction and what artifacts the agent should produce. At the workspace layer, we need to think about what files are staged into it and what final output artifacts should be brought back after the run. At the execution environment layer, we need to determine what dependencies should be made available and whether network or shell access is allowed. 1.5 OpenAI Agents SDK In the OpenAI Agents SDK, a SandboxAgent exactly implements the pattern we discussed above. To configure the code-executing agent with the Agents SDK, we first need to describe the workspace with a Manifest, which basically specifies which local files should be staged into the workspace. A simple example is shown below: # pip install "openai-agents[docker]" from pathlib import Path from agents.sandbox import LocalFile, Manifest manifest = Manifest( entries={ "input/data.csv": LocalFile(src=Path("data/data.csv")), }, ) This says: take a local file and make it available inside the workspace as input/data.csv. Then, we specify the agent’s model, instructions, and the workspace manifest: from agents.sandbox import SandboxAgent agent = SandboxAgent( name="coding agent", instructions="Inspect the input files, write and run code when useful, and save requested artifacts.", model="gpt-5.4", default_manifest=manifest, ) Next, we should create the execution sandbox. If we use Docker: # pip install "openai-agents[docker]" import docker from agents.sandbox.sandboxes.docker import DockerSandboxClient from agents.sandbox.sandboxes.docker import DockerSandboxClientOptions docker_client = DockerSandboxClient(docker.from_env()) sandbox_options = DockerSandboxClientOptions(image="my-agent-sandbox:latest") sandbox_session = await docker_client.create( manifest=manifest, options=sandbox_options, ) await sandbox_session.apply_manifest() Here, the image argument of DockerSandboxClientOptions specifies the Docker image used by the sandbox. That is where we can customize the image, for example, by pre-installing the dependencies so that the agent can directly use them during the run without installing on the fly. Finally, we connect the agent and the sandbox session at runtime: from agents import Runner, RunConfig from agents.sandbox import SandboxRunConfig result = await Runner.run( agent, "Analyze input/data.csv and save a short report under output/report.md.", run_config=RunConfig( sandbox=SandboxRunConfig(session=sandbox_session), ), ) After the run, the sandbox workspace can also be persisted as a tar archive: workspace_archive = await sandbox_session.persist_workspace() await sandbox_session.aclose() We can then extract the output files we care about (e.g., reports, charts, tables, etc) and copy them back to the host machine. Of course, there are other ways to enable code execution in the Agents SDK besides the above-mentioned SandboxAgent. For example, you can attach CodeInterpreterTool to a regular agent, which allows the agent to run code in an OpenAI-managed environment. This comes in handy if you don’t want to manage Docker images and local runtimes yourself. If the workflow is more command-line oriented, the SDK also provides shell execution through ShellTool. With SandboxAgent, shell is included by default as part of its sandbox capabilities. 2. Case Study: An Agent That Analyzes a CSV In this case study, we’ll build an agent that can write code and perform data analysis. 2.1 The Case Study Setup Here, we consider a time series anomaly detection task. Specifically, we’ll task the agent to look into an hourly building energy dataset and to identify unusual energy use events. I created a synthetic dataset in plain CSV: data/building_energy.csv with three columns: timestamp, energy_kwh, outdoor_temp_c The time series data is visualized below: Figure 1. Hourly building energy consumption and outdoor temperature used as the input data for the agent. (Image by author) To complete the task, the agent needs to inspect the CSV, build a normal baseline behavior, and compare the observations against the expected patterns. We ask the agent to save three output files: output/anomalies.csv output/energy_anomalies.png output/anomaly_report.md 2.2 Prepare the Docker Runtime Before configuring the agent, we first need to prepare its code execution environment. Here, we use a Docker container. This container will serve as the agent’s temporary machine, with a working directory, a Python runtime, and a set of libraries that the agent can use to perform data analysis. Note that the agent will only run code inside that container, our host machine stays outside the run. To define that environment, we create a Dockerfile: FROM python:3.12-slim ENV MPLBACKEND=Agg RUN pip install --no-cache-dir numpy scipy pandas matplotlib WORKDIR /workspace Note that we give the agent numpy, scipy, pandas, and matplotlib. Those libraries should be enough for the current task. We also set MPLBACKEND=Agg, which lets matplotlib save figures without needing a display. This is especially useful here because the code runs inside a non-interactive container. Next, we can build the image: import subprocess IMAGE_NAME = "energy-agent-sandbox:latest" subprocess.run(["docker", "build", "-t", IMAGE_NAME, "."], check=True) Later, when we create the sandbox session, we can pass this image name into DockerSandboxClientOptions. That’s how the sandbox knows which execution environment to use. For this case study, you need to make sure that Docker is installed and running on your machine. The reason is simple: later, our Python code will ask Docker to create the sandbox session, so the Python process needs to be able to talk to the Docker daemon. On Windows or macOS, you can install Docker Desktop. On Linux, install Docker Engine directly from Docker’s official package repository. You can check if Docker is properly set up by running: docker –versiondocker run hello-world 2.3 Define and Run the Agent Now we define the actual agent. We start with the manifest, which tells the sandbox which local file should be available inside the workspace: from pathlib import Path from agents.sandbox import LocalFile, Manifest manifest = Manifest( entries={ "input/building_energy.csv": LocalFile(src=Path("data/building_energy.csv")), }, ) In the code snippet above, we stage the local CSV file into the sandbox workspace as: input/building_energy.csv Next, we define the agent instruction for defining its role, expected outcome, as well as the libraries at its disposal: # Note: This instruction is iterated with AI INSTRUCTIONS = """ You are a practical data analyst. Use the sandbox workspace to inspect files, write and run code when useful, and save clear artifacts. Keep conclusions grounded in computed evidence. The sandbox has Python with numpy, scipy, pandas, and matplotlib available. """.strip() Finally, we create the SandboxAgent: from agents.sandbox import SandboxAgent agent = SandboxAgent( name="Energy anomaly analyst", instructions=INSTRUCTIONS, model="gpt-5.4", default_manifest=manifest, ) To run the agent, we used the following prompt: PROMPT = """ I have an hourly energy-consumption export for one building at input/building_energy.csv. The columns are timestamp, energy_kwh, and outdoor_temp_c. outdoor_temp_c is in degrees Celsius. Please investigate the file and look for energy-use abnormal events. Ignore tiny fluctuations that look like normal operating noise. Use code in the sandbox to do the analysis, then save these files: - output/anomalies.csv - output/energy_anomalies.png - output/anomaly_report.md In the report, explain your method briefly, and give plausible explanations based only on the timestamps, energy values, and outdoor temperature. Use plain ASCII text such as deg C instead of the degree symbol. """.strip() Note that in the prompt above, we explicitly specified the files we expect back. Next, we create a Docker sandbox session from the image we built earlier: import docker from agents.sandbox.sandboxes.docker import DockerSandboxClient from agents.sandbox.sandboxes.docker import DockerSandboxClientOptions docker_client = DockerSandboxClient(docker.from_env()) sandbox_options = DockerSandboxClientOptions(image=IMAGE_NAME) sandbox_session = await docker_client.create( manifest=manifest, options=sandbox_options, ) await sandbox_session.apply_manifest() Then, we can run the agent: from agents import Runner, RunConfig from agents.sandbox import SandboxRunConfig result = await Runner.run( agent, PROMPT, max_turns=25, run_config=RunConfig( sandbox=SandboxRunConfig(session=sandbox_session), ), ) 2.4 Inspect the Results After the run, the agent created the three files we requested.To bring them back to our local project folder, we need to persist the sandbox workspace and extract the expected files: from pathlib import Path workspace_archive = await sandbox_session.persist_workspace() OUTPUTS_DIR = Path("outputs") shutil.rmtree(OUTPUTS_DIR, ignore_errors=True) OUTPUTS_DIR.mkdir(parents=True, exist_ok=True) with tarfile.open(fileobj=workspace_archive, mode="r:*") as tar: for filename in ["anomalies.csv", "energy_anomalies.png", "anomaly_report.md"]: source = tar.extractfile(f"output/{filename}") (OUTPUTS_DIR / filename).write_bytes(source.read()) await sandbox_session.aclose() Now we can see that the following files exist in the local outputs/ folder: anomalies.csv energy_anomalies.png anomaly_report.md The agent found one clear abnormal event, as shown in the energy_anomalies.png: Figure 2. The agent correctly identified the abnormal event. (Image by author) We can further inspect how the agent reached this conclusion: for item in result.new_items: print(type(item).__name__, item) In my run, I can roughly see that the agent first inspected the workspace and loaded the CSV with pandas. It then checked the row count, column names, data types, and missing values. After that, it wrote and ran an anomaly detection script with numpy and pandas. The script first built an expected hourly baseline, followed by computing residuals and robust z-scores. Finally, the agent generated the requested plot, saved the CSV, and output a markdown report. It even validated the outputs to wrap up the work. We now have a working code-executing agent. 3. Practical Things To Keep In Mind As we’ve seen in the previous case study, there are a few details we need to consider when building the code-executing agent: Start with the agent’s instruction, be explicit about its role, its task, and its expected outcome; Decide what files should enter the workspace. This is the set of files the agent will work on; Decide what runtime the agent can use, including the necessary libraries; State explicitly about the output file names and locations. This makes the later extraction and copy-paste easy. Once those pieces are clear, you can reuse the same pattern for many other agentic workflows. So, what would you build next with this capability?
Build an LLM Agent That Can Write and Run Code
Full Article
Original Source
Read the full article at Towardsdatascience →KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.