Station 4 · Tools & Actions
An LLM on its own can only produce text. A tool is the thing that lets it act — search the web, run code, query a database, send a message. This is where an agent stops talking and starts doing.
What you'll walk away with
Concept 1
A tool is just a function the agent is allowed to call. You register it, describe what it does, and hand it to the model. From then on the model can choose to call it.
Here's the split that trips people up: the LLM decides WHEN to call a tool, but your code decides WHAT it does. The model can't magically fetch the weather — it can only say "I'd like to call get_weather with this city." Your code actually runs, hits the real service, and hands the result back.
Reads the goal, picks a tool, fills in the arguments, and reads the result. It never touches the real world directly.
You write the function body — the actual search, query, or API call — and control exactly what it's allowed to do.
Tools are like the apps on your phone. You (the brain) decide when to open Maps or the calculator — but each app already knows how to do its one job. An agent with no tools is a phone with no apps: it can think, but it can't call, navigate, or pay for anything. Adding a tool is like installing an app that unlocks one new ability.
Concept 2
The model has never seen your code. All it gets is the definition you write. So a good tool definition is basically a tiny instruction manual the model reads before deciding to use it.
Four parts make a tool usable:
A vague description = the agent uses the tool wrong. "Gets data" tells the model nothing about when to reach for it. "Returns the current temperature and conditions for a given city, right now" tells it exactly. You're not writing this for a human — you're writing it for the model that has to pick.
Concept 3
Here's a weather tool defined properly — a clear name, a description the model can act on, typed parameters, and a defined result. Notice how much is explanation, not logic.
def get_weather(city: str, units: str = "fahrenheit") -> dict: """Return the CURRENT temperature and conditions for a city. Use this when the user asks about weather happening RIGHT NOW. Do not use it for forecasts or past weather. Args: city: City and region, e.g. "Austin, TX" units: "fahrenheit" or "celsius" (default fahrenheit) Returns: { "temp": number, "conditions": string } # e.g. 41, "raining" """ try: data = weather_api.fetch(city, units) # YOUR code does the real work return { "temp": data.temp, "conditions": data.sky } except TimeoutError: return { "error": "weather service timed out — try again" }
Concept 4
Most useful agents are built from a small set of familiar tool types. Each one unlocks a whole category of tasks:
Look up current facts the model's frozen training can't know.
Run real code for exact math, data crunching, or logic.
Read or write records — prices, users, inventory, your files.
Call any outside service: weather, maps, payments, translation.
Send a message or notification on your behalf.
Read, write, and edit files — how coding agents change your project.
Reading is safe. But tools that act — send an email, charge a card, delete files — can't be undone. A good agent puts limits on these: confirm before sending, never delete without a check, and only allow what the task truly needs. We give this its full treatment in Station 10 · Safety & Guardrails.
Checkpoint
You add a tool but write its description as just "gets info." What's the likely problem?
The model never sees your function body — it only sees the name, description, and schema. A vague description like "gets info" gives it nothing to decide when this tool applies, so it guesses: calling it for the wrong requests or skipping it when it's actually needed. Clear, specific descriptions are how you steer an agent's tool use.
See it yourself — 5 minutes
Pick a task an agent might do for you — say, "book a restaurant." On paper, define the one tool it would need:
Recap. A tool is a function the agent can choose to call — the model decides when, your code decides what. The definition is everything: a clear name + description, a typed input/output schema, and error handling are what make an agent use a tool correctly. Vague description in, wrong behavior out. Next, we'll look at how you talk to the agent itself: prompting.