What Is a Tool?
Giving the model hands.
A model on its own is a brain in a jar. It can't look anything up, and it can't change anything. A tool is simply a function that the model is allowed to ask for. The surprise is that the model never runs it. It only asks. Your code does the rest.

- A brain in a jar
- A tool is a function
- The model only asks
How a tool call works
Here's the sequence. You send your message, along with a list of tools. The model decides that it needs one, and it replies with a request. Which tool, with which arguments. Your code runs that function. Then you send back the result, and the model continues. So you stay in control. Nothing happens unless your code does it.
Describing a tool
A tool is described with three things. A name, a description, and its inputs. The model only sees this description. It never sees your code. So the description is really a prompt, and it's what the model uses to decide when to call it. Run it. Clear descriptions matter more than clever code.
from google.genai import types
schema = types.FunctionDeclaration(
name="get_order",
description="Look up one order by its ID, such as A17.",
parameters={
"type": "object",
"properties": {"order_id": {"type": "string", "description": "The order ID"}},
"required": ["order_id"],
},
)
print(schema.name, "->", schema.description)get_order -> Look up one order by its ID, such as A17.
Juno's toolbox
Here are Juno's first tools. A small shop file, with orders, stock, and three functions. Get order, check stock, and refund. See how each function has type hints, and a one line description. Those become the tool description automatically. Run it, and look up an order directly, the way that the model will.
from shop import get_order, check_stock
print(get_order("A17"))
print(check_stock("Helmet"))
print(get_order("Z99")){'item': 'Carbon wheelset', 'price': 640, 'status': 'delivered', 'days_ago': 12}
{'item': 'Helmet', 'in_stock': 0}
{'error': 'No order Z99'}Also uses shop.py
ORDERS = {
"A17": {"item": "Carbon wheelset", "price": 640, "status": "delivered", "days_ago": 12},
"B42": {"item": "Chain", "price": 28, "status": "shipped", "days_ago": 2},
"C09": {"item": "Helmet", "price": 95, "status": "delivered", "days_ago": 45},
}
STOCK = {"Carbon wheelset": 3, "Chain": 14, "Helmet": 0}
REFUNDS = []
def get_order(order_id: str) -> dict:
"""Look up one order by its ID, such as A17."""
return ORDERS.get(order_id, {"error": f"No order {order_id}"})
def check_stock(item: str) -> dict:
"""Return how many of an item are in stock."""
return {"item": item, "in_stock": STOCK.get(item, 0)}
def refund(order_id: str, amount: float) -> dict:
"""Refund money to the customer for an order."""
REFUNDS.append((order_id, amount))
return {"refunded": amount, "order_id": order_id}Also uses scripted.py
class Scripted:
"""A stand-in model that replays a fixed list of replies."""
def __init__(self, replies):
self.replies = list(replies)
self.calls = 0
def ask(self, messages):
self.calls += 1
return self.replies.pop(0)Summary
A tool is a function plus a description, and the model only ever asks. Next, we'll do the full exchange by hand, so that you can see every step.
Key takeaways- The model asks, your code runs
- Descriptions are prompts
- Type hints help