FoundationsBeginnerLesson 46 min read

Tools: giving the model hands

A tool is any button the model is allowed to press. Click each part of the diagram to see where trust is won and lost.

Lesson in motion

In 60 seconds

Tools: giving the model hands

A tool is any button the model is allowed to press. Click each part of the diagram to see where trust is won and lost.

1/4
In simple words
The model cannot do anything by itself. It can only write. So we made a deal: if it writes a special sentence, a normal computer program will do the thing for it. That sentence is a tool call.
A tool has three parts: a name, a description the model reads to decide when to use it, and a set of arguments it must fill in.
Here is a real one, simplified:
PartExampleWho writes it
Namesend_emailDeveloper
Description"Sends an email. Use when the user asks to contact someone."Developer β€” but see Module 15
Argumentsto, subject, bodyThe model, at run time
Result"Sent, message id 8812"The outside world β€” untrusted

Tap any box in the diagram

Humanthe real bossgoalThe modelwrites text onlytool callTool runnerordinary codedoes itThe real worldemail, money, files, DBresult textResultuntrusted!the red loop is the one attackers ride
The human

You set the goal and, in a well-built system, you approve the risky steps. You are the only part of this picture that can be held responsible. Never design a system that quietly removes you from it.

Click any box. Four of these five parts are trustworthy. The result arrow β€” the dashed red one coming back from the world β€” is where attacks enter.

Tools are ranked by how sorry you will be

RiskToolsRule of thumb
LowRead a public page, do maths, check the timeLet it run freely
MediumRead private files, query a database, search internal docsLog everything, limit scope
HighSend email, post publicly, write to a database, run codeAsk a human first
ExtremeMove money, delete data, change permissions, deployAsk a human, every single time, with the details shown
Do this
A good habit from day one: sort your tools into read tools and write tools. Read tools are cheap to allow. Write tools are where you spend your caution budget.

Watch and read more

Lab

A tool registry with real argument validation, and the injection it stops.

~15 min

The problem

Take the agent from Lab 3. Add a schema for every tool β€” argument names, types, ranges, allow-lists β€” and reject any call that fails validation before executing. Then write a tool result that tries to make the agent call send_email with an address you choose, and confirm your validation blocks it.
Starter codepython
from dataclasses import dataclass
from typing import Callable

@dataclass
class Tool:
    name: str
    run: Callable
    validate: Callable[[dict], str | None]   # returns an error, or None

def refund_validate(args):
    if not isinstance(args.get("amount"), (int, float)):
        return "amount must be a number"
    if not 0 < args["amount"] <= 5000:
        return "amount must be between 0 and 5000"
    if not args.get("order_id", "").startswith("ORD-"):
        return "order_id must look like ORD-xxxx"
    return None

You are done when

Hard questions

Try to answer before you reveal. If you can answer these, you understood the lesson.

Q1Your validation caps refunds at β‚Ή5,000. An injected agent issues 400 refunds of β‚Ή4,999 in one hour. Was your control useless?Reveal
It was necessary and insufficient. Per-call validation bounds one action; it says nothing about aggregate. You need a second, different control: a rate limit and a cumulative spend cap per run and per hour, enforced in the tool runner. This is the general shape β€” per-action limits and per-window limits are independent controls, and attackers move to whichever you did not build.
Q2Why validate arguments in the tool runner rather than asking the model to produce valid arguments?Reveal
Because the model is the component you cannot trust. Asking it nicely is a request; the runner is enforcement. Concretely: an injected model will happily emit {"amount": 999999} while explaining that it is following your rules. Validation in ordinary code cannot be argued with, and it is testable.

Please sign in to continue.

Questions people ask

Can the model invent a tool that does not exist?

It can try. It will write a call to transfer_funds even if you never built one. A correct tool runner rejects unknown tool names outright. If yours passes them through to some generic executor, you have a serious hole.

What if the model puts nonsense in the arguments?

Then your tool must reject it. Validate every argument like it came from a stranger on the internet β€” because functionally, it did. Type checks, ranges, allow-lists, maximum amounts.

Is MCP a tool?

MCP (Model Context Protocol) is a standard way to plug whole sets of tools into an agent, like a USB port for capabilities. Very useful, and a real supply-chain risk, because you are now trusting someone else's tool descriptions. Module 15.

Should tool results be shown to the user?

Ideally yes, at least in a log. Hidden tool output is how bad things stay hidden. If a human never sees what came back, nobody notices the poisoned instruction that arrived with it.

Lesson test

5 questions. Get 3 right (60%) to pass and complete this lesson.

Sign in with your phone number to take the test and save your progress