Claude Academy

Unofficial, machine-generated summaries, as of 2026-11-09.

Claude on Google Cloud: 06-Temperature
  • Temperature reshapes the probabilities Claude samples the next token from. It runs from 0 to 1; in the example "about" has 30% and "would" 20%, and near 0 Claude almost always takes the top token (shown as "about" at 100%), while near 1 probability spreads out (23% down to 9% across seven tokens).
  • Choose the temperature range by task. Low (0.0–0.3) for factual answers, coding, data extraction and moderation; medium (0.4–0.7) for summarization, educational content, problem-solving and constrained creative writing; high (0.8–1.0) for brainstorming, creative writing, marketing and jokes.
  • Higher temperature raises the odds of variety without guaranteeing it. Generating movie ideas at 0.0 kept returning a time-travelling archaeologist premise, while 1.0 gave more variety, though similar outputs can still recur; the chat helper gains a temperature=1.0 parameter.
Claude on Google Cloud: 05-System prompts
  • A system prompt makes Claude answer as the named role would. It is a plain string passed as system to the create call; the math-tutor example tells Claude to give hints and guide step by step rather than hand over answers or say "use a calculator".
  • The change in output is large. For "How do I solve 5x + 2 = 3 for x?", Claude without a system prompt gives the full solution; with the tutor prompt it asks what a good first step to isolate x would be.
  • The API rejects system=None, so add it conditionally. The reusable chat(messages, system=None) builds a params dict and includes system only when one is supplied.
Claude on Google Cloud: 04-Multi-turn conversations
  • The API keeps no conversation history between requests. Every call is independent, so a follow-up like "Write another sentence" after a quantum-computing question gets a sentence about something random.
  • Context comes from resending the whole message list each time. Your code keeps the list, appends Claude's reply as an "assistant" message and the follow-up as a "user" message, then sends everything; the lesson wraps this in three helpers, add_user_message, add_assistant_message and chat.
Claude on Google Cloud: 03-Making a request
  • The SDK needs its vertex extra and a Vertex-specific client. Install with %pip install "anthropic[vertex]<1", then create AnthropicVertex(region="global", project_id="your-project-id"); the lesson's model is claude-haiku-4-5@20251001, stored in a variable for reuse.
  • max_tokens is a budget, not a target. At 1000, Claude writes whatever length it judges appropriate and only stops if it would exceed the limit.
  • Messages carry the conversation as role-tagged dictionaries. Each has a role ("user" for human-written input, "assistant" for Claude's output) and content; client.messages.create takes model, max_tokens and this messages list.
  • The generated text sits at message.content[0].text. The full response object carries a lot of metadata, and this pattern extracts just the text.
Claude on Google Cloud: 02-Vertex AI Setup
  • Anthropic models must first be enabled in Vertex's Model Garden. In the Google Cloud console, open Model Garden, search "Anthropic", pick the model and click Enable; if there is no Enable button, you already have access.
  • The SDK uses gcloud's application-default credentials automatically. After installing the gcloud CLI, run gcloud init, gcloud auth login, gcloud config set project YOUR_PROJECT_ID and gcloud auth application-default login; no further credential handling is needed in code.
Claude on Google Cloud: 01-Accessing the API
  • Never call the API directly from client code. Requests carry secret credentials that anyone could read in client code, so the lesson routes every request through a server you control, which talks to Vertex using Anthropic's SDKs (Python, TypeScript, Go, Ruby) or Google's Vertex SDKs.
  • Every request needs four fields. Google Cloud credentials to authorize it, the model name, a messages list with the user's input placed in a "user" message, and max tokens to cap how much the model generates.
  • Claude builds a response one token at a time. Input is tokenized, each token becomes an embedding (a list of numbers standing for its possible meanings), embeddings are adjusted by their neighbours to settle meaning (e.g. "quantum" as physics, computing or "very small"), and an output layer gives next-word probabilities. Claude samples using a mix of probability and randomness rather than always taking the top word, appends it, and repeats.
  • Generation stops on one of three conditions. The max-tokens limit is reached, the model emits an end-of-sequence token (an invisible signal of a natural ending), or it produces a predefined stop sequence.
  • The response metadata is worth watching. Vertex returns the generated message, usage counts of input and output tokens, and the stop reason; the server forwards the text to the client, and the lesson advises monitoring the metadata to track usage and understand model behaviour.
Claude with Amazon Bedrock: 65-Qualities of agents
  • Agents observe the environment far more than they change it. In the Claude Code example of adding a test for a corner case, three of four tool calls (two file reads, one test run) gathered information and only one modified a file; Computer Use likewise gets a screenshot back from every action.
  • Effective agents run a small, focused toolset in a loop. The lesson says agents should keep calling a few simple, well-defined tools until they hit an iteration limit, an error, or the success criteria, which lets them course-correct.
  • Context comes from tools, not from long prompts or RAG. Claude has no built-in knowledge of your environment, so the lesson argues the quality of an agent's context-gathering tools directly sets how well it performs.
  • Point agents at high-value tasks where mistakes are cheap. Writing code is the model case, expertise-heavy but with errors that can be caught and fixed; the lesson rates Computer Use's error cost very low and Claude Code's low but not negligible, and warns off high-stakes economic or safety decisions.
  • Only continuous evaluation makes agents reliable. The lesson says the sole dependable method is to define evaluation criteria and keep testing the agent's prompts and tool descriptions against real scenarios.
Claude with Amazon Bedrock: 64-How Computer Use works
  • Computer use is ordinary tool use with a different tool. The flow is the same as a get_weather call: you send tool schemas, Claude returns a tool-use request, your server runs it and sends the result back; only now the tool clicks, types, scrolls and takes screenshots.
  • A minimal schema is expanded behind the scenes into the full interface. You send a small computer_20250124 tool schema with the display size, and it is converted into a detailed specification with action, coordinate, duration and text properties.
  • Claude never controls the computer directly; your infrastructure does. Claude only issues tool requests, and your server executes them in an environment that can simulate input, which in the reference implementation is a Docker container running Firefox.
  • Anthropic's reference implementation removes the need to build this yourself. It needs a Docker runtime (orbstack.dev is given as an example), a local AWS profile (usually "default"), and the code from the Anthropic quickstarts repository on GitHub, then starts with one docker run command and shows a chat panel beside a browser.
Claude with Amazon Bedrock: 63-Computer Use
  • Computer use lets Claude perform tasks, not just describe them. It takes screenshots, clicks, types, moves between applications and tabs, and follows multi-step processes that need visual feedback, which the lesson says suits QA testing of user interfaces.
  • Claude can run a QA test plan and find real bugs. Given three test cases for a React "@" mention autocomplete, it passed typing "Did you read @" and pressing Enter, but found the dropdown appeared in the wrong place after backspace, and reported this with screenshots.
  • The testing run follows a repeatable structure. Claude opens the app in a browser, works through each case step by step, verifies with screenshots, refreshes the page between tests for a clean state, and ends with a pass/fail summary report; the lesson stresses it runs identically after every code change.
  • Computer use should always run in an isolated environment. The typical setup is a Docker container with a desktop, a controllable browser and a chat interface, fully separated from your main system so your data is not at risk.
  • Give specific tasks and success criteria, then verify the findings. The lesson's best practices are to break complex workflows into small steps, state clear success criteria, and manually check any important result Claude reports.
Claude with Amazon Bedrock: 62-Automated debugging
  • Production-only errors are costly to find by hand. In the example, a chatbot deployed to AWS Amplify failed silently on spreadsheet generation that worked locally, and the cause, "The provided model identifier is invalid", was buried in CloudWatch logs.
  • A scheduled GitHub Action can hand the whole debugging loop to Claude. Run daily, it checks out the repo, pulls the last 24 hours of CloudWatch logs with the AWS CLI, has Claude deduplicate the errors and fix each one, then commits and opens a pull request.
  • Claude traced the example failure to a typo'd model ID. The invalid identifier was referenced only in production configuration; Claude corrected it in lib/ai/providers.ts and the pull request carried Error, Root Cause and Fix Implemented sections.
  • The pull request keeps a human review step in the loop. The lesson presents the PR as the point where you verify a fix before merging, alongside proactive detection and documented explanations.
  • The workflow needs limits and permissions set deliberately. The lesson lists CloudWatch access permissions, repository write permissions for PRs, a cap on errors processed to fit the context window, deduplication logic, and running off-peak.
Claude with Amazon Bedrock: 61-Parallelizing Claude Code
  • Running several Claude Code instances at once is a major productivity gain. Because Claude is lightweight, the lesson says you can give each copy a separate task and in effect get a team of virtual engineers, though instances editing the same files will produce conflicting code.
  • Git worktrees give each instance an isolated copy of the project. Each worktree is a full copy of the codebase on its own branch in its own directory, so an instance works without interference and its branch is merged back like any other.
  • Claude Code can automate creating its own worktrees. The example prompt has it create a worktree in a .trees folder (stopping if one exists), symlink untracked dependencies such as .venv, and launch VS Code in that directory.
  • Custom slash commands turn the long prompts into reusable commands. A .md file in .claude/commands becomes a command, and $ARGUMENTS is replaced by what you pass, so /project:create_worktree feature_a builds a worktree named feature_a.
  • A second command lets Claude merge worktrees and resolve conflicts. It changes into the worktree, examines the latest commit, returns to the root, merges the branch, and resolves conflicts from its understanding of each branch's changes; the lesson claims capacity multiplies by the number of instances.
Claude with Amazon Bedrock: 60-Adding MCP servers to Claude Code
  • Claude Code's built-in MCP client lets servers add new capabilities. Each connected server can supply tools, prompts and resources; the example adds a custom server whose document_path_to_markdown tool converts PDF and Word files to markdown.
  • One command registers a server with Claude Code. claude mcp add documents uv run main.py takes a server name of your choosing and the command that starts the server; you stop Claude Code first and it connects on restart.
  • Existing MCP servers already cover common development services. The lesson lists sentry-mcp for fixing logged bugs, playwright-mcp for browser automation, figma-context-mcp, mcp-atlassian for Confluence and Jira, firecrawl-mcp-server for scraping, and slack-mcp for posting messages.
  • Combining servers tailors Claude Code to your own workflow. The suggested pattern pairs Sentry for production errors, Jira for ticket requirements and Slack for team notification, plus custom servers for in-house tools.
Claude with Amazon Bedrock: 59-Claude Code in action
  • Claude Code is meant to cover the whole project lifecycle. The lesson frames it across five stages, Discover, Design, Build, Deploy, and Support and Scale, rather than as a code-writing tool only.
  • /init records your codebase in a CLAUDE.md Claude rereads automatically. It notes structure, dependencies, commands and patterns; CLAUDE.md files can be project-level (checked into git), local (not checked in) or user-level (all projects), and the # shortcut appends quick notes.
  • Planning before coding gets better results on complex features. The workflow is to have Claude read the relevant files, ask it to plan the solution while explicitly not writing code, then have it implement the plan.
  • Test-driven development costs more upfront but makes Claude far more effective. Claude reads the context, proposes test cases without writing code, implements only the relevant tests, then iterates on code until they pass, which the lesson says catches unconsidered edge cases.
  • Claude Code also handles routine development chores. The lesson lists environment setup and dependency installs, staging and committing with descriptive messages, running and interpreting tests, and /clear to reset context.
Claude with Amazon Bedrock: 58-MCP review
  • Each MCP primitive is controlled by a different layer of the stack. The lesson's organizing claim is that Claude controls tools, your application controls resources, and the user controls prompts.
  • Tools are model-controlled and extend what Claude can do. Claude alone decides when to call them; asked for the square root of 3 using JavaScript, it chose a JavaScript execution tool without any prompting from the app or user.
  • Resources are app-controlled and get data into your application. Your code decides when to fetch them, for autocomplete, file pickers, or adding context to messages; Claude's "Add from Google Drive" lists documents in the UI and injects the chosen one into the chat.
  • Prompts are user-controlled predefined workflows. Users trigger them through buttons, menu options or slash commands, like the writing, learning and coding buttons under Claude's chat input.
Claude with Amazon Bedrock: 57-Prompts in the client
  • Listing prompts is a thin wrapper over the client session. list_prompts awaits the session's list_prompts call and returns result.prompts.
  • get_prompt interpolates arguments and returns messages ready for Claude. The arguments, such as a doc_id for the "format" prompt, are passed as keyword arguments to the server's prompt function, and the returned messages can go straight to Claude.
  • In the client, prompts surface as slash commands. Typing "/" lists /format; choosing it and a document sends the interpolated prompt as a user message, and Claude then uses the server's tools to fetch the document and return it reformatted.
  • Server prompts should be well-tested and specific to the server's purpose. The workflow is to write and evaluate the prompt, define it with @mcp.prompt, and let any client request it with arguments, making it reusable across clients.
Claude with Amazon Bedrock: 56-Defining prompts
  • Server-supplied prompts beat what users would write themselves. A one-line "Convert report.pdf to markdown" works, but the lesson argues a tested, detailed prompt covering edge cases does better, and server authors can craft that once for every user.
  • Prompts are defined with a decorator, like tools and resources. @mcp.prompt takes a name and description, and the function returns a list of base.Message objects, so a prompt can hold several user and assistant messages; base is imported from mcp.server.fastmcp.prompts.
  • The example "format" prompt chains the server's own tools. It takes a doc_id, tells Claude to read the document, rewrite it with markdown headers, bullets and tables, and save it with the edit_document tool.
  • Test prompts in the MCP Inspector before shipping them. The Prompts tab takes the parameters (doc_id set to outlook.pdf in the example) and shows the generated messages, confirming interpolation and content.
  • Prompts give quality control, consistency and reuse. The lesson lists authors refining prompts before users see them, everyone getting the same prompt, domain specialization, and use across multiple client applications.
Claude with Amazon Bedrock: 55-Accessing resources
  • Resources put data into the prompt without a tool call. When a user types "@", the client sends a ReadResourceRequest for docs://documents to populate autocomplete, and the selected document's content goes straight into the prompt to Claude.
  • The client's read_resource must branch on MIME type. It calls the session's read_resource with an AnyUrl, takes the first item of result.contents, and returns json.loads of the text for application/json or the raw text otherwise.
  • Resources suit relatively static reference material. The lesson credits them with lower latency, no extra calls during the conversation, a better autocomplete experience, and a cleaner split between static data and dynamic operations, for things like documentation and reports.
Claude with Amazon Bedrock: 54-Defining resources
  • Resources are read-only endpoints, like GET handlers in HTTP. They are addressed by URI, can return strings, JSON or binary data, and carry a mime_type as a hint to the client; a client fetches one with a ReadResourceRequest.
  • Resources are either direct or templated. Direct ones have fixed URIs such as docs://documents; templated ones carry parameters such as docs://documents/{doc_id}, which the Python SDK parses and passes to the function as keyword arguments of the same name.
  • The SDK serializes return values for you. With @mcp.resource, list_docs returns a Python list as application/json and fetch_doc returns text/plain, raising ValueError for an unknown ID, with no manual JSON conversion.
  • The Inspector lists direct and templated resources separately. Started with uv run mcp dev mcp_server.py, it shows direct ones under Resources and templated ones under Resource Templates, each testable for its exact response.
  • Resources let clients fetch data proactively, without tools. The lesson names autocomplete lists, file contents, database records and configuration as uses, and document mentions injected into prompts as the key one.
Claude with Amazon Bedrock: 53-Implementing a client
  • Real projects build an MCP client or a server, rarely both. The course builds both only so the interaction can be seen end to end.
  • The client wraps the SDK's ClientSession to manage cleanup. The session from the MCP Python SDK does the low-level communication but needs careful resource cleanup at shutdown, which the custom MCP Client class handles.
  • The application needs just two client calls: list_tools and call_tool. The CLI lists tools to send to Claude and runs tools when Claude asks; each is a one-line await on the session, and uv run mcp_client.py runs a test harness that prints the tool definitions.
  • MCP tool schemas differ from what Bedrock expects. The MCP spec has its own tool format, so the project's to_bedrock_tools function in core/bedrock.py converts MCP definitions before they reach Claude.
  • The full loop runs from a plain question to a tool call. With uv run main.py, asking for the contents of report.pdf makes Claude pick read_doc_contents, which the client executes on the server before Claude answers.
Claude with Amazon Bedrock: 52-The server inspector
  • The SDK's browser inspector tests a server without a full application. mcp dev mcp_server.py starts it on a local URL, typically port 6277; the lesson warns the interface is under active development and may look different.
  • Tools can be run and checked directly from the inspector. After Connect and List Tools, selecting read_doc_contents with "deposition.md" returns its text, and edit_document can be run with old and new strings and then verified with another read.
  • The inspector supports a fast edit-restart-test loop. It keeps a history of tool calls for repeating tests, so you change server code, restart the inspector and verify immediately.
Claude with Amazon Bedrock: 51-Defining tools with MCP
  • The MCP Python SDK replaces hand-written JSON schemas with decorators. @mcp.tool plus type hints and pydantic Field descriptions generates the tool schema from the function signature, with validation and error handling handled by the SDK.
  • The course code breaks on the newer SDK major version. It uses version 1; version 2 renamed FastMCP, so the from mcp.server.fastmcp import FastMCP import fails; the pin is uv add "mcp[cli]<2" or pip install "mcp[cli]<2".
  • The example server keeps six documents in an in-memory dictionary. FastMCP("DocumentMCP", log_level="ERROR") serves docs keyed by ID, such as deposition.md and report.pdf, each mapped to a one-line content string.
  • Two tools read and edit documents, each rejecting unknown IDs. read_doc_contents returns a document's text; edit_document does a find-and-replace with Python's str.replace using doc_id, old_str (which must match exactly, including whitespace) and new_str; both raise ValueError for a missing doc_id.
  • The Claude Agent SDK's @tool decorator works differently. It takes an explicit input_schema, either a dict mapping names to types like {"latitude": float} or a full JSON Schema for enums, ranges, optional or nested fields, rather than Field annotations; the lesson advises checking which SDK tool code imports.
Claude with Amazon Bedrock: 50-Project setup
  • The course project is a CLI chatbot over in-memory documents. It gives Claude tools to read and update documents, lets users mention a document with @doc_name and run commands with /command_name, and keeps all files in memory to stay focused on MCP.
  • Building both client and server in one codebase is for teaching only. In real projects you would usually build an MCP server to distribute a service to other developers, or a client to connect to existing third-party servers, not both.
Claude with Amazon Bedrock: 49-MCP clients
  • MCP is transport agnostic. Client and server most often run on the same machine and talk over standard input/output, but they can also connect over HTTP, WebSockets or other network protocols.
  • Two request/result pairs carry most of the traffic. ListToolsRequest/ListToolsResult asks a server what tools it provides, and CallToolRequest/CallToolResult runs a named tool with arguments and returns the output.
  • Your server no longer executes tools; the MCP server does. In the "What repositories do I have?" example, your server gets the tool list through the client, sends query plus tools to Claude, then on a tool-use reply asks the client to run it; the MCP server calls GitHub and the result returns via the client to Claude for the final answer.
  • The many steps buy a clear division of responsibility. The lesson concedes the flow is long but argues each component has one job, and the client hides the server communication from your application logic.
Claude with Amazon Bedrock: 48-Introducing MCP
  • MCP moves tool definition and execution onto dedicated servers. An MCP client in your server connects to MCP servers holding tools, prompts and resources, each wrapping an outside service such as GitHub, AWS or a database.
  • Without MCP, broad integrations mean writing many tool schemas yourself. Supporting a question like "What open pull requests are there across all my repositories?" would require authoring, testing and maintaining tools for GitHub's repositories, pull requests, issues, projects and more.
  • Anyone can write an MCP server, often the service provider. The lesson gives AWS releasing an official server for its services as an example, and says calling an API directly still leaves you writing the schemas and functions.
  • MCP complements tool use rather than duplicating it. Tool use is Claude calling functions; MCP is about who provides them, already implemented in a server instead of authored by you.
Claude with Amazon Bedrock: 47-Rules of prompt caching
  • Caching is manual, set by cache points in the request. It is not automatic; a {"cachePoint": {"type": "default"}} part caches the work for everything before it and nothing after it, and the first request writes the cache that follow-ups read within its 5-minute life.
  • The cache is used only when the prefix is identical. Any change before the cache point, even adding "Please" to the start of the prompt, forces Claude to reprocess everything from scratch.
  • A cache point can cover a whole conversation history. Placed at the end of a user/assistant/user sequence, it caches the processing for all those messages, assistant turns included.
  • Content under the minimum length is not cached. The total before the cache point must be at least 1024 tokens; one "Hi there!" falls short, while repeating it about 500 times qualifies.
  • System prompts and tool definitions are the best caching targets. Cache points can go at the end of the tools list or the system prompt, and the lesson calls these the most valuable because they rarely change between requests.
Claude with Amazon Bedrock: 46-Prompt caching
  • Claude normally discards its input processing after every response. It tokenizes the prompt, creates embeddings and adds context before generating output, then throws that work away, so a follow-up that resends the same message forces the same work again.
  • Prompt caching stores that work for reuse on repeated content. The cache maps specific input messages to their processing results, making follow-up requests that hit it cheaper and faster.
  • The short cache life still fits common usage. The cache lives 5 minutes and only helps with repeated content, but the lesson argues chatbots, document analysis and other tools constantly resend system prompts, history and large documents within a session.
Claude with Amazon Bedrock: 45-Citations
  • Citations address the trust problem in PDF answers. The lesson argues users otherwise have to take Claude's reading of a document on faith, and citations show where each piece of information came from.
  • One document parameter enables citations. Adding "citations": {"enabled": True} to the document block (format "pdf", bytes source) makes Claude track and return where it found information.
  • Cited responses add structured parts mapping statements to the source. Alongside text parts, the response carries citations content giving the document, page numbers and exact supporting text, which the lesson says makes answers verifiable and auditable for professional and research use.
Claude with Amazon Bedrock: 44-PDF support
  • A PDF is sent as a document part, not an image part. The part is {"document": {"format": "pdf", "name": ..., "source": {"bytes": ...}}}, where name is the filename without its extension and the bytes are the file read in binary mode. A text part with the instruction follows it.
  • Claude reads the whole multi-page PDF, including layout and images. In the lesson's example it summarized a Wikipedia article on Earth in one sentence. The lesson lists extraction, question answering, structure analysis and mixed text-and-image PDFs as supported uses.
  • PDF input becomes more useful when combined with citations. Citations let Claude point to specific parts of the document in its answer, which the lesson recommends for research and content-extraction workflows.
Claude with Amazon Bedrock: 43-Image support
  • Image input has hard per-request limits and a token cost. The limits are up to 20 images across all messages in a request, at most 3.75MB each, and at most 8000px in height or width. Each image costs ⌈width/28⌉ × ⌈height/28⌉ tokens.
  • Each image goes in as its own part of the user message. The part is {"image": {"format": "png", "source": {"bytes": ...}}}, followed by a text part. Sending several image parts in one message lets Claude compare them or find a common theme.
  • Prompt engineering raises vision accuracy just as it does for text. Asked plainly, Claude counted 13 marbles in a photo of 12. A prompt that had it number each marble and then re-count row by row from the bottom-left got 12, and so did a one-shot example image labelled with its correct count of 11.
  • Complex visual assessments need detailed, step-by-step prompts. The worked example is an insurer scoring fire risk from satellite images instead of sending inspectors. The prompt walks Claude through dense trees near the house, emergency access routes, overhanging branches and overall tree spacing.
Claude with Amazon Bedrock: 42-Extended thinking
  • Extended thinking returns a visible reasoning part before the answer. The response has a reasoning-content part and then the text part. The reasoning shows how Claude broke the problem down, which helps when debugging complex tasks.
  • Use extended thinking only after evaluations show prompt work isn't enough. It improves accuracy on complex tasks, but every thinking token is billed and it adds latency. The lesson's rule is to optimize the prompt first, then turn thinking on only if the evaluations still fall short.
  • A signature makes the reasoning tamper-proof, and redacted reasoning still works. The signature lets reasoning be passed back in later turns while proving it was not modified, which the lesson presents as a safety measure. Reasoning flagged by safety systems comes back as an encrypted redactedContent field. You can't read it, but you can pass it back without losing context, and a special test string forces this case so you can test your handling of it.
  • Current models use adaptive thinking, and manual budgets are being removed. On Claude Opus 5 and Sonnet 5, thinking is adaptive and on by default, and "display": "summarized" is needed to see the reasoning. The effort parameter guides how much Claude thinks. type: "enabled" with budget_tokens is deprecated on Opus 4.6 and Sonnet 4.6, and Opus 4.7 and later reject it with a 400 error.
  • Older models still need a manual thinking budget. Claude Haiku, Sonnet and Opus 4.5 and earlier have no adaptive thinking. They take type: "enabled" with budget_tokens, minimum 1024, tuned through evaluations. For a new task, the lesson says to read the reasoning on a few typical requests and re-run evaluations before keeping the setting.
Claude with Amazon Bedrock: 41-Contextual retrieval
  • Chunks lose document context, so Claude adds it before indexing. Each chunk is sent with the source document and a prompt asking for a short snippet that places the chunk in the document. That snippet is put in front of the chunk, and the combined "contextualized chunk" is what goes into the vector and BM25 indexes.
  • For documents too long to send whole, use partial context. Instead of the full document, the prompt gets a few chunks from the start, which often hold summaries or abstracts, plus the chunks just before the target. In the diagram, chunks 1–3 and 7–8 serve as context for chunk 9.
  • The added context matters more as documents get more cross-referenced. In the example, a chunk is described as Section 2 of an Annual Interdisciplinary Research Review, sitting between Methodology and Financial Analysis, in a report covering ten research domains. The lesson says simple documents may show little improvement.
Claude with Amazon Bedrock: 40-Reranking results
  • Hybrid search can still put the wrong chunk first. For "What did the eng team do with INC-2023-Q4-011?", the merged results can rank the cybersecurity section above the software engineering section, even though the engineering section is the better answer.
  • Re-ranking asks Claude to reorder the merged results by relevance. After the vector and BM25 results are merged, a reranker prompt gives Claude the user question and the candidate documents, and asks for the top k in decreasing order of relevance.
  • Have Claude return chunk IDs, not chunk text. Each chunk gets a unique ID in advance, so Claude only returns a short list such as ["1p5g", "51n3", "ab83"], which is much faster than copying text back. The code reads this list from a document_ids JSON field, using a stop sequence on ```.
  • Re-ranking adds latency in exchange for better accuracy. The lesson says Claude correctly ranks the engineering section first for an engineering-team query, at the cost of an extra model call on every search.
Claude with Amazon Bedrock: 39-A multi-search RAG pipeline
  • One Retriever class runs every search index and merges the results. The vector and BM25 indexes both expose add_document() and search(). The Retriever sends documents and queries to each index, then merges what comes back.
  • Reciprocal Rank Fusion merges results by rank, not raw score. Scores from different search methods can't be compared, so each document scores Σ 1/(k + rank) across the systems, with k typically 60 (1 gives clearer numbers). With k=1, Section 2 (ranks 1 and 2) scores 0.833, Section 6 (ranks 3 and 1) scores 0.75 and Section 7 (ranks 2 and 3) scores 0.583, in that order.
  • Hybrid search beat either method alone on the incident-ID query. For "what happened with INC-2023-Q4-011?" the cybersecurity incident section came first at about 0.0325, followed by Section 2 (software engineering) at about 0.0320.
  • Any index with the same interface can be added. Because the Retriever depends only on add_document() and search(), the lesson says a different embedding model or a domain-specific search can be plugged in without other changes.
Claude with Amazon Bedrock: 38-BM25 lexical search
  • Semantic search misses exact identifiers that appear in the text. A query for incident "INC-2023-Q4-011" returned the Cybersecurity and Financial Analysis sections rather than Cybersecurity and Software Engineering, the two that mention the ID. Embeddings match on meaning, not on exact strings.
  • BM25 ranks chunks by how often they contain rare query terms. It tokenizes the query, counts how often each term appears across documents, gives rarer terms more weight, and scores chunks by how many high-weight terms they contain. A common word like "a" counts for little, while a unique ID counts for a lot.
  • BM25 found the right sections and uses the vector store's interface. With add_document() and search(), the same query returned the Software Engineering and Cybersecurity sections. The lesson's next step is to run both searches in parallel and merge the results.
Claude with Amazon Bedrock: 37-Implementing the RAG flow
  • The basic RAG flow takes five steps of code. Split report.md into sections with chunk_by_section, embed each chunk, store it in a VectorIndex, embed the user's query, then call store.search(user_embedding, 2). The embedding step makes one API call per chunk, so it is slow.
  • Store each chunk's text with its embedding. The lesson calls this the key design decision. A search that returns only vectors is useless for building a prompt, so each vector is saved with {"content": chunk}.
  • Lower cosine distance means a closer match. For "What did the software engineering dept do last year?", the software engineering section came first at a distance of 0.71 and the methodology section second at 0.72.
Claude with Amazon Bedrock: 36-The full RAG flow
  • A made-up two-number embedding shows how the pipeline works. In the imaginary model, the first number measures how medical a text is and the second how much it is about software. The medical section, which says "bug", embeds as [0.97, 0.34]. The software section, which says "infection vectors", embeds as [0.30, 0.97].
  • Embeddings are normalized to length 1 before they are stored. The embedding API usually does this. The vectors become [0.944, 0.331] and [0.295, 0.955], points on the unit circle, and are stored ahead of time in a vector database until a query comes in.
  • The query goes through the same model, and cosine similarity finds the closest chunk. "What did the software engineering dept do this year?" embeds as [0.1, 0.89], or [0.112, 0.993] after normalization. Its cosine similarity is 0.983 with the software chunk and 0.398 with the medical one. Similarity runs from −1 to 1, and cosine distance is 1 − similarity, so near 0 means similar.
  • The best-matching chunk and the question go into Claude's prompt. The full flow is: chunk, embed, store, embed the query, find the most similar chunks, build the prompt, send it to Claude. The lesson says understanding the math helps when retrieval returns unexpected chunks.
Claude with Amazon Bedrock: 35-Text embeddings
  • Finding relevant chunks needs semantic search, not keyword matching. In the example, the question "How many bugs did engineers fix this year?" shares the word "bug" only with the medical chunk, not the software chunk. Embeddings match on what a text means rather than which words it uses.
  • An embedding is a list of numbers that scores the text's meaning. A model typically outputs 1024 numbers between −1 and +1. You can think of each one as scoring some quality, such as how happy the text is or how much it mentions oceans, but what each number actually measures is learned in training and can't be read by people.
  • Bedrock embeddings come from Amazon Titan through invoke_model. The example uses amazon.titan-embed-text-v2:0 with dimensions=1024 and normalize=True. Access may have to be requested in the Bedrock console, and v1 is fine for learning.
Claude with Amazon Bedrock: 34-Text chunking strategies
  • Bad chunking puts the wrong context in front of the model. In the example, "How many bugs did engineers fix this year?" can pull up the medical research section because it calls a pathogen (XDR-47) a "bug", so the model answers wrongly.
  • Size-based chunking is simple but cuts through words and context. A 325-character document split into three chunks of about 108 characters breaks "significant" into "signific" and "ant". Overlapping chunks fix the lost context at the cost of some duplication, which the lesson says is usually worth it. The example defaults are 150 characters with 20 of overlap.
  • Structure-based chunking works well only when the format is guaranteed. Splitting markdown on \n## lines the chunks up with the document's sections. It is unreliable for plain text or documents formatted inconsistently.
  • Pick a strategy by document type, then test and refine. Character-based chunking is the safest fallback for user uploads. Sentence-based (5 sentences with 1 of overlap) suits prose but breaks on code that uses periods. Section-based gives the best results on structured internal documents. Semantic grouping is described as more relevant but costly.
Claude with Amazon Bedrock: 33-Introducing Retrieval Augmented Generation
  • Putting a whole large document in the prompt hits hard limits. For something like an 800-page financial report, token limits may not fit it at all. Very long prompts also make Claude less effective, cost more and run slower.
  • RAG sends Claude only the chunks relevant to each question. The document is split ahead of time into sections like Risk Factors or Balance Sheet. A question about company risks retrieves only the Risk Factors chunk, which scales to large documents and collections with smaller, cheaper prompts.
  • RAG adds complexity, so it isn't always worth it. It needs a chunking step, a way to search the chunks, and a choice among chunking strategies, and the retrieved chunks may still miss context the answer needs. The lesson says simply including everything is sometimes fine.
Claude with Amazon Bedrock: 32-The text editor tool
  • Claude has the text editor tool's schema built in, but you implement it. Unlike a custom tool, you don't write the schema. Your code still has to carry out the view, str_replace, create and insert commands Claude sends, routed under the name str_replace_based_edit_tool.
  • The tool version must match the model. Claude 4 and later use text_editor_20250728. Earlier models use text_editor_20250124, where the tool is named str_replace_editor and also has an undo_edit command. The lesson points to the AWS documentation for current IDs.
  • With file access, Claude can work as a coding assistant. Asked to describe ./main.py, Claude sends {"command": "view", "path": "./main.py"} and answers from the file it reads. Asked to add a function that calculates pi to 5 digits and a test file, it reads, edits and creates the files itself.
Claude with Amazon Bedrock: 31-Flexible tool extraction
  • One generic to_json tool can replace a schema for each extraction task. Its input schema is an object with additionalProperties: True, so it accepts any structure. The structure you want is written in the prompt, and tool_choice="to_json" forces Claude to call it.
  • Changing the output structure is a prompt edit. Adding a field such as "num_topics": int takes one line in the prompt and no schema changes.
  • The lesson puts it at about 90% of the quality for 10% of the setup. It recommends the flexible tool for prototyping, simple extractions and requirements that change often. Dedicated schemas remain the choice for critical production extraction, complex nested data and the highest accuracy.
Claude with Amazon Bedrock: 30-Structured data with tools
  • A tool's input schema can produce more reliable structured output. You define a tool whose parameters are the fields you want, and Claude "calls" it with the extracted data as arguments. The lesson says this beats prefill-and-stop-sequence prompting, though it takes more setup, which is why both methods are taught.
  • Force the specific tool, then stop after the tool call. toolChoice can be auto (the default), any (must use some tool), or tool with a name (must use that tool). For extraction the named option is almost always right. The data is read from the tool-use arguments and no follow-up turn is sent.
  • Worked example: pull title, author and topics into a schema. The article_details tool requires title and author as strings and topics as an array of strings. The course's chat helper takes tool_choice="article_details" and builds the nested toolChoice object for you.
Claude with Amazon Bedrock: 29-Batch tool use
  • Claude often makes independent tool calls one at a time. Asked for March 12th, 2025 plus 50 days and plus 100 days, it could request both in one message. The lesson says some versions tend to make the calls sequentially instead, which is less efficient.
  • A batch_tool pushes Claude to bundle calls into one request. Its schema takes a list of invocations, each with a tool name and its arguments as a JSON string. With it in place, the date question came back as a single batch call containing both calculations.
  • The batch handler sends each invocation through the existing run_tool. run_batch parses each invocation's arguments and collects each tool's name and output. Unlike other tools, batch_tool gets the raw tool_input rather than **tool_input.
Claude with Amazon Bedrock: 28-Adding multiple tools
  • Once tool use is set up, a new tool takes two changes. Add its schema to the tools list passed to chat, and add a branch for its name in run_tool. An unknown name raises an exception. This lesson adds add_duration_to_datetime and set_reminder, the latter only printing for now.
  • Claude plans and chains several tools for a single request. "Set a reminder to go to the doctor. The appointment is in 100 days" led Claude to get the current date, add 100 days and set the reminder. It explained its plan first and set the reminder for 2025-07-12. The lesson adds the date-arithmetic tool because Claude is not perfect at that math on its own.
Claude with Amazon Bedrock: 27-Multi-Turn conversations with tools
  • Check the stop reason before processing tools. If the code assumes every response needs tool handling, plain answers like "What is 1+1?" add empty tool-result messages to the history. A stop reason of tool_use means Claude wants a tool. The others are end_turn, max_tokens and stop_sequence.
  • chat should return the parts, the stop reason and the joined text. The lesson joins the text of every text part rather than assuming the first part is text, which it calls more robust.
  • A loop runs tools until Claude stops for another reason. run_conversation calls Claude, adds the reply to the history, and while the stop reason is tool_use runs the tools and appends their results as a user message. "What time is it?" uses the tool, and "What is 1+1?" is answered directly.
Claude with Amazon Bedrock: 26-Sending tool results
  • Tool results go back as a user message after the full history. The history must run: user question, then the assistant's tool-use message (added with add_assistant_message), then a user message holding the tool-result parts from run_tools.
  • The final call must include the original tool schemas. Without them, Claude would not understand the tool references in the history or what get_current_datetime does.
  • The tool supplies information Claude doesn't have, such as the exact time. With the result in the history, Claude answered "The current date and time is 2025-04-03, 12:54:00." The lesson notes that Claude knows the date but not the current time.
Claude with Amazon Bedrock: 25-Running tool functions
  • Assume a response can contain several tool requests. An assistant message can be a text part followed by one or more toolUse parts. run_tools filters the parts for toolUse and handles each one.
  • run_tool sends each call to its function, unpacking the arguments. Claude always sends arguments as a dictionary, so the function is called with **tool_input. An unknown tool name raises an exception.
  • Each result must carry the matching tool use ID. A result part has toolUseId, content (the output serialized as a string), and status set to "success" or "error". The IDs tell parallel calls apart: two calculator calls with IDs ab3 (10 + 10) and po9 (30 + 30) can come back in any order.
  • Return errors to Claude instead of letting them crash the loop. Running the tool inside try/except and returning Error: … with status "error" lets Claude change its approach. The lesson presents this as Claude handling tool errors intelligently.
Claude with Amazon Bedrock: 24-Handling tool use responses
  • toolChoice controls whether, and which, tool Claude must use. auto (the default) lets Claude decide, any requires some tool, and a named tool forces that tool. The lesson notes the named option is especially useful for testing.
  • A tool-use reply has a text part and a toolUse part. The toolUse part has toolUseId, which the result must echo back, the tool name from your schema, and an input dictionary of arguments. In the example it calls get_current_datetime with date_format %H:%M:%S.
  • The message helpers must accept both strings and lists of parts. add_user_message and add_assistant_message wrap a string as a text part and pass a list through unchanged. chat now returns the text and the full parts list, because each next request needs the whole history, including the tool-use message.
  • A stopReason of "tool_use" means Claude wants a tool. Because chat doesn't return this field yet, the lesson detects tool use for now by looking for a part with a toolUse key. A later lesson adds the stop reason to what chat returns.
Claude with Amazon Bedrock: 23-JSON Schema for tools
  • A tool spec has two parts: when to use it, and its arguments. The name and description at the top help Claude decide when to call the tool. The inputSchema below describes the arguments in standard JSON Schema, an existing data-validation format not invented for AI.
  • Generate the schema from sample arguments rather than writing it by hand. Write a dictionary of the function's arguments with sample values, convert it to JSON (Python True becomes true), paste it into an online JSON-to-JSON-Schema converter, and remove the $schema line it adds.
  • The descriptions are the most important part of the schema. The tool description should be 3–4 sentences on what it does, when to use it and what it returns, and every property needs a detailed description. The get_weather example lists its return fields and valid location formats such as "London,UK", and Claude itself can draft the descriptions.
Claude with Amazon Bedrock: 22-Tool functions
  • Reminders need custom tools for time, date math and scheduling. The lesson says Claude may know the date but not the exact time, handles date addition poorly when looking many days ahead, and has no way to set a reminder. So three tools are built: get the current date and time, add a duration to a date, and set a reminder.
  • Tool functions should validate inputs and return meaningful errors. They are plain Python functions with descriptive argument names. Claude will retry a call after an error, so errors should say what went wrong. The first example is get_current_datetime(date_format="%Y-%m-%d %H:%M:%S").
  • A detailed JSON Schema tells the model when and how to call. The description should say what the tool does, when to use it and what it returns, in about 3–4 sentences, and each parameter needs a detailed description. The lesson notes that JSON Schema is a general data-validation standard and that online tools can generate schemas.
Claude with Amazon Bedrock: 21-Introducing tool use
  • Tools give the model access to live, external information. By default Claude knows only its training data, so "What's the weather in San Francisco, California?" gets an apology. Tools are the bridge to outside data sources.
  • Tool use is a four-message exchange between server and model. You send the question along with instructions for getting extra data, and Claude asks for the specific data it needs. Your server runs code to fetch it (for example, a weather API call) and returns it, and Claude answers using it.
  • The code is written in a different order than it runs. Implementation jumps between the tool function, its JSON schema, the ToolUse and ToolResult parts, and adding the schema to the request. The lesson says this is why tool use seems complex at first.
Claude with Amazon Bedrock: 20-Providing examples
  • Sample input/output pairs teach what instructions alone miss, such as sarcasm. A tweet calling a film the best since "Plan 9 from Outer Space" reads as positive but is sarcastic. One-shot or multi-shot examples in <sample_input>/<ideal_output> tags, introduced explicitly, show that the correct label is "Negative".
  • Examples suit corner cases, complex formats and defining "good". For tricky cases the prompt can add a warning with more examples, such as "Be especially careful with tweets that contain sarcasm", followed by a flight-delay tweet labeled Negative. Examples also pin down complex output formats such as specific JSON structures.
  • Mine your evaluation report's top-scoring outputs for examples. Copy the input and output of a response that scored 10, or your highest score. Then add a sentence saying why it is ideal, so Claude learns the reasons behind the format as well as the format itself.
Claude with Amazon Bedrock: 19-Structure with XML tags
  • XML tags separate instructions from interpolated data. In a large input such as 20 pages of sales records, Claude can confuse the data with the instructions, and wrapping it in <sales_records> draws the boundary. Tag names are free-form, and specific names generally work better than generic ones.
  • Tags distinguish multiple content types within one prompt. A debugging prompt separates <my_code> from <docs>, so Claude knows which is the code to fix and which is reference material. Even small inputs benefit, such as athlete details grouped in an <athlete_information> block.
  • Expect modest gains on simple prompts. The lesson says tags help most with large context, several distinct content types, or interpolated content that could be mistaken for instructions. Simple prompts may not improve dramatically.
Claude with Amazon Bedrock: 18-Being specific
  • Guidelines narrow the range of outputs an open prompt produces. Without guidance, a short-story prompt could produce 200 or 2,000 words, one character or five, and a wildly varying structure.
  • Quality guidelines shape the output; process steps shape the reasoning. Quality guidelines set length, structure and content, for example under 1,000 words with at least one supporting character. Process steps dictate a sequence: brainstorm 3 talents, pick the best, outline the scene that reveals it, then brainstorm supporting characters.
  • Adding guidelines roughly doubled the meal-plan score. Six guidelines (accurate calories, protein/fat/carb amounts, meal timing, only foods that fit the restrictions, portions in grams, budget-friendly if mentioned) raised the score from 3.92 to 7.86. A process-steps version scored 7.3.
  • Use process steps for hard problems that need multiple angles. They are recommended for troubleshooting, decision making, critical thinking, or whenever Claude should take a wider view. The example is a sales team's 30% quarterly drop, examined across market conditions, individual performance, organizational changes and customer feedback.
Claude with Amazon Bedrock: 17-Being clear and direct
  • Open with a plain instruction and an action verb, not a question. The lesson calls the first line the most important part of the prompt. "Write three paragraphs about how solar panels work" replaces a rambling query about rooftop sun panels. "Identify three countries that use geothermal energy. Include generation stats for each" replaces a chatty question.
  • Rewriting only the opening line raised the score substantially. Changing "What should this person eat?" to "Generate a one-day meal plan for an athlete that meets their dietary restrictions" lifted the eval score from 2.32 to 3.92.
Claude with Amazon Bedrock: 16-Prompt engineering
  • Prompt engineering is a loop: evaluate, apply a technique, re-evaluate. You set a goal, write an initial prompt, evaluate it, apply one technique and evaluate again. The running example generates one-day meal plans for athletes from their height, weight, goal and dietary restrictions.
  • An evaluator class generates datasets and grades cases concurrently. PromptEvaluator(max_concurrent_tasks=...) speeds up runs; the lesson advises starting low, around 3, to avoid rate-limit errors. generate_dataset takes a task description, an input spec and a number of cases. run_evaluation accepts extra criteria such as a daily calorie total, a macronutrient breakdown, and meals with exact foods, portions and timing.
  • A weak baseline score is expected and useful. The naive "What should this person eat?" prompt scored 2.3 out of 10 in the output.html report; the screenshot shows 50 test cases and a 0.0% pass rate. That score becomes the baseline for the techniques that follow.
Claude with Amazon Bedrock: 15-Code based grading
  • Syntax validators score output full marks if it parses, zero otherwise. validate_json uses json.loads, validate_python uses ast.parse and validate_regex uses re.compile, each returning 10 or 0. Each test case carries a "format" field (json, python or regex) that selects its validator.
  • Tighter instructions and prefilling help outputs pass the code grader. Suggested additions to the prompt are "Respond only with Python, JSON, or a plain Regex" and "Do not add any comments or commentary or explanation". A prefilled code fence with stop sequences helps as well.
  • Average the model and syntax scores, weighting by what matters. The simple combination is (model_score + syntax_score) / 2, and the weights can be adjusted. The lesson says a single score means little on its own; its value comes from comparing scores across prompt iterations.
Claude with Amazon Bedrock: 14-Model based grading
  • Graders come in three kinds: code, model or human. Code graders run programmatic checks such as length, required or banned words, JSON/Python/regex syntax and readability. Model graders make an extra API call to judge quality, instruction following, completeness, helpfulness and safety. Human graders are the most flexible but slow and tedious.
  • Define the criteria first, then assign each to a grader type. For the code-generation prompt, format (code only) and valid syntax go to a code grader. Task following goes to a model grader because it needs flexibility.
  • Ask the grader for strengths, weaknesses and reasoning, not just a score. The grader prompt asks for 1–3 strengths, 1–3 weaknesses, reasoning and a 1–10 score as JSON, using the prefill and stop-sequence technique. The lesson says that without this context, models tend to default to middling scores around 6.
  • Averaging grader scores gives a trackable but imperfect metric. run_test_case now records the score and reasoning, and run_eval prints the mean. The lesson concedes that model graders can be somewhat inconsistent.
Claude with Amazon Bedrock: 13-Running the eval
  • The pipeline is three nested functions: run, test, evaluate. run_prompt merges a test case into the template and calls Claude. run_test_case runs the prompt and grades the result, for now with a hardcoded score of 10. run_eval loops over the dataset and collects an output, test_case and score record for each case.
  • Even a small run is slow before optimization. The lesson warns that a full dataset can take 30+ seconds even with Claude Haiku. The unconstrained version 1 prompt also returns verbose output.
  • Grading, not orchestration, is where evaluation gets hard. The lesson calls this simple loop the foundation most AI evaluation systems are built on. In its view the real sophistication lies in the grading logic and in prompt optimization.
Claude with Amazon Bedrock: 12-Generating test datasets
  • The example prompt must return only AWS code, without explanation. The goal is to turn a task description into a Python function, a JSON configuration or a regex, with no headers, footers or explanation. Version 1 is simply "Please provide a solution to the following task: {task}".
  • Test cases can be hand-written or generated by a fast model. generate_dataset asks Haiku for 3 AWS tasks as a JSON array of {"task": ...} objects. It uses the "json" prefill and "" stop sequence so the output parses. Generated tasks included extracting account IDs from ARNs, JSON schemas for EC2 configurations and regexes for S3 bucket names.
  • Save the dataset to disk and enlarge it for production. It is written to dataset.json so it doesn't have to be regenerated each time. Three cases are enough for development, but the lesson says production evaluation needs far more examples, with more variety.
Claude with Amazon Bedrock: 11-A typical eval workflow
  • The loop: draft, build a dataset, run, grade, revise, repeat. First draft a prompt. Then build a dataset of inputs, by hand or generated by Claude; real ones run from tens to thousands of records. Merge each input into the template and send it to Claude, grade each question-answer pair, then change the prompt and rerun.
  • A grader scores each answer, and the average becomes the metric. Scores run from 1 to 10 (10 is perfect, 4 has room for improvement, 1 is poor or wrong). The three sample questions scored 10, 4 and 9, for an average of 7.66.
  • Comparing averages across versions shows which prompt is better. Adding "Answer the question with ample detail" raised the score from 7.66 to 8.7. The lesson reads this as a sign the change improved performance across its test cases.
Claude with Amazon Bedrock: 10-Prompt evaluation
  • Engineering improves prompts; evaluation measures whether they actually work. Prompt engineering is the craft, with techniques such as multishot prompting and XML tags. Prompt evaluation is automated testing that checks outputs against expected answers, compares prompt versions and reviews outputs for errors.
  • Testing a prompt once, or a few times, is a trap. Option 1, testing once, risks breaking in production on unexpected inputs. Option 2 patches a corner case or two but still misses what real users send. The instructor says all engineers fall into both, themselves included.
  • An evaluation pipeline with objective scores justifies its upfront cost. Option 3 scores the prompt and iterates on the data, at the price of more work and cost. The lesson argues that learning evaluation first is what lets you measure whether later prompt-engineering techniques help.
Claude with Amazon Bedrock: 09-Structured data
  • By default, structured output arrives wrapped in headers and commentary. For an example app that generates AWS EventBridge rules, Claude returns a heading, a fenced json block and an explanatory sentence. Users then can't copy the whole response as usable JSON.
  • Prefill the opening code fence and stop at the closing one. If the assistant message is prefilled with "json" and the stop sequence is "", Claude skips its own header and halts before closing the block, so only the JSON is returned. It can then be strip()ped and validated with json.loads.
  • The same delimiter trick works for any copyable format. It applies to Python snippets, bulleted lists, CSV and config files: identify the delimiters Claude would naturally put around the content, prefill the opening one and stop on the closing one.
Claude with Amazon Bedrock: 08-Controlling model output
  • A prefilled assistant message steers how the response begins. If the message list ends with an assistant turn such as "Coffee is better because", Claude continues from that text without repeating it, so the caller has to join the two parts. Prefills like "Tea is better because" or "They are the same because" steer the answer elsewhere.
  • Stop sequences end generation the moment a listed string appears. They are set as stopSequences in inferenceConfig. "Count from 1 to 10" with stop sequence "5" returns "1, 2, 3, 4,", because the stop string itself is excluded. With several sequences, generation halts at whichever appears first. Suggested uses are controlling length, stopping at breakpoints in structured output and not running past delimiters.
Claude with Amazon Bedrock: 07-Streaming
  • Streaming shows text as it's generated, not after a long wait. The lesson says a complete response can otherwise take 10–30 seconds. converse_stream returns at once with a stream object, a generator that yields events as text is produced.
  • Only contentBlockDelta events carry the text to display. Events arrive in a fixed order: messageStart, many contentBlockDelta, contentBlockStop, messageStop, then metadata. Each chunk is at event["contentBlockDelta"]["delta"]["text"], and the chunks are concatenated into the full message.
  • Real apps forward chunks to the frontend and store the result. The suggested pattern sends each chunk over WebSockets or Server-Sent Events, updates the UI live, saves the complete message when streaming ends and handles errors that occur mid-stream.
Claude with Amazon Bedrock: 06-Temperature
  • Temperature reshapes the probabilities used to sample each token. Generation runs through tokenization, prediction and sampling. In the example, "about" has a 30% chance of coming next and "would" 20%. Near 0 the top token becomes near-certain, and at 0 the output is deterministic. Near 1 the probability spreads more evenly, illustrated as 23% down to 9% across seven tokens.
  • Match the temperature range to how much creativity the task needs. Low (0.0–0.3) suits factual answers, coding, data extraction and moderation. Medium (0.4–0.7) suits summarization, educational content, problem-solving and constrained creative writing. High (0.8–1.0) suits brainstorming, creative writing, marketing and jokes.
  • The default is maximally creative, so lower it for precision. The default temperature is 1.0, and you override it with inferenceConfig: {"temperature": ...}. For movie ideas, 1.0 produced an origami-master fantasy. At 0.0 the model returned near-identical "time-traveling archaeologist/historian" plots run after run.
Claude with Amazon Bedrock: 05-System prompts
  • Assigning a role beats listing do's and don'ts per message. Putting rules in each user message means anticipating every edge case. The lists grow unwieldy, users can see the internal instructions, and the rules don't adapt to the question. A system prompt such as "You are an AWS cloud support specialist" instead has Claude respond as that professional naturally would.
  • A role prompt narrows answers and declines off-topic requests in character. Without it, "How do I host a Postgres database?" got an answer covering multiple cloud providers and self-hosting. With the AWS specialist prompt, the answer kept to RDS, Aurora and EC2 with AWS setup steps, and a request for a bread recipe was politely declined.
  • The system prompt is a top-level, non-empty converse parameter. It is passed as system=[{"text": ...}] and cannot be an empty string. It can change between requests but not partway through a single messages list. Some models on Anthropic's own API accept system-role messages mid-conversation, but Bedrock does not support this.
Claude with Amazon Bedrock: 04-Multi-Turn conversations
  • Neither the service nor the model stores any conversation history. Each Bedrock API call is independent. Sent alone, the follow-up "And 3 more?" gets a reply with no context, so the application must keep the full message list itself and resend all of it with every request.
  • Helper functions append user and assistant turns to one list. The lesson defines add_user_message, add_assistant_message and chat. After "What's 1+1?" and its answer are appended, the follow-up correctly yields "2 + 3 = 5".
  • Message roles must strictly alternate between user and assistant. The API requires the pattern user → assistant → user → assistant and does not allow two messages with the same role in a row.
Claude with Amazon Bedrock: 03-Making a request
  • A request needs a runtime client, a model ID and a user message. The client is boto3.client("bedrock-runtime", region_name="us-west-2"), the call is client.converse(modelId=..., messages=[...]), and the generated text sits at response["output"]["message"]["content"][0]["text"].
  • Inference profiles avoid misleading errors from regional model availability. Not every model is hosted in every AWS region, and calling one from a region without it returns a cryptic "model doesn't exist" error. An inference profile routes the request to a region that hosts the model. Profile IDs are listed under "Cross-region inference" in the Bedrock console, not the main model catalog. The course uses us.anthropic.claude-haiku-4-5-20251001-v1:0 for Claude Haiku 4.5.
  • Message content is a list so one message can be multimodal. User and assistant messages share the same role-plus-content-list structure, with blocks for text, images (for example png bytes) or other media. The lesson says this shared format is what makes it simple to chain requests into conversations.
Claude with Amazon Bedrock: 02-Accessing the API
  • Your server, not the browser, brokers every request to the model. The user's message goes to your server, which uses the Bedrock client to send it to AWS Bedrock with a model ID (such as Claude Haiku or Claude Sonnet). Bedrock returns an assistant message with the generated text, and the server forwards it back to the user's browser.
Claude with Amazon Bedrock: 01-Overview of Claude Models
  • Three model tiers trade intelligence against speed and cost. All three share core capabilities (text generation, coding, image analysis): Opus is the most intelligent, at moderate latency and higher cost; Sonnet is the balanced default, with strong coding and precise edits to complex codebases; Haiku is the fastest and cheapest. The course's examples use Claude Haiku 4.5.
  • The fastest tier reasons only when given an explicit thinking budget. Haiku 4.5 supports extended thinking with a token budget, but unlike Opus and Sonnet it won't decide on its own how much reasoning a request needs. The lesson positions it for real-time, user-facing apps, with thinking held in reserve for occasional harder tasks.
  • Teams often mix models within a single application. The suggested split is Haiku for speed-critical user-facing interactions, Sonnet for main business logic and Opus for complex reasoning, so each part is tuned for its own cost and performance needs.
Building with the Claude API: 67-Workflows vs agents
  • Workflows trade flexibility for accuracy and testability. A workflow is a predefined series of Claude calls for a known problem, so each step focuses on one subtask; the lesson says this gives higher accuracy, more predictable execution and far easier evaluation, at the cost of upfront design work and a constrained UX in which the exact inputs must be known.
  • Agents trade reliability for flexibility. Given basic tools and left to plan, an agent can combine them in unexpected ways, handle situations nobody anticipated and ask the user for more input. The stated costs are a lower task-completion rate and behaviour that is harder to instrument, test and evaluate, because the steps aren't known ahead of time.
  • Default to workflows; use agents only when truly required. The lesson's reasoning is that the engineer's job is to solve problems reliably, and users want a product that works consistently rather than a "fancy agent". Agents are reserved for unpredictable, varied requests that need creative problem-solving.
Building with the Claude API: 66-Environment inspection
  • Agents act blindly unless they can observe their results. In computer use, every action such as typing or clicking is immediately followed by a screenshot, because a click might navigate, open a menu or change anything else, and without seeing the result Claude cannot tell whether the action succeeded.
  • Read before writing. Claude should read a file's current contents before modifying it; the example shows Claude reading 31 lines of main.py before adding a 5-line get_items route for "/items", so the change doesn't break existing code.
  • System prompts can direct an agent to verify its own output. For a video-generation agent, the lesson suggests instructing it to run whisper.cpp through bash to produce timestamped captions that check dialogue placement, and to use FFmpeg to extract screenshots at regular intervals for visual inspection, then compare the result against the original requirements.
  • Design every action around how Claude will know it worked. Inspection is said to improve progress tracking, error detection, quality checks before a task is declared complete, and adaptation. In practice that means reading files before edits, screenshotting after UI actions, checking API responses and validating generated content.
Building with the Claude API: 65-Agents and tools
  • Agents get a goal and tools, not a fixed sequence. That suits varied, unpredictable tasks, since one agent built to work reasonably well can be deployed across many problems. The lesson flags that this flexibility costs reliability and money, and that reliable, economical task completion is often harder with agents.
  • Simple tools chain into surprisingly complex capabilities. With get_current_datetime, add_duration_to_datetime and set_reminder, Claude answers "what day of the week is it in 11 days?" by chaining the first two and sets a gym reminder for next Wednesday with all three. Asked "when does my 90-day warranty expire?", it recognises it must first ask when the item was bought.
  • Give agents reasonably abstract tools, not hyper-specialized ones. Claude Code has generic bash, read, write, edit, glob and grep, but no "refactor code", "install dependencies", "run tests" or "create migration" tool. The lesson credits that abstraction with letting it handle programming scenarios its developers never planned for.
  • Combinable tools let one agent serve both automated and interactive flows. A social-media video agent with bash (for FFmpeg), generate_image, text_to_speech and post_media can create and post a video outright, or generate a sample image, ask for approval, then proceed. The lesson argues that adapting to user feedback this way would be difficult in a rigid workflow.
Building with the Claude API: 64-Routing workflows
  • One generic prompt can't serve requests needing different handling. In a social-media video-script generator, "programming" calls for educational content with clear definitions while "surfing" calls for entertainment built on excitement and visual appeal.
  • Routing categorizes first, then dispatches to a specialized prompt. The example defines six genres, each with its own template: Entertainment, Educational, Comedy, Personal vlog, Reviews and Storytelling. An initial Claude call asked to categorize "Python functions" against that list returns "Educational", and the educational template then generates the script.
  • Each input goes to exactly one pipeline, not all of them. Each pipeline can carry its own workflow, prompts or tools, which is what lets it be tightly optimized for its category.
  • Routing pays only when categories are clear and classification reliable. The lesson's conditions are diverse request types, categories that cover the use cases, a categorization step Claude handles reliably, and a specialization benefit that outweighs the routing step's overhead. Customer service bots and content-generation tools are the cited fits.
Building with the Claude API: 63-Chaining workflows
  • Chaining splits a large task into focused sequential steps. The example is a six-step social-media pipeline: find trending Twitter topics, select one, research it and write a short-video script (those three with Claude), make the video with an AI avatar and text-to-speech, then post it. The stated benefits are keeping Claude on one aspect at a time, handling subtasks that can't be parallelized, and room for non-LLM processing between steps.
  • Long prompts with many constraints get some constraints ignored. Asking for a technical article with no mention of AI authorship, no emojis, no clichés and a professional tone can still return an emoji-filled article calling itself your "friendly neighborhood AI assistant".
  • Accept an imperfect draft, then run a targeted revision pass. The second call hands back the article with numbered steps: remove any AI self-identification, remove all emojis, and replace cringey writing with what a technical writer would produce. The lesson says this works because Claude can focus entirely on revising instead of balancing creation against constraint adherence.
Building with the Claude API: 62-Parallelization workflows
  • One prompt juggling many criteria gives less reliable decisions. In a material-designer app that picks metal, polymer, ceramic, composite, elastomer or wood from a photo of a part, a bare prompt lacks criteria, and one massive prompt holding every material's criteria forces Claude to weigh them all simultaneously.
  • Split into independent parallel evaluations, then aggregate. The same image goes to Claude several times at once, each request carrying one material's criteria, and all the analyses then feed a final Claude call that compares them and recommends a material. The sub-tasks need not be identical; each can have its own prompt, tools or criteria.
  • Parallel sub-prompts can be tuned and extended independently. A weak metal analysis can be refined without touching the others, and adding a material is just one more request that can't interfere with existing criteria; the lesson also claims more consistent results from the reduced load per request.
  • Use it only when the decision decomposes into independent pieces. The signals given are multiple criteria, several options to compare, or several domains of expertise, and each sub-task must be able to run on its own and contribute a distinct analysis.
Building with the Claude API: 61-Agents and workflows
  • Choose by how well you can picture the steps. Workflows fit when the exact flow is known in advance or the app's UX constrains users to a set of tasks; agents fit when you don't know what task or parameters Claude will receive. The lesson notes that the earlier tool-use exercises in the course were already agents.
  • Image-to-CAD is a workflow because its steps are known. Users drop in an image of a metal part and get a STEP file: Claude describes the object, models it with the CadQuery library, a rendering is made, and Claude grades the rendering against the original image and fixes any issues.
  • The evaluator-optimizer pattern loops a producer against a grader. The producer creates output, the grader checks it against criteria, and rejected output goes back with feedback until the grader accepts it. The lesson offers such named patterns as repeatable recipes that have worked for other engineers, while stressing that naming one does nothing until the code is written.
Building with the Claude API: 60-Adding MCP servers to Claude Code
  • Claude Code's built-in MCP client lets servers extend it. Servers can expose tools (actions), prompts (templates) and resources (data). One is registered with claude mcp add [server-name] [command-to-start-server], for example claude mcp add documents uv run main.py, and Claude Code connects to it automatically on startup.
  • A custom server tool gets used automatically when relevant. With a document_path_to_markdown tool on the server, asking Claude to "Convert the tests/fixtures/mcp_docs.docx file to markdown" makes it call that tool and return the converted content.
  • Combining servers tailors Claude to your existing workflow. Listed integrations are sentry-mcp, playwright-mcp, figma-context-mcp, mcp-atlassian (Confluence and Jira), firecrawl-mcp-server and slack-mcp. The suggested setup pairs Sentry for production errors, Jira for ticket requirements and Slack for team notifications with custom servers for internal tools.
Building with the Claude API: 59-Claude Code in action
  • /init writes a CLAUDE.md that carries project context forward. Claude scans the codebase's structure, dependencies, style and architecture and records build commands, guidelines and patterns in a file included in every later conversation. CLAUDE.md files come in project (shared), local (not checked into git) and user (all projects) scopes, and # adds a note to any of them.
  • Feed context, then plan, then implement. Have Claude read the relevant files first so it sees existing patterns, then ask for a plan while telling it explicitly not to write code yet, then ask it to implement. The worked example reads math.py and document.py, plans a document_path_to_markdown tool reusing the existing binary_document_to_markdown function, then says "Implement the plan".
  • A test-driven variant gives Claude clear success criteria. After feeding context, Claude brainstorms test cases, writes the most relevant ones, then iterates on the code until they pass; the lesson says this often produces more robust code.
  • Treat Claude Code as an effort multiplier, not a code generator. It is pitched as a collaborator across five phases (Discover, Design, Build, Deploy, Support and Scale) that can also stage and commit to git, run tests and manage dependencies, with /clear resetting context. Results are said to scale with the context and structure provided.
Building with the Claude API: 58-Claude Code setup
  • Claude Code is a terminal assistant extensible through MCP. It ships with file search, read and edit, terminal command execution and web access, and MCP servers can add tools for databases, APIs or other services. It runs on macOS, Windows (natively or inside WSL) and Linux.
  • Setup is an install plus running claude to log in. Install via Step 1 of the Claude Code quickstart, then the first claude run prompts for an Anthropic account login; the full guide is at docs.anthropic.com.
Building with the Claude API: 57-Anthropic apps: Claude Code and computer use
  • Claude Code and Computer Use are studied as working agents. The module runs Claude Code, then Computer Use, then agents in general, using the two apps to show tool integration, multi-step execution, environmental interaction and autonomous problem-solving that will inform building your own agents.
  • Computer Use extends Claude from text to a full desktop. Its tools let Claude browse websites, operate desktop applications and navigate visual interfaces, which the lesson says dramatically expands what's possible; Claude Code, by contrast, is the terminal assistant for editing files, fixing bugs and answering coding questions.
Building with the Claude API: 56-Prompts in the client
  • Client prompt support is two thin wrappers over the session. list_prompts returns result.prompts from the session, and get_prompt(prompt_name, args) returns result.messages, a conversation that can be fed straight into Claude.
  • Prompt arguments arrive as keyword arguments on the server. The client's args dictionary must contain the keys the server's prompt function expects, such as doc_id for format_document, and the server interpolates them into the template.
  • In the CLI, prompts surface as slash commands. Typing / lists prompts; choosing "format" asks which document (e.g. plan.md), sends the interpolated prompt to Claude, and Claude can then use tools to fetch more data and finish the task. The lesson asks that prompts be relevant to the server, thoroughly tested and designed to work with its tools.
Building with the Claude API: 55-Defining prompts
  • Server-authored prompts beat what users would write themselves. A user's "convert report.pdf to markdown" works, but a tested prompt with specific formatting, structure and output rules gives more consistent, higher-quality results. The lesson frames prompts as the server author's domain expertise, worth offering only for tasks central to the server.
  • A prompt is a decorated function that returns messages. @mcp.prompt(name="format", description=...) wraps format_document(doc_id: str = Field(...)), which returns [base.UserMessage(prompt)] using base from mcp.server.fastmcp.prompts. The example prompt tells Claude to add headers, bullets and tables and to use the edit_document tool.
  • Check interpolation in the MCP Inspector before shipping. In the Prompts section, selecting "format" with doc_id outlook.pdf and clicking Get Prompt shows the generated messages, here one message with role "user".
Building with the Claude API: 54-Accessing resources
  • Resources put data directly in the prompt, skipping tool calls. When a user types "@report.pdf", the app fetches it through the MCP client and includes its contents in the prompt to Claude, which the lesson says is faster and more efficient than having Claude call a tool for it.
  • read_resource takes the first content item and parses by MIME type. It calls session().read_resource(AnyUrl(uri)) and uses result.contents[0]; a TextResourceContents with mimeType application/json goes through json.loads, anything else returns as text. It needs json and pydantic's AnyUrl.
  • The client is a building block; application logic stays separate. Other parts of the app call read_resource to list resources or fold their data into prompts, while the client alone handles communication with the server.
Building with the Claude API: 53-Defining resources
  • Resources expose data like GET handlers; tools perform actions. The motivating feature is @-mentions of documents: list all documents for autocomplete when the user types @, and inject a mentioned document's contents into the prompt. The client sends a ReadResourceRequest whose URI acts as the resource's address.
  • Direct resources use static URIs; templated ones take parameters. docs://documents backs list_docs (application/json), while docs://documents/{doc_id} backs fetch_doc (text/plain), which raises a ValueError for an unknown id. The Python SDK parses URI parameters into keyword arguments for the function.
  • MIME types are hints to clients; the SDK handles serialization. Resources can return strings, JSON or binary, and return values are serialized automatically with no manual conversion to JSON strings.
  • The Inspector lists the two kinds separately. Running uv run mcp dev mcp_server.py shows static resources under Resources and parameterized ones under Resource Templates; clicking one shows the exact response a client would get, such as the JSON list of names from docs://documents.
Building with the Claude API: 52-Implementing a client
  • Real projects usually build an MCP client or a server, not both. The course builds both only so the two sides can be seen working together.
  • A custom MCPClient class wraps the SDK's ClientSession for cleanup. The ClientSession is the actual connection to the server and needs proper resource cleanup, which the wrapper class handles automatically.
  • Two methods cover the app's needs: list tools and call tools. list_tools returns result.tools from the session, and call_tool(tool_name, tool_input) passes Claude's chosen tool and input to the server. A test harness using async with MCPClient(command="uv", args=["run", "mcp_server.py"]) should print the read_doc_contents and edit_document definitions.
  • End to end, the client fetches tools and executes Claude's calls. Asking "What is the contents of the report.pdf document?" sends the tools with the question, Claude picks read_doc_contents, the client runs it, and the result about the 20m condenser tower goes back to Claude for its answer.
Building with the Claude API: 51-The server inspector
  • The Inspector tests a server without wiring up an application. mcp dev mcp_server.py starts a development server on port 6277 with a local browser URL, and Connect launches the server, exposing Resources, Prompts, Tools, Ping, Sampling and Roots tabs. The lesson warns the interface is under active development and may look different.
  • Test tools by listing, filling parameters and running, then chain checks. In Tools, "List Tools" shows read_doc_contents and edit_document; running the reader with "deposition.md" returns its text. After an edit, re-running the read tool confirms the change, giving a fast change-test-debug loop in isolation.
Building with the Claude API: 50-Defining tools with MCP
  • The Python SDK generates tool schemas from decorators and type hints. FastMCP("DocumentMCP", log_level="ERROR") creates the server in one line, and @mcp.tool(name=..., description=...) with Pydantic Field descriptions produces the JSON schema Claude needs. The stated gains are built-in validation, less boilerplate, and type safety with IDE support.
  • The example server reads and edits documents held in memory. Six documents sit in a dict keyed by id (deposition.md, report.pdf, financials.docx, outlook.pdf, plan.md, spec.txt). read_doc_contents returns one by id, and edit_document does find-and-replace via Python's replace(), with old_str described as having to match exactly, including whitespace.
  • Raise descriptive errors Claude can act on. Both tools raise ValueError(f"Doc with id {doc_id} not found") for an unknown id, a message the lesson says Claude can understand and potentially respond to.
Building with the Claude API: 49-Project setup
  • The project is a CLI chatbot over in-memory documents. An MCP client handles the user's side of the conversation and a custom MCP server manages documents with read and update tools. Real projects typically build only one side, exposing a service as a server or connecting to existing servers as a client.
  • Setup is an API key, dependencies, then a test run. From cli_project.zip, put the Anthropic API key in .env, install with uv (recommended) or pip, and start with uv run main.py or python main.py; the main files are main.py, mcp_client.py and mcp_server.py.
  • Verify the baseline with a question whose answer you know. Ask "what's 1+1?" and confirm the answer is actually 2, not merely that a reply appeared; that proves the key, dependencies and chat loop work. A question like "what do the documents say?" can only be answered by the model alone at this point, because the document tools don't exist yet.
  • Match verification effort to the cost of being wrong. A broken setup costs every later lesson while checking costs two questions, so after each new layer (a tool, a data source, an MCP server) ask one known-answer question before building the next. The lesson's maxim: a baseline you have verified is the only baseline you can debug against.
Building with the Claude API: 48-MCP clients
  • MCP is transport agnostic. Client and server most commonly run on the same machine and talk over standard input/output, but they can also connect over HTTP, WebSockets or other network protocols.
  • Two message pairs do most of the work. ListToolsRequest/ListToolsResult asks the server what tools it provides; CallToolRequest/CallToolResult asks it to run one with given arguments and returns the output.
  • One tool-using query passes through every component in turn. For "What repositories do I have?", the app gets the tool list via the client, sends query plus tools to Claude, receives a tool-use request, has the client send a CallToolRequest that the MCP server turns into a GitHub call, then returns the result to Claude for the final answer. The lesson concedes this is many steps but argues each component has a clear responsibility, with the client hiding the server communication.
Building with the Claude API: 47-Introducing MCP
  • MCP moves tool authoring and execution off your server. Without it, a GitHub chatbot needs a schema and a function for every capability (repositories, pull requests, issues, projects and more), all of which you write, test and maintain. An MCP server wraps the outside service and supplies those tools ready-made, alongside prompts and resources.
  • Anyone can write an MCP server; providers often ship official ones. The lesson's example is that AWS might release an official server with tools for its services.
  • MCP differs from tool use in who does the work. Calling an API directly means authoring the tool definitions yourself; with MCP someone else has already written the schemas and functions. The lesson calls "MCP is just tool use" a misconception: the two are complementary, not the same.
Building with the Claude API: 46-Code execution and the Files API
  • The Files API uploads once, then references by file ID. Instead of base64-encoding an image or PDF into every message, you upload it in a separate call, get back metadata with a unique ID, and cite that ID in later messages; useful for repeated references and large files.
  • Code execution is a server-side tool you don't implement. You include the predefined schema ({"type": "code_execution_20250522", "name": "code_execution"}) and Claude can run Python, several times per conversation if needed, in an isolated Docker container with no network access, as in computing pi to the 50th decimal place.
  • With no network, the Files API is the container's door. Data goes in as a container_upload block carrying the file ID, and generated files come out as code_execution_output blocks whose file IDs are downloaded through the Files API. Responses interleave text, server tool use (the code) and code execution tool result blocks, often over several execution cycles.
  • One request can produce a full analysis with plots. Uploading streaming.csv (subscription tier, viewing hours, churn) and asking for the major drivers of churn with at least one detailed plot yields a downloadable multi-panel chart; it reports 500 users, a 38.6% churn rate and customer-service interactions as the top driver.
  • The pairing generalizes to any computational task you delegate. The lesson lists image processing, document parsing and transformation, mathematical modeling and custom report generation, with you controlling inputs and outputs through the Files API.
Building with the Claude API: 45-Prompt caching in action
  • Cache tool schemas by marking only the last tool. The lesson adds cache_control: {"type": "ephemeral"} to a copy of the final tool in the list, copying both the list and that tool rather than editing tools[-1] in place, so later reordering doesn't leave a stray cache field behind.
  • System prompts must become a text block to be cached. The plain string is wrapped as [{"type": "text", "text": system, "cache_control": {"type": "ephemeral"}}], because the string form has nowhere to put the cache field.
  • The usage fields show whether the cache was written or read. The first request reports the tokens written in cache_creation_input_tokens; follow-ups report the same count in cache_read_input_tokens; any change shows up as fresh creation tokens, and a single changed character invalidates the cache for that component.
  • Caching is layered: tools, then system prompt, then messages. Changing only the system prompt gives a partial read for the tools plus a write for the new prompt, so you pay only for what changed. That partial read happens only if the tools alone reach the minimum length, since a breakpoint under the minimum writes nothing.
  • It pays off for stable, frequently repeated context. The default cache lives 5 minutes and is refreshed free on each use, with a 1-hour option at extra cost. The lesson says this suits apps making frequent calls with consistent tools and system prompts, not long-term storage.
Building with the Claude API: 44-Rules of prompt caching
  • Caching is opt-in, through manually placed cache breakpoints. Nothing is cached automatically. You add cache_control: {"type": "ephemeral"} to a block, which requires the longhand text-block form because the shorthand string has no place for the field.
  • Everything up to the breakpoint is cached, and must match exactly. Content after the breakpoint is processed normally. A follow-up only gets the cache if everything up to and including the breakpoint is identical, so even adding "please" forces a full reprocess.
  • A breakpoint caches all earlier messages, across roles. A breakpoint in the last user message also covers the earlier user and assistant messages. Breakpoints also work on system prompts, tool definitions, image blocks and tool use/result blocks, and the lesson calls system prompts and tools the best candidates because they rarely change.
  • Order is tools, system prompt, messages; up to four breakpoints. Knowing this order lets you put one breakpoint after the tools and another partway through the conversation history, so a change in one part doesn't throw away the cache for the parts before it.
  • Content under the minimum length is silently left uncached. For Claude Haiku 4.5, the course's model, the cached prefix must total at least 4,096 tokens across all the blocks, not per block. No error is returned; the only sign is that cache_creation_input_tokens and cache_read_input_tokens both come back 0.
Building with the Claude API: 43-Prompt caching
  • Without caching, Claude discards its input preprocessing after each request. The lesson describes tokenizing, creating embeddings and adding context from the surrounding text before any output is generated. All of that is thrown away once the response is sent.
  • Repeated content means repeated work. In a follow-up that refines a summary of the same long text, Claude has to redo all the preprocessing on input it handled moments earlier.
  • Caching stores that work so identical input can reuse it. The first request writes to the cache, which the lesson likens to a lookup table, and follow-ups read from it. Cached portions run faster and cost less.
  • The benefit is narrow: frequent, identical content within a short window. The cache lasts 5 minutes by default, refreshed free on each reuse, or 1 hour at a higher cache-write price. The lesson's examples are asking many questions about one large document and iterative editing against fixed base content.
Building with the Claude API: 42-Citations
  • Citations let users check answers against your documents. The lesson's point is that without them, users can't tell whether an answer, such as how Earth's atmosphere formed, came from the supplied document or from training data.
  • Enable them with two fields on the document block. Add a title (e.g. "earth.pdf") and "citations": {"enabled": True} next to the base64 PDF source.
  • Responses become structured, with source data on each claim. Each citation carries cited_text, document_index (which matters when you send several documents), document_title, and start_page_number/end_page_number.
  • The value comes from building a UI on top of them. The example shows numbered citation markers that users can hover over to see the source passage, so they can verify claims and read the surrounding context.
  • Plain-text sources work too, with character positions instead of pages. You use a text source with media_type text/plain. The lesson recommends citations wherever accuracy, authoritative sources or transparency matter.
Building with the Claude API: 41-PDF support
  • PDF input works almost exactly like image input. You change the file to .pdf, rename image_bytes to file_bytes for clarity, set the block type to "document", and set media_type to "application/pdf". The base64 encoding and the paired text prompt stay the same.
  • Claude reads more of a PDF than its text. The lesson says it handles embedded images and charts, tables and their relationships, and the document's structure and formatting. It presents this as a one-stop way to extract information, shown by a one-sentence summary of a Wikipedia article on Earth saved as a PDF.
Building with the Claude API: 40-Image support
  • Image inputs have hard limits and cost tokens by size. A request can carry up to 600 images (100 on models with a 200k-token context window), each at most 10MB after base64 encoding, and at most 8000px per side for one image or 2000px when sending several. Images go in as base64 or a URL, and cost ⌈width/28⌉ × ⌈height/28⌉ tokens.
  • Images are just another content block in the user message. You put an image block with a base64 source and media type next to a text block with the question, and Claude replies with text as usual.
  • Simple image prompts give unreliable answers. Asked "How many marbles are in this image?", Claude answered 13 when there were 12. The lesson's point is that the usual prompt-engineering techniques apply to images too.
  • Step-by-step methods and worked examples fix accuracy. A prompt that has Claude number each marble and then recount row by row from the bottom-left got 12. So did a one-shot prompt that first showed an image labeled as having 11 marbles.
  • Real tasks need structured, multi-step prompts. The lesson's insurance example rates fire risk from satellite imagery instead of sending inspectors. The prompt walks through finding the residence, measuring tree overhang in bands (0–25% up to 75%+), checking fire paths and defensible space, and assigning a 1–4 rating with one sentence of findings per step.
Building with the Claude API: 39-Extended thinking
  • Extended thinking gives Claude a visible scratchpad before it answers. The response becomes a thinking block followed by a text block. The lesson says this improves reasoning and accuracy on hard problems and shows how Claude reached its answer, at the price of paying for thinking tokens, more latency, and more complex response handling.
  • Reach for thinking only after prompt optimization falls short. The lesson's rule is to run your prompt evaluations without thinking first and enable it only if accuracy still misses the requirement. It also notes that thinking doesn't work with message pre-filling and limits how temperature can be used.
  • Thinking blocks are signed so they can't be tampered with. A cryptographic signature proves the thinking text wasn't modified, which the lesson says stops developers from altering the reasoning in ways that could steer the model toward unsafe behavior.
  • Flagged reasoning comes back as an encrypted redacted block. When internal safety systems flag the thinking, the block still holds the reasoning in encrypted form, so the full message can be sent back in later turns without losing context. A special trigger string can force a redacted block, so you can test that your code handles one without crashing.
  • Enable it with a thinking object and a budget below max_tokens. You send thinking: {"type": "enabled", "budget_tokens": ...}. budget_tokens must be at least 1024 and max_tokens must exceed it; the lesson's helper sets max_tokens to the budget plus 1000.