From Claude Code to Micro-Agent: The Rabbit Hole of AI Coding Agents on Vintage Hardware
Every developer knows the feeling. You see a shiny new tool, your brain sparks with possibilities, and you immediately try to run it on hardware that has no business hosting it(well maybe only me).
This is the story of how a simple desire to try Claude Code led me down a rabbit hole of instruction set failures, API translation layer frustration, context-window blowouts, and ultimately, writing my own lightweight AI coding agent in Ruby.
The Catalyst: Fighting with Claude Code
It started innocently enough. I wanted to see what Claude Code could do.
My weapon of choice? An old, trusty Dell laptop powered by an Intel Core 2 Duo P8700 processor. I kicked off the installation, only to watch it pull down a massive package over 280MB in size. For a CLI tool, that felt extremely bloated.
But the real kicker came when I tried to run it:
Illegal Instruction
The harsh reality of legacy hardware hit home. Claude Code (or its underlying Node binaries) compiled down to modern instruction sets requiring AVX and AVX2, extensions that my Core 2 Duo completely lacks. 280MB of bandwidth, gone.
The Pubnix & Proxy Detour
Refusing to give up, I shifted tactics and moved to a pubnix (a public UNIX server). Of course, running an AI agent on a shared public server comes with an obvious caveat: someone could easily sniff your process arguments or environment variables and steal your API key. Worse yet, I didn't actually have a dedicated Anthropic API key on hand. I wondered: How hard could it be to use an Anthropic-to-OpenAI API translator?
I found two translation projects via a quick web search. What followed was a classic developer nightmare: Python version conflicts, NPM dependency hell, and incompatible environments. Frustrated, I sat down and wrote my own custom API translator from scratch.
It finally ran! I hooked up Claude Code to my translator, typed a command, and... absolute silence.
Only the basic /btw command functioned. The moment Claude Code tried to do anything involving actual file editing, it failed completely. As it turns out, Claude Code passes a gargantuan list of tools and system instructions out of the box. This massive payload instantly saturated the OpenAI-compatible endpoint's context limit.
All that work, and the context window choked before the model could even think.
The Birth of Micro Agent
If you can't use a heavy tool, you build a precise one. I abandoned the bloated frameworks and wrote a lean, custom AI coding agent called Micro Agent, implemented as a lightweight Ruby CLI.
Micro-Agent features a flexible architecture allowing it to pivot between different LLM backends using profile commands. To test it, I decided to give it a classic litmus test: Write a simple program to output "Hello, World!" in amd64 NASM assembly for Linux, along with a Makefile to compile it.
I hooked it up to a local, smaller model profile (gemma4:e2b) to see how an optimized, smaller intelligence would handle low-level engineering tasks. What followed was a glorious, looping comedy of errors.
The Battle of the Assembly Code: A Log Summary
While Micro-Agent successfully integrated with system tools, the smaller model architecture struggled immensely with syntax, build systems, and execution guardrails. It took far more prompts and manual intervention to get a "Hello, World" binary compiled than it ever would have taken to write it by hand.
Here is the condensed, sanitized terminal archive from the file micro-agent.txt showing the agent trying to complete the task:
ben@box5:~/Projects/micro-agent/a$ ../micro-agent.rb
💻 Welcome to MicroAgent CLI
micro-agent > /api use 0
🎯 Switched active profile targeting to Context ID Engine Node: [0: gemma4:e2b]
micro-agent > make a simple program to say "Hello, World!" in amd64 NASM for
linux, and make a makefile for it
🤖 Thinking... Writing hello.asm and initial Makefile...
... [15+ Security Gate Permission Prompts Condensed] ...
❌ FAILURE 1: The model generates a flawed Makefile with invalid space
indentation.
'make' throws a "missing separator" syntax error.
🤖 Thinking... Correcting Makefile syntax...
❌ FAILURE 2: The model rewrites the Makefile but ruins the dependency logic,
blindly repeating strings and breaking standard GNU Make patterns.
🤖 Thinking... Attempting to execute 'make' again... Target fails.
❌ FAILURE 3: The model decides to bypass 'make' entirely and chain commands
via the shell:
🛠️ Executing: execute with args: {"command"=>"nasm -f elf64 hello.asm -o
hello.o && ld hello.o -o hello"}
⚠️ Execution blocked! The micro-agent core engine explicitly bans command
chaining (&&) for security.
❌ FAILURE 4: The model attempts a raw NASM compilation but fails because it
used Python/C shell style '#' characters for comments inside hello.asm.
micro-agent > nasm does not support using '#' for comments, use ';;' instead.
🤖 Thinking... Rewriting hello.asm with proper ';;' comment syntax...
... [More Permission Prompts] ...
micro-agent > run the make command
❌ FAILURE 5: The model panics, completely loses track of the directory state,
deletes/overwrites the Makefile with broken targets, and accidentally purges
hello.asm.
When it tries to recreate hello.asm, the user manually rejects the file write
out of sheer exhaustion.
⚠️ [Security Gate] Grant agent permission to 'write_file' on 'hello.asm'? (y/n): n
✅ Objective reached or agent stopped.
Taking Back Control
At this point, the agent hit an environmental wall, forcing me to temporarily suspend the process (^Z) and inspect the damage.
The agent had left behind an absolute mess in the build script (build.sh). It had attempted to use gcc to link a raw entry-point assembly file. When executed, the GNU linker threw a massive fit:
/usr/bin/ld: hello.o: in function
_start': hello.asm:(.text+0x0): multiple definition of_start'; (.text+0x17): undefined reference to `main' collect2: error: ld returned 1 exit status
Because gcc automatically injects the standard C runtime (crt1.o), it provides its own _start symbol and looks for a developer-defined main function. My assembly file explicitly defined _start and lacked a main.
To fix it, I manually bypassed the broken script and linked it directly using the raw linker:
ben@box5:~/Projects/micro-agent/a$ ld hello.o -o hello
ben@box5:~/Projects/micro-agent/a$ ./hello
Hello, World!
Segmentation fault
Success... followed immediately by a Segmentation Fault. The agent's code printed the string via system calls but failed to clean up the stack or invoke the proper sys_exit sequence. I had to manually jump into emacs to fix the register placements and structural bugs inside hello.asm myself until it finally executed cleanly.
When I brought Micro-Agent back to the foreground (fg) and asked it to review the modifications, it admitted its own execution blindness, noting that security restrictions prevented it from testing its own output.
Lessons Learned
- Model Size Dictates Logical Rigor: Small local models like
gemma4:e2bare fantastic for text processing or basic scripts, but they break down when navigating multi-step compilation pipelines. They struggle to retain context over strict formatting rules (like Makefile tabs vs spaces) and will loop endlessly when a command fails. - Larger Contexts Shine: When switching Micro-Agent over to heavier, remote configurations—such as
openai/gpt-oss-120b—the loops disappear. Higher-parameter models anticipate linking requirements, comment rules, and runtime environments effortlessly. - The Irony of Automation: Sometimes, setting up an autonomous agent to automate a 10-line assembly script takes 10x more time, prompts, and debugging than just pulling up a text editor and typing the assembly code out yourself.
Yet, despite the hiccups, Micro-Agent works. It's ultra-lightweight, it runs on virtually any machine, it doesn't suffer from modern instruction set bloat, and it keeps the developer firmly in control of the security gates. For vintage laptop enthusiasts and minimalist developers alike, building your own agent is a journey well worth taking.
tags: micro-agent, ai, claude, openai