learn-claude-with-phoebe / Deep dive 6.5
Learn Claude with Phoebe · Deep-dive track 6.5

Features of Claude

Six platform features that separate a demo from a production system: extended thinking when the problem is hard, vision and native PDFs when the input isn't text, citations when the answer must be auditable, prompt caching when the bill must be sane, and a managed code sandbox when the answer needs pandas.

🔴 Deep dive DS & AI 45 min self-paced or live
0-5 · Setup 5-35 · Core 35-45 · Try it
Part 0

Why this page exists

Deep dives 6.1-6.4 taught you to call the API, engineer prompts, wire tools, and build RAG. This page covers the feature layer that the official "Features of Claude" module walks through: the request-level switches that change what Claude can see, how hard it thinks, how answers are grounded, and what a month of production traffic costs. Every card is runnable Python against the current API.

Core - the module spine Advanced - read when you need it ★ Runnable code Covers "Features of Claude" from all 3 engineering courses
★ What you walk out with Working code for each feature, the decision rules for when each one pays, and the two prompt-caching rules that decide whether your token bill drops 80% or not at all.
Part 1 · thinking, images, PDFs

Buying reasoning, feeding non-text inputs 15 min

Three features that change WHAT Claude works with: a reasoning budget for hard problems, image blocks for anything visual, and document blocks for real PDFs.

CoreExtended thinking: paying for reasoning where it matters5 min

Extended thinking gives Claude a scratchpad before it answers. You set a token budget; Claude reasons inside it, then writes the final answer. You pay for the thinking tokens, so the whole game is knowing when it's worth it.

★ Extended thinking, minimal working exampleimport anthropic client = anthropic.Anthropic() resp = client.messages.create( model="claude-sonnet-4-5", max_tokens=16000, thinking={"type": "enabled", "budget_tokens": 8000}, messages=[{ "role": "user", "content": "We have 3 warehouses, 14 SKUs, and the demand table below. " "Plan a rebalancing that minimises transfer cost. Show your reasoning." }], ) for block in resp.content: if block.type == "thinking": print("--- thinking ---") print(block.thinking) elif block.type == "text": print("--- answer ---") print(block.text)
  • When it pays: multi-step math, constrained planning, tricky data analysis, debugging with several interacting causes. Anything where a human would want scratch paper.
  • When it's wasted tokens: lookups, reformatting, summarisation, classification. The model answers those in one pass anyway; the budget just sits there as spend risk.
  • Reading the response: thinking arrives as separate thinking blocks before the text block. Log them in dev (they are gold for debugging prompts), hide them from end users. Note budget_tokens must be less than max_tokens.
  • Tuning: start around 4k-8k for hard analytical questions. If the thinking block ends abruptly mid-reasoning, the budget was too small; if it's short and the budget huge, dial it down.
Budget as a dial, not a switch Run your eval set (deep dive 6.2) at budgets 0 / 2k / 8k and plot accuracy against cost. Most workloads have an obvious knee in that curve - that knee is your production setting.
CoreVision: images as content blocks5 min

Images are just another content block in the messages you already know. Two sources: base64 for local files, URL for anything already hosted.

★ Chart reading from a local screenshotimport anthropic, base64 client = anthropic.Anthropic() with open("q2_revenue_chart.png", "rb") as f: img_b64 = base64.standard_b64encode(f.read()).decode("utf-8") resp = client.messages.create( model="claude-sonnet-4-5", max_tokens=2048, messages=[{ "role": "user", "content": [ {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": img_b64}}, {"type": "text", "text": "Extract every series in this chart as a markdown table, " "then flag any month where the trend reverses."}, ], }], ) print(resp.content[0].text) # Hosted image: swap the source for # {"type": "image", "source": {"type": "url", "url": "https://..."}}
  • Chart reading: dashboards, plots from papers, that PNG a stakeholder pasted into Slack. Claude reads axes, legends, and trends - ask for a table, not a description, and you get data back.
  • Screenshot QA: "does this UI match the spec?" with the screenshot and the spec in the same message. Cheap visual regression review.
  • Document photos: phone photos of receipts, whiteboards, forms. For born-digital PDFs, use the document block in the next card instead - it keeps layout.
  • Practical limits: up to 100 images per request; resize huge images to roughly 1568px on the long edge before encoding, since bigger only burns tokens.
CorePDF support: document blocks beat text extraction5 min

You could run a PDF through an extraction library and paste the text. Native PDF support sends the file itself as a document block, and Claude sees each page as text AND image together.

★ Native PDF question-answeringimport anthropic, base64 client = anthropic.Anthropic() with open("vendor_contract.pdf", "rb") as f: pdf_b64 = base64.standard_b64encode(f.read()).decode("utf-8") resp = client.messages.create( model="claude-sonnet-4-5", max_tokens=2048, messages=[{ "role": "user", "content": [ {"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": pdf_b64}}, {"type": "text", "text": "List every payment obligation with its due date and the " "clause number it comes from."}, ], }], ) print(resp.content[0].text)
  • When native wins: layout that carries meaning (two-column reports, forms), tables that extraction mangles, scanned pages where there is no text layer at all, and anything with charts or stamps inside.
  • When extraction is fine: clean single-column born-digital text you'll reuse across many calls - extracted text is cheaper per call and easier to cache.
  • Cost model: each PDF page costs its text tokens plus an image's worth of tokens, so a 100-page contract is a real spend. Cache it (Part 2) if you'll ask more than one question.
Part 2 · citations and caching

Auditable answers, sane bills 12 min

Citations make answers point at exact source passages. Caching makes the tenth question against the same document nearly free. Together they are the compliance-and-cost story for document workloads.

CoreCitations: answers that point at passages4 min

Enable citations on a document block and every claim in the answer arrives with the exact source span attached - page numbers, character ranges, quoted text. This is the format compliance teams actually accept, because "the model said so" becomes "clause 4.2, page 7 says so".

★ Citation-grounded answers over a policy docimport anthropic client = anthropic.Anthropic() policy_text = open("expense_policy.txt").read() resp = client.messages.create( model="claude-sonnet-4-5", max_tokens=2048, messages=[{ "role": "user", "content": [ {"type": "document", "source": {"type": "text", "media_type": "text/plain", "data": policy_text}, "title": "Expense policy v3.2", "citations": {"enabled": True}}, {"type": "text", "text": "Can I expense a client dinner over $150? Cite the policy."}, ], }], ) for block in resp.content: if block.type == "text": print(block.text) for c in (block.citations or []): print(f' source: "{c.cited_text[:80]}..."')
  • Works on plain-text documents, PDFs (citations carry page numbers), and pre-chunked custom content. Also on search results returned by your own tools.
  • Why it beats "please quote your sources" in the prompt: cited spans are structured fields extracted from the document, not generated text, so they can't be hallucinated quotes. Render them as footnotes or links in your UI.
  • The fit: policy Q&A, contract review, regulatory summaries, anything a human will be held accountable for repeating.
Real world

A data team shipped a "policy bot" twice. Version 1 answered from a RAG index with no citations; legal refused to let staff rely on it. Version 2 sent the policy as a citations-enabled document block and rendered every claim with its clause reference; legal signed off in a week. Same model, same accuracy - the citation format was the approval.

CorePrompt caching part 1: the mechanics4 min

Every call re-sends your whole prompt. If 45k of those tokens are the same system prompt and the same big document every time, you are paying full input price to re-process identical bytes. A cache_control breakpoint tells the API: everything up to here is stable, keep the processed prefix warm.

★ Caching a large stable prefiximport anthropic client = anthropic.Anthropic() big_doc = open("50_page_handbook.txt").read() # large, stable def ask(question: str): return client.messages.create( model="claude-sonnet-4-5", max_tokens=1024, system=[ {"type": "text", "text": "You are the internal handbook assistant. Answer only " "from the handbook below.\n\n" + big_doc, "cache_control": {"type": "ephemeral"}}, # breakpoint here ], messages=[{"role": "user", "content": question}], # variable part ) r1 = ask("What is the remote work policy?") r2 = ask("How many review cycles per year?") print(r1.usage.cache_creation_input_tokens) # big on the first call print(r2.usage.cache_read_input_tokens) # big on the second: cache hit
  • Where to put breakpoints: after the largest stable prefix - system prompt, tool definitions, big reference documents. Up to 4 breakpoints per request for layered prefixes.
  • TTL: the cache lives about 5 minutes and every hit refreshes it, so steady traffic keeps it warm indefinitely. A 1-hour TTL option exists for spiky workloads.
  • The economics: cache writes cost a bit more than normal input, cache reads cost a small fraction of it. Check usage.cache_read_input_tokens in every response - that field is your proof the cache is actually hitting.
Token price relative to normal input Normal input 1.0x Cache write (first call) ~1.25x Cache read (every hit) ~0.1x A cache hit ratio below 80% on a document workload means one of the caching rules is being broken.
🔍 Click to zoom - a cache hit costs about a tenth of a normal input token
Token typePrice vs normal inputWhere you see it in usage
Normal input1.0x baselineinput_tokens
Cache write (first call)~1.25xcache_creation_input_tokens
Cache read (every hit)~0.1xcache_read_input_tokens
CorePrompt caching part 2: the rules that make or break it4 min

Caching fails silently: you never get an error, you just quietly pay full price. Three rules decide whether you hit.

  • Rule 1 - minimum length. A prefix below the minimum cacheable size (1024 tokens on most models, 2048 on the fastest ones) is never cached, no matter the breakpoint. Don't bother caching a two-line system prompt.
  • Rule 2 - byte-identical prefix. The cache key is the exact bytes of everything before the breakpoint. One changed character - reordered JSON keys, a trailing space, a different tool list - and it's a miss. Serialize your prefix deterministically.
  • Rule 3 - order matters. Stable content first, variable content last. The moment something variable appears, everything after it is uncacheable. Structure requests as: tools, then system + big docs (breakpoint), then per-user context, then the question.
Real world

The classic mistake: a team put Current time: 2026-07-07 09:14:03 at the TOP of their system prompt. Every request had a different first line, so every request was a cache miss on the entire 40k-token prefix. Their "cached" bill was identical to the uncached one for three weeks before anyone read the usage fields. Moving the timestamp into the user message fixed it in one line.

Verify, don't assume Log cache_read_input_tokens / (input_tokens + cache_read_input_tokens) as your cache hit ratio. If it isn't above 80% on a document workload, one of the three rules is being violated - almost always rule 2.
Part 3 · the managed sandbox

Code execution and the Files API 8 min

Sometimes the right answer to "analyse this CSV" is not prose - it's Claude writing and running pandas. The code execution tool gives Claude a managed Python sandbox; the Files API gets your data into it.

AdvancedUpload a CSV, let Claude run pandas on it5 min

Two pieces: upload the file once via the Files API, then reference it in a message with the code execution tool enabled. Claude writes Python, runs it in the sandbox, reads the output, and iterates - the same loop a data scientist runs in a notebook.

Managed sandbox or your own code tool Must the code touch YOUR infrastructure? yes no DIY tool (6.3) warehouse, APIs, network Managed sandbox ad-hoc file analysis The managed sandbox is deliberately isolated: no network is a feature there, a blocker here.
🔍 Click to zoom - isolation is a feature for uploads, a blocker for your warehouse
★ CSV analysis in the managed sandboximport anthropic client = anthropic.Anthropic() # 1. Upload the data once via the Files API uploaded = client.beta.files.upload( file=("sales_2026.csv", open("sales_2026.csv", "rb"), "text/csv"), ) # 2. Ask for analysis with the code execution tool enabled resp = client.beta.messages.create( model="claude-sonnet-4-5", max_tokens=4096, betas=["code-execution-2025-05-22", "files-api-2025-04-14"], tools=[{"type": "code_execution_20250522", "name": "code_execution"}], messages=[{ "role": "user", "content": [ {"type": "text", "text": "Profile this file: shape, dtypes, null counts, and the " "3 strongest correlations with monthly_revenue. " "Then flag outlier rows."}, {"type": "container_upload", "file_id": uploaded.id}, ], }], ) for block in resp.content: if block.type == "text": print(block.text)
  • What the sandbox has: Python with the standard data stack (pandas, numpy, matplotlib and friends), a filesystem for your uploaded files, no network access. Claude sees stdout, stderr, and generated files, and can retry when its own code errors.
  • Files created in the sandbox (cleaned CSVs, plots) come back as file references you can download via the Files API - so "clean this file and give it back" is a one-message pipeline.
AdvancedManaged sandbox vs DIY tool: which one when3 min
  • Managed wins when the work is exploratory analysis on uploaded data: you skip building an executor, sandboxing it, capturing output, and handling retries. That's real security engineering you don't have to own.
  • DIY (your own code tool from deep dive 6.3) wins when the code must touch YOUR infrastructure: the warehouse, internal packages, live APIs, network calls. The managed sandbox is deliberately isolated - no network is a feature there, a blocker here.
  • The hybrid most data teams land on: managed sandbox for ad-hoc file analysis, a narrow read-only warehouse tool for governed data access. Which is exactly where the MCP page (6.6) picks up.
Try it yourself

Three exercises ◐ 35-45 min

Source material

Official courses covered

This page teaches the "Features of Claude" module that all three 8-hour engineering courses share, plus the code execution and Files API lectures specific to the API course.

Features of Claude module - all 3 coursesextended thinking, images, PDF support, citations, prompt caching mechanics and rules
Code execution & Files API - Building with the Claude APImanaged sandbox, file upload, analysis loop, managed vs DIY decision

Deep dive 6.5 cheat sheet · pin this

Extended thinkingthinking={"type":"enabled","budget_tokens":N}. Buy it for math, planning, tricky analysis; skip it for lookups and reformatting.
Images{"type":"image","source":{...}} content blocks, base64 or URL. Ask for a table, not a description.
PDFsSend as document blocks when layout, tables, or scans matter; extract to text when it's clean prose you'll cache.
Citations"citations":{"enabled":true} on document blocks. Structured source spans, not generated quotes - the compliance format.
Cachingcache_control {"type":"ephemeral"} after the big stable prefix. Byte-identical, min length, stable-first order. Reads ~0.1x input price, ~5 min TTL refreshed on hit.
Code executionFiles API upload + code_execution tool = managed pandas sandbox. Managed for uploads, DIY tools for your own infrastructure.