Press play and we will build the function-calling loop together — define, ask, execute, return — and then the half nobody demos: allowlists, confirmation gates, and a money tool that computes once, acts once, and refuses rather than guesses.
Conversation simulated model · scripted
Tool runtime real code · runs here
Add one yourself, then run the loop again — the tool reads the same list you just changed.
Loop trace — the four beats
Beat 1 you · Beat 2 the model asks (simulated) · Beat 3 your code executes (real) · Beat 4 the result goes back. Only beat 2 is scripted on this page.
Ch. 1 / Mental model ▶ narrated
A language model produces text. That is the whole of its physical capability. Tool use does not change that — it changes what some of that text means to the program on the other side.
"How many hours is that?"
Emits a structured request: calculator(expression). Then stops.
Recognises it, decides, executes, catches errors.
Result re-enters the conversation as a message.
The model's output is a suggestion with a schema attached. Nothing in the protocol obliges you to run it.
you are the executorAfter asking, the turn ends. Nothing happens until your code sends a result back and asks for another turn.
two round trips minimumIf your function wrote to a database, the model only learns that from the string you return. Silence reads as success.
return what happenedCh. 2 / Mental model ▶ narrated
You send a list of tools alongside the conversation. Names, descriptions, parameter schemas. Every turn.
The model replies with a tool-use block: a name, an id, and an arguments object. Its turn ends there.
Your code validates and runs the real function. This is the only beat where anything happens in the world.
You append a tool-result message carrying the same id, and ask for another turn.
Underneath it all there is just an array of messages that keeps growing. Step through one and watch it fill up — this is the ledger you will be staring at when something goes wrong.
messages[] real array, rendered live
What just happened
Ch. 3 / The first real skill ▶ narrated
A tool definition has three parts, and every one of them is read by the model before it decides anything. The name is a hint. The description is an instruction. The parameter schema is a contract you must still enforce yourself.
Short, lowercase, verb plus object. find_free_slot beats calendarHelper. The model reads it as a summary.
first thing it scansSay what it does, when to use it, and when not to. This is the highest-leverage text in your whole system.
this is a promptJSON Schema. Types, enums, required list, units in the name. Descriptions on fields are read too.
and validated by youBelow is a working checker. It is not an opinion generator — it counts things and reports what it counted. Load the weak example, read the findings, then load the strong one and watch which checks flip.
Findings measured on your text
Every line above is a count or a boolean taken from what you typed. No scores are invented and nothing is sent anywhere.
Ch. 4–12 / Locked
You've heard the setup. The remaining 9 chapters are where Tool Use actually gets built — the guardrails, the hands-on builds, the full narrated walkthrough and the end-of-workshop check.
One file. Yours forever. Works offline, in any browser, on any device.