Tools
Learn how AI agents use tools to interact with the real world. Understand tool schemas, tool selection, execution, results, safety, and practical Python patterns.
By the end of this lesson, you will be able to:
- Explain what a tool is in an AI agent system.
- Understand the difference between an LLM response and a real tool execution.
- Design clear tool names, descriptions, and input schemas.
- Build a simple Python tool registry and execution loop.
- Understand tool selection, validation, errors, retries, and permissions.
- Choose when to use a tool, RAG, a deterministic function, or a human approval step.
What Is a Tool?
A tool is a capability that an AI application can invoke to perform an operation outside the model's text generation. Examples include searching a knowledge source, calling an API, running a calculation, reading a database, or creating a ticket.
The model decides what information or action may be useful based on the available tool descriptions.
Your application executes a real function or service and returns a structured result.
Why Agents Need Tools
Language models are strong at reasoning over text, but many real tasks require current data or actions. Tools connect the model to systems that can provide those capabilities.
Retrieve information that is outside the model's static knowledge.
Delegate exact arithmetic instead of relying on generated mental math.
Look up permitted customer, product, order, or inventory information.
Open tickets, send messages, update records, or trigger workflows with authorization.
Tool Calling vs Tool Execution
These are two different stages. The model can produce a structured tool call request. The application then performs the actual tool execution.
This separation is important for security. The model should recommend an action; the application remains responsible for deciding whether that action is actually allowed.
A Good Tool Has a Clear Contract
A tool description is an interface contract between the model and your application. The model needs enough information to select the correct tool without guessing.
Specific
Prefer get_order_status over a vague name like helper.
Action-oriented
Explain what the tool does and when it should be used.
Explicit
Define required fields, types, ranges, and allowed values.
Structured
Return predictable data that the model can interpret reliably.
Tool Schemas
A schema describes the arguments a tool accepts. For example, an order-status tool might require an order ID and reject unknown fields.
tool = {
"name": "get_order_status",
"description": "Get the current shipping status for an order.",
"parameters": {
"type": "object",
"properties": {
"order_id": {"type": "string"}
},
"required": ["order_id"]
}
}In a real API, the exact schema format depends on the framework or model provider. The design principle is the same: make the contract explicit.
Tool Registry in Python
Your application can maintain a registry that maps safe tool names to actual Python functions.
def get_weather(city):
return {"city": city, "temperature_c": 28, "condition": "Sunny"}
def calculate_total(price, quantity):
return {"total": price * quantity}
tools = {
"get_weather": get_weather,
"calculate_total": calculate_total,
}
print(tools["calculate_total"](19.99, 3))The registry creates a controlled boundary: only functions that you explicitly register can be called.
How an Agent Selects a Tool
The model receives the user's goal plus the available tool descriptions. It can then return either a final response or a structured tool request.
Good tool descriptions reduce ambiguity. Poor descriptions can cause wrong-tool selection, missing arguments, or unnecessary calls.
Example 1: Weather Tool
Suppose a user asks: βWill I need an umbrella in London today?β A model may recognize that current weather information is required.
The model identifies that a current condition is needed rather than inventing an answer.
The application checks that the city argument is valid and allowed.
The weather service returns structured conditions.
The model turns the tool result into a natural-language answer.
Example 2: Customer Support Tool
Imagine a support agent with these tools: get_order_status, get_tracking_events, and create_support_ticket.
Retrieve the permitted order status using the customer's authenticated account.
If the order is delayed, retrieve tracking details.
The next action depends on the information returned.
Create a ticket only when the business rules allow it.
This is where tools become especially useful in an agent loop: the result of one operation can influence the next permitted operation.
Tool Results Should Be Structured
Returning predictable fields makes downstream reasoning easier and reduces ambiguity.
result = {
"status": "delayed",
"carrier": "Example Express",
"estimated_delivery": "2026-09-14",
"events": 4,
}
if result["status"] == "delayed":
print("Explain the delay and check the next permitted action.")Avoid returning huge unstructured blobs when a small set of relevant fields is enough.
Validation: Never Trust Tool Arguments
Model-generated arguments are untrusted input. Validate them before calling a real service.
Confirm strings, numbers, arrays, and objects have the expected types.
Reject impossible quantities, oversized requests, or invalid dates.
Verify that the current user can access the requested resource.
Restrict actions, destinations, fields, and operations to approved values.
Permissions and Least Privilege
Do not expose every internal capability to every agent. Give each agent the smallest useful set of tools.
Lower risk
Searching public documentation or reading permitted records may need fewer safeguards.
Higher risk
Creating or updating records should have stronger validation.
Review carefully
Sending messages or publishing content can create real-world consequences.
Require approval
Deletion, payments, and account changes often need explicit human or policy approval.
Tool Errors Are Normal
Networks fail, APIs time out, records disappear, and inputs can be invalid. A robust agent should handle tool errors instead of pretending the action succeeded.
def safe_call(tool, arguments):
try:
return {"ok": True, "data": tool(**arguments)}
except ValueError as exc:
return {"ok": False, "error": "invalid_input", "message": str(exc)}
except TimeoutError:
return {"ok": False, "error": "timeout", "message": "Tool timed out."}
result = safe_call(get_weather, {"city": "London"})
print(result)Keep error messages structured so the model can decide whether to retry, ask the user, choose another tool, or stop.
Retries and Idempotency
Retries can help with temporary failures, but blindly repeating an action can be dangerous.
A temporary timeout while fetching information may be reasonable to retry.
Retrying a payment or message can accidentally duplicate the action.
Design APIs so repeating the same request does not unintentionally create duplicates.
Use bounded retries and stop when the error indicates a permanent failure.
Tools vs RAG
RAG and tools can overlap, but they solve different problems.
Find relevant chunks from a document or knowledge collection and provide them as context.
Call a service, calculate a value, query a live system, or change something.
For example, answering a company policy question may use RAG, while checking a live order status requires a tool. An agent can use both.
Tools vs Deterministic Functions
Not every function needs an LLM to choose it. If the application always knows which function should run, call it directly.
Call directly
Use normal application code when the next action is already known.
Tool selection
Let the model choose among permitted capabilities when the next step depends on the task.
Add approval
Keep business policy outside the model and require explicit authorization.
Use an agent
Agentic execution is useful when observations influence subsequent actions.
Tool Calling in an Agent Loop
A simple framework-free mental model looks like this:
def run_agent(goal, model, tools, max_steps=5):
state = {"goal": goal, "history": []}
for _ in range(max_steps):
decision = model(state, list(tools))
if decision["type"] == "final":
return decision["answer"]
if decision["type"] == "tool":
name = decision["name"]
arguments = decision["arguments"]
if name not in tools:
return "Tool is not allowed."
result = tools[name](**arguments)
state["history"].append({
"tool": name,
"result": result,
})
return "Stopped: step limit reached."This is a teaching model, not a production security boundary. Real systems should add schema validation, authorization, logging, rate limits, and safer execution isolation.
Observability
Tool-using agents are difficult to debug if you only store the final answer. Record enough information to understand what happened.
Which capability did the model request?
What inputs were submitted after validation?
What did the tool return, and was it successful?
How long did the model and external operation take?
Common Tool Design Mistakes
A huge tool catalog increases selection ambiguity and maintenance.
If the model cannot tell when to use a tool, tool selection becomes unreliable.
Never pass model-generated values directly into sensitive operations without validation.
Return focused, structured results instead of unnecessary raw payloads.
External calls should have bounded execution time.
Without logs, failures and unexpected actions are hard to investigate.
Mini Project: Build a Safe Tool Agent
Design a small Python agent that can answer a user's request using three tools:
Accept two numbers and an operation from a strict allow list.
Return a few relevant pieces of information from a small local collection.
Create a ticket only after validating the required fields and applying an approval rule.
Let the model select tools, execute them through a controlled registry, and stop after a bounded number of steps.
Challenge: Add a policy that prevents the agent from creating a ticket unless the user has explicitly requested escalation.
Quick Quiz
A) A larger language model B) A callable capability that performs an operation C) A prompt template only
A) The text generator itself B) The application or tool runtime C) The user only
A) They hide arguments B) They define the tool's input contract C) They remove validation
A) Yes B) No, validate and authorize them first C) Only for write operations
30-Second Recap
Key Takeaways
The best tool is not the most powerful one. It is the smallest clearly defined capability that lets the system complete a useful task safely and predictably.