Polyaxon v3 is coming →

Build a coding agent with Polyaxon sandboxes

Give an open model a bounded read, edit, and check loop in a Polyaxon workspace, then retain the patch and evidence behind its completion claim.

October 13, 2026by Polyaxon

A model saying “fixed” is not enough to accept a code change. It needs an interface for reading the relevant files, making a patch, seeing check results, and finishing against the code that was actually checked.

This tutorial builds that loop with Qwen3-4B and a native Polyaxon sandbox. The task is deliberately small: repair a Python amount parser that returns a float so it instead follows a supplied Decimal contract. The result is an action transcript, a patch, and a check outcome you can inspect.

A model proposes actions to a controller, which reads and edits a CPU sandbox and runs fixed checks; completion is accepted only for the current checked patch

Make the environment part of the design

Research such as ReAct examines repeated interaction between model reasoning and environmental feedback. SWE-agent studies how the agent-computer interface changes software-engineering behavior. Their lesson for this example is practical: the file and action interface deserves explicit design. This small fixture does not reproduce their benchmark environments or results. ReAct, SWE-agent.

We use four JSON actions:

ActionController behavior
readRead amounts.py or the supplied check file
writeReplace amounts.py, subject to a size bound
checkRun the fixed python -m unittest -q test_amounts command
finishAccept only a changed file that matches the current successful check

The controller interprets the action; the model does not receive a Polyaxon client or choose an arbitrary shell command. A JSON schema makes the response easier to parse, while local validation enforces the permitted paths and actions. The loop has a twelve-turn budget and a thirty-second check timeout.

This is a benign teaching task. Code under test still executes with the sandbox container's authority. An action allowlist and file hashes do not turn that interpreter into a trusted adversarial verifier. Production acceptance requires an independent verification environment and an appropriate policy for network, filesystem, dependencies, and hidden cases.

Separate the model from the editing workspace

The model runs as a GPU service. The editing environment uses a small CPU service with Python. This lets you reuse a model deployment without reserving a GPU for every workspace.

Start with a configured Polyaxon project, a client supporting the native sandbox APIs, and CPU/GPU queues. The compute agent must support sandboxes; your identity needs service creation, approval, and stop permissions. The GPU node needs compatible NVIDIA drivers and model-download access.

git clone https://github.com/polyaxon/polyaxon-examples.git
cd polyaxon-examples/blog/polyaxon-coding-agent
python -m pip install -r requirements.txt
polyaxon run -f model.yaml -p YOUR_PROJECT --queue YOUR_AGENT/YOUR_GPU_QUEUE

The model service pins Qwen3-4B and the vLLM v0.11.2 image. It exposes the model as coding-agent, sets an 8,192-token length limit, and uses a two-hour termination timeout. Approve it if required and wait for health before starting the controller.

The controller creates the workspace directly from Python:

from polyaxon.client import SandboxClient

sandbox = SandboxClient(owner="acme", project="agent-lab")
run = sandbox.create(
    name="amount-parser-repair",
    content={
        "queue": "research/cpu",
        "termination": {"timeout": 1800},
        "component": {
            "plugins": {"auth": False, "mountArtifactsStore": False},
            "run": {
                "kind": "service",
                "container": {"image": "python:3.12-slim"},
            },
        },
    },
)

Creation excerpt. The full controller supplies CPU/memory limits, approves the run, waits for Running, checks the sandbox endpoint, and handles cleanup.

The native client configures the sandbox service; no separate Polyaxonfile is needed for the workspace. Disabling the normal auth and artifact-store mounts reduces the files exposed there. It does not establish a complete network or credential-isolation policy. Keep the controller's credentials outside the model-editable filesystem. See the Python sandbox tutorial for the underlying API.

Give the model feedback it can act on

The original parser simply removes a dollar sign and calls float. Four supplied checks require Decimal output, thousands separators, surrounding whitespace, and rejection of invalid input. The controller writes both files into /tmp and asks the model for one action at a time.

The complete controller calls the current sandbox file and process APIs:

source = sandbox.fs.read_text("/tmp/amounts.py", length=8192)
sandbox.fs.write("/tmp/amounts.py", replacement)
result = sandbox.process.exec(
    command=["python", "-m", "unittest", "-q", "test_amounts"],
    workdir="/tmp",
    timeout_ms=30_000,
)

API excerpts; replacement is validated by the controller before writing.

The model receives bounded stdout/stderr and the exit/timeout outcome. It can then edit again or request completion. Invalid paths or actions produce feedback instead of being executed. The example uses a JSON action protocol, so it does not depend on a model-specific function-call parser.

A write invalidates the prior check; a successful check binds to current file bytes and the supplied fixture; finish requires that same patch; the trusted controller remains outside the workspace

The useful invariant is that a new write invalidates the previous successful check. Before each check, the controller restores the supplied fixture. It compares patch and fixture bytes after execution and binds a successful result to the patch hash. finish checks those bytes again. This avoids accepting a later unverified edit, but it remains a smoke check for this controlled fixture, not proof that an implementation handles every amount correctly.

Run once and inspect the evidence

Get the model URL and run the controller in your configured local environment:

polyaxon ops service -p YOUR_PROJECT -uid MODEL_UUID --external --url
export SERVICE_URL='PASTE_THE_RETURNED_URL'
export POLYAXON_TOKEN='YOUR_CONFIGURED_POLYAXON_TOKEN'
python agent.py --owner YOUR_ORG --project YOUR_PROJECT --queue YOUR_AGENT/YOUR_CPU_QUEUE --allow-checks --out agent-output

The explicit --allow-checks flag authorizes the supplied check command. This command creates and approves a real workspace, sends model requests, and executes the fixture there. The service URL retains its routing prefix; authentication uses Polyaxon's token header.

Inspect the resulting patch before trusting it. actions.jsonl records model actions and feedback; patch.diff records the edit; outcome.json records acceptance and turns; workspace.json retains the run UUID. A failed or exhausted loop remains a failure even if the model described its attempt confidently.

The controller requests workspace stop in finally. If it loses connectivity, inspect the recorded run UUID; a stop request is not confirmation that the Pod terminated. The workspace also has a thirty-minute timeout. Stop the shared model service when finished:

polyaxon ops stop -p YOUR_PROJECT -uid MODEL_UUID

Polyaxon provides the scheduled workspace, file/process APIs, and run lifecycle. The application defines permitted actions and acceptance. This uses current execution APIs; the campaign controller discussed in the autoresearch roadmap is a separate planned capability.

The example was source-reviewed but not executed. It supplies no task-success rate or security benchmark.

References