Back to blog

Making Claude Code Powerful: A Consolidated Field Guide to Context, Skills, Agents, and Memory

Making Claude Code Powerful: A Consolidated Field Guide to Context, Skills, Agents, and Memory
The goal of this document is simple: understand Claude Code well enough that you stop fighting it.

Most frustration with AI coding tools comes from one root cause — the model either has too little of the right context, or too much of the wrong context. Almost every feature below is, at heart, a lever on that one problem.

The Real Problem: Context Is a Budget, Not a Bucket

When you open Claude Code, it feels like you’re talking to something with infinite attention. You are not.

Every message you send, every file Claude reads, every command it runs, and every tool result it gets back is poured into a single finite space called the context window. When that space fills up, older content gets summarized or dropped.

This matters because of a non-obvious consequence: the more irrelevant material in the window, the worse the answers get. A 400-line grep dump that you no longer care about doesn't just waste tokens — it competes for the model's attention with the three lines that actually matter. The skill of using Claude Code well is mostly the skill of curating what's in the window.

So the first tool to learn is the one that lets you see the budget.

/context — Look at What You're Actually Spending

Typing /context renders a breakdown of everything currently occupying the window: the system prompt, your CLAUDE.md files, tool definitions, memory, and the running conversation. Think of it as the itemized receipt for a meal you're still eating.

/context

A typical readout shows you, roughly:

  • System prompt + tools — fixed overhead you don’t control much.
  • CLAUDE.md / project instructions — everything you wrote to guide Claude.
  • Messages — the live conversation, which grows with every turn.
  • Free space remaining — your runway before summarization kicks in.

The reason this view is worth checking is that the expensive items are often invisible.

A bloated CLAUDE.md, a giant pasted log, or a file Claude read "just to check" can quietly consume a third of your budget. You can't trim what you can't see.

Limiting Context Deliberately

Seeing the spend is step one; controlling it is step two. The practical levers:

  • /clear — wipe the conversation and start fresh. Use this aggressively between unrelated tasks. A new task should rarely inherit the debris of the last one.
  • /compact — summarize the conversation in place instead of wiping it. Where /clear throws everything away, /compact distills the transcript into a summary and keeps going, so you reclaim space without losing the thread. Add instructions to steer what survives: /compact focus on the auth refactor, drop the test-debugging detour keeps the topic you care about and sheds the rest. (Claude also compacts automatically when the window fills — calling it yourself just does it earlier and on your terms.)
  • Scoped instructions — instead of “look at the codebase,” say “look only at src/auth/session.go." You decide what enters the window rather than letting Claude explore broadly.
  • Delegate the noisy work — push high-volume searches into agents (covered below) so their thousands of lines of output never touch your main window. This is the single highest-leverage habit for keeping context clean.
The mental model: you are the editor of the context window. Claude is a very capable writer, but if you let it hoard every draft, the desk gets buried.

Skills vs. Agents: Two Words for Two Very Different Things

This is the distinction people most often get backwards, so it’s worth being precise. Both extend what Claude can do, but they live in completely different places.

Skills Run Inside Your Current Conversation

A skill is a predefined prompt template that executes in your current conversation.

When you type /pr-description or /branch-review, it injects a specialized prompt into this same context window — same model, same memory, same tool access. Think of it as a macro that tells Claude how to approach a specific task. Skills don't spawn anything new; they just guide the current Claude instance.

The consequence is that a skill sees everything you’ve already discussed. /branch-review can review your branch using the context of the conversation you've been having — the bug you mentioned, the file you just edited, the constraint you described three messages ago. That shared memory is the whole point.

Agents Run in a Fresh, Separate Instance

An agent is a separate Claude instance spawned via the Agent tool. Each agent gets its own fresh context window with no memory of your current conversation.

You write a self-contained prompt briefing it on what to do, and it runs independently — potentially in parallel with other agents or with your main conversation. When it finishes, it returns a single result message back.

Because an agent starts blank, you must brief it like a competent colleague who just walked into the room: what to do, why, what’s already been ruled out. The upside of that blank slate is isolation — an agent can read 5,000 lines of search results, reason over them, and hand you back a two-paragraph answer. The noise stays in its window, not yours.

The Key Differences

Practical example: /branch-review (a skill) reviews your branch using this conversation's context — it already knows what you were worried about. But if you needed to simultaneously search for how five different functions are used across the codebase, you'd spawn five Explore agents in parallel.

The decision rule is short: need shared context → skill. Need isolation or parallelism → agent.

Hooks: Deterministic Guardrails the Model Can’t Forget

Everything above relies on Claude choosing to do the right thing. Hooks are the opposite — they’re deterministic.

A hook is a shell command you register to run automatically in response to an event, like “before a tool runs” or “after a file is edited.” The model doesn’t decide whether to honor a hook; the system runs it every time, no exceptions.

That determinism is exactly why hooks are valuable. An instruction in CLAUDE.md like "always run the formatter after editing" is a suggestion the model usually follows. A hook that runs the formatter on every edit is a guarantee. When correctness matters, you want the guarantee.

Some illustrative uses (described, not coded):

  • Auto-format on save — a hook fires after every file edit and runs your formatter, so style never drifts regardless of whether Claude remembered.
  • Block edits to protected paths — a pre-edit hook inspects the target file and refuses changes to, say, migrations/ or a lockfile, returning an error the model must respect.
  • Run tests after a change — a post-edit hook runs the relevant test suite and feeds failures back into the conversation as if you’d reported them.
  • Lint before commit — a hook gates the commit on a clean lint pass, catching problems the model wouldn’t reliably catch on its own.

The mental shift: CLAUDE.md is policy you hope is followed; hooks are policy that is enforced. Use hooks for the rules that must hold every single time — and feedback from a hook is treated as coming from you, so a blocked action genuinely stops Claude in its tracks.

CLAUDE.md vs. Auto Memory: Instructions You Write vs. Notes Claude Writes

Both shape Claude’s behavior across a session, but they come from opposite directions. The one-line version:

CLAUDE.md = instructions you write. Auto memory = notes Claude writes itself.

CLAUDE.md example: “Run npm test before committing. Use 2-space indentation."

Auto memory example: Claude notices you consistently prefer async/await over raw promises, and notes that for next session — without you having to say it again.

Use CLAUDE.md when you want to guide Claude's behavior upfront. Use auto memory to let Claude learn from your corrections without manual effort. The two are complementary: one is the constitution you author, the other is the running notebook Claude keeps.

CLAUDE.md / Instructions File — General good practices

  1. Keep it under ~200 lines. CLAUDE.md loads into every conversation, so every line is permanent context overhead whether it's relevant or not. Brevity is a feature, not a style preference.
  2. Only include load-bearing rules. Trivia dilutes the important instructions and burns budget on rules that mostly don’t apply. Say the essential things clearly, then stop.
  3. Push directory-specific guidance into ./rules. Don't cram area-specific instructions into the top-level file. Keep focused rules next to the code they govern (frontend rules near the frontend, migration rules near the migrations).
  4. Put configuration in the right settings.json scope. Use ~/.claude/settings.json for personal defaults that follow you across every project, ./.claude/settings.json for team-shared settings committed to the repo, and ./.claude/settings.local.json for personal, gitignored overrides on a single project. The more local the file, the higher its precedence.

A Short Note on Prompt Caching (and the Token Bill)

Behind the scenes, Claude Code caches the stable prefix of your conversation so it doesn’t have to re-process the entire history on every turn. When the cache is warm, follow-up turns are faster and cheaper because the unchanged front of the conversation is reused rather than re-read.

The catch is that certain actions invalidate that cache and force a full re-read of the summarized context — which spikes the token cost of that turn. .

Actions That Dissolve the Cache

These all reshape or rewrite the conversation prefix instead of simply appending to it, so they invalidate the cache and force an expensive, operation-heavy uncached pass:

  • Triggering summarization / compaction — running /compact (or hitting auto-compact) rewrites the entire history into a condensed summary, so the old cached prefix no longer exists and must be re-read from scratch.
  • Editing or rewriting earlier turns — anything that alters what came before the current point (rather than adding after it) changes the cached prefix and breaks it.
  • Large context-altering commands — commands like /clear or other context-management operations that restructure the window reset or rebuild the prefix.
  • Changing the system prompt / instructions mid-session — modifying rules, CLAUDE.md/AGENTS.md, or other always-on context shifts the stable front of the conversation so the cache no longer matches.
  • Reordering or removing messages — pruning or moving history breaks prefix continuity.

By contrast, cache-friendly actions leave earlier history untouched: a normal follow-up message, a tool call and its result, or any steady, additive turn.

The practical takeaway: prefer steady, additive turns, and recognize that a command which compacts or rewrites the whole conversation buys you cleanliness at the price of one expensive uncached pass.

Agents and Subagents, In Detail

We met agents earlier as the isolation-and-parallelism tool. Here’s the fuller picture, because this is where Claude Code goes from “a helpful chat” to “a system that gets real work done.”

Why Agents Exist

Two problems motivate them.

First, context pollution: some tasks generate enormous intermediate output — searching a large codebase, reading dozens of files, parsing long logs. If that lands in your main window, it crowds out everything that matters.
Second, serial bottlenecks: if you have five independent questions, asking them one after another is slow when they could run at once.

An agent solves both. It runs in its own fresh window, so the mess stays contained, and multiple agents run concurrently, so independent work happens in parallel. The agent does the heavy lifting and hands back only the distilled result.

Specialized Agent Types

Not all agents are general-purpose. Claude Code ships focused ones, each tuned for a job:

  • Explore — a fast, read-only search agent for locating code: find files by pattern, grep for symbols, answer “where is X defined?” It reads excerpts rather than whole files, so it’s ideal for breadth, not deep analysis.
  • Plan — an architect agent that designs implementation strategy and returns step-by-step plans without writing code.
  • general-purpose — the catch-all for multi-step research and execution that doesn’t fit a narrower type.

The reason to reach for a specialized agent is that its constraints are features. Explore won’t get lost trying to refactor; Plan won’t start editing before you’ve agreed on an approach.

Briefing an Agent Well

Because an agent starts with zero memory of your conversation, the quality of its result is bounded by the quality of your brief. A good agent prompt reads like a handoff to a sharp colleague:

  • State the goal and why it matters — so the agent can make judgment calls instead of following a narrow instruction off a cliff.
  • Share what you’ve already ruled out — dead ends you don’t want re-explored.
  • Specify the output you want — “report in under 200 words,” “list file paths and line numbers,” “tell me if it’s safe and what breaks if not.”

The anti-pattern is the terse command — “fix the bug” — handed to something that has no idea which bug, which file, or what you’ve already tried. Terse prompts produce shallow, generic work

Parallelism in Practice

The figure shows the payoff:
three different jobs — locating the code, designing the approach, and researching the supporting pieces — that would have serially dumped thousands of lines into your context instead run at once, each in the agent type suited to it, and return three clean summaries.
Your main window stays focused on the actual question.

When Not to Use an Agent

Agents aren’t free — spawning one has overhead, and a blank-slate instance can’t lean on the rich context you’ve built up in the main conversation.

If the target is already known (you have the file path, you know the symbol), just use a direct tool. If the task genuinely needs the conversation’s history, that’s a job for the main instance or a skill, not an agent. Reserve agents for open-ended exploration, high-volume output you want contained, and independent work you can run in parallel.

The Decision Ladder

Pulling it together, here’s how to reach for the right tool:

  1. Context feeling heavy or off-topic? → check /context, then /clear between unrelated tasks.
  2. Want this conversation’s Claude to do a specific task with full context? → a skill (/branch-review, /pr-description).
  3. Need high-volume search or several independent jobs at once?agents, briefed like colleagues, ideally in parallel.
  4. Have a rule that must hold every single time? → a hook, not a line in CLAUDE.md.
  5. Want to guide Claude upfront?CLAUDE.md (kept under ~200 lines; directory-specific rules in ./rules).
  6. Want Claude to remember your corrections automatically? → let auto memory do it.
  7. Configuring behavior? → personal-everywhere in ~/.claude/settings.json, team-shared in ./.claude/settings.json, personal-per-project in ./.claude/settings.local.json.

The thread running through all seven is the same one we started with: deliberately manage what’s in the context window, and enforce the things that matter rather than hoping they’re followed.
Do that, and Claude Code stops being a clever autocomplete and starts being a system you can trust with real work.

Originally published on Medium.