2.6. Workshop
In one glance
- You will: Build eight small checkpoints and explain the behavior each one verifies.
- You need: Step 1 completed; Python and SQLite familiarity. No API key is needed for checks.
- Time: about 160 minutes, hands-on.
How does the workshop progress?
Each step copies your preceding source into a new learner-owned directory.
mise run lab -- list
Run workshop commands from the repository root. At each exercise below, run start N once, edit the created file, then run check N until it passes. If the directory already exists, continue editing it; a refused restart protects your work. All checks are offline. The learning/ directory is ignored by Git and survives runtime-state resets; copy or commit your work in your own repository for a durable backup.
start N carries your previous file forward and appends a scaffold for the step: each new function with its signature, a docstring, the page to read, and a body that raises NotImplementedError naming the missing behavior. A commented TOOLS = [...] line waits at the end, because attaching a tool to the agent is your decision, not the scaffold's. The first check fails until you replace every stub.
Check where you stand at any time:
mise run lab -- status
It marks each step passing, failing, or not started, then prints the one command that moves you forward. A failing check N ends with the page that owns the concept. mise run lab -- solution N prints the worked solution without changing your file. start N --reference starts from the preceding reference checkpoint when you deliberately join later. Starting an existing step always fails without overwriting it.
Your turn: can your tools retrieve only real incidents?
Implement list_open_incidents() and get_incident(incident_id) and attach them to your agent.
- Mode:
capstone carry-forward - Goal: Return only open rows and report missing incident IDs without inventing data.
- Files to touch:
learning/step-2/learner_agent/agent.py. - Preflight: Run
mise run lab -- start 2andmise run lab -- check 2. Predict the result forINC-999and an SQL-like string. Read 3.1. Tools and inspect the seed schema; open SQLite withmode=ro. - Gate that proves completion:
mise run lab -- check 2returns exactly INC-002, INC-005, and INC-010, rejects unknown IDs, and accepts no invented evidence. - Final state: Keep the tools and compare with
mise run lab -- solution 2. Usemise run lab -- run 2only when you choose to spend model quota.
Your turn: can two conversations keep separate state?
Implement remember_incident(incident_id, tool_context) using ADK's conversation state.
- Mode:
capstone carry-forward - Goal: Remember a valid incident without leaking it to another conversation.
- Files to touch:
learning/step-3/learner_agent/agent.py. - Preflight: Run
mise run lab -- start 3. Predict whether an unknown ID should replace a valid remembered ID. Read 2.4. Sessions. - Gate that proves completion:
mise run lab -- check 3verifies isolated state and rejects the invalid replacement. - Final state: Keep the new function and include it in the agent's tool list. Compare with
mise run lab -- solution 3after making your own attempt.
Your turn: can you prevent an unapproved action?
Implement propose_restart(service, tool_context) as a simulated action with explicit approval.
- Mode:
capstone carry-forward - Goal: Validate the service, request confirmation, require a rationale, and avoid repeating an approved action.
- Files to touch:
learning/step-4/learner_agent/agent.py. - Preflight: Run
mise run lab -- start 4. Predict the state after denied, incomplete, and replayed approvals. Read the confirmation section of 3.1. Tools. - Gate that proves completion:
mise run lab -- check 4verifies no effect before approval, denial behavior, required rationale, and one recorded simulated effect after replay. - Final state: Keep the guarded function. This exercise stores synthetic state only; the completed reference adds transactional audit and crash recovery before deployment.
Your turn: can you bound the investigation workflow?
Implement build_workflow(model) with an investigation stage followed by a recommendation stage.
- Mode:
capstone carry-forward - Goal: Use a two-stage ADK
Workflownamedtriage_workflow; share evidence while excluding write tools. - Files to touch:
learning/step-5/learner_agent/agent.py. - Preflight: Run
mise run lab -- start 5. Predict whether a recommendation stage needs restart authority. Read 3.5. Workflows. - Gate that proves completion:
mise run lab -- check 5verifies the investigate → recommend structure and excludes the restart tool from both stages. These are structural checks, not live reasoning-quality measurements. - Final state: Keep the workflow.
mise run lab -- run 5 --workflowopens this composition in ADK Web and consumes quota when you send a message. Compare this small sequence with the reference's richer plan → investigate → evidence review → recommend graph.
Your turn: can a grader detect missing and invented evidence?
Implement grade_answer(answer, expected_ids) to compare incident IDs rather than wording.
- Mode:
capstone carry-forward - Goal: Reject answers that omit an expected ID or add an invented one.
- Files to touch:
learning/step-6/learner_agent/agent.py. - Preflight: Run
mise run lab -- start 6. Predict each label inagents/python/labs/cases.jsonbefore running the grader. Read 4.4. Evaluations. - Gate that proves completion:
mise run lab -- check 6agrees with all recorded labels, including false-positive and missing-evidence cases. - Final state: Keep your grader and its cases. Record the result with MLflow when the evaluation lesson introduces it; grade new held-out cases before making a quality claim.
Your turn: can retrieved text stay data?
Implement neutralize(text) and read_runbook(slug) so a runbook reaches the model fenced as data, with injected instructions removed.
- Mode:
capstone carry-forward - Goal: Reject a traversal slug before any file access, fence runbook text between
DATA_STARTandDATA_END, and remove instruction-like phrases without touching benign evidence. - Files to touch:
learning/step-7/learner_agent/agent.py. - Preflight: Run
mise run lab -- start 7. Predict each label inagents/python/labs/injections.jsonbefore running the check. Two cases try to slip past a naive filter: fullwidth letters, and a line that closes your fence early. Read 4.5. Guardrails. - Gate that proves completion:
mise run lab -- check 7flags all five attacks, leaves all four benign lines byte-identical, and refuses../../.env. - Final state: Keep both functions and attach
read_runbooktoTOOLS. Then readagents/data/runbooks/cascade-failure.mdthrough your tool: it quotes an attack as a warning, and your filter neutralizes the quote too. A pattern list is a tripwire, not a parser; fencing, least privilege, and human approval are the defenses that do not depend on wording.
Your turn: can you share read tools without sharing authority?
Implement build_mcp_server() so another agent can call your three read tools, but never propose_restart.
- Mode:
capstone carry-forward - Goal: Return an MCP SDK 2.x
MCPServerexposing exactlylist_open_incidents,get_incident, andread_runbook, each annotated read-only. - Files to touch:
learning/step-8/learner_agent/agent.py. - Preflight: Run
mise run lab -- start 8. Predict whyremember_incidentandpropose_restartstay off the server even though both are useful. Read 3.3. MCP. - Gate that proves completion:
mise run lab -- check 8connects a real MCP client in process, lists exactly the three read tools, checks their read-only annotations, and callsget_incidentfor a known and an unknown ID. - Final state: Keep the server factory. The in-process client speaks MCP revision
2026-07-28with no network. 5.2. MCP Gateway later puts the reference server behind a gateway allowlist, the platform version of the same boundary.
What proves this page worked?
mise run lab -- status
mise run lab -- check 8
You are done when:
statusmarks all eight steps passing, and you can explain the failure each check catches.- You can distinguish a Python behavior check, workflow structure check, grader calibration, guardrail regression, and live model evaluation.
- You can name one attack your step 7 filter would miss, and the control that still contains it.
- Your work is preserved and you know where each worked solution lives.
Continue to 4.8. Developer Handoff after consulting the capability and quality pages needed for your exercises.