Wire the real model — swap fake_llm for the Anthropic SDK shape — step 9 of 9
One last thing before we move on. Same surface as a write step — but the lesson doesn't complete until this passes.
Final drill. Build the full agent loop using the real-SDK shape.
Write run_agent(question, max_iters) that:
- Loads the API key via
os.getenv("ANTHROPIC_API_KEY")(mocked to a known value for the demo). If missing, return{"ok": False, "error": "missing key"}immediately. - Otherwise, builds
messages = [{"role": "user", "content": question}]and loops up tomax_iterstimes callingfake_create(messages)(which returns aMockMessage). - On
response.stop_reason == "end_turn": collect all text blocks fromresponse.content, join them with" ", return{"ok": True, "answer": <joined text>, "iters": <iteration count>, "tokens": <input + output>}. - On
response.stop_reason == "tool_use": for eachtool_useblock, dispatch throughTOOLS[block.name](**block.input)to get a result string. Append the assistant turn (passingresponse.contentdirectly through) AND a user turn withtool_resultblocks. Continue. - On cap exhaustion: return
{"ok": False, "error": "capped", "iters": max_iters}.
Token tracking: sum response.usage.input_tokens + response.usage.output_tokens
across every call. Include the running total in the success
return.
Expected output:
ok=True iters=2 tokens=120 answer=Found Tokyo's best ramen, 2026 guide.
One last thing before we move on. Same surface as a write step — but the lesson doesn't complete until this passes.
Final drill. Build the full agent loop using the real-SDK shape.
Write run_agent(question, max_iters) that:
- Loads the API key via
os.getenv("ANTHROPIC_API_KEY")(mocked to a known value for the demo). If missing, return{"ok": False, "error": "missing key"}immediately. - Otherwise, builds
messages = [{"role": "user", "content": question}]and loops up tomax_iterstimes callingfake_create(messages)(which returns aMockMessage). - On
response.stop_reason == "end_turn": collect all text blocks fromresponse.content, join them with" ", return{"ok": True, "answer": <joined text>, "iters": <iteration count>, "tokens": <input + output>}. - On
response.stop_reason == "tool_use": for eachtool_useblock, dispatch throughTOOLS[block.name](**block.input)to get a result string. Append the assistant turn (passingresponse.contentdirectly through) AND a user turn withtool_resultblocks. Continue. - On cap exhaustion: return
{"ok": False, "error": "capped", "iters": max_iters}.
Token tracking: sum response.usage.input_tokens + response.usage.output_tokens
across every call. Include the running total in the success
return.
Expected output:
ok=True iters=2 tokens=120 answer=Found Tokyo's best ramen, 2026 guide.
this step needs the editor
on desktop today; in the app (coming soon). save your spot and we'll bring you back here when you're ready.