How to Build an AI Coding Assistant That Runs in the Cloud
Build an AI coding assistant that writes code, runs it, verifies output, and iterates - all in an isolated cloud environment. Works with any LLM.
How to Build an AI Coding Assistant That Runs in the Cloud
The AI coding assistants that actually work - the ones that don't just suggest code but write, run, test, and fix it - all share one thing in common: they have access to a real computer.
They can create files. Run commands. Install packages. Start servers. Check output. Fix errors. Iterate until things work.
Building one of these isn't as hard as it sounds. You need three things:
- An LLM that can reason about code (GPT-4, Claude, etc.)
- A set of tools that let the LLM interact with a filesystem and terminal
- An isolated environment where it's safe to let the LLM do whatever it needs
This guide walks through the architecture and implementation.
The architecture
┌──────────────────────────────────┐
│ Your Application │
│ │
│ User asks: "Build me a REST API" │
│ │
│ 1. Send task to LLM │
│ 2. LLM returns tool calls │
│ 3. Execute tools in workspace │
│ 4. Send results back to LLM │
│ 5. Repeat until done │
└───────────┬───────────────────────┘
│
┌────▼────────────────────┐
│ Cloud Workspace │
│ (Isolated MicroVM) │
│ │
│ - Write files │
│ - Run commands │
│ - Read output │
│ - Start servers │
│ - Full Linux terminal │
└─────────────────────────┘The LLM doesn't run code directly. Your application acts as a bridge: it sends the LLM's instructions to the workspace, executes them, and returns the results. The LLM sees the output and decides what to do next.
Step 1: Set up the workspace
Create a persistent workspace to serve as the coding agent's development environment:
import { OblienClient } from 'oblien';
import { Workspace } from 'oblien/workspace';
const client = new OblienClient({
clientId: process.env.OBLIEN_CLIENT_ID,
clientSecret: process.env.OBLIEN_CLIENT_SECRET,
});
const ws = new Workspace(client);
const devBox = await ws.create({
image: 'node-22',
cpus: 4,
memory_mb: 8192,
writable_size_mb: 20480,
});This workspace is a full Linux VM with Node.js, npm, and common build tools. The coding assistant will use it for everything - writing files, running commands, installing packages.
Step 2: Define the tools
The LLM needs tools to interact with the workspace. Define these as function calls your LLM can invoke:
Write a file
async function writeFile(path, content) {
await ws.fs.write(devBox.id, {
path: path,
content: content,
});
return `Written ${path}`;
}Read a file
async function readFile(path) {
const file = await ws.fs.read(devBox.id, { path: path });
return file.content;
}Run a command
async function runCommand(command) {
const result = await ws.exec(devBox.id, {
cmd: ['bash', '-c', command],
timeout_seconds: 60,
});
return {
stdout: result.stdout,
stderr: result.stderr,
exitCode: result.exit_code,
};
}List files
async function listFiles(path) {
const files = await ws.fs.list(devBox.id, { path: path });
return files.map(f => f.name).join('\n');
}These four tools - write, read, run, list - are enough for a surprisingly capable coding assistant.
Step 3: The agent loop
The core pattern is a loop: send the task to the LLM, execute any tool calls, return the results, repeat until the LLM says it's done.
async function runCodingAgent(task) {
const messages = [
{
role: 'system',
content: `You are a coding assistant with access to a Linux workspace.
You can write files, read files, run commands, and list directories.
Write code, test it, fix errors, and iterate until the task is complete.
Always verify your code works by running it.`
},
{ role: 'user', content: task }
];
while (true) {
const response = await llm.chat(messages, { tools: toolDefinitions });
if (response.done) {
return response.finalMessage;
}
for (const toolCall of response.toolCalls) {
let result;
switch (toolCall.name) {
case 'write_file':
result = await writeFile(toolCall.args.path, toolCall.args.content);
break;
case 'read_file':
result = await readFile(toolCall.args.path);
break;
case 'run_command':
result = await runCommand(toolCall.args.command);
break;
case 'list_files':
result = await listFiles(toolCall.args.path);
break;
}
messages.push({ role: 'tool', content: JSON.stringify(result) });
}
}
}That's the entire agent loop. The LLM decides what to do, your code executes it in the workspace, and the cycle continues.
Step 4: What the agent can do now
With just those four tools and a cloud workspace, your coding assistant can:
- Create a project from scratch - Initialize a directory, create package.json, write source files, install dependencies
- Debug code - Read error output, identify the issue, edit the file, run again
- Run tests - Execute test suites, read failures, fix the failing code
- Refactor - Read existing code, understand the structure, write improved versions
- Install and configure tools -
npm install,pip install,apt-get install- whatever it needs - Start servers - Run a dev server and verify it responds correctly
- Work with databases - Create tables, seed data, write queries
All in an isolated environment where mistakes don't matter. The agent can rm -rf the wrong directory and it only affects the workspace.
Making it better
Add a "preview" tool
If your agent builds web applications, expose the workspace port and give the LLM a preview URL:
async function exposePreview(port) {
const preview = await ws.publicAccess.expose(devBox.id, {
port: port,
label: 'dev-preview',
});
return preview.url; // https://abc123.preview.oblien.com
}Now the agent can start a dev server, get a live URL, and even verify the output.
Add a "search" tool
For large codebases, let the agent search instead of reading every file:
async function searchCode(query) {
const results = await ws.search.content(devBox.id, {
query: query,
is_regex: false,
});
return results;
}Isolate risky operations
For tasks that involve untrusted code (running user-submitted code, testing generated code), create a temporary workspace:
async function runInSandbox(code) {
const sandbox = await ws.create({
image: 'node-22',
cpus: 1,
memory_mb: 512,
ttl_seconds: 30,
allow_internet: false,
});
try {
const result = await ws.exec(sandbox.id, {
cmd: ['node', '-e', code],
timeout_seconds: 10,
});
return result;
} finally {
await ws.delete(sandbox.id);
}
}The sandbox is air-gapped - no internet, no access to the main workspace. Perfect for testing code the agent isn't sure about.
Why the workspace matters
You could build a coding assistant that runs code locally, or in a Docker container, or on a shared server. But a cloud workspace is the right choice because:
Isolation. The agent runs arbitrary code based on LLM decisions. If the LLM hallucinates a destructive command, it only affects the workspace. Your server, your database, your other users' environments are unaffected.
Persistence. The workspace survives reboots. The agent can work on a project over multiple sessions. Files, installed packages, and configuration persist.
Resource control. You control exactly how much CPU, memory, and disk the agent gets. No risk of a runaway process eating your server's resources.
Reproducibility. Every workspace starts from a known image. You can reset to a clean state with snapshot restore.
Frameworks that do this for you
Don't want to build the agent loop from scratch? These frameworks handle the reasoning and tool use - you just provide the execution environment:
- OpenClaw - Open-source agent framework with built-in tool use and planning
- Claude Code - Anthropic's coding agent, designed for exactly this workflow
- LangChain - Define workspace operations as custom tools
- CrewAI - Multi-agent teams with tool delegation
- OpenHands - Open-source AI software engineer
All of these can be deployed on Oblien workspaces. The framework handles the AI reasoning, the workspace handles the safe execution.
Summary
An AI coding assistant needs four things:
- An LLM that can reason about code
- Tools that let it read, write, and execute code
- A loop that connects the LLM's decisions to the tools
- An isolated environment where it's safe to run anything
Oblien provides #3 and #4. Every workspace is a hardware-isolated microVM with a full Linux environment, persistent storage, and network isolation. Your coding assistant gets a real computer to work with, and you get the guarantee that it can't break anything outside its workspace.
How to Boot a Full Linux VM in Under 200 Milliseconds
Most VMs take 30–60s to boot. Firecracker does it in under 200ms. Learn the engineering behind sub-second boot for AI agents and sandboxes.
How to Build a Multi-Agent System Where AI Agents Talk to Each Other
Architect a multi-agent system where AI agents collaborate in isolated environments, communicating securely over a private network.