Claude Code's Four Layers: Agents, Skills, Hooks, and Memory
Most developers treat Claude Code like a fancy autocomplete. You type a prompt, it writes some code, you move on. That's fine for quick tasks, but you're leaving serious power on the table.
Claude Code has four programmable layers that fundamentally change how you interact with it. Once you understand them, you stop repeating yourself, stop babysitting the AI, and start building workflows that compound over time. I've been running this setup across multiple projects, and the difference between vanilla Claude Code and a properly configured one is night and day.
Here's the mental model I use every day.
Memory: The Persistent Brain (CLAUDE.md)
Every time you start a Claude Code session, it reads a file called CLAUDE.md from your project root. Think of it as the AI's long-term memory - architecture decisions, coding conventions, domain knowledge, anything Claude should always know without you repeating it.
This is where you put things like:
There are actually three levels of memory:
.claude/CLAUDE.md in your repo (shared with the team)~/.claude/CLAUDE.md (your preferences across all projects)The key insight? CLAUDE.md isn't documentation for humans. It's instructions for the AI. Write it that way. Be direct, be specific, and skip the prose. "Use single dash (-) not em dash" is better than a paragraph explaining your punctuation philosophy.
I've found the best CLAUDE.md files are living documents. After every session where Claude does something wrong or you correct its approach, update CLAUDE.md so it doesn't happen again. It's like training a teammate - except the lessons actually stick between conversations.
Skills: Repeatable Workflows as Slash Commands
Skills are where things get interesting. Instead of typing the same 200-word prompt every time you want a code review or a new component, you write a SKILL.md file once and invoke it with a slash command forever.
Every skill lives in a directory with a SKILL.md file as the entry point:
.claude/skills/
└── review-component/
├── SKILL.md # Main instructions (required)
├── template.md # Optional template
└── examples/ # Optional example outputs
The SKILL.md has two parts - YAML frontmatter that tells Claude when to use it, and markdown content with the actual instructions:
---
name: review-component
description: Reviews React components for performance and accessibility issues
---
When reviewing a component:
1. Check for unnecessary re-renders
2. Verify accessibility attributes
3. Look for missing error boundaries
4. Flag any inline styles that should be in the design system
Two invocation modes make skills flexible. You can call them manually with /review-component, or Claude can auto-trigger them based on the description in the frontmatter. If you don't want Claude deciding when to run a skill - say, a deploy workflow - add disable-model-invocation: true to keep it manual only.
The real power comes from composition. Skills can spawn parallel agents, inject dynamic context using shell commands with the !`command` syntax, and reference supporting files for detailed specs. I have one skill that pulls the current PR diff, runs three review agents in parallel, and aggregates their findings. What used to be a 15-minute manual process now takes about 30 seconds.
Skills also support argument passing. A skill like /fix-issue 423 can receive that issue number through the $ARGUMENTS placeholder and go fetch the GitHub issue, understand the requirements, implement the fix, and write tests - all from a single command.
Hooks: Deterministic Guarantees
Here's the thing about LLMs - they're probabilistic. You can ask Claude to always run prettier after editing a file, and it'll do it most of the time. Most of the time isn't good enough when you're shipping production code.
Hooks solve this. They're shell commands that execute at specific lifecycle events, and they run every single time. No exceptions.
The lifecycle events cover everything you'd want to automate:
The configuration lives in .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
That matcher is key - "Edit|Write" means this hook only fires after file-editing tools, not after every tool call. You can target specific tools, MCP servers, or even use regex patterns.
The exit code 2 pattern is particularly powerful for PreToolUse hooks. If your script exits with code 2, the action is blocked before it executes. Claude gets feedback about why it was blocked and adjusts its approach. I use this to prevent edits to protected files like .env and package-lock.json, and to block any bash command that tries to drop database tables.
There are also prompt-based and agent-based hooks for decisions that need judgment rather than hard rules. A prompt hook sends the context to a fast model (Haiku by default) for a quick yes/no decision. An agent hook spawns a full subagent that can read files and run commands to verify conditions. I use a Stop hook that checks whether all requested tasks are actually complete before Claude declares it's done - it's caught half-finished work more times than I can count.
Agents: Parallel Delegation
Custom agents are markdown files that define specialized workers. They live in .claude/agents/ for project-specific ones or ~/.claude/agents/ for personal ones that work across all your projects.
The frontmatter controls everything - tools, model, and scope:
---
name: code-reviewer
description: Reviews code for style, bugs, and project conventions
tools: Read, Glob, Grep
model: sonnet
---
You are a code reviewer for a Next.js portfolio site.
Focus on:
- Component composition patterns
- Performance implications
- Accessibility compliance
- Design system consistency
Claude Code ships with three built-in agents:
The constraint on subagents is that they report back to the parent - they can't talk to each other directly. For parallel independent coordination, Agent Teams (launched February 2026) let multiple Claude sessions coordinate, message each other, and divide work.
Where agents really shine is parallelization. When I'm doing a large refactor, I'll spin up one agent to explore the codebase and map dependencies, another to plan the migration path, and a third to check for breaking changes in downstream consumers. All running simultaneously, all reporting back to the main session.
The Decision Framework
After months of working with this system, here's how I decide which layer to use:
NeedLayerWhyClaude should always know XMemoryStatic knowledge, loads every sessionI repeat this workflow oftenSkillsWrite once, invoke with a slash commandThis must happen every timeHooksDeterministic, not probabilisticThis task needs isolationAgentsParallel work, specialized contexts
The layers aren't mutually exclusive - they compose. A skill can spawn agents. A hook can enforce that a skill runs before every commit. Memory informs how agents do their work. The whole system is greater than the sum of its parts.
Getting Started
If you're new to this, don't try to set up all four layers at once. Start with CLAUDE.md - document your project's conventions and watch how much less you need to repeat yourself. Then add one or two skills for your most common workflows. Hooks come next for the things that absolutely must happen. Agents are the last piece, for when you're ready to parallelize.
The teams I've seen get the most out of Claude Code aren't the ones writing the cleverest prompts. They're the ones who invest a few hours configuring these four layers and then benefit from that investment in every session that follows. It's the difference between using a tool and building a system.