Practical Guide

AI Assisted Development
That Actually Works

Ever notice the more you let it think for you, the worse the results get? This is how you fix that.

January 2026 25 min read

Context Engineering

Context engineering is optimising token utility to deal with the inherent constraints of LLMs. That sentence explains most of what separates developers who get good results from those who don't.

The model gives you what it thinks is most likely correct, based on your input. Vague in, vague out. Precise in, precise out. Your job is shaping the input until the most likely output is what you actually want.

Every time you send a message, the entire conversation history gets sent again. The model reads it fresh. No memory between sessions. No persistent understanding of your project beyond what you explicitly provide. It's like explaining your codebase to a new contractor every single time you need something done.

Your 200k token context window

How it fills up during a typical session

System
Chat History
Files + Tools
Reasoning
System prompts (~20k)
Conversation (~80k)
Code + tool output (~60k)
Space for thinking (~40k)

Run /context mid-session to see exactly how your context window is being used. A fresh session in a typical monorepo costs around 20k tokens baseline. The remaining 180k fills up fast.

Context Poisoning

When your conversation gets long and messy, the model makes worse decisions. Too much noise drowns out the signal. If you're fighting the model, the problem is almost always upstream.

Context poisoning in practice:

poisoned context
# 2 hours into a session... you: Add a loading spinner to the submit button I'll add the loading spinner. But first, based on our earlier discussion about the auth refactor (which we later abandoned), I should check if the button component still uses the old handleSubmit pattern we discussed reverting... # Claude is confused by abandoned decisions still in context # It's trying to reconcile contradictory information # Simple task becomes archaeology expedition
clean context
# Fresh session with intentional context... you: Working on the checkout form in src/components/CheckoutForm.vue. Add a loading spinner to the submit button that shows during API calls. I'll add a loading spinner to the submit button. Looking at CheckoutForm.vue, I can see it uses the handleSubmit function. I'll add a isLoading ref and update the button template... Clean context = direct path to solution

Context poisoning looks like

Long threads with multiple failed attempts. Contradictory instructions from earlier. Abandoned approaches still influencing decisions. Claude second-guessing itself constantly.

Clean context looks like

Fresh session with focused goal. Only relevant files mentioned. Clear requirements stated upfront. Previous decisions documented in files, not conversation history.

The fix is simple but counterintuitive: start fresh more often. A new conversation with clean, focused context will outperform a long thread where you've been iterating for hours.

The /clear workflow

When you've built up understanding with Claude, have it write that understanding to a markdown file before clearing context. Then reference that file in your fresh session. You keep the knowledge without the noise.

Planning Mode and Clarifying Questions

In Claude Code, hit shift + tab twice to enter Plan Mode. This forces the model to think before acting. No file edits, no commands, no changes until you approve.

But the real power is in what happens next. In Plan Mode, Claude uses the AskUserQuestion tool to interview you about ambiguous requirements before proposing anything.

claude code - plan mode
you: Add authentication to the API # Claude analyses codebase, then asks structured questions How should authentication be implemented? A) JWT tokens (stateless, good for microservices) B) Session-based (simpler, requires session store) C) OAuth 2.0 (if integrating with external providers) # You select B Where should sessions be stored? A) Redis (recommended for production) B) Database (simpler setup) C) In-memory (development only) # After 2-3 questions, Claude produces a detailed plan Plan written to .claude/plans/auth-implementation.md

This approach eliminates the endless loop of "that's not what I meant" corrections. Instead of making assumptions and going down the wrong path, Claude pauses and asks you directly what you want. By the time it starts coding, 90% of decisions are already made.

The developers getting the best results with large features work this way: start with a minimal spec, let Claude interview you to fill in the gaps, then execute while the shared understanding is still in context.

The workflow looks like this:

1

Enter Plan Mode with a minimal prompt

"Add user authentication to the API" is enough. Don't try to specify everything upfront.

2

Answer the clarifying questions

Claude asks 3-4 structured questions about architecture, tradeoffs, and edge cases. Each question has sensible options based on codebase analysis.

3

Review and refine the plan

Claude produces a detailed plan with task breakdown, dependencies, and execution order. Edit it directly if needed.

4

Execute with the plan context intact

Keep the same session. Claude understands the decisions you made together. The shared context is valuable here.

Chrome DevTools MCP for Visual Review

Claude Code can't see what its generated code actually looks like in the browser. It's coding blind. Chrome DevTools MCP fixes this.

install chrome devtools mcp
$ claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest # Restart Claude Code to load the new server $ claude # Now Claude can see the browser you: Navigate to localhost:3000 and check if the header looks right Navigating to localhost:3000... Taking screenshot... The header is rendering, but I notice the navigation items are stacking vertically instead of horizontally. The flexbox container appears to be missing flex-direction: row.

This turns Claude into a virtual front-end debugger. Instead of relying on static code analysis, it examines the actual rendered state. If an element is computed to be 5000px wide due to a flexbox issue, Claude can see that and recommend a fix.

The visual iteration loop

The real power is having Claude review its own work. After implementing a UI component, tell Claude to screenshot it and verify the layout. It catches problems humans miss after staring at the same code for hours.

Workflow example prompt
# After Claude implements a feature:
"Navigate to localhost:3000/dashboard, take a screenshot,
and verify the component matches what we discussed.
Check for:
- Correct spacing between cards
- Hover states working
- Mobile responsiveness at 375px width"
# Claude will screenshot, analyse, and either confirm
# or identify specific issues with line numbers for fixes

Available tools include: navigate pages, take screenshots, click elements, fill forms, check console errors, inspect network requests, and run performance traces. You can test entire user flows without leaving your conversation.

Using Separate Agents to Review Work

A simple but effective approach from Anthropic's engineering team: have one Claude write code while another reviews it. Similar to working with multiple engineers, sometimes having separate context is beneficial.

Why this works

The first agent accumulates context about implementation decisions, workarounds, and compromises. A fresh agent sees only the output, judging it without that baggage. Problems that seemed acceptable mid-implementation become obvious to fresh eyes.

There are two practical ways to do this:

1. Separate terminal sessions

Run two Claude Code instances. One implements, one reviews. They can even communicate through shared scratchpad files if you want them to collaborate.

terminal 1 - implementer
you: Implement the payment processing module based on spec.md # Claude implements... Done. Files modified: src/payments/*.ts you: Write a summary of what you did to reviews/payment-summary.md
terminal 2 - reviewer
you: Review src/payments/ for security issues, edge cases, and code quality. Check against reviews/payment-summary.md for intent. Reviewing payment processing module... Issues found: 1. No rate limiting on payment attempts (security) 2. Missing validation for negative amounts 3. Error messages expose internal details

2. Subagents for parallel review

Subagents run in their own context windows. Delegate security audits, test generation, or code review to specialised subagents without polluting your main conversation.

.claude/agents/security-reviewer.md markdown
---
name: security-reviewer
description: Reviews code for security vulnerabilities
tools: Read, Grep, Bash
model: sonnet
---
You are a security-focused code reviewer.
# Focus areas
- Input validation and sanitisation
- Authentication and authorisation flaws
- SQL injection, XSS, CSRF
- Secrets in code or logs
- Dependency vulnerabilities
# Output format
For each issue:
- Severity: Critical / High / Medium / Low
- Location: file:line
- Issue: clear description
- Fix: specific recommendation

The main benefit is context isolation. Each subagent gets its own context window, preventing any single session from getting poisoned with too much implementation detail.

CLAUDE.md - Your Project Memory

A CLAUDE.md file in your project root gets loaded automatically every session. This is where you put everything Claude needs to know about your project: tech stack, conventions, architecture decisions, things to avoid.

CLAUDE.md markdown
# Project: E-commerce Dashboard
# Stack: Vue 3 + TypeScript + Pinia + Vitest
# Conventions
- Components: PascalCase, single file
- Composables: use* prefix, in src/composables/
- No any types. Use unknown and narrow.
- Tests live next to source files
# Architecture decisions
- Auth tokens stored in httpOnly cookies, not localStorage
- All API errors go through centralised handler
- Feature flags via src/config/features.ts
# Don't
- Don't commit until I approve
- Don't use Options API
- Don't add npm dependencies without asking

Files merge hierarchically. Enterprise settings at the top, user preferences in ~/.claude/CLAUDE.md, then project root, then directory-specific files. You can put a CLAUDE.md in src/components/ with component-specific patterns.

Keep it concise. Every line gets loaded every time. Treat it as a reference guide, not documentation. Point to docs rather than duplicating them.

Skills: Automatic Context Loading

Skills are folders with a SKILL.md file describing when the skill should activate. Unlike slash commands which you trigger manually, skills activate automatically when Claude recognises a matching context.

Skills are proving more reliable than MCPs for most use cases. Better context efficiency, more consistent activation at the right moments, and they don't sit there consuming tokens when you're not using them.

The key advantage: MCPs consume context constantly once connected. Skills load only when relevant, then unload. The model also follows skill instructions more reliably because there's less competing noise in the context window.

.claude/skills/vue-testing/SKILL.md markdown
---
name: vue-testing
description: Vue 3 component testing with Vitest
tools: Read, Write, Bash
---
When writing tests for Vue components:
# Setup
- Use @testing-library/vue for rendering
- Mock Pinia stores with createTestingPinia()
- Mock API calls, never hit real endpoints
# Structure
- Describe block per component
- Test user behaviour, not implementation
- One assertion per test where practical
# Naming
- ComponentName.test.ts in same directory
- Describe: "ComponentName"
- Test: "should [expected behaviour] when [condition]"

Put skills in ~/.claude/skills/ for personal use across all projects, or .claude/skills/ for project-specific ones. Claude will automatically load the vue-testing skill when you ask it to write tests for a Vue component.

S

Skills

High context efficiency. Activate automatically based on task. Better instruction following. Load on demand.

M

MCPs

Lower context efficiency. Always consume tokens when connected. Best for live external data like databases or APIs.

/

Slash Commands

Manual trigger only. Good for explicit workflows you want to invoke on demand. Code reviews, commit messages.

H

Hooks

Automatic lifecycle reactions. Run linting after edits, require approval for bash commands. No manual invocation.

Commands That Change Everything

Claude Code has features that most people never discover. These aren't hidden, but they're easy to miss if you're just using it as a chat interface. Each one solves a specific problem that would otherwise slow you down.

/rewind - Undo mistakes instantly

Made a wrong turn? Claude edited files you didn't want touched? The /rewind command lets you roll back to any previous point in your conversation. It reverts both the conversation state and any file changes.

rewind in action
you: Refactor the auth module to use JWT Refactoring src/auth/... Modified 12 files # Wait, that broke everything. Undo it. you: /rewind Available checkpoints: 1. Before "Refactor the auth module" (2 min ago) 2. After "Add login endpoint" (15 min ago) 3. Session start (45 min ago) # Select checkpoint 1 Rewound to checkpoint. 12 files restored.

This is particularly useful when you're experimenting. Try something ambitious, and if it doesn't work, rewind and try a different approach. No manual git stashing required.

/clear over /compact - Fresh context wins

When your context window fills up, you have two options: /compact to summarise and compress, or /clear to start fresh. From experience, /clear is almost always the better choice.

Compact tries to preserve important information while discarding the rest. In theory this sounds ideal. In practice, it often keeps the wrong things and Claude starts doing stuff you don't expect. The summarisation introduces subtle misunderstandings that compound over time.

The /compact trap

Keeps a compressed version of context that may not accurately represent what you actually need. Claude's behaviour becomes unpredictable because it's working from a lossy summary.

The /clear approach

Start fresh with exactly the context you need. Reference your CLAUDE.md, point to specific files, state your current goal. Takes 30 seconds and gives you reliable behaviour.

Don't be precious about your conversation history. If you've built up valuable understanding, have Claude write it to a markdown file before clearing. Then reference that file in your fresh session. You keep the knowledge without the accumulated noise.

the clean context workflow
you: /context Context usage: 156k / 200k tokens (78%) # Instead of /compact, save what matters and start fresh you: Write a summary of our decisions and current state to docs/auth-progress.md Written to docs/auth-progress.md you: /clear # Now start fresh with clean, intentional context you: Read docs/auth-progress.md - we're continuing the auth implementation. Next step is the session middleware.

Essential commands reference

/context

Check your context window usage. Run this regularly. If you're above 60%, consider clearing.

/clear

Nuke the conversation. Start fresh. Almost always better than /compact for maintaining output quality.

/rewind

Roll back to a previous checkpoint. Reverts both conversation and file changes.

/model

Check or switch models. Opus 4.5 handles both planning and implementation well. Only switch down for rate limits or cost.

/permissions

View and modify what Claude is allowed to do. Tighten for sensitive work.

/install-skill

Add skills from the community. Skills beat MCPs for most tasks - better context efficiency, more reliable timing.

Practical Use Cases

Some tasks are perfect for AI assistance. Others waste time. Knowing the difference matters more than any technique.

Analysing unfamiliar codebases

Point Claude Code at a complex codebase and ask questions. How does the auth flow work? Where are database connections handled? What happens when this endpoint gets called?

You can script out an entire SQL database, save the schema to files, and have Claude explain how everything connects. Understanding someone else's spaghetti becomes dramatically faster.

TDD workflow

Have Claude write tests first, then implement code to pass them. The tests become validation checkpoints. Instead of you manually checking if implementation works, Claude runs the tests itself to verify correctness.

tdd workflow
you: Write tests for a function that validates email addresses. Include edge cases. Don't implement yet. Writing tests to tests/validateEmail.test.ts... - should return true for valid email - should return false for missing @ - should return false for multiple @ - should handle subdomains - should reject spaces you: Now implement to pass all tests. Run them after each attempt. Implementing src/utils/validateEmail.ts... Running tests... 3/5 passing Fixing edge case handling... Running tests... 5/5 passing All tests pass.

SDLC automation

GitHub Actions combined with Claude Code handles the tedious parts: auto-generate tests on PR creation, update docs on PR approval, analyse bug reports in Issues. Keep human review in the loop for anything substantial.

What Not to Do

Pasting entire codebases

Context limits exist. Context poisoning is real. Be surgical about what you include. Reference files by path rather than pasting contents.

Skipping planning

Rewrites take longer than planning. The time you save is time you'll spend debugging. Use Plan Mode for anything non-trivial.

Assuming memory exists

Every conversation starts fresh. Claude doesn't remember yesterday's session. Set up context explicitly every time.

Using too many tools

Imagine using PowerPoint, Google Slides, Canva, and Keynote for slides. Pick Claude Code plus one backup and learn them properly.

Finding Your Workflow

Everything in this guide is a starting point. The developers getting the best results aren't following a prescribed method. They've experimented, failed, adjusted, and built workflows that fit how they actually work.

Some people swear by Plan Mode for everything. Others find it slows them down for quick fixes and only use it for multi-file changes. Some teams have elaborate CLAUDE.md files with dozens of conventions. Others keep it minimal and let skills handle the specifics.

There's no correct answer. There's only what works for you.

1

Start with the basics

Get comfortable with Plan Mode and the /context command. Understand how your context window fills up. These fundamentals apply regardless of what workflow you build.

2

Notice your friction points

Where do you waste time? Repeating the same instructions? Fixing the same types of mistakes? Context getting poisoned mid-session? Each friction point is an opportunity for a skill, hook, or workflow change.

3

Build incrementally

Don't try to set up the perfect system on day one. Add one skill when you notice a pattern. Create a slash command when you've typed the same prompt five times. Let your setup evolve with your needs.

4

Share what works

If you're on a team, document workflows that prove effective. A shared CLAUDE.md with team conventions. Skills for your tech stack. Slash commands for common review patterns. Consistency multiplies the benefits.

Example workflows people actually use

The spec-driven approach

Plan Mode interview to build spec. Clear context. New session references spec file. Implementation happens with all decisions already made. Works well for features with multiple stakeholders.

The TDD loop

Write tests first. Implement to pass. Review with fresh agent. Commit. Particularly effective for business logic where correctness matters more than speed.

The visual verification loop

Implement UI component. Chrome DevTools screenshot. Claude reviews its own work. Fix issues. Screenshot again. Best for frontend work where "it compiles" doesn't mean "it looks right".

The parallel review

One agent implements. Second agent reviews with fresh context. Third agent writes tests. Sounds heavyweight but moves faster than sequential work with context poisoning.

The point isn't to copy these exactly. It's to recognise that workflows exist on a spectrum from fully manual to heavily automated, and you get to choose where you sit based on your project, your team, and your preferences.

The meta-skill

Learning to use AI tools effectively is itself a skill that improves with practice. The developers who started six months ago and iterated on their workflows are dramatically more productive than developers just starting today with the same tools. Put in the reps. Pay attention to what works. Adjust.

The Bottom Line

Context engineering is the discipline. Plan Mode resolves ambiguity upfront. Chrome DevTools MCP lets Claude see its own work. Fresh agents provide unbiased review after you're done building.

The tools are good. Use them properly: planning first, visual verification, clear context for review. The results follow.

Shape context badly and you'll spend more time fixing AI output than you would have spent writing the code yourself.

The model is a tool. You're the engineer.