Working efficiently with Claude Code
tags: #tech #claude code #agentic ai #claude.mdI was working with claude and reading through claude.md documentation, and I wanted to capture some of my findings as well as part of the discussions I had with Claude Code regarding the documentation. This is part of the result of that exercise. I am documenting it here so that I can reference it in the future if needed.
Highest-impact strategies, roughly in order of effect:
Model selection
Switch to a cheaper model for simple tasks — reading files, writing boilerplate, quick edits. Use /model to toggle.
Haiku 4.5 is the cheapest; Sonnet 4.6 is a good middle ground. Only use Opus when you need it.
Context management
/compact: Compresses conversation history in place, preserving context but using far fewer tokens. Use it when a session gets long./clear: Wipes context entirely. Best when switching to a completely different task.- Start a new conversation for each distinct task rather than one long mega-session. (The
/clearcommand is a good way to do this.)
A well-maintained CLAUDE.md
Claude reads CLAUDE.md at the start of every session. The better it describes your project structure, commands, and conventions, the less Claude needs to explore the codebase itself (which burns tokens).
Current Best Practices as of April 2026
Length: Under 200 lines per file. Adherence drops and token cost rises as it grows.
What to include:
- Build/test commands
- Project architecture and file layout
- Coding conventions and naming patterns
- Anything Claude needs in every session
What to leave out:
- Multi-step procedures: Put those in skills instead.
- Instructions only relevant to one subdirectory: Use a subdirectory CLAUDE.md lazy-loaded, doesn’t cost tokens at startup.
- Task-specific steps: They belong in the conversation, not the file.
Structure: Markdown headers and bullets. Concrete and verifiable beats vague: “Use 2-space indentation” is better than “format code properly.”
Hierarchy: Files load in this order, each overriding the last:
~/.claude/CLAUDE.md: user-level./CLAUDE.md: project rootsubdir/CLAUDE.md: lazy-loaded per directory./CLAUDE.local.md: gitignored, personal overrides
Scaling beyond 200 lines: Split into .claude/rules/ directory with scoped files (e.g., testing.md, styling.md).
You can also scope rules to specific file paths with YAML frontmatter so they only load when Claude touches matching files.
YAML frontmatter format
---
paths:
- "glob/pattern/**"
- "another/pattern/*.ext"
---
# Your rules here
Rules with paths load only when Claude touches a matching file. Rules without paths load at startup every session.
.claude/rules/testing.md — if you ever add tests:
---
paths:
- "**/*.test.js"
- "**/*.spec.js"
---
- Use describe/it blocks
- Mock external HTTP calls
.claude/rules/styling.md — scoped to SCSS files:
---
paths:
- "_sass/**/*.scss"
- "assets/css/**/*.scss"
---
- Variables live in `_sass/minima/`
- Follow existing Monokai color variable naming
- No inline styles; use existing variables
.claude/rules/content.md — scoped to your collections:
---
paths:
- "_dev_notes/**/*.md"
- "_musings/**/*.md"
- "_posts/**/*.md"
---
- Frontmatter must include layout, title, categories, tags
- Code blocks use fenced syntax with a language tag
- References section goes at the bottom after a `---` divider
Key points
- paths is the only supported frontmatter field — no priority, when, or conditionals
- Brace expansion works: */.{ts,tsx} matches both extensions
- Files without paths frontmatter in .claude/rules/ load at startup just like CLAUDE.md
- Subdirectories inside .claude/rules/ are also discovered
Token trick — HTML comments () are stripped before context injection, so you can leave maintainer notes in CLAUDE.md without paying for them.
Targeted prompts
- Avoid “look around and figure it out” prompts: Give Claude the specific file path or symbol name upfront.
- When you only need part of a large file, say so: “read lines 50–100 of X” rather than letting it read the whole thing.
- Batch related requests into one message instead of multiple back-and-forth turns.
Use the Explore subagent for research
When you need codebase exploration, spawning an Explore agent keeps the search results out of your main context window. You only get the answer, not all the intermediate tool output.
Reduce permission prompts
Run /fewer-permission-prompts — it analyzes your session and adds common read-only operations to your allowlist, cutting down on
the round-trips that burn tokens on overhead.
Auto-memory
Your memory system (already configured) means you don’t have to re-explain your project preferences each session — that
re-explanation costs tokens every time.
Filter output before it hits context
Pipe commands to trim what Claude actually sees:
npm test 2>&1 | tail -30 # only last 30 lines
npm test 2>&1 | grep -E "FAIL|PASS|Error" # only relevant lines
bundle exec jekyll build 2>&1 | grep -v "^ Generating" # strip noisy lines
Whatever gets piped is what lands in context, so filtering at the shell level is the cheapest option.
Run commands in the background
When you ask Claude to run something with run_in_background, it kicks off the process and you get a notification when it
finishes. The full streaming output never enters the context window. You only get the final result when it completes.
This is particularly useful for slow builds or test suites.
Spawn a subagent for the whole task
For a multi-step workflow like “make this change, run tests, fix failures, run tests again”, hand the entire thing to a
general-purpose agent. It does all the tool calls internally, and you only get back the final summary. None of the intermediate
bash output, file reads, or retries appear in your main context.
You can’t spawn agents directly from the terminal.
The way to trigger it is just to describe the task in a way that makes it clear you want it handled end-to-end. For example:
“Run the tests, fix any failures, and report back with what changed.”
“Explore the _dev_notes/ folder and tell me which files are missing a References section.”
When the scope is multi-step or research-heavy, Claude will (or should) spawn a subagent automatically. You can also be
explicit:
“Use an agent to do this so it doesn’t flood the main context.”
That tells Claude directly to delegate the work rather than doing it inline.