Why I Split My System Prompt Into 27 Files
System prompts are code. Structure them like it.
Drew Breunig and Srihari Sriraman recently compared the system prompts of six coding agents. They swapped prompts between tools and watched behavior change dramatically — same model, different instructions, different workflow. Their conclusion: “A given model sets the theoretical ceiling of an agent’s performance, but the system prompt determines whether this peak is reached.”
That shouldn’t surprise anyone who’s looked at the numbers. Claude’s chatbot system prompt alone runs ~23,000 tokens — over 11% of the context window consumed before the user says a word.
Most people treat system prompts like documentation. A place to dump preferences, maybe some formatting rules. An afterthought.
If you use AI tools daily and they still feel unreliable, this is probably why. The instructions are an afterthought instead of architecture.
Anthropic treats them like code.
The system prompt defines how Claude searches the web, when it asks for clarification, how it formats artifacts, what it refuses to do. Every behavior you see in the chatbot traces back to those 23,000 tokens of carefully engineered instructions.
If the system prompt is programming, then prompt engineering isn't about clever phrasing — it's about architecture. Enterprise AI teams already build modular prompt systems, but that pattern hasn't made it to individual users yet.
I split my system prompt into 27 files, not because I'm obsessive (okay, maybe a little), but because a monolith doesn't scale.
The Monolith Problem
Put everything in one file. Watch it break.
Context waste. Your monolith loads Python formatting rules while you’re writing TypeScript. It loads database conventions while you’re editing markdown. At 23K tokens, you’re burning 11% of your context window before you’ve asked a question — on instructions that mostly don’t apply to what you’re doing right now.
Relevance dilution. Even the instructions that do apply get weaker. Your critical constraint on line 847 is buried in hundreds of lines of unrelated rules. The model processes everything, but attention is finite. More noise around the signal means the signal hits softer.
No composability. You work across multiple contexts — maybe a day job, side projects, and personal notes. They share some conventions and differ on others. With a monolith, you either duplicate everything into separate files (and watch them drift) or maintain one file with conditional logic that becomes unreadable. Neither scales.
Maintenance risk. Every edit touches everything. You fix a formatting rule and accidentally break the code review instructions. The blast radius of any change is the entire prompt. Version control helps, but doesn’t solve the underlying coupling.
Anthropic can afford a 23K monolith. They control the training loop. When a prompt patch works, they train the behavior into the next model and remove the patch. They’re building a general-purpose chatbot with a 200K context window and resources to optimize around it.
You’re not Anthropic. You need something that scales with your actual workflow.
The Modular Alternative
Split by when it matters, not by topic.
The architecture has three tiers:
rules/
├── core/ # Always loaded (10 files, ~10K tokens)
│ ├── hard-walls.md
│ ├── user-profile.md
│ ├── intent-interpretation.md
│ ├── thinking-partner.md
│ ├── document-traversal.md
│ ├── writing-style.md
│ ├── session-protocol.md
│ ├── work-state.md
│ ├── memory.md
│ └── eval-protocol.md
├── shared/ # Project-wide patterns (9 files)
│ ├── file-management.md
│ ├── project-structure.md
│ ├── prd-conventions.md
│ ├── summarization.md
│ └── ...
├── context-a/ # Loads only for Context A files (3-4 files)
│ ├── context.md
│ ├── collaborators.md
│ └── portfolio.md
└── context-b/ # Loads only for Context B files (3-4 files)
├── context.md
├── collaborators.md
└── portfolio.mdI manage three separate work contexts in one environment, which is why mine reaches 27. A single-context setup needs core plus a few shared files. Maybe eight. The architecture is the same; the scale matches what you actually manage.
Core loads every session. These are the rules that apply regardless of what you’re working on: hard constraints, your proficiency level and preferences, how to interpret requests, writing style, thinking partner behavior, session mechanics, and live memory. About 10K tokens across 10 files. Non-negotiable.
Shared loads for anything in this project. File conventions, structural patterns, tooling preferences. The stuff that applies everywhere in your environment but wouldn’t make sense in a different one.
Context-specific loads only when you’re working with matching files. I work in the music industry and also maintain personal projects and life admin in the same workspace. When I’m editing a product spec, the work rules load — industry terminology, collaborator names, organizational patterns. When I’m in a personal project, those rules swap out and personal context surfaces. Neither pollutes the other.
The mechanism is simple. Each rule file can declare which paths trigger it:
---
paths:
- "work/context-a/**"
---Glob patterns. When Claude reads or edits a file matching that pattern, the rule loads. No match, no load.
The result: ~10K tokens of targeted rules always present, plus only the context-specific rules relevant to current work. Instead of 23K tokens of generic instructions, you get focused context that changes with what you’re actually doing.
Martin Fowler’s team independently describes this pattern as context engineering — path-based rules that load only when files match, limiting both token usage and change-set size. Modularization isn’t just organization, it’s a token budget strategy.
When deciding where a rule belongs, I use a simple filter:
If a rule doesn’t pass any of these gates, it probably doesn’t need to exist.
Hooks: Rules That Can’t Be Ignored
Instructions are suggestions. The model follows them most of the time, but “most of the time” isn’t good enough for constraints that matter.
Some rules in my system aren’t instructions at all. They’re code. Shell scripts that run automatically after every file write or edit, inspecting the result and blocking the operation if it violates a constraint.
Three hooks, three different jobs:
Frontmatter validator checks that every note has a
type:property and that context-linked notes have acontext:wikilink. Violations block the write and return remediation instructions. The model has to fix the file before it can move on.Date validator checks that timestamps in memory and work-state files match the current date. Catches a surprisingly common failure mode: the model inferring today’s date from stale file contents instead of using the system-provided value.
Wikilink checker scans for links pointing to notes that don’t exist. This one warns instead of blocking — orphan links aren’t always wrong (you might be about to create the target note), but they’re worth flagging.
Instructions rely on the model’s compliance. Hooks enforce mechanically. When I add a hard wall to hard-walls.md, I’m asking Claude to follow it. When I add a hook, I’m making it impossible not to. The hooks catch what instructions miss — especially during long sessions when the model starts drifting from its earlier context.
Build a modular rule system without hooks and you’re still relying on the model to police itself.
Scaffolds and Structures
Claude Code’s system prompt doesn’t grow in a straight line. It bounces around with each model release, patches added to smooth over quirks, then removed when the next version handles them natively. In an earlier version comparison, a workaround for the “how many R’s in strawberry” problem appeared in Claude 3.7’s prompt, then vanished in 4.0. The patch worked, so they trained it into the model. Once the model learned the behavior, the scaffold came down.
Your rules should work the same way.
Some rules compensate for current model limitations. Claude sometimes over-explains basics to experts. Claude sometimes forgets constraints from earlier in the conversation. Claude sometimes hallucinates file contents instead of reading them. Sriraman’s follow-up analysis shows just how hard these scaffolds work: one agent prompt repeats the instruction to batch tool calls seven times, in different phrasings, because the model’s training biases resist it. These are scaffolds. Write them, use them, but expect them to become obsolete as models improve.
Other rules encode knowledge the model will never have. Your preferences. Your organizational context. Your collaborators and their communication styles. The acronyms that mean something specific in your domain. These are structures. They’ll stay relevant because they’re about you, not about Claude.
That split changes how you maintain the system. When a new model drops, audit your scaffolds. Some can probably go. Your structures stay. Over time, a well-maintained rule system gets smaller and more focused as scaffolds fall away and structures remain.
Start with two files: hard constraints and user profile. Those two cover the gap between what the model knows generically and what it needs to know about you. Add context folders when the monolith starts fighting you.
This is part of a series on context engineering — building systems that help AI work with your workflows instead of against them. Next week: there’s no one-size-fits-all AI setup. So I built a starter kit you can make your own.


The conditional loading point is what most people miss. I went through a similar evolution with my agent's instruction file - started as one growing http://CLAUDE.md that hit 800+ lines before I realized the problem wasn't length but specificity.
What worked for me was a different split than pure file paths: behavioral rules in the base file (what the agent always needs), domain workflows as skills (loaded on demand), and a self-extending memory layer the agent manages itself.
The base file stayed under 200 lines. Skills handle the rest. Token cost dropped and consistency went up because the agent only loads what's relevant.
Full breakdown after 1000+ sessions of iterating on this: https://thoughts.jock.pl/p/how-i-structure-claude-md-after-1000-sessions
Curious - do your 27 files ever conflict with each other when multiple load at once?