Domain 2: Applications and Integration
33.1% of examTranslate business requirements into functional and infrastructure requirements
Key Points
- A business requirement translates into functional requirements (what the system must do) and infrastructure requirements (latency, throughput, residency, availability, budget).
- Five extraction questions: latency sensitivity, volume, accuracy/criticality, data sensitivity, and cost ceiling.
- A low-latency, user-facing chat and an overnight bulk-analysis job sit at opposite ends of nearly every one of these axes.
- Solution architecture is driven by the requirement, not by defaulting to the biggest model or the realtime API.
Decision Rules
When: "Cost is the primary concern and results aren't needed until morning"
→Read this as a batch requirement, not a reason to parallelize synchronous calls.
When: A requirement doesn't explicitly name latency, volume, criticality, sensitivity, or cost
→Extract all five before choosing an architecture.
When: Output feeds an automated action vs. a human review step
→Let that criticality difference change the model tier and reliability bar you design for.
✗ Anti-Patterns to Reject
- Defaulting to the biggest model or the realtime API regardless of the stated requirement.
- Treating latency, volume, accuracy, data sensitivity, and cost as independent knobs rather than one coherent profile.
Apply the systems life cycle to Claude applications
Key Points
- Claude applications still follow the standard SDLC: requirements -> design -> implementation -> testing/evaluation -> deployment -> operation -> maintenance.
- Non-deterministic, model-version-dependent behavior means evals with success criteria replace single equality assertions.
- Model-version pinning and regression testing gate every upgrade, not just the initial launch.
- Production monitoring of quality, latency, token cost, and error rate is an ongoing life-cycle activity.
Decision Rules
When: Testing a stochastic Claude output
→Build an eval with success criteria, not a single equality assert.
When: A new model version becomes available
→Re-run evals against the pinned prompt/model pair before adopting it.
When: An application already passed its launch evals
→Keep production monitoring running -- a passing launch eval does not make monitoring optional.
✗ Anti-Patterns to Reject
- Treating testing/evaluation as a single pre-launch gate rather than a recurring activity.
- Assuming a passing eval at launch means monitoring afterward is optional.
Work with the Messages API's core request/response mechanics
Key Points
- A request is a messages list (alternating user/assistant), plus model, required max_tokens, and optional top-level system, tools, temperature, stream.
- The system prompt is a top-level parameter, not a message with role: "system".
- stop_reason (end_turn, max_tokens, stop_sequence, tool_use) tells integration code why generation stopped and what to do next.
- usage reports input_tokens/output_tokens plus cache read/creation tokens -- the basis for cost modeling.
- The API is stateless: it keeps no memory between calls, so the full conversation must be resent every request.
- Streaming (server-sent events) lowers perceived latency without changing total tokens or cost; a tool_use stop_reason requires executing the tool and returning a tool_result; vision uses image content blocks alongside text.
Decision Rules
When: Setting the system prompt
→Use the top-level system parameter, never a role: "system" message.
When: A response's stop_reason is tool_use
→Execute the tool and send a tool_result block in a new user message -- it is not a final answer.
When: Building a multi-turn conversation
→Resend the full conversation on every call; the API retains no memory of prior turns.
When: Deciding whether to stream
→Expect lower perceived latency, not lower cost or fewer total tokens.
✗ Anti-Patterns to Reject
- Believing the system prompt is a role: "system" message.
- Forgetting that max_tokens is required on every request.
- Assuming streaming reduces total token cost.
Apply extended thinking, prompt caching, batch processing, and vendor choice
Key Points
- Extended thinking is an explicit reasoning budget spent before the answer; thinking tokens are billed as output tokens -- not a free upgrade.
- Prompt caching (cache_control) discounts a stable, reused prefix: cache reads are much cheaper, cache writes cost slightly more than normal input; it pays off through reuse.
- The Message Batches API processes many requests asynchronously within 24 hours at a substantial (roughly 50%) per-token discount.
- Realtime (Messages API, often streaming) fits interactive, user-waiting work; batch fits high-volume, cost-sensitive, 24h-tolerant work.
- The same Claude models are available via Amazon Bedrock and Google Vertex AI -- differences are auth, endpoint/region, and model-ID naming, not model behavior.
Decision Rules
When: A workload is high-volume, cost-sensitive, and tolerant of a next-day turnaround
→Use the Message Batches API, not parallelized synchronous calls.
When: Many requests share a long, unchanging prefix
→Mark it with cache_control for prompt caching.
When: A task's reasoning depth genuinely needs it
→Turn on extended thinking and accept the added output tokens and latency.
When: Choosing among the direct API, Amazon Bedrock, and Google Vertex AI
→Decide on cloud footprint, data residency, and procurement, not model behavior differences.
✗ Anti-Patterns to Reject
- "Batch is just parallel realtime calls" -- it is a distinct asynchronous API with its own SLA and discount.
- Applying extended thinking uniformly across a pipeline instead of only to steps that need it.
- Assuming vendor choice (Bedrock vs. Vertex AI vs. direct API) changes model quality.
Apply software-engineering foundations and error handling to Claude integrations
Key Points
- The Claude API is HTTPS + JSON: status codes, headers, request/response shape, idempotency, and pagination apply like any REST service.
- Async/await and concurrency are the right tools for I/O-bound LLM calls; the SDKs ship async clients for exactly this.
- Git branching, PRs, and history are the substrate for reviewing and rolling back prompt/model changes, same as any code change.
- Prompts and model IDs are reviewable, versioned artifacts, not incidental strings exempt from SDLC/code review.
- 429/529/5xx are transient -- retry with exponential backoff and jitter; 400/401 are your bug -- fix and resend, retrying unchanged won't help.
Decision Rules
When: An LLM call is I/O-bound inside a request path
→Use an async client to parallelize it rather than blocking synchronously.
When: A response returns 429 or 529/5xx
→Retry with exponential backoff and jitter.
When: A response returns 400 or 401
→Fix the payload or credentials; retrying unchanged will fail identically.
When: A prompt or model ID changes
→Route it through the same code review and version control as a code change.
✗ Anti-Patterns to Reject
- Applying backoff-and-retry to 400/401 errors.
- Treating prompts and model IDs as "just strings" exempt from code review and version control.
- Retrying without jitter, risking synchronized retry storms across clients.
Match instruction mechanisms to the Claude interface in use
Key Points
- Four interfaces, four distinct instruction mechanisms: API/SDKs (system param + messages/tools/params), claude.ai (chat + Project instructions/knowledge), Claude Desktop (chat + connected MCP servers), Claude Code (CLAUDE.md + settings.json + slash commands).
- Each row is a genuinely different authoring surface, not a stylistic variant of the same thing.
- Instructions don't transfer verbatim across surfaces -- a CLAUDE.md shapes Claude Code, it does not configure a raw Messages API call.
Decision Rules
When: Designing for a raw Messages API integration
→Remember its only instruction channel is the system parameter plus message content -- there is no CLAUDE.md concept there.
When: Designing for Claude Code
→Use CLAUDE.md, settings.json, and slash commands, not API-style system-parameter conventions.
When: A described design says "set up a CLAUDE.md for the chatbot"
→Recognize the wrong instruction mechanism matched to the wrong surface.
✗ Anti-Patterns to Reject
- Assuming instructions transfer verbatim across surfaces (CLAUDE.md does nothing for a raw Messages API call).
- Treating "Claude" as one monolithic product with a single instruction surface.
Design content boundaries, schema output, session hygiene, and plugin management
Key Points
- Content boundaries: keep trusted instructions separate from untrusted data (user input, retrieved documents, tool output); delimit clearly (e.g., XML-style tags).
- Schema design: define a JSON schema and use structured output/tool-forcing for machine-readable output that is strict but not brittle.
- Session hygiene: because the API is stateless and context is finite, deliberately decide what carries forward -- compact long threads, start fresh when polluted, don't let stale tool output accumulate.
- Plugin management: explicitly track which MCP servers/plugins are enabled, their permissions, and their versions.
Decision Rules
When: Untrusted content (user input, retrieved document, tool output) enters the prompt
→Delimit it clearly so it cannot be read as an instruction.
When: Designing a machine-readable output schema
→Make it strict enough to parse reliably but not so rigid it fails on reasonable variation.
When: A session's context becomes polluted with stale or irrelevant history
→Start a fresh session rather than continuing to patch a degraded thread.
When: Connecting plugins/MCP servers
→Track enablement, permissions, and versions explicitly, not as an install-once inventory.
✗ Anti-Patterns to Reject
- Placing unsanitized untrusted text directly in the prompt without delimiting it.
- Treating maximum schema rigidity as strictly safer, when an overly rigid schema fails on legitimate edge cases.
- Continuing to patch a polluted session with more instructions instead of starting fresh.
Manage Claude application configuration as versioned artifacts
Key Points
- CLAUDE.md is project/repo memory for Claude Code and belongs in version control, reviewed like code.
- settings.json is Claude Code's settings surface: permissions, hooks, tool allow/deny lists, environment, model selection, MCP servers.
- Model-version pinning: use an explicit model ID rather than a floating "latest" alias -- a reproducibility hazard.
- Prompt versioning: treat prompts as artifacts with version history so a quality regression can be traced to a specific change.
- Plugin dependencies: track plugin/MCP-server versions like any other software dependency.
Decision Rules
When: A team wants the same coding conventions applied for everyone on a repo
→Commit them to a project-level CLAUDE.md, not each developer's personal ~/.claude/CLAUDE.md.
When: Deploying to production
→Pin an explicit model ID and gate any upgrade behind re-run evaluations.
When: A quality regression appears in production
→Use prompt version history to correlate it to a specific prompt change.
✗ Anti-Patterns to Reject
- Relying on a floating "latest" model alias in production.
- Treating CLAUDE.md as a personal scratch file rather than checked-in, reviewed project memory.
- Treating plugin/MCP-server versions as unimportant background detail.