Quick reference
Every trap from all 25 lessons — 100 of them — grouped by domain. This is revision material, not a substitute for the lessons: the traps make sense once you've read the reasoning behind them. Print-friendly with Ctrl/Cmd + P.
Applications & Integration
- 2.1 Optimizing for a stated preference while breaking a hard constraint
- 2.1 Assuming latency tolerance when the requirement never states it
- 2.1 Reading "faster" as a throughput problem when it means perceived latency
- 2.1 Treating every mention of documents as a vision requirement
- 2.2 Treating an unexplained behaviour change as a model defect
- 2.2 Shipping prompt changes without an evaluation gate
- 2.2 Versioning code but not prompts, tools, or model references
- 2.2 Defining success only after the system is built
- 2.3 Parsing content[0].text without checking stop_reason
- 2.3 Putting a timestamp or request ID before the cache checkpoint
- 2.3 Assuming caching engaged because cache_control was set
- 2.3 Fixing a batch-shaped workload with a smaller model
- 2.3 Believing Batch is faster
- 2.4 Diagnosing a concurrency failure as a model or prompt problem
- 2.4 Retrying a unit that includes a non-idempotent write
- 2.4 Spreading model references across many call sites
- 2.4 Treating 429 and 400 the same way
- 2.5 Concatenating retrieved content directly into the system prompt
- 2.5 Treating the content boundary as a security control on its own
- 2.5 Sharing conversation context across users to save tokens
- 2.5 Typing constrained fields as free-form strings
- 2.6 Keeping team conventions in personal settings
- 2.6 Running a rolling model alias in production
- 2.6 Treating prompt edits as copy changes
- 2.6 Putting credentials in CLAUDE.md
Model Selection & Optimization
- 5.1 Believing temperature 0 produces byte-identical output
- 5.1 Confusing max_tokens with the context window
- 5.1 Reaching for few-shot examples as a first response
- 5.1 Enabling extended thinking on simple bounded tasks
- 5.2 Treating a 400 as an SDK bug
- 5.2 Reaching for websockets when streaming is what is needed
- 5.2 Retrying a request that failed SDK-side validation
- 5.3 Defaulting everything to the top tier "to be safe"
- 5.3 Downgrading tier as the first cost lever
- 5.3 Treating a behaviour change after an upgrade as a bug
- 5.3 Choosing a tier from the domain rather than the workload
- 5.4 Downgrading the tier before caching and trimming
- 5.4 Assuming a cache checkpoint engaged because the field was set
- 5.4 Optimising before measuring
- 5.4 Changing tier without an evaluation gate
Agents and Workflows
- 1.1 Choosing an agent because the task "involves AI" or feels sophisticated
- 1.1 Justifying subagents by speed
- 1.1 Building an agent loop with no termination condition
- 1.1 Reading a conversational interface as evidence of an agent
- 1.2 Using a system prompt instruction as a hard guarantee
- 1.2 Writing a custom agent loop with no reason beyond preference
- 1.2 Treating the request-execute gap as latency to remove
- 1.2 Self-hosting when the scenario emphasises shipping speed and thin ops
- 1.3 Choosing on popularity, stars, or recency
- 1.3 Dismissing team familiarity as a soft factor
- 1.3 Defaulting to a custom implementation to avoid choosing
Prompt & Context Engineering
- 6.1 Fixing drift by increasing context window size
- 6.1 Fixing drift by lowering temperature
- 6.1 Reaching for compaction when the tool output is the bulk
- 6.1 Treating any long-session degradation as a prompting problem
- 6.2 Stacking negative instructions
- 6.2 Burying conditional rules in a long system prompt
- 6.2 Adding few-shot examples before diagnosing the real cause
- 6.2 Sanitizing untrusted input after the model has read it
- 6.3 Calling a JSON parser directly on the response text
- 6.3 Retrying without feeding the validation error back
- 6.3 Relying on human review to catch wrong output
- 6.3 Typing constrained fields as free-form strings
Tools and MCPs
- 8.1 Choosing few-shot examples to fix description-level misrouting
- 8.1 Reaching for a routing classifier as the first step
- 8.1 Consolidating two similar tools immediately
- 8.1 Rewriting descriptions but never rereading the system prompt
- 8.1 Rewriting descriptions when the real problem is tool count
- 8.2 Modelling read-only data as a tool
- 8.2 Choosing a transport by preference
- 8.2 Building a custom server when a maintained one covers the need
- 8.2 Treating MCP as a capability upgrade
- 8.3 Building an MCP server for a single application's one-off need
- 8.3 Rewriting descriptions when the toolkit is simply too large
- 8.3 Treating a Skill as an executable integration
- 8.3 Copy-pasting a custom tool across six applications
Security and Safety
- 7.1 Adding a system-prompt line as an injection defense
- 7.1 Assuming injection requires a malicious user in the session
- 7.1 Logging raw tool output containing PII
- 7.1 Treating tagging alone as sufficient
- 7.2 Offering one guardrail as a complete solution
- 7.2 Excusing broad credentials because the agent is internal
- 7.2 Letting an agent inherit its launcher's full credentials
- 7.2 Relying on permissive defaults plus documentation
- 7.3 Answering a "regardless of what the model decides" question with prompt wording
- 7.3 Using hooks as a substitute for the other layers
- 7.3 Hooking every tool call
- 7.3 Assuming a hook can judge intent
- 7.4 Putting a key in a prompt
- 7.4 Committing credentials to CLAUDE.md or a config file
- 7.4 Rotating only after a suspected compromise
- 7.4 Monitoring only failed authentication