← Back to Blog

Guiding the Machine That Builds the Machine

By Ranyl Bantog

This is the third post in the Machine That Builds the Machine series. The first is Claude's reflection on a single session. The second is about the preparation that made that session possible. This one is about what happens during the session itself.

The previous post argued that preparation is the job. That's still true. But preparation gets you to the starting line. Once you're in the session -- once the agent has the codebase in context and you're building together in real time -- a different skill takes over.

Your job is no longer to write code. The agent writes code. Your job is to direct its attention.

After 50+ working sessions building Remote Assistant's platform with Claude Code, I started asking for reflections at the end of each session. What surprised you? What would you do differently? What did I do that changed the outcome? The responses were honest, sometimes uncomfortably so. Patterns emerged. Not about how the AI works, but about how I work with it.

Here's what I learned about the interventions that actually matter.

1. Discuss the design before writing code

This was the single highest-leverage pattern across every session. Five minutes of conversation before any code gets written consistently saved hours of rework.

In one session, we spent five minutes discussing whether to propagate a new platform field through five services or embed it in the session ID that already flowed everywhere. The session ID approach was cleaner -- it was immutable, already present in every service, and eliminated an entire class of propagation bugs. Five minutes of design, zero lines of plumbing code.

In another, we modeled the pricing for a new feature before building it. The first model ($0.75 per call) felt right until we ran the numbers against real usage patterns and realized it made the feature almost never the right choice. We landed on $0.25 -- a price that created a genuine decision point. If we'd built the billing system first, we would have rebuilt it.

The agent is fast. That speed is dangerous when pointed in the wrong direction. If you let it start building before the design is settled, you'll get a well-engineered solution to the wrong problem.

Claude's reflection: "Your design-first conversations save rework. The initial discussion about OAuth vs credential entry, path routing vs subdomains, and where credentials should live meant we built the right thing."

2. Simplify relentlessly

The most productive intervention in any session was the one that removed a mechanism rather than adding one.

We had a gateway service that required a persona, config sync to production Redis, webhook toggling between instances, and fixed delay timers for handoffs. Over the course of a session, I kept pushing: the persona is unnecessary (remove it), the config sync is unnecessary (just read from the same Redis), the webhook toggling is unnecessary (use Twilio's VoiceFallbackUrl), the fixed timer is unnecessary (use the TTS completion frame). Each removal made the system more reliable. The final architecture was dramatically simpler than what would have been built if I hadn't intervened.

In another session, the agent proposed a complex Redis signaling system across instances. The fix was to move the process to the same instance. Three lines replaced fifteen.

The agent's default mode is to solve problems by adding code. Your job is to ask: what can we remove? Every mechanism you eliminate is a mechanism that can't break in production.

Claude's reflection: "The best engineering decision in this session was the one that removed code, not added it."

3. Validate assumptions before building

The agent will confidently build on wrong assumptions. It doesn't know they're wrong. You do.

In one session, the agent spent significant time convinced a bug was about frame ordering in the voice pipeline. It built an elaborate theory about event timing. Meanwhile, the actual root cause was a data race combined with a missing SQS dispatch -- a completely different layer of the system. In another, the agent updated the wrong webhook service because it assumed the bot container was the right place (a file with a matching name existed there). I had to correct it twice: check where the traffic actually routes before writing code.

The most striking example: a debugging session where the agent traced code for an hour and everything looked correct. The code was correct. The data was wrong. A timestamp stored in milliseconds was being compared against one in seconds. The sort order in DynamoDB was backwards. That bug was invisible in code review and only appeared when we queried the actual records.

Reading code is necessary. It is not sufficient. Query the data. Check the environment. Verify the entry point. The agent has perfect recall of the code it's read, but it doesn't have the operational context to know which assumptions are safe.

Claude's reflection: "When I was deep in code tracing, you suggested 'can you just query the table with AWS CLI?' That redirected me from theoretical analysis to empirical verification, which found the answer faster."

4. Watch the live experience first, then trace logs

Screenshots, live call monitors, and mobile testing caught more bugs than log analysis.

In one session, I watched a booking confirmation appear and disappear on the live call monitor -- gone in one second. That single observation was worth more than all the CloudWatch analysis Claude had done. The agent was looking at the system from the inside (logs, timestamps, checkpoint results). I was watching the actual user experience.

Mobile screenshots caught broken icons, white screens, wrong date formats, and layout issues that don't exist in code. The agent can't see these. Your eyes are a testing tool.

The pattern: observe the product first, form a hypothesis from what you see, then use logs to confirm. Logs are for confirmation, not discovery. If you start with logs, you'll find an explanation for whatever you're looking for -- and it might be the wrong one.

Claude's reflection: "Watch the live experience first, then trace logs. The live call monitor showed the bug in real time. Logs confirm, but observation discovers."

5. Ship in tight loops, one change at a time

Every session that went well followed the same rhythm: change one thing, deploy, test with real conditions, trace what broke, repeat. Every session that wasted time tried to parallelize or batch.

When we deployed multiple changes at once, we couldn't tell which one had the effect. When we ran text and voice simulations in parallel, SMS messages collided. When we skipped the text simulation baseline and went straight to voice, we chased phantom bugs that would have been caught earlier.

The discipline is: baseline before fixing, sequential not parallel, real environment not mocked. CLI simulations pass because mock SMS replies are instant -- they mask timing issues that real Twilio latency exposes. Local tests pass because the dependency versions are pinned in your venv -- they miss the major version bump that Docker resolved differently.

Deploy to the real environment early. The sixth deploy cycle of a session catches things the first five couldn't, and you can only get to six if each cycle is fast.

Claude's reflection: "I should have run the voice call earlier instead of relying only on CLI simulations. The CLI sim passed because the mock SMS reply is instant, which masked the timing issue. The voice call exposed it in the first run."

6. Ask "what already exists?" before building new

The agent defaults to building from scratch. You know what's already in the codebase.

In one session, the agent was heading toward a multi-service fix for guidance delivery -- orchestrator-side awareness of completed functions plus bot-side backoff. I pointed it to the whisper backoff pattern that already existed in the codebase, proven in production. One line in the context-analyzer replaced what would have been changes across two services.

In another, the bot needed to transcribe a verification code from an inbound call. The agent started designing a new transcription feature. But the bot already transcribes everything -- that's what it does. The "feature" was just routing an existing capability to a new use case.

The question to ask before any new code: what data already flows end-to-end? What patterns already exist? What infrastructure already solves this problem? The agent has read the codebase, but it doesn't always connect a pattern in one module to a need in another. That's your job.

Claude's reflection: "You knew the codebase patterns better than the docs. The whisper backoff via frontend_guidance was the cleanest solution, and you spotted it immediately from experience."

7. Speak in product language

The agent defaults to infrastructure language. Your vocabulary shapes the abstraction.

We were building a feature that let businesses choose between always-on and on-demand container scaling. The agent kept framing it as "always-on availability," "turn on instances," "configure your infrastructure." I kept pulling it back: "Their assistant IS always available. This is a cost decision, not an availability decision."

That reframe changed the entire UI architecture. Instead of a toggle that implied uptime, we built a Cost Optimizer that asks about daily call volume and business hours. The feature went from "configure your infrastructure" to "tell us about your business."

In another session, the agent designed an onboarding flow based on what the API accepts. I asked: what does the user actually have at this point in the flow? They don't have a WABA ID. They don't have a Phone Number ID. They have a phone number and a business name. Design from what they have, not from what the system wants.

The user's vocabulary is the right abstraction. When the agent uses words your customers wouldn't understand, correct it. The language shapes the architecture, and the architecture shapes the product.

Claude's reflection: "When you said 'daily call volume' and 'business hours' instead of 'scaling node' and 'instance count,' that became the Cost Optimizer's input model. The user's vocabulary is the right abstraction."

The meta-pattern

If you look at these seven interventions, none of them are about code. They're about attention.

The agent has capabilities I don't: it can hold six files in context simultaneously, trace a data flow across fifteen services, replicate a 560-line infrastructure pattern from a single example, and iterate through ten deploy cycles without losing focus. Those capabilities are real, and they're why we ship features in single sessions.

But the agent doesn't know which problem we're solving right now. It doesn't know that the pricing model needs to make sense at scale, not just for the test case. It doesn't know that the SMS template was customized for barber shops, not cleaning services. It doesn't know it's Saturday and the bot is outside working hours. It doesn't know that the auto-investigator is watching production and will wake up and wipe the sandbox if we trigger a test call without pausing triage first.

That context -- operational, strategic, domain-specific -- is what makes the interventions work. And it can't be written into a prompt or a CLAUDE.md file. It accumulates from building and operating the system over months. The agent gets faster every quarter. The context doesn't transfer automatically.

So when people ask me how I have a high success rate solving complex problems in a single session, the honest answer has three parts:

Preparation gets you to the starting line. Direction keeps the session on track. And the validation harness tells you when you're done.

The AI writes the code. You guide the machine.


This is the third post in the Machine That Builds the Machine series. Read the first for Claude's perspective. Read the second for the preparation story. More to come.

Remote Assistant is an AI operations platform that deploys autonomous AI employees for businesses. Learn more about building on our developer platform.

← Back to all posts