AI

Stop Blaming Claude. Your Context Window is the Problem.

Why your AI coding results degrade over time, and how orthogonal context architecture with CLAUDE.md files and custom agents dramatically improves performance.

Chris (Founder)
12 min read

TL;DR: This article shows you how to structure your AI coding context for dramatically better results. If you want to skip ahead: Jump to the audit prompts you can use right now to fix your own setup—no consultants needed.

Every week, I see developers complain that Claude is getting worse.

“Opus has been nerfed.”

“It’s not as good as it was.”

“Anthropic is throttling the model.”

They’re wrong.

I’ve been using Claude Code daily to build CloudRepo, and other projects, for about six months now.

Our results improve every single day.

Not because Anthropic secretly gives me a better, or ‘unnerfed’, model, but because I’ve learned to manage what goes into Claude’s context window.

If you think the models are degrading, or that Anthropic is somehow ‘nerfing’ Opus, you’re almost certainly doing something wrong.

It’s fixable.

A note on scope

While I’m using Claude Code as my primary example, these principles apply to any LLM-based coding tool.

Context pollution is a universal problem—whether you’re using Cursor, Copilot, Aider, or any tool that merges instructions into prompts.

The industry is converging on patterns like agents.md for exactly this reason. Claude Code happens to have excellent built-in mechanisms for managing context (which is one reason I use it), but the underlying lesson—stop polluting your context—applies everywhere.

How Claude Code Actually Works

When you run Claude Code, it doesn’t just receive your prompt. It loads a substantial amount of context before your message ever reaches the model:

  1. System instructions - Claude Code’s base capabilities and rules
  2. CLAUDE.md files - Your project-specific instructions, loaded hierarchically
  3. Custom agent definitions - If you’re using specialized agents
  4. Skill prompts - If you’ve invoked a slash command
  5. Recent conversation history - Previous messages in the session
  6. File contents - Any files Claude has read during the session

All of this context competes for the model’s attention. When you send “fix this bug,” Claude must process your request alongside everything else in its context window.

Diluted context produces diluted results.

Context attention comparison (click to enlarge)

When your context is 80% irrelevant to the current task, Claude’s attention is distributed across information it doesn’t need.

The relevant 20% gets proportionally less focus.

Your results suffer accordingly.

The Monolithic CLAUDE.md Anti-Pattern

Most developers start their Claude Code journey by creating a single CLAUDE.md file at their project root. It begins reasonably:

# My Project
We use React for the frontend and Go for the backend.

Over time, this file grows. Someone adds TypeScript conventions. Someone else adds Go formatting rules. Database patterns get documented. Deployment instructions appear. Testing conventions accumulate.

Six months later, your CLAUDE.md looks like this:

# My Project
## Frontend (React)
- Use functional components with hooks
- Prefer Tailwind CSS over styled-components
- State management with Zustand
- Testing with Vitest
[... 50 more lines of React conventions ...]
## Backend (Go)
- Use standard library where possible
- Error handling patterns: wrap with fmt.Errorf
- Database access through sqlc
[... 50 more lines of Go conventions ...]
## Infrastructure (Terraform)
- Use modules for reusable components
- State stored in S3 with DynamoDB locking
- Naming convention: environment-service-resource
[... 50 more lines of Terraform patterns ...]
## Database (PostgreSQL)
- Migrations managed with golang-migrate
- Always use transactions for multi-statement operations
[... 50 more lines of database conventions ...]
## CI/CD (GitHub Actions)
- Lint on every PR
- Deploy to staging on merge to main
[... 50 more lines of CI/CD details ...]

This file has become a “jack of all trades, master of none.”

When you’re working on a React component, Claude loads 400 lines of context, but only 50 are relevant.

The Go conventions, Terraform patterns, database rules, and CI/CD details all compete for attention—despite being completely irrelevant to your current task.

Anti-pattern comparison (click to enlarge)

This is why your results degrade over time.

As your CLAUDE.md grows, your context becomes increasingly polluted.

It’s not that Claude is getting worse. It’s that you’re giving Claude progressively worse context.

The Orthogonal Architecture Pattern

The solution is to structure your context files so only relevant information loads for any given task.

I call this orthogonal context architecture.

Claude Code automatically loads CLAUDE.md files hierarchically based on which directories it visits during a task.

If you’re working in frontend/src/components/, Claude loads:

  1. Root CLAUDE.md (project-level context)
  2. frontend/CLAUDE.md (frontend-specific context)
  3. frontend/src/CLAUDE.md (if it exists)
  4. And so on down the tree

By placing domain-specific instructions in the appropriate directory’s CLAUDE.md, you ensure they only load when relevant.

my-project/
├── CLAUDE.md # Project-level only
│ └── Company context, team structure, general conventions
├── frontend/
│ └── CLAUDE.md # Frontend-specific
│ └── React patterns, Tailwind usage, component conventions
├── backend/
│ └── CLAUDE.md # Backend-specific
│ └── Go patterns, API conventions, error handling
├── infrastructure/
│ └── CLAUDE.md # Infrastructure-specific
│ └── Terraform patterns, AWS conventions, deployment
└── database/
└── CLAUDE.md # Database-specific
└── Schema conventions, migration patterns, query optimization
Hierarchical context loading (click to enlarge)

Now when Claude works on a frontend task, it loads only project context + frontend context. The backend, infrastructure, and database instructions stay out of the context window entirely.

Result: Higher signal-to-noise ratio. Better responses.

What Goes in Root vs. Component CLAUDE.md Files

Root CLAUDE.md should contain only:

  • Company/project identity and purpose
  • Team structure and agent responsibilities
  • High-level architecture overview (which components exist, their relationships)
  • Cross-cutting conventions that truly apply everywhere
  • Pointers to component-specific documentation

Component CLAUDE.md should contain:

  • Technology-specific patterns and conventions
  • Domain-specific terminology and rules
  • Testing approaches for that component
  • Common gotchas and warnings
  • Agent ownership declaration

If an instruction only applies to one domain, it belongs in that domain’s CLAUDE.md, not root.

Custom Agents: Domain Specialists

Beyond CLAUDE.md files, Claude Code supports custom agents—specialized assistants with focused expertise. Each agent has its own system prompt that loads only when that agent is invoked.

At CloudRepo, we’ve defined 12 agents across three departments:

DepartmentAgentResponsibility
Engineeringstaff-clojure-engineerBackend API development (Clojure)
Engineeringstaff-angular-engineerAdmin portal (Angular 21)
Engineeringstaff-terraform-engineerInfrastructure and DevOps
Engineeringstaff-api-testerAPI testing with Postman/Newman
GTMstaff-astro-engineerMarketing website (Astro 5)
GTMstaff-content-strategistContent creation
GTMstaff-technical-writerUser documentation
Productstaff-product-managerProduct strategy
Productstaff-software-architectSystem architecture
Agent responsibility matrix (click to enlarge)

Each agent owns exactly one domain—non-overlapping responsibilities.

The Clojure engineer never touches Angular code.

The Angular engineer never touches infrastructure.

When the orchestrator (me or Claude Code’s main agent) routes a task to the Clojure engineer, only Clojure-relevant context loads.

Compare this to having a single “developer” agent that knows everything about your stack. That agent’s prompt would be huge, and most of it would be irrelevant to any given task.

Stop polluting your context.

Agent Definition Example

A simplified agent definition:

You are the staff-clojure-engineer for CloudRepo.
## Your Responsibilities
- Backend API development in apps/api/ and apps/apex/
- Ring/Jetty 12 web services
- DynamoDB data access patterns
## You Do NOT Handle
- Frontend code (Angular or Astro)
- Infrastructure (Terraform)
- CI/CD pipelines
## Clojure Conventions at CloudRepo
- Namespace pattern: io.cloudrepo.\*
- Use KV protocol for database access
- Hot reload via REPL: (reset) function

There’s no mention of Angular, Terraform, or frontend patterns. This agent’s context is laser-focused on Clojure backend development.

Custom Skills: On-Demand Context

Skills (slash commands) provide another layer of context optimization. Unlike CLAUDE.md files that load based on directory location, skills load only when explicitly invoked.

This is perfect for workflows that are:

  • Used occasionally, not constantly
  • Highly specific in their instructions
  • Complex enough to benefit from detailed guidance

At CloudRepo, we have 27 custom skills:

SkillPurposeWhen It Loads
/admin:validateFull validation suiteOnly when validating admin code
/admin:modernize-viewApply design system to legacy componentsOnly when modernizing
/postman:iterateTest-fix-retry loop with trace diagnosisOnly when debugging API tests
/gtm-sprintContent planning workflowOnly during GTM sprints

Skills act as temporary context injection.

When you invoke /postman:iterate, a detailed workflow loads that explains exactly how to run tests, diagnose failures with trace IDs, fix code, hot-reload, and retry.

This is 50+ lines of highly specific instructions that would be noise in most contexts but are essential for that particular workflow.

After the skill completes, that context doesn’t persist. Your next task starts with a clean context window again.

Skill invocation flow (click to enlarge)

CloudRepo Case Study: Real Numbers

Here’s how this works at CloudRepo.

Context Architecture

LevelFilesPurpose
Root1Company identity, team structure, architecture overview
Apps5Component-specific patterns (api, apex, web, admin + shared)
Infrastructure4Terraform patterns per environment
Tools3Supporting utilities
Total13 CLAUDE.md files

Agent Coverage

DepartmentAgentsDomains Covered
Engineering5Clojure, Angular, Terraform, API Testing, Architecture
GTM5Astro, Content, Docs, Sales, GTM Strategy
Product2Product Management, Architecture
Total12 agents

Skills by Component

ComponentSkillsExample
Admin17/admin:knip, /admin:lint, /admin:modernize-view
Postman3/postman:test, /postman:iterate, /postman:debug
API3/api:start, /api:stop, /api:status
GTM2/gtm-sprint, /gtm:distribute
Other3/dev:start, /context:audit, /create-command
Total28 skills

The Result

When working on an Angular admin task, Claude loads:

  • Root CLAUDE.md (~150 lines)
  • Admin CLAUDE.md (~400 lines)
  • Angular engineer agent prompt (~100 lines)
  • Any invoked skill prompt (variable)

What Claude does NOT load:

  • Clojure backend conventions
  • Terraform infrastructure patterns
  • Astro marketing site patterns
  • API testing workflows
  • 10 other agent definitions

Approximately 15% of our total documented context loads for any given task. The other 85% stays out of the context window, ensuring high signal-to-noise ratio.

Context efficiency breakdown (click to enlarge)

A Real Improvement We Made This Week

While writing this article, we audited our own context architecture and found orthogonality issues:

Problem 1: Our root CLAUDE.md contained a table of 9 admin-specific slash commands.

This meant every task—including Clojure backend work and Terraform infrastructure—loaded admin portal tooling into context.

Solution: Moved the slash commands table to apps/admin/CLAUDE.md. Root now has a generic pointer:

“Each component defines its own slash commands. Run /help to see available commands.”

Problem 2: The same 15-line “agent iteration loop” workflow was duplicated in both apps/api/CLAUDE.md and postman/CLAUDE.md.

Solution: Kept the canonical version in postman (which owns testing), replaced the api version with a reference and API-specific commands only.

Small improvements, but they reduce context pollution across every task in those domains.

Auditing Your Own Codebase

Use this prompt to analyze your own CLAUDE.md (or whatever your tool uses):

Analyze my CLAUDE.md file for orthogonality issues:
1. List every distinct domain/concern mentioned
(frontend, backend, infrastructure, testing, etc.)
2. For each concern, identify which lines contain
instructions specific to that domain
3. Flag any lines that mix multiple domains
in a single instruction
4. Suggest how to split this into separate CLAUDE.md
files based on my directory structure:
[paste your directory structure here]
5. Identify any instructions that should become
custom agents or skills instead
Be specific with line numbers and provide
before/after examples for the split.

After running this audit, look for these red flags:

  • Domain mixing: Instructions that mention multiple technologies in one section
  • Universal rules that aren’t universal: Conventions that actually only apply to one area
  • Duplicated content: Same instructions appearing in multiple places
  • Workflow instructions: Step-by-step processes that should be skills, not static documentation

Starting Fresh: Templates for New Projects

For new projects:

Root CLAUDE.md Template

# [Project Name]
[One paragraph describing what this project does]
## Architecture
| Component | Location | Stack | Purpose |
| --------- | -------- | ------ | --------- |
| [name] | [path] | [tech] | [purpose] |
## Team
[List agents and their responsibilities if using custom agents]
## Conventions
[Only truly universal conventions that apply to ALL code]

Component CLAUDE.md Template

# [Component Name]
[One paragraph describing this component's purpose]
## Agent Coordination
This directory is owned by the [agent-name] agent.
## Technology Stack
- [List specific technologies for this component]
## Conventions
[Domain-specific conventions]
## Testing
[How to test code in this component]
## Common Commands
[Component-specific commands]

Progressive Complexity

Don’t over-engineer from day one. Start with:

  1. Single CLAUDE.md - Until you notice domain mixing
  2. Split by major boundary - When frontend/backend conventions conflict
  3. Add agents - When you find yourself context-switching between specializations
  4. Add skills - When you have repeatable workflows that need detailed instructions

Let the architecture emerge from actual pain points, not theoretical purity.

Measuring Success

Apply these patterns and you’ll see improvement in several ways:

Qualitative:

  • Claude’s responses are more consistently on-target
  • Fewer “wrong framework” mistakes (React patterns in Angular code, etc.)
  • Claude remembers and applies domain conventions correctly
  • Less time correcting or re-prompting

Quantitative:

  • Track re-prompt frequency for the same task
  • Note when Claude applies patterns from the wrong domain
  • Count “hallucinated” imports or APIs that don’t exist in your stack

If you’re seeing improvement in these metrics after restructuring your context, you’re on the right track.

The ultimate test: You stop experiencing the “Opus is getting worse” frustration that fills Reddit threads.

When your context is clean, the model performs consistently.

You spend less time complaining and more time shipping.

Stop polluting your context.

Conclusion: The Model Isn’t the Problem

Claude Code gets better every day—not because Anthropic is shipping improvements (though they are), but because I’m getting better at managing what goes into the context window.

The developers complaining about model degradation are often the same ones with 500-line monolithic CLAUDE.md files mixing frontend, backend, infrastructure, and deployment instructions into one context-polluting blob.

The fix isn’t to complain on Twitter or Reddit. The fix is to:

  1. Audit your current context architecture
  2. Split monolithic files into domain-specific files
  3. Define custom agents with non-overlapping responsibilities
  4. Create skills for complex, occasional workflows
  5. Measure the improvement in response quality

Your AI coding results are a function of the context you provide. Give Claude focused, relevant context, and you’ll get focused, relevant responses.

Stop polluting your context. Fix your context window.


Let’s Connect

Found this useful? Have questions? I’d love to hear from you.

Reach out:

I’m happy to have conversations about AI-augmented development, context architecture, or how you’re applying these patterns in your own work.

Need more structured help? I occasionally take on “hands off keyboard” AI consulting engagements for teams who want dedicated time applying these patterns to their codebases. Not the purpose of this article—just mentioning it’s possible if you need it.


At CloudRepo, we use Claude Code to build our entire product—from Clojure backend to Angular admin portal to Astro marketing site to Terraform infrastructure. The patterns in this article are extracted from real production workflows. If you’re curious about the artifact repository we built this way, check out CloudRepo.

Ready to save 90% on your repository hosting?

Join thousands of teams who've switched to CloudRepo for better pricing and features.