I like "vibe coding" as much as anyone. You toss a prompt into an LLM, it spits out code, and you squint at it wondering if it'll work. Sometimes it does. Sometimes it invents a library that has never existed on this planet, solar system, and probably multiverse. That's how you learn the word hallucination.
Early ChatGPT 3.5 made this worse because the context window was tiny. You'd paste in a stack trace and the model would lose the top half before it reached the bottom. The first time it confidently stated a "fact" that was completely fake, it was clarifying. I stopped treating the model like a coworker and started treating it like a tool with sharp edges.
The next step past vibe coding is self-correction. Not the model apologizing ...it does that already! I mean an agent that runs commands, hits a wall, reads the error, fixes itself, and tries again-without you having to click "try again, dummy."
From "hands" to logic: why OpenClaw-style control matters
If you've played with OpenClaw-style architectures, you know the big idea: give the agent "hands." Let it operate a real shell, a real filesystem, real tools. That's where bugs stop being abstract and start being undeniable.
Agents don't need more personality. They need feedback loops.
A loop that looks like this:
- Generate a command or code change
- Run it in a real PTY/bash shell
- If it fails, capture stderr + stack trace
- Ask a "Critic" to diagnose the failure
- Patch and retry
- Stop only after a clean run or a hard limit
At that point, it stops being a demo and becomes a system.
The orchestrator: LiteLLM + a Builder/Critic split
The Builder/Critic pattern works because it's iterative and it stays anchored to what actually happened. Coding quizzes taught me that people can charm their way through a narrow test. Terminals don't care.
LiteLLM is handy here because it normalizes providers. You can use one model to build and another to critique without rewriting your stack every time a vendor tweaks their API.
A rough sketch:
from litellm import completion
def call(model, messages):
return completion(model=model, messages=messages).choices[0].message["content"]
builder_model = "gpt-4.1-mini"
critic_model = "claude-3.5-sonnet"
Then you wire the loop.
The reflection pattern (the part that actually matters)
The agent needs to see the raw failure. Not your summary. The actual error output.
import subprocess, textwrap
def run(cmd):
p = subprocess.run(cmd, shell=True, capture_output=True, text=True)
return p.returncode, p.stdout, p.stderr
def reflect(task, cmd, stdout, stderr):
prompt = f"""
Task: {task}
Command attempted:
{cmd}
STDERR:
{stderr}
Fix the issue. Output a corrected command or a patch.
"""
return call(critic_model, [{"role":"user","content":prompt}])
Now the agent reacts to reality instead of guessing.
The best part is that most failures are boring. Missing dependency. Wrong path. Bad quoting. Off-by-one. The kind of stuff that burns time because humans are also juggling Slack, CI noise, and half-finished context.
Source of truth: put the whole messy loop in S3
If you don't store iterations, you get a vibe coding hangover. You end up with working code and no idea why it works or what changed.
This is also how fake "AI automation" happens. I worked at a SaaS shop that sold "AI magic," and a chunk of it was spreadsheet column mapping and data formatting. The support team told me to watch them do it. It was Excel with extra steps. That kind of thing scales right up until it doesn't.
So: store every attempt. Store the inputs, outputs, diffs, and the final validated artifact. S3 works. Boring is good.
A simple key scheme:
runs/{run_id}/attempt_{n}/command.txtruns/{run_id}/attempt_{n}/stderr.txtruns/{run_id}/final/
Now you have an audit trail and a clean "blessed" output that your production system can trust.
Next: physical systems that can recover
I want to push this pattern into robotics and puzzle-like systems. Escape rooms with agents. Props that can tell they failed, figure out why, and retry. Also: small language models on phones, and small robots running on small AI chips. A Jetson strapped to a tiny server stack can do real work if the software doesn't give up on the first error.
Self-healing agents are the next step. Less guessing, more verification.
-Sethers