AI Agents and Agentic Systems
Intermediate 15 min Module 2 of 6
Module 2 of 6

Tool Use and Function Calling

The thing that turns a language model into an agent is the ability to call tools. Without tools, a model can only describe what it would do. With tools, it can actually do it. This module explains how tool calling works, how you define tools for an agent, and how the agent decides which tool to reach for.

By the end of this module you will be able to

What Is a Tool?

In everyday life, a tool is anything that extends what you can do with your hands. A calculator does math faster than you can. A phone lets you talk to someone across the world. A map tells you where you are. For an AI agent, a tool is the same idea: any function or API the agent can call to get information or take action that it cannot do by generating text alone.

Common agent tools include: web search (get current information), a calculator (do arithmetic accurately), a calendar API (read and write events), a database query (look up records), an email API (send messages), and a file reader (process documents). The agent's language model decides which tool to call and with what arguments. The tool runs, returns a result, and the model reads the result and continues.

The key distinction A tool produces a real output: a search result, a database row, a sent email, a file's contents. The agent cannot fake this by generating text. It has to call the tool and read what comes back.

How Function Calling Works

You describe each tool to the model using a structured specification, usually in JSON. The specification says: here is the tool's name, here is what it does, and here are the parameters it accepts. When the model decides to use the tool, it outputs a structured call that matches the specification. Your system intercepts that call, runs the real function, and feeds the result back into the model's context.

Here is what a simple tool specification looks like:

Fig 2 · Tool Call Flow
Language Model Function Call Tool Executor Result back to model result re-enters the model context for next reasoning step
{
  "name": "search_web",
  "description": "Search the web for current information on a topic.",
  "parameters": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "The search query to submit."
      }
    },
    "required": ["query"]
  }
}

When the model wants to search, it outputs something like: call search_web with query "quarterly earnings Apple 2026." Your code catches that, runs the actual web search, and returns the results. The model reads the results and decides what to do next.

Toolformer: Teaching Models to Use Tools on Their Own

In early 2023, researchers at Meta AI published Toolformer, a method for training language models to decide on their own when and how to call tools. Before Toolformer, tool use had to be explicitly programmed in: the model was told which tool to call in which situation. Toolformer showed that models could learn this from examples (Schick et al., arXiv:2302.04761).

The key idea was self-supervised fine-tuning. The researchers generated a dataset of tool calls that actually helped the model answer questions, then filtered out the ones that did not improve the answer, then fine-tuned the model on the filtered examples. The resulting model could call a calculator when it needed math, a search engine when it needed current facts, and a calendar when it needed dates, all without being told which tool to use for each question.

What problem does Toolformer solve that simple function calling does not?
Simple function calling requires you to write rules: call the calculator for math, call the search API for news. Toolformer gives the model judgment: it learns to decide whether using a tool will improve its answer and when to skip the tool entirely. That judgment is harder to program than it sounds, especially when the same question could reasonably be answered from training data or from a live API.

Three Categories of Tools

Read tools let the agent gather information without changing anything. Examples: web search, database lookup, file reader, calendar query, weather API, stock price feed. These are low-risk because they do not modify any external system.

Write tools let the agent create or modify things in the world. Examples: send email, create a document, update a database record, submit a form, post to a calendar. These carry more risk because their effects are real and may be hard to reverse.

Code execution tools let the agent write and run code. Examples: Python interpreter, SQL runner, JavaScript sandbox. These are the most powerful and the most risky, because the agent can potentially do anything the execution environment allows.

Design principle Start with read-only tools. Add write tools only when you need them, and add human approval checkpoints before any write action that is hard to reverse.

How the Agent Chooses Which Tool to Call

The agent does not have a lookup table that says "if the question is about the weather, call weather_api." Instead, the model reads the tool descriptions you provided and matches the current task to the tool that fits. This is why good tool descriptions matter: if your description of a tool is vague, the model may call the wrong one or skip a useful one entirely.

Good tool descriptions are specific about what the tool returns. Instead of "gets information," write "searches the web using Google and returns the top 5 results with title, URL, and a one-sentence summary of each." That level of specificity helps the model decide whether the tool is right for the current step.

A Second Analogy: The Plugin System

A useful way to think about function calling is the plugin system in modern software. A base application (say, a spreadsheet program) cannot do everything out of the box. But you can install plugins that extend it: a currency converter, a chart renderer, a data importer. Each plugin has a defined interface: here are the functions it exposes, and here are the arguments those functions accept.

Function calling works the same way. The base language model is the application. The tools are the plugins. The JSON schema is the plugin interface definition. When the model wants to use a plugin, it calls it by name with the right arguments. The plugin runs, returns a result, and the model reads that result to continue its work. The model does not need to know how the plugin works internally, only what it does and what it expects as input.

This analogy also clarifies why tool descriptions matter so much. If a plugin has a vague description, you do not know when to use it or what it will return. The same is true for agent tools. A description like "does email stuff" is useless. "Sends a plain-text email from the authenticated sender account. Returns success or a delivery error message" tells the model exactly when to reach for this tool and what to expect back.

Common misconception "The agent automatically knows which tool to use." It does not. The model reads your tool descriptions and reasons about which tool fits the current situation. If your descriptions are vague or overlapping, the model will make the wrong choice. Writing precise tool descriptions is as important as writing a good system prompt.

A Finance Example: Trade Settlement

A financial services firm processes securities trades that require settlement, meaning the transfer of securities and cash between counterparties. A settlement agent might have access to these tools: a trade-lookup API (read), a counterparty-record API (read), a settlement-status API (read), a nostro-balance API (read), a settlement-instruction writer (write), and an exception-flag tool (write). During a task, the agent reads the trade details, checks counterparty records, verifies balance availability, and either submits settlement instructions or flags the trade for a human reviewer if a discrepancy is found. Each of those tool calls is explicit, logged, and auditable. That auditability is one of the main reasons regulated industries are drawn to function-calling architectures over less structured approaches: you always know exactly which tools the agent called and with what arguments.

Python · Function Calling with Tool Definition and Parsing
import json, openai

# Step 1: Define the tool schema
tools = [{
    "type": "function",
    "function": {
        "name": "get_stock_price",
        "description": "Get the current price of a stock by ticker symbol. "
                       "Returns a float representing the price in USD.",
        "parameters": {
            "type": "object",
            "properties": {
                "ticker": {
                    "type": "string",
                    "description": "The stock ticker, e.g. AAPL or MSFT"
                }
            },
            "required": ["ticker"]
        }
    }
}]

# Step 2: Let the model decide to call the tool
response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user",
               "content": "What is Apple's stock price right now?"}],
    tools=tools,
    tool_choice="auto"
)

# Step 3: Parse the tool call from the response
msg = response.choices[0].message
if msg.tool_calls:
    call = msg.tool_calls[0]
    args = json.loads(call.function.arguments)
    # args == {"ticker": "AAPL"}

    result = fetch_stock_price(args["ticker"])  # your real function

    # Step 4: Return the result to the model
    follow_up = openai.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "user", "content": "What is Apple's stock price?"},
            msg,
            {"role": "tool", "tool_call_id": call.id,
             "content": str(result)}
        ]
    )
    print(follow_up.choices[0].message.content)
Try this

Write a tool definition for a real tool you use regularly: a Slack message sender, a Google Calendar event creator, or a spreadsheet row appender. Define its name, a one-sentence description of what it does and what it returns, and its parameters with types and descriptions. Then compare your definition to the JSON format in the diagram above. Notice where you were vague and what information the model would need to call your tool correctly.

Knowledge check
What is the purpose of the JSON schema when defining a tool for an agent?
Correct. The schema is the model's instruction manual for the tool. Without it, the model cannot reliably call the tool with the right arguments.
Not quite. The JSON schema describes the tool: its name, what it does, and what parameters it accepts. The model reads this description to decide when and how to call the tool.
Which category of tool carries the most risk in an agentic system?
Correct. Code execution tools are the most powerful and risky because the agent can run arbitrary code, which may have effects beyond what was intended.
Code execution tools are the most risky because they let the agent run arbitrary code with real effects on the execution environment. Read tools change nothing; write tools change specific things; code tools can change anything the environment allows.
What was the key insight of the Toolformer paper (Schick et al., 2023)?
Exactly right. Toolformer showed that fine-tuning on self-supervised examples of helpful tool use gives models judgment about when to call a tool, rather than requiring hard-coded rules.
The key insight was that models can be trained to decide for themselves when a tool call helps, using self-supervised fine-tuning on examples where tool use actually improved the answer.
Interactive 2: Tool Schema Builder Try it

Change the tool type, parameter count, and return type to see how a realistic JSON function schema changes. This is the exact format an agent receives before deciding which tool to call.

Parameter count: 2    Schema complexity: Medium
Before you go
Reflection: Pick one task you do regularly that involves looking up information and then doing something with it. Write the tool definitions for every tool the agent would need. Which ones are read and which are write?
You might also like
Was this module helpful?
← Module 1: What Is an Agent? Module 3: Memory and Context →