Why I Stopped Asking My LLM for Code and Started Asking for Context
Adil Sher
Author
I was debugging a checkout race condition at 2 AM last month when I realized something was deeply wrong with how I'd been using AI. I'd spent three hours feeding Claude increasingly frantic prompts-"Fix the race condition," "No, that's still broken," "Why isn't this working?"-and getting increasingly worse responses. I was treating the AI like a code vending machine that had broken, not understanding that I'd never actually set it up to succeed in the first place. I hadn't given it the context. I hadn't established what we were actually trying to do. I just demanded the output.
This is what the original article calls "vibe coding," and I'd been doing it wrong the entire time.
The Three-Level Problem I Kept Missing
The framework that clicked for me is deceptively simple: Context → Process → Output. Most developers (including me) skip straight to demanding output. We ask for the feature, the fix, the implementation, all the Having without any of the Being.
When you do this, the LLM doesn't fail because it's stupid. It fails because it's literally hallucinating in a void. It has no anchor for what "correct" even means. A race condition fix in a legacy monolith looks completely different from a fix in a distributed system. A checkout flow that works for a subscription model breaks for one-time purchases. These aren't subtle differences, they're foundational contextual choices that determine everything downstream.
The article uses a river metaphor that stuck with me: if the code output (Having) is at the bottom of the river, and you try to fix bugs by arguing with the output in chat, you're standing downstream with a bucket trying to clean the water. You need to move upstream to the source, the context and process.
What I Changed: The Pre-Code Setup
Here's what I do differently now:
Before touching code, I establish context. I write out: What system am I working in? What are the constraints? What has already been tried and why did it fail? What are the actual failure modes I'm worried about, not the symptoms, but the root boundaries of the problem space?
For that checkout race condition, this meant: "We're using Stripe + PostgreSQL. We have 50k concurrent users during sales. The issue is double-charging on simultaneous payment submissions. Previous attempts with optimistic locking failed because of transaction rollback cascades." That's not fluff. That's the entire difference between a good solution and a bad one.
Then I establish process. What's the verification loop? How will I know if this is actually fixed? What tests exist already? What's the rollback plan? This forces me to think like I'm pairing with someone who needs explicit instructions, not just code.
Only then do I ask for code. And here's the thing, at that point, the output is almost boring. It's just the mechanical working-out of a problem I've already defined upstream.
My Take: This Changes Everything About AI Tooling
I think most developers are using LLMs at maybe 20% of their actual capability because we're treating them like autocomplete for production code, not like thinking partners for problem decomposition.
The article goes deep on this with attention mechanisms and Makefiles and Smalltalk, which felt overly abstract to me at first. But the core insight is solid: you can't skip the context phase and fix it later by arguing with outputs. The architecture of how you use the tool has to match the structure of what you're trying to accomplish.
What I'd add from my own experience: this is actually about respecting your own thinking process, not just the AI's. When I force myself to write out context before asking for code, I catch my own fuzzy thinking. Half the time, I realize I don't actually understand the problem well enough to ask for a solution. That's valuable. That's what senior development is.
What I still disagree with: the article leans heavily on complex theoretical frameworks (4-Vector Scars, Makefiles as DAGs, references to obscure monographs). I get what it's trying to do, but in my work, simpler structure works better. A markdown file with constraints, a list of what we've tried, and a clear success criterion beats elaborate process scaffolding.
The Question This Raises for Me
If context really is the bottleneck, then the actual skill in using AI isn't prompt engineering, it's problem framing. That's a different skill entirely. It means the developers who get the most from LLMs won't be the ones who memorize prompt tricks. They'll be the ones who already think clearly about their systems.
So here's what I'm testing: can I make context-setting so mechanical that it's boring? A template, a checklist, the same structure every time? I suspect that's the real productivity gain.
Source: This post was inspired by "Being, Doing, Having: Why 50 Years of Senior Craft Lives in Context, Not Code" by Dev.to. Read the original article