Prompt and Context Engineering (11.0%)
What the exam tests: writing and iterating on prompts, placing instructions in the right component, managing the context window over long sessions, and producing and validating output your code can trust.
Prompt engineering (4.6%)
The principles Anthropic documents, in the order that usually pays off:
Be clear and direct. State the task, the audience, the success criteria, and the format. Treat Claude like a capable new colleague with no context.
Give context and the reason. "Keep it under 100 words because it shows in a mobile notification" works better than "be brief." Use examples (few-shot). Three to five varied examples, wrapped in <example> tags, steer format and tone more reliably than description.
Structure with XML tags. Separate instructions, documents, and examples:
<instructions>, <document>, <examples>.
Let Claude think. For complex reasoning, enable adaptive thinking or raise effort rather than writing "think step by step" into every prompt.
Assign a role in the system prompt when expertise or tone matters.
Chain complex tasks into separate calls rather than one giant prompt.
System versus user placement.
- Put in the system prompt Put in the user turn
- Role, persona, tone The specific request
- Stable rules and policies Per-request data and documents
- Tool-use guidance The question about that data
- Output format conventions Untrusted content, clearly tagged
For long documents (20K tokens or more), put the documents near the top of the prompt and the question at the end; this measurably improves answer quality.
Placement across components. In a full app, instructions live in several places: system prompt, tool descriptions, CLAUDE.md, Skills, and mid-conversation system messages on models that support them. Keep each instruction in one place and make sure they do not contradict each other. A tool's description is the right home for when and how to use that tool. Output constraints. Say what to do rather than what not to do ("respond in flowing prose paragraphs" beats "no markdown"). Match your prompt's style to the output you want. Iterative refinement. Write a prompt, run it against an eval set, read failures, change one thing, and re-run. Keep prompts in version control.
Input sanitization. Strip or escape content that could break your structure, such as stray closing tags in user input, and cap input length. Model-specific note. Assistant-message prefill (starting Claude's reply for it) is no longer supported on current models; use structured outputs or system-prompt instructions to control format instead.
Context engineering (3.8%)
Context engineering is deciding what goes into the window on each turn. More is not better: irrelevant tokens cost money and degrade attention.
- Problem What it looks like Techniques
- Context bloat Window fills with old tool outputs
- and logs
Tool output pruning (context editing clears old tool results), return summaries from tools, paginate large results
- Context drift Over a long session the agent for‐
- gets early instructions or goals
- Restate key goals, keep a running task file or memory, compac‐
- tion that preserves decisions
- Hitting the limit Requests fail or quality drops near
- the window size
- Compaction (server-side summarization of earlier turns near a
- threshold), starting a fresh session with a handoff summary
- Cross-task
- contamination
Details from task A leak into task B Context isolation via subagents or separate sessions Compaction vs context editing. Compaction summarizes earlier history into a shorter block. Context editing deletes specific old content (such as tool results) without summarizing. When using server-side compaction, append the full response.content back each turn, not just the text, or the compaction state is lost.
Context isolation. Give a subagent the narrow task and only the context it needs; have it return a concise result. The main agent's window stays clean.
Output handling (2.6%)
Structured outputs. Constrain the response to a JSON schema with output_config: {format: {type: "json_schema", ...}}, or use the SDK's messages.parse() helper with a Pydantic or Zod model. For tool arguments, set strict: true on the tool definition.
Response validation. Validate every output against its schema and business rules before use. Check stop_reason first: a max_tokens stop means incomplete JSON.
Defensive parsing. Parse with a real JSON parser, never string matching. Handle missing optional fields. Escaping in tool inputs can vary between models.
Skepticism toward confident output. Fluent, confident text can be wrong. Verify facts against sources (citations help), recompute numbers in code, and route high-stakes outputs to human review.
Worked example 7.1: rewriting a weak prompt
Before:
Summarize this meeting transcript. Be concise. DON'T make things up!!!
{transcript}
Problems: no audience, no format, no definition of "concise," shouting instead of a reason, and the transcript is not separated from instructions.
After:
You will summarize an internal product meeting for engineers who missed it.
They need to know what was decided and what they must do, not the discussion.
<transcript>
{transcript}
</transcript>
Write the summary in this format:
<summary>
Decisions: a bulleted list, one line each.
Action items: a bulleted list of "owner: task (due date if stated)".
Open questions: anything raised but not resolved.
</summary>
Only include points stated in the transcript. If a section has nothing, write "None." The readers will act on this summary, so an invented action item would cause real work. What changed: a clear audience and purpose, data in tags, an explicit output structure, an instruction to say "None" rather than invent, and a calm reason in place of capital letters. For long transcripts, the transcript appears before the instructions about the output, which keeps the question near the end.
Worked example 7.2: few-shot examples that steer format
A ticket tagger keeps producing inconsistent tags ("Billing," "billing issue," "Payments"). Adding examples fixes the vocabulary:
Tag each support ticket with exactly one of: billing, login, bug, feature_request, other.
PROMPT AND CONTEXT ENGINEERING (11.0%)
<examples>
<example><ticket>I was charged twice this month.</ticket><tag>billing</tag></example>
<example><ticket>Password reset email never arrives.</ticket><tag>login</tag></example>
<example><ticket>Export to CSV crashes the app.</ticket><tag>bug</tag></example>
<example><ticket>Can you add dark mode?</ticket><tag>feature_request</tag></example>
</examples>
<ticket>{ticket}</ticket>
Examples should be diverse (cover each class), realistic, and consistent with the instructions. For a closed set like this, structured outputs with an enum give a hard guarantee on top of the examples.
Worked example 7.3: structured outputs in code
messages=[{"role": "user", "content": f"Extract the invoice fields.\n\n<invoice>{text}</
invoice>"}], output_format=Invoice,
)
invoice = result.parsed_output # an Invoice instance, already validated (The raw API equivalent is output_config: {format: {type: "json_schema", schema: ...}} on messages.create; exact helper argument names vary by SDK version, so check the SDK reference.) Even with a schema guarantee, apply business validation: does total_cents match the sum of line items? Is due_date after the invoice date? A schema guarantees shape, not truth.
Worked example 7.4: defensive parsing without structured outputs
Sometimes you receive JSON inside free text, for example from a legacy prompt. Parse defensively: import json, re
def extract_json(text: str) -> dict | None:
match = re.search(r"<json>(.*?)</json>", text, re.DOTALL) # ask for tags in the prompt if not match:
retry_with_feedback("Your previous answer was not valid JSON inside <json> tags.") The right long-term fix is structured outputs, but the exam still tests the defensive habits: delimiters, real parsers, required-field checks, and a retry path with feedback.
Worked example 7.5: managing context in a long agent run
A migration agent runs for three hours. By hour two it has 600,000 tokens of history, mostly old file contents and test logs, and it starts repeating finished work.
A layered fix:
Tool output pruning. Tools return summaries ("42 tests passed, 3 failed: test_a, test_b, test_c") instead of full logs. Context editing clears old tool results automatically after they are used.
A progress file. The agent keeps PROGRESS.md with completed modules, current module, and decisions. It reads this file at each step.
Compaction. Near a threshold, earlier turns are summarized server-side, preserving decisions and current state. Subagents for exploration. "Find every caller of legacy_auth()" goes to a subagent that returns a list, not 40 file reads. Result: the working context stays around 100,000 tokens, quality holds, and cost per step falls.
Worked example 7.6: placing instructions across components
A team's agent has the same rule in four places, worded differently: the system prompt says "never refund over $100," a tool description says "refunds up to $250 are allowed," CLAUDE.md says "check with finance for large refunds," and a Skill says "auto-approve refunds under $500." Claude will behave inconsistently because the instructions conflict. The fix: Decide the policy once ($100 limit).
Enforce it in code: the refund tool rejects amounts over $100 and returns an error explaining the limit.
Describe it once, in the refund tool's description, where Claude reads it at the moment of use.
PROMPT AND CONTEXT ENGINEERING (11.0%)
Remove the other copies.
Scenario drills
A prompt says "Do not use bullet points" and Claude still uses them. Suggest a better instruction. A RAG app retrieves 30 chunks per question and quality is worse than with 5. Why? Structured outputs return valid JSON, but a field is sometimes semantically wrong. What next?
A chatbot's system prompt includes the user's name and today's date at the top. Name two problems.
An agent's instructions are 6,000 words of rules accumulated over a year. What is the likely effect, and what should you do?
You want Claude to admit when the answer is not in the provided documents. How do you prompt for it?
Answers:
Describe the target positively: "Write in flowing prose paragraphs," and match the prompt's own style to prose.
Context dilution: more irrelevant text competes with the relevant chunks and costs more tokens; retrieve fewer, better-ranked chunks.
Add business-rule validation and examples covering the confusing case, ask for supporting quotes, and add the case to the eval set.
It breaks prompt caching across users and days, and it mixes per-request data into stable instructions; move both to the user turn. Contradictions and diluted attention, plus higher cost per call; audit and prune to the rules still needed, and enforce hard rules in code.
Tell it explicitly: "If the documents do not contain the answer, say you could not find it in the provided documents." Citations make this easier to verify.
Common traps
Writing "NEVER do X" in capitals. Modern models over-react to shouting; explain the reason calmly.
Putting per-request data in the system prompt (and breaking the prompt cache). Using prefill to force JSON on current models; it returns an error. Use structured outputs. Letting tool outputs accumulate unbounded in a long agent loop.
Trusting model-generated JSON or numbers without validation.
Check yourself
Where should a customer-service persona and refund policy go: system prompt or user turn?
A 4-hour agent session starts ignoring its original constraints. Name this problem and two fixes.
Which API feature guarantees the response matches a JSON schema?
You pass three 40-page contracts and a question. Where should the question go? Why is compaction different from context editing?
Answers: The system prompt. Context drift; restate goals in a task or memory file, use compaction that preserves key decisions, or delegate sub-tasks to subagents. Structured outputs (output_ config.format), or strict: true for tool inputs. At the end, after the documents. Compaction summarizes history; context editing removes specific old content without summarizing.
PROMPT AND CONTEXT ENGINEERING (11.0%)