I Took an Actual Claude Code Course So I’d Stop Prompting Like a Layman. A solo Flutter developer who used Claude Code for two years without formal training reports that taking an actual course revealed he had been misusing the tool, confusing model selection with effort levels. The developer, Saqib Wani, explains that Claude Code has two independent dials—model (Haiku, Sonnet, Opus, Fable) and effort—and that raising the model fixes reasoning errors while raising effort fixes incomplete work. He notes that Haiku does not support effort levels and that switching models mid-conversation can break caching, and he recommends leaving models at default effort unless a task requires more thoroughness. For about two years, I’ve shipped production Flutter apps as a solo developer. Builds, CI/CD, backend, all of it — just me. So when Claude Code showed up, I did what every developer with a deadline does: I opened a terminal, typed a vague sentence, and hoped for magic. Sometimes I got magic. More often I got a Claude that read half the codebase, guessed the other half, and confidently shipped a fix for a bug I didn’t have. I assumed that was just how it worked. Type, pray, repeat. Then I actually sat down and took a proper course on how Claude Code is supposed to be used, and it was mildly humiliating. Not because the tool changed — because I realized I’d been driving a car with six gears stuck in first, the whole time, and blaming the road. This is the note-dump I kept while going through it — rewritten into something you can actually read on your lunch break instead of a wall of bullet points in a Google Doc. Part 1 is the foundation: how Claude actually “thinks” about your project, and how to stop it from thinking too much or too little. Part 2 https://medium.com/@saqibwani273/claude-code-isnt-just-a-terminal-anymore-subagents-agent-teams-plugins-and-mcp-explained-ae767bdd0f91?postPublishedType=initial gets into subagents, agent teams, plugins, and MCP — the stuff that turns Claude Code from a smart autocomplete into something closer to a small team. Let’s start with the thing almost nobody explains properly: model vs. effort are two completely different dials. If you’ve used Claude Code for more than a week, you’ve picked a model — Haiku, Sonnet, Opus, or the newer Fable tier. What most people don’t realize is that there’s a second, independent dial sitting right next to it: effort . Here’s the distinction, stripped down: Same brain, different amount of homework. That’s the whole distinction, and it fixes a diagnostic problem I used to have constantly: when Claude got something wrong, I’d reflexively jump to a bigger, pricier model. Half the time that wasn’t the actual problem. Here’s the cheat sheet I now actually use: What happenedWhat’s actually wrongWhat to changeConfidently wrong answer, or fumbled something ambiguousReasoning ceilingRaise the model Skipped a file, didn’t run tests, stopped halfwayDidn’t try hard enoughRaise the effort You set both with /model and /effort there are flags and settings-file equivalents too, and an env var, CLAUDE CODE EFFORT LEVEL, that overrides everything else if you've set it . One gotcha worth tattooing on your monitor: Haiku doesn't support effort levels at all , so switching to and from Haiku can silently reset whatever effort you had dialed in. You won't get an error. It'll just quietly go back to default. My rule of thumb now: leave each model at its default effort unless a specific task is clearly asking for more thoroughness. Treat it as a general preference, not something you fiddle with every five minutes — that’s a good way to burn tokens micromanaging a setting that mostly doesn’t need touching. One more practical point that’s easy to overlook: models are stateless , so switching models mid-conversation can break your cache. If you’re deep into a session and swap models on a whim, you’re not just changing “how smart” — you might be quietly torching the caching that was keeping your costs down. I used to treat the context window like a bottomless bag — throw everything in, Claude will sort it out. It won’t, not gracefully. The mental model that finally clicked for me: context rot isn’t Claude forgetting things, it’s Claude’s attention getting diluted. Everything technically stays “in window,” but the reliability of recalling any specific piece drops as the pile grows. Picture trying to find one sticky note on a desk with three Post-its versus a desk buried under three hundred. Nothing’s been thrown away. Good luck finding the one you need. There’s a structural reason for this too, not just vibes: attention scales roughly quadratically with context length. So a longer conversation isn’t just “more tokens counted” — it’s meaningfully more compute per turn, which means real cost creeping up even before you hit any hard limit. The rough numbers I picked up: Claude Code does have auto-compaction it summarizes the conversation when things get long , but by default it kicks in painfully late — around 95% full. Which means the quality dip has usually already started by the time the safety net triggers. The fix isn’t clever, it’s just discipline: keep context minimal and relevant, and checkpoint with /clear periodically instead of letting one session run for six hours because closing the terminal felt like losing progress. A few focused sessions beat one bloated marathon, both for accuracy and for your bill. If there’s one file that separates “Claude that gets your codebase” from “Claude that’s guessing,” it’s CLAUDE.md. Run /init in an existing codebase and Claude Code will generate one for you — and honestly, this is a task where you don't need to reach for your priciest model. It's mostly reading and summarizing, not deep reasoning, so Sonnet handles it fine. Save the expensive model for the parts that actually need judgment. What actually goes in there: project structure, conventions, the tech stack, common commands, architecture, how data flows through the app. Basically the onboarding doc you’d hand a new hire, except this new hire re-reads it every single session. The catch — and it’s a real one — is that everything in CLAUDE.md gets loaded into context on every session. A bigger file means more tokens spent before you’ve even asked your first question. I learned this the annoying way: my first CLAUDE.md was a kitchen-sink dump of everything I thought might someday be useful, and it was quietly taxing every single conversation I had. Trim it to what Claude actually needs to know upfront, not everything you know . By default, Claude Code will ask before doing anything remotely risky, which is safe but gets old fast if you’re working solo and trust it with certain actions. .claude/settings.json has a permissions object where you define allow, deny, ask, and a defaultMode — basically a rulebook for what Claude can do without stopping to check in with you. This matters most when you're not running in full auto-approve mode, since that's when the prompts actually show up. There’s a shortcut worth knowing: /fewer-permission-prompts looks at how you've actually responded to previous permission prompts and updates .claude/settings.local.json accordingly. Instead of hand-writing the rulebook, you let your own past behavior write it for you. One hierarchy detail that tripped me up once: if a team-wide, top-level setting conflicts with an individual’s local setting, the top-level one wins. Makes sense once you think about it — you don’t want one dev’s local config silently overriding a rule the whole team agreed on — but it’s not obvious until you hit it. CLAUDE.md is always loaded. Skills are the opposite: they sit dormant until they’re relevant, which makes them a much cheaper way to give Claude specialized knowledge. A skill is just a folder containing a SKILL.md file — instructions plus a description field that acts as the trigger. Personal ones live in ~/.claude/skills/