Validate tool inputs — when the model invents arguments — step 9 of 9
Checkpoint
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 agent loop with full validation. Write
run_validated_agent(question, max_iters) that:
- Maintains
messages = [{"role": "user", "content": question}]. - Loops up to
max_iterstimes callingfake_create(messages)→ aMockMessagewith.stop_reasonand.content(a list ofMockTextBlockand/orMockToolUseBlock). - On
end_turn: collect text from text blocks, return{"ok": True, "answer": <text joined with " ">, "validation_errors": <count>, "iters": <iter num>}. - On
tool_use: for each tool_use block, calldispatch_with_validation(block.name, block.input). Track how many results came back asVALIDATION_ERROR:orUNKNOWN_TOOL:— increment avalidation_errorscounter per such result. Append the assistant turn + a user turn withtool_resultblocks (each with the righttool_use_id). - On cap: return
{"ok": False, "error": "capped", "iters": max_iters}.
Expected output:
ok=True iters=3 validation_errors=1 answer=Found a 2026 ramen guide.
⌘↵ runs the editor.read, then continue.
Checkpoint
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 agent loop with full validation. Write
run_validated_agent(question, max_iters) that:
- Maintains
messages = [{"role": "user", "content": question}]. - Loops up to
max_iterstimes callingfake_create(messages)→ aMockMessagewith.stop_reasonand.content(a list ofMockTextBlockand/orMockToolUseBlock). - On
end_turn: collect text from text blocks, return{"ok": True, "answer": <text joined with " ">, "validation_errors": <count>, "iters": <iter num>}. - On
tool_use: for each tool_use block, calldispatch_with_validation(block.name, block.input). Track how many results came back asVALIDATION_ERROR:orUNKNOWN_TOOL:— increment avalidation_errorscounter per such result. Append the assistant turn + a user turn withtool_resultblocks (each with the righttool_use_id). - On cap: return
{"ok": False, "error": "capped", "iters": max_iters}.
Expected output:
ok=True iters=3 validation_errors=1 answer=Found a 2026 ramen 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.