Tool use stack: schema -> validation -> dispatch -> structured observation tool catalog (as seen by the model) add(a int, b int) -- Add two integers a and b. Use for any integer addition. multiply(a int, b int) -- Multiply two integers. Prefer multiplication over looped addition. argument validation type coercion "5" -> 5 if unambiguous enum check status in {open,closed,pending} required fields missing -> structured error observation range / min / max numeric bounds checked sandbox policy per-tool timeout, fs surface, network never raise to the loop -- every failure becomes an observation the model reads dispatch parallel tool calls assistant turn emits N tool_use blocks each has distinct tool_use_id runtime executes independents in parallel results correlated back by tool_use_id swap the id and routing goes wrong Anthropic, OpenAI, Bedrock all require it execution exceptions caught timeouts enforced results stringified with shape hints structured JSON preferred over prose circuit breaker on repeat failures span emitted (OTel GenAI tool_call) audit trail for post-mortems BFCL V4 composition Agentic 40% Multi-turn 30% Live 10% Non-Live 10% Hallucination 10% single-turn solved; memory, dynamic decisions, long chains remain open gorilla.cs.berkeley.edu/leaderboard.html