Agentic Coding: Architecture
Agentic Coding: Architecture - THE LGTM
Agentic Coding: Architecture
Codebases built for AI agents look different. Clear boundaries, explicit conventions, and architectural guardrails let agents move fast without creating chaos. Here's how to design for agent-first development.
Last Updated: April 5, 2026
The Architecture Problem
AI agents excel at local changes. They struggle with:
- Understanding implicit conventions
- Maintaining architectural boundaries
- Recognizing long-term patterns
- Avoiding coupling and drift
The solution: Make architecture explicit. Remove guesswork. Encode constraints.
Agent-Friendly Architecture Principles
1. Explicit Boundaries
Every module should have clear:
- Public interface (what's exposed)
- Dependencies (what it can use)
- Responsibilities (what it does)
- Invariants (what must stay true)
// Good: Explicit module contract
/**
* @module AuthService
* @description Handles user authentication and session management
* @dependencies UserRepository, TokenService, EmailService
* @invariants Sessions expire after 24h, passwords never logged
*/
2. Convention Over Configuration
Agents work best with clear, consistent patterns:
src/
features/
user/
api/ # API routes
domain/ # Business logic
infrastructure/ # External adapters
index.ts # Public exports
order/
api/
domain/
infrastructure/
index.ts
Same structure everywhere. Agent knows where to look, where to add.
3. Dependency Rules as Code
Don't document architecture — enforce it:
// archunit test example
describe("Architecture Rules", () => {
it("domain should not depend on infrastructure", () => {
const domain = classes().that().resideInAPackage("domain")
const infra = classes().that().resideInAPackage("infrastructure")
expect(domain).toNotDependOn(infra)
})
it("api should only depend on domain", () => {
const api = classes().that().resideInAPackage("api")
const allowed = classes().that().resideInAnyPackage("domain", "shared")
expect(api).toOnlyDependOn(allowed)
})
})Architecture Documentation for AI
The AGENTS.md Pattern
Inspired by OpenAI's Codex harness, AGENTS.md files tell agents how to work in your codebase:
# Project: E-Commerce Platform
## Architecture Overview
Hexagonal architecture with clear domain/infrastructure separation.
## Tech Stack
- TypeScript, Node.js
- PostgreSQL (database)
- Redis (caching)
- RabbitMQ (events)
## Conventions
- Use functional programming style in domain layer
- All DB access through repository pattern
- API validation with Zod schemas
- Errors use Result pattern, not exceptions
## File Organization
src/
domain/ # Pure business logic, no deps
application/ # Use cases, orchestration
infrastructure/ # DB, HTTP, external APIs
api/ # Routes, controllers
## Testing
- Unit: Jest, in __tests__ alongside code
- Integration: Supertest, in tests/integration
- Mock external services, never hit real APIs
## Common Tasks
### Adding a new feature
1. Define types in domain/types/
2. Implement logic in domain/services/
3. Add repository method if needed
4. Create API route in api/routes/
5. Write tests for all layers
Per-Module README
Complex modules get their own documentation:
src/features/payment/
├── README.md # Module-specific guidance
├── ARCHITECTURE.md # Design decisions, patterns
├── API.md # Public interface documentation
└── .agent-instructions # Tool-specific hintsMulti-Agent Architecture Patterns
Pattern 1: Supervisor Pattern
One agent orchestrates, delegates to specialists:
Supervisor Agent
├── Planning Agent: breaks down tasks
├── Frontend Agent: implements UI
├── Backend Agent: implements API
├── Testing Agent: writes tests
└── Integration Agent: coordinates PRUse when: Complex features spanning multiple domains.
Pattern 2: Pipeline Pattern
Agents in sequence, each specializing in one phase:
Requirements Agent → Design Agent → Code Agent → Test Agent → Review AgentUse when: Formal development process with handoffs.
Pattern 3: Parallel Agents
Multiple agents work simultaneously:
Task: Implement user dashboard
Agent A: Build API endpoints
Agent B: Create React components
Agent C: Write tests
Agent D: Update documentationUse when: Tasks can be decomposed into independent workstreams.
Architectural Guardrails
Static Analysis
// eslint rules for architecture
{
"rules": {
"no-restricted-imports": ["error", {
"patterns": ["../infrastructure/** from domain/**"]
}],
"boundaries/element-types": ["error", {
"default": "disallow",
"rules": [
{ "from": "domain", "allow": ["domain"] },
{ "from": "api", "allow": ["domain", "application"] }
]
}]
}
}Code Generation Templates
Scaffold new modules correctly:
# Agent uses template to create new feature
def create_feature(name):
generate(f"src/features/{name}/domain/types.ts")
generate(f"src/features/{name}/domain/service.ts")
generate(f"src/features/{name}/infrastructure/repository.ts")
generate(f"src/features/{name}/api/routes.ts")
generate(f"src/features/{name}/__tests__/service.test.ts")Steering Files (Kiro Pattern)
Project-level instructions guide agent behavior:
# .kiro/steering.yaml
architecture:
pattern: hexagonal
layers:
- domain
- application
- infrastructure
code_style:
prefer: functional
async: promises (not callbacks)
errors: result type (not exceptions)
testing:
coverage: 80% minimum
mocking: required for external depsReducing Architectural Drift
Drift Detection
Automated checks for architectural erosion:
- Circular dependencies: madge, dependency-cruiser
- Complexity creep: CodeScene, SonarQube
- Boundary violations: ArchUnit, eslint
- Dead code: ts-prune, knip
Refactoring Agents
Agents can maintain architecture:
Agent Task: "Refactor auth module to hexagonal"
1. Identify current violations
2. Move domain logic to domain/
3. Extract repository interface
4. Move DB code to infrastructure/
5. Update imports
6. Run architecture tests
7. Verify all tests passTechnology Choices for Agentic Work
Statically Typed Languages
TypeScript, Rust, Go, Kotlin → compiler catches agent mistakes
Explicit Dependency Injection
Constructor injection → clear dependency graph for agents
Clear Module Boundaries
ESM, packages → explicit exports, no implicit sharing
Standard Tooling
Prettier, ESLint, standard configs → deterministic formatting
Agent-Specific Patterns
1. Prompt-First Development
Write the prompt first, then implementation:
TODO.md:
"Implement user registration with email verification"
SPEC.md:
- Validate email format
- Check for existing users
- Hash password with bcrypt
- Send verification email
- Create session on verification
Agent implements SPEC.md, guided by TODO.md2. Snapshot Architecture
Save architecture state for reference:
docs/architecture/
2026-01-15-baseline.md
2026-02-20-auth-refactor.md
2026-03-10-payment-module.mdAgents reference these when making changes.
3. Context Windows as Architecture
Structure code so agents can understand:
- Files < 500 lines (fits in context)
- Functions with clear single purpose
- Explicit dependencies (no magic)
- Good naming (agent understands intent)
The Bottom Line
Architecture for agents is architecture for humans — just more explicit:
- ✅ Clear boundaries
- ✅ Documented conventions
- ✅ Enforced rules
- ✅ Explicit dependencies
- ✅ Consistent patterns
- ✅ Automated checks
Agents can write code fast. Good architecture ensures they write the right code.