I have been writing about agentic coding and spec-driven development over the past few weeks, and a pattern keeps coming up in the replies and DMs. People try the workflows I describe, get mediocre results, and conclude that the tools are overhyped or that their codebase is somehow incompatible with AI assistance.
Nine times out of ten, the problem is not the prompt. It is the context.
When Andrej Karpathy started talking about “context engineering” and Shopify CEO Tobi Lutke picked up the term, they were naming something that experienced AI tool users had been doing intuitively for months. The realization is simple but has massive implications: the quality of what the model sees matters far more than the quality of how you ask.
Martin Fowler published a deep analysis of context engineering for coding agents. Faros AI built an entire framework around it. The community is treating this as the next evolution of how developers work with AI. And after spending the last month deliberately applying these principles to my own workflow, I think they are right.
Let me walk through what context engineering actually is, why it works, and how to start using it today.
What Context Engineering Means (And What It Does Not)
Prompt engineering is about crafting how you ask. You learn to write clear instructions, use specific language, structure your requests in a way the model responds well to. It is a valuable skill and it is not going away.
Context engineering is a layer above that. It is about designing the entire information ecosystem that the model has access to when it processes your request. Not just your prompt, but everything else: your codebase files, git history, dependency information, team conventions, documentation, tool definitions, and conversation history.
Think of it this way. If prompt engineering is directing a scene in a play, context engineering is building the entire stage, choosing the props, setting the lighting, and casting the actors. The director’s instructions matter, but they only work if the stage is set correctly.
This distinction explains a frustrating experience that many developers have: you write a perfectly clear prompt, the model understands exactly what you want, and it still generates bad code. Not because it misunderstood you, but because it did not have the right context to make good decisions. It wrote code that is technically correct but does not follow your patterns, uses the wrong library version, or ignores constraints it had no way of knowing about.
The prompt was fine. The context was missing.
The Full Context Stack
Faros AI identified eight layers of context that affect how well an AI coding agent performs. Understanding these layers is the first step to improving your results.
1. System prompts and instructions. The baseline instructions that tell the model how to behave. In Claude Code, this is your CLAUDE.md file. In Cursor, it is your rules configuration. Most developers either skip this entirely or write a novel that the model half-ignores.
2. Codebase context. The files, functions, and patterns in your actual project. This is the most powerful form of context because it shows the model what “good” looks like in your specific environment. When the agent reads your existing middleware before writing new middleware, it learns your patterns without you having to describe them.
3. Git history and recent changes. What changed recently, who changed it, and why. This prevents the agent from undoing recent intentional decisions or duplicating work that is already in progress on another branch.
4. Dependencies and libraries. Your package.json, lock files, and imported modules. Without this, the agent might suggest a library you do not use or write code for the wrong version of one you do.
5. Tool definitions. What the agent can actually do. Can it run tests? Read files? Execute shell commands? The available tools shape what strategies the agent considers.
6. Team standards and patterns. Coding conventions, architectural decisions, naming patterns, testing requirements. The stuff that makes code feel like it belongs in your project versus feeling like it was written by an outsider.
7. Conversation history. What you have already discussed in the current session. This degrades over time in long sessions and is a major source of inconsistency.
8. Retrieved documentation. API docs, architecture decision records, design documents. External knowledge that the model cannot infer from the code alone.
Most developers only think about layers one and two. The developers getting genuinely good results from AI agents are managing all eight.
The Five Core Strategies
The research converges on five strategies for managing context effectively. I have been using all five and the difference in output quality is noticeable.
Context Selection
Not everything is relevant. For an authentication task, the agent needs your auth middleware, user model, and session configuration. It does not need your email templates or payment processing code. Feeding it everything is tempting because it feels thorough, but it actually hurts performance.
The “lost-in-the-middle” phenomenon is well documented: model accuracy drops significantly when the relevant information is buried in the middle of a large context window. More context is not always better context. Relevant context is better context.
In practice, this means being deliberate about which files you point the agent to. Instead of letting it search your entire codebase, tell it where to look. “Read src/middleware/auth.ts and src/models/user.ts before implementing this” gives better results than “figure out how auth works in this project.”
Context Compression
When context gets too large, summarize instead of truncate. The agent does not need the full implementation history of your auth system. It needs the key decisions: “We use JWT tokens with 15-minute expiry, refresh tokens stored in httpOnly cookies, and middleware validates on every request.”
That single sentence gives the agent more useful context than reading through 500 lines of auth code and trying to infer the design decisions.
I keep a section in my CLAUDE.md that summarizes architectural decisions in this compressed format. Not the full rationale, just the decision and the constraint. It is one of the highest-leverage things I have done for AI-assisted development.
Context Ordering
Where you put information in the context matters. Models have a recency bias, meaning they pay more attention to what appears last. They also have a primacy effect, paying attention to what appears first. The middle gets less attention.
The practical recommendation from the research is:
- Put critical rules and constraints at the beginning (they get respected because of primacy)
- Put the current task and immediate context at the end (leveraged by recency bias)
- Put reference material and examples in the middle (available if needed but not dominant)
Production teams that moved their coding standards to the beginning of the context reported 35 to 40 percent reductions in code style violations. Same rules, same model, just better placement.
Context Isolation
Instead of giving one agent a massive context with everything, split complex tasks across specialized agents with focused contexts. Each agent sees exactly what it needs and nothing else.
This is why spec-driven development works as well as it does. Breaking work into discrete tasks with clear boundaries is not just organizational. It is a context engineering strategy. Each task carries only the context it needs, which keeps the agent focused and reduces the chance of irrelevant information interfering with the output.
In Claude Code, subagents serve this purpose. You can spawn a focused agent for a specific subtask with a curated context, get the result, and bring it back to the main session. The main session stays clean.
Format Optimization
How you structure information affects both token efficiency and comprehension quality.
The research findings here are practical:
- YAML and XML are more token-efficient than JSON for configuration data
- Markdown with clear headers helps the model navigate structured documents
- Code blocks with language tags enable syntax-aware parsing
- Tables work better than prose for comparisons and structured data
This sounds like a small detail, but when your context window is a finite resource, format efficiency compounds. A CLAUDE.md written in clear markdown with headers is functionally better than the same information written as a wall of prose. Not because it contains different information, but because the model can parse and navigate it more effectively.
How I Set Up Context Engineering in Practice
Let me get specific about what this looks like in my day-to-day workflow with Claude Code, because abstract strategies only matter if you can apply them.
CLAUDE.md: Less Is More
My CLAUDE.md file is under 200 lines. I have seen developers write 800-line instruction files and wonder why the agent ignores half of it. The research is clear: if your instructions are too long, important rules get lost in the noise.
Here is what I include:
- Build and test commands (the agent needs to know how to verify its own work)
- Architectural decisions in compressed format (what we use and why, in one sentence each)
- Three to five non-obvious conventions that the agent cannot infer from reading the code
- File references pointing to examples of patterns to follow
Here is what I do not include:
- Code style guidelines (that is a linter’s job, not an LLM’s job)
- Obvious conventions the agent can learn from reading existing code
- Long explanations or rationale (the agent needs the rule, not the story behind it)
The insight from the community that changed my approach: never send an LLM to do a linter’s job. LLMs are slow and expensive compared to ESLint or Prettier. If a convention can be enforced by a tool, enforce it with that tool and leave it out of your context.
Rules Files for Scoped Context
Beyond the global CLAUDE.md, I use scoped rules that only load when relevant. For example, a rule file that only activates when the agent is working on TypeScript files, or a rule that only applies in the test directory.
This is context isolation applied at the configuration level. The agent working on a React component does not need to see my database migration conventions. The agent writing tests does not need to see my deployment configuration. Scoping rules to relevant contexts keeps each interaction focused.
The Kitchen Sink Anti-Pattern
One pattern I had to break was the “kitchen sink session.” You start with one task, then ask something unrelated, then go back to the first task. By the end, your conversation context is a mess of unrelated information, and the agent starts making connections between things that have nothing to do with each other.
The fix is simple: use /clear between unrelated tasks. Every new task gets a fresh context with only the relevant information. It feels wasteful, like you are “throwing away” the conversation, but the quality improvement is immediate and significant.
Context Engineering for Different Task Types
Not every task needs the same context strategy. Here is how I think about it:
Bug Fixes
Context needed: the error, the file where it occurs, recent git changes to that file, and the test that should catch it. Context not needed: your entire codebase architecture. Keep it tight. Point the agent to exactly what is broken and let it focus.
New Features
Context needed: the spec (if you have one), examples of similar existing features in the codebase, architectural constraints, and the files that will need to change. This is where the full context stack matters most, because the agent needs enough information to make decisions that are consistent with the rest of your system.
Refactors
Context needed: the files being refactored, the pattern you are moving toward, and the test suite that validates nothing breaks. Context not needed: why you are refactoring. The agent does not care about your tech debt motivations. It cares about the target pattern and the verification criteria.
Code Reviews
This is an underappreciated use case for context engineering. When you ask an agent to review code, the context should include your team’s quality standards, common anti-patterns you have seen, and examples of what good code looks like in your project. Without this context, the agent gives generic review feedback. With it, the feedback is specific to your codebase.
The Measurable Difference
I tracked my own results over four weeks: two weeks using my normal workflow and two weeks deliberately applying context engineering principles.
The difference was not in speed. I did not ship features significantly faster. The difference was in rework. The amount of time I spent correcting, adjusting, or redoing AI-generated code dropped noticeably. First-pass acceptance rate went up. The number of times I had to say “no, not like that, look at how we do it in the existing code” went way down.
That matches what the research predicts. Context engineering does not make the model smarter. It makes the model better informed. A well-informed model makes fewer wrong assumptions, which means less time spent on corrections.
For a solo developer or a small team, the compounding effect of fewer corrections per AI interaction is significant. It is the difference between AI feeling like a productive collaborator and AI feeling like a junior developer who never reads the existing code before writing new code.
Common Mistakes I See Developers Making
After talking about this topic with dozens of developers in communities and on X, a few patterns keep coming up.
Treating context like a dump truck. More is not better. Dumping your entire codebase into the context window because “the model should figure out what is relevant” does not work. You are the architect. Curate what the model sees.
Ignoring context window management. Long sessions degrade. The model’s effective attention on earlier parts of the conversation diminishes as the context fills up. If your session is getting long and the output quality is dropping, that is not a model limitation. That is a context management problem. Clear the session and start fresh with focused context.
Writing CLAUDE.md once and never updating it. Your project evolves. Your conventions change. Your architectural decisions shift. If your context files do not keep up, you are giving the model outdated instructions that conflict with the current codebase. The model will not know which one to trust.
Not using isolation for complex tasks. Trying to do everything in one session is the context engineering equivalent of putting your entire application in one file. Break complex work into focused tasks with curated contexts. The setup cost is minimal and the quality improvement is real.
Where This Is Going
Context engineering is still early. The tooling is improving fast. Claude Code added rules files, skills, hooks, and MCP servers specifically to give developers more control over context. Cursor’s rules system serves a similar purpose. GitHub Copilot is moving in this direction too.
I think within a year, the term “context engineering” will feel as natural as “version control” or “CI/CD.” It will be something every professional developer understands and practices, not because it is trendy, but because the quality gap between engineered context and ad-hoc prompting is too large to ignore.
The developers who start building this skill now, who invest in their CLAUDE.md files, who set up scoped rules, who think carefully about what their AI agents see before they see it, those developers are going to consistently outperform developers who just type prompts and hope for the best.
The model is not the bottleneck anymore. The context is. And unlike the model, context is something you control entirely.
That is a powerful position to be in.