﻿{
    "cells":  [
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "# Module 2 Self-Driven Lab\n",
                                     "\n",
                                     "Use this notebook as your workspace for **Tool Design \u0026 Schema Safety**. The answer-key notebook sits next to this file. Work through each checkpoint before comparing against the completed version.\n"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "# Module 2 â€” Tool Design \u0026 Schema Safety\n",
                                     "\n",
                                     "A multi-stage walkthrough of how Claude selects tools, how the agentic loop splits work between server-side and client-side execution, and how strict schemas prevent runtime errors. By the end of this notebook you will:\n",
                                     "\n",
                                     "1. Understand how tool **descriptions** drive selection.\n",
                                     "2. Define a toolbox that mixes server-side built-ins (`web_search_20260209`, `code_execution_20260120`) with a client-side custom tool (`add_lead_to_crm`).\n",
                                     "3. Inspect `stop_reason` to drive the agentic loop.\n",
                                     "4. Handle the loop\u0027s client-side leg (CRM write).\n",
                                     "5. Verify grounding with citations on the final answer."
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## Setup"
                                 ]
                  },
                  {
                      "cell_type":  "code",
                      "execution_count":  null,
                      "metadata":  {

                                   },
                      "outputs":  [

                                  ],
                      "source":  [
                                     "# Setup cell. Run this before the exercise cells below.\n",
                                     "import anthropic\n",
                                     "from dotenv import load_dotenv\n",
                                     "\n",
                                     "load_dotenv()\n",
                                     "client = anthropic.Anthropic()"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## 1. Concepts: Tool Selection \u0026 Strict Mode\n",
                                     "\n",
                                     "**Tool descriptions are the primary selection mechanism.** Claude reads each tool\u0027s `description` and `name` to decide which tool to call. If two tools have overlapping purposes (e.g. `analyze_content` vs. `analyze_document`), Claude may misroute the request â€” write descriptions that disambiguate exactly when each tool is appropriate.\n",
                                     "\n",
                                     "**Dynamic filtering** with `web_search_20260209` plus `code_execution_20260120` lets Claude write Python that post-processes search results *before* they enter the context window â€” saving tokens and improving signal.\n",
                                     "\n",
                                     "**Strict mode (`strict: True`)** uses grammar-constrained sampling to force tool inputs to conform 100% to your JSON schema. No trailing commas, no missing required fields, no surprise keys. Strict schemas must declare `additionalProperties: False`.\n",
                                     "\n",
                                     "\u003e **ZDR warning:** standard web search alone is ZDR-eligible. Adding `code_execution_20260120` for dynamic filtering makes the **entire request non-ZDR** because execution state is held server-side."
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## 2. Defining the Toolbox\n",
                                     "\n",
                                     "Both `web_search` and `code_execution` are server-side built-ins â€” Anthropic runs them and feeds the results back to Claude. `add_lead_to_crm` is a **client-side** custom tool: when Claude calls it, your code is responsible for executing the action and returning the result.\n",
                                     "\n",
                                     "Note the explicit `name` field on every entry. `code_execution_20260120` requires `name` even though it\u0027s a built-in server tool â€” omitting it causes a 400 `BadRequestError`."
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## Checkpoint 1\n",
                                     "\n",
                                     "Implement this step yourself. Use the preceding explanation and the module page as your guide, then compare your approach with the answer key after you have a working version.\n"
                                 ]
                  },
                  {
                      "cell_type":  "code",
                      "execution_count":  null,
                      "metadata":  {

                                   },
                      "outputs":  [

                                  ],
                      "source":  [
                                     "# TODO: Implement checkpoint 1 for Module 2.\n",
                                     "# Keep the cell focused, run it, inspect the output, then move to the next checkpoint.\n",
                                     "\n",
                                     "raise NotImplementedError(\u0027Complete checkpoint 1\u0027)\n"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## 3. The Initial Request \u0026 `stop_reason`\n",
                                     "\n",
                                     "Send the user\u0027s prospecting goal with the toolbox attached. Don\u0027t print just the final text â€” inspect `stop_reason` and walk the content blocks. On the first turn you should see `tool_use`, not `end_turn`."
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## Checkpoint 2\n",
                                     "\n",
                                     "Implement this step yourself. Use the preceding explanation and the module page as your guide, then compare your approach with the answer key after you have a working version.\n"
                                 ]
                  },
                  {
                      "cell_type":  "code",
                      "execution_count":  null,
                      "metadata":  {

                                   },
                      "outputs":  [

                                  ],
                      "source":  [
                                     "# TODO: Implement checkpoint 2 for Module 2.\n",
                                     "# Keep the cell focused, run it, inspect the output, then move to the next checkpoint.\n",
                                     "\n",
                                     "raise NotImplementedError(\u0027Complete checkpoint 2\u0027)\n"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## 4. Handling the Agentic Loop\n",
                                     "\n",
                                     "Web search runs **server-side** â€” Anthropic executes it and feeds the results back to Claude inside the same request. Your CRM write is **client-side** â€” your code must execute it and return a `tool_result` block before Claude can finish its turn.\n",
                                     "\n",
                                     "The full flow:\n",
                                     "\n",
                                     "1. **Turn 1** â€” Claude calls `web_search`. The API runs it server-side and silently injects results into Claude\u0027s context.\n",
                                     "2. **Turn 2** â€” Claude reasons over the results and emits a `tool_use` block for `add_lead_to_crm`.\n",
                                     "3. **Turn 3** â€” your application performs the database write and sends a `tool_result` block back. Claude generates the final `end_turn` response.\n",
                                     "\n",
                                     "Skeleton for the client-side leg:"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## Checkpoint 3\n",
                                     "\n",
                                     "Implement this step yourself. Use the preceding explanation and the module page as your guide, then compare your approach with the answer key after you have a working version.\n"
                                 ]
                  },
                  {
                      "cell_type":  "code",
                      "execution_count":  null,
                      "metadata":  {

                                   },
                      "outputs":  [

                                  ],
                      "source":  [
                                     "# TODO: Implement checkpoint 3 for Module 2.\n",
                                     "# Keep the cell focused, run it, inspect the output, then move to the next checkpoint.\n",
                                     "\n",
                                     "raise NotImplementedError(\u0027Complete checkpoint 3\u0027)\n"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## 5. Final Verification \u0026 Citations\n",
                                     "\n",
                                     "Once the loop terminates with `end_turn`, inspect the final text blocks. Web search automatically attaches citations to grounded claims â€” verify them so you can audit the sources Claude relied on."
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## Checkpoint 4\n",
                                     "\n",
                                     "Implement this step yourself. Use the preceding explanation and the module page as your guide, then compare your approach with the answer key after you have a working version.\n"
                                 ]
                  },
                  {
                      "cell_type":  "code",
                      "execution_count":  null,
                      "metadata":  {

                                   },
                      "outputs":  [

                                  ],
                      "source":  [
                                     "# TODO: Implement checkpoint 4 for Module 2.\n",
                                     "# Keep the cell focused, run it, inspect the output, then move to the next checkpoint.\n",
                                     "\n",
                                     "raise NotImplementedError(\u0027Complete checkpoint 4\u0027)\n"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## Architectural Summary\n",
                                     "\n",
                                     "- **Safety:** nullable types in the schema (`[\"string\", \"null\"]`) prevent Claude from inventing a budget figure when one isn\u0027t in the search results.\n",
                                     "- **Efficiency:** `code_execution_20260120` is **free** when bundled with `web_search` or `web_fetch`, so dynamic filtering costs nothing extra in token generation.\n",
                                     "- **Compliance:** that same bundling makes the request non-ZDR. Standard web search alone stays ZDR-eligible.\n",
                                     "- **Selection:** tool descriptions, not names alone, drive Claude\u0027s routing. Disambiguate any tools whose purposes overlap."
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## Reflection\n",
                                     "\n",
                                     "Before opening the answer key, write down what worked, what failed, and which API behavior or agent-design rule you would rely on in production.\n"
                                 ]
                  }
              ],
    "metadata":  {
                     "kernelspec":  {
                                        "display_name":  "Python 3",
                                        "language":  "python",
                                        "name":  "python3"
                                    },
                     "language_info":  {
                                           "name":  "python",
                                           "version":  "3.9"
                                       }
                 },
    "nbformat":  4,
    "nbformat_minor":  5
}
