Last Week
The home screen implementation is complete with responsive design supporting everything from portrait phones to landscape tablets. Dark mode works beautifully – a telltale sign of an app “written with love.” All UI work was done in isolation with mock data, keeping the presentation layer pure until the backend integration is ready.
The Context Window Crisis
Working with Claude Code revealed a fundamental limitation of AI-assisted development: the 128,000 token context window. Every piece of research, every line of generated code, every test output – it all accumulates in the context until the system hits 80% capacity and demands compaction.
Context compaction is lossy compression for AI memory. The system attempts to summarize and retain what it thinks will be needed, but critical details about syntax, best practices, and architectural decisions often get lost. The result? Significant quality degradation and the dreaded “You’re absolutely right” responses when correcting mistakes the AI wouldn’t have made with full context.
What does it mean in English?
Imagine working with a brilliant assistant who can only remember about 100 pages of information at once. When their notebook fills up, they have to summarize everything into 20 pages before continuing. Important details get lost in the summary, and suddenly they’re making mistakes they wouldn’t have made before. Subagents solve this by giving you multiple assistants, each with their own fresh 100-page notebook, specialized for specific tasks.
Nerdy Details
Understanding the Context Window Problem
The Claude Opus model provides 128,000 tokens (roughly equivalent to words, though not exactly). Here’s how quickly that fills up:
// Single feature implementation might include:
// 1. Research phase (10,000-20,000 tokens)
- Library documentation pages
- Stack Overflow solutions
- Best practice guides
// 2. Implementation phase (15,000-30,000 tokens)
- Generated view model (2,000 tokens)
- Generated UI components (5,000 tokens)
- Generated tests (8,000 tokens)
- Repository layer updates (3,000 tokens)
// 3. Debugging phase (40,000+ tokens easily)
- Test output logs (10,000+ tokens per run)
- Stack traces (2,000 tokens each)
- Gradle build outputs (5,000+ tokens)
// Total: Already approaching 80,000-100,000 tokens
Claude Code enforces a hard stop at ~102,400 tokens (80% of 128K) to leave room for responses:
# Simplified context management logic
class ContextManager:
MAX_TOKENS = 128000
SAFETY_THRESHOLD = 0.8
def check_context(self, current_tokens: int) -> bool:
if current_tokens >= self.MAX_TOKENS * self.SAFETY_THRESHOLD:
raise ContextWindowExceeded(
f"Context at {current_tokens} tokens. "
f"Compaction required before continuing."
)
return True
The Compaction Problem Illustrated
When compaction occurs, the AI attempts intelligent summarization:
// Original context (before compaction):
"""
Research findings:
- Voyager navigation library uses Screen interface
- Each screen must override Content() composable
- Navigation state managed via LocalNavigator
- Important: Always use remember {} for navigation operations
- Testing requires MockNavigator with specific setup
- Dark mode requires MaterialTheme wrapper with custom colors
Implementation details:
- HomeScreen implements responsive grid layout
- LazyVerticalGrid for tablet, LazyColumn for phone
- WindowSizeClass determines layout strategy
- Dark mode colors: primary=#BB86FC, surface=#121212
- Animation specs: tween(300) for all transitions
"""
// After lossy compaction:
"""
Summary: Implemented home screen with Voyager navigation.
Used responsive layouts and dark mode support.
Some testing considerations noted.
"""
Critical implementation details vanish, leading to:
- Incorrect API usage
- Lost architectural decisions
- Forgotten test requirements
- Missing animation specifications
Enter Subagents: Fresh Context Windows On Demand
Subagents fundamentally change the game by providing isolated, specialized context windows:
// Master agent configuration
class MasterAgent(
private val contextWindow: ContextWindow = ContextWindow(128000)
) {
fun delegateToSubagent(task: Task): Result {
// Each subagent gets a FRESH 128K context window
val subagent = SubagentFactory.create(
type = task.type,
contextWindow = ContextWindow(128000), // New window!
claudeMdFile = getSpecializedInstructions(task.type)
)
return subagent.execute(task)
}
}
The Seven Subagents Architecture
Based on practical experience, here’s a battle-tested subagent organization:
# .claude/subagents.yaml
subagents:
ui_designer:
description: "Handles all UI/UX implementation"
context_preserved:
- Material Design guidelines
- Responsive design patterns
- Dark mode specifications
- Animation timing functions
trigger_phrases:
- "implement screen"
- "create component"
- "responsive layout"
test_enforcer:
description: "Writes and debugs tests"
context_preserved:
- Test framework setup
- Mocking strategies
- Coverage requirements (95% domain)
- Common test patterns
trigger_phrases:
- "write tests"
- "debug test failure"
- "coverage report"
debugger:
description: "Analyzes logs and stack traces"
context_preserved:
- Error patterns database
- Common Kotlin/Gradle issues
- Debugging strategies
trigger_phrases:
- "analyze error"
- "debug issue"
- "stack trace"
git_operator:
description: "Handles version control"
context_preserved:
- Commit message conventions
- Branch strategy
- PR templates
trigger_phrases:
- "commit changes"
- "create PR"
- "merge conflict"
architect:
description: "Ensures clean architecture"
context_preserved:
- Layer boundaries
- Dependency rules
- Design patterns
trigger_phrases:
- "architecture review"
- "refactor for clean"
- "dependency injection"
researcher:
description: "Library research and documentation"
context_preserved:
- Project dependencies
- Version compatibility matrix
- API documentation links
trigger_phrases:
- "research library"
- "find solution"
- "best practice"
performance_optimizer:
description: "Performance and optimization"
context_preserved:
- Baseline metrics
- Optimization techniques
- Profiling results
trigger_phrases:
- "optimize performance"
- "reduce memory"
- "improve speed"
Subagent Claude.md Files
Each subagent has specialized instructions:
# .claude/ui_designer_claude.md
You are a specialized UI implementation agent for a Kotlin Multiplatform app.
## Core Responsibilities
- Implement responsive layouts using WindowSizeClass
- Ensure dark mode compatibility
- Follow Material Design 3 guidelines
- Maintain 60fps animations
## Critical Rules
1. ALWAYS use LazyColumn/LazyGrid for lists
2. NEVER hardcode dimensions - use dp/sp appropriately
3. ALWAYS test on phone portrait, phone landscape, tablet
4. Dark mode colors must meet WCAG AA contrast ratios
## Layout Breakpoints
```kotlin
when (windowSizeClass.widthSizeClass) {
WindowWidthSizeClass.Compact -> // Phone portrait
WindowWidthSizeClass.Medium -> // Phone landscape/small tablet
WindowWidthSizeClass.Expanded -> // Tablet/desktop
}
Animation Standards
- Enter/Exit: 300ms tween
- Shared element: 400ms spring
- Loading states: 200ms fade
**Real-World Context Preservation Example**
Without subagents (single context):
```kotlin
// Early in conversation
"Implement home screen with responsive grid"
// AI reads Material Design docs, Grid layout guides (15K tokens)
// Generates implementation (5K tokens)
// Later, after more features...
"Add dark mode support"
// Context nearly full, must compact
// Material Design docs summarized to "use dark colors"
// Results in: backgroundColor = Color.Black // Wrong!
// Should have been:
backgroundColor = MaterialTheme.colorScheme.background // Correct
With subagents:
// Master agent
"Implement home screen with responsive grid"
// Delegates to ui_designer subagent
// ui_designer subagent (fresh context)
// Reads Material Design docs fully
// Implements correctly
// Later...
"Add dark mode support"
// Delegates to ui_designer subagent again
// ui_designer subagent (fresh context again!)
// Has full Material Design guidelines
// Implements correctly with proper theme colors
Measuring Subagent Effectiveness
// Metrics before subagents
data class DevelopmentMetrics(
val contextCompactionsPerFeature: Float = 2.3f,
val errorsAfterCompaction: Int = 5,
val "you're absolutely right" responses: Int = 8,
val manualFixesRequired: Int = 12,
val timePerFeature: Duration = 4.hours
)
// Metrics after subagents
data class ImprovedMetrics(
val contextCompactionsPerFeature: Float = 0.0f, // None!
val errorsAfterCompaction: Int = 0,
val "you're absolutely right" responses: Int = 1,
val manualFixesRequired: Int = 2,
val timePerFeature: Duration = 2.5.hours
)
Practical Subagent Invocation Patterns
# Explicit subagent summoning
"Use the test_enforcer agent to write comprehensive tests for HomeViewModel"
# Implicit delegation (master agent decides)
"Debug why the tests are failing with NullPointerException"
# Master recognizes this needs debugger subagent
# Multi-agent workflow
"Implement the dashboard screen with tests and commit the changes"
# Master orchestrates:
# 1. ui_designer -> implements screen
# 2. test_enforcer -> writes tests
# 3. git_operator -> commits with proper message
Advanced Subagent Communication
The master agent aggregates subagent results:
class MasterAgent {
suspend fun implementFeature(request: FeatureRequest): FeatureResult {
val tasks = planTasks(request)
val results = tasks.map { task ->
when (task.type) {
TaskType.UI -> uiDesignerAgent.execute(task)
TaskType.TEST -> testEnforcerAgent.execute(task)
TaskType.DEBUG -> debuggerAgent.execute(task)
else -> executeLocally(task)
}
}
return FeatureResult(
code = results.filterIsInstance<CodeResult>(),
tests = results.filterIsInstance<TestResult>(),
documentation = aggregateDocumentation(results)
)
}
}
Subagent Context Window Optimization
Each subagent can be tuned for its specific needs:
# Debugger needs large context for logs
debugger:
model: claude-3-opus # 128K context
token_allocation:
input: 100000 # Large space for logs
output: 28000
# Git operator needs minimal context
git_operator:
model: claude-3-haiku # Smaller, faster model
token_allocation:
input: 10000
output: 5000
Next Week
Focus shifts to connecting the beautiful UI to the backend reality. This means wiring up view models to the domain and data layers, replacing mock data with live Supabase queries. The subagent architecture will be crucial for managing the complexity of integration tests, state management debugging, and maintaining clean architecture boundaries across all layers.
The productivity gains from subagents have been transformative – from constant context battles to smooth, uninterrupted development flow.