Skip to content
SparkTime, home
AI From Zero to Productive
Lessons
1 · Understanding Modern AI
2 · Talking to AI Effectively
3 · AI for Learning
4 · AI for Work and Productivity
5 · AI for Developers
6 · AI for Career Growth
7 · Research, Verification and Responsible AI
8 · Automation and AI Agents
9 · Build Your Personal AI System
Lesson 31 of 35

Lesson 31 · Automation and AI Agents

Tool Use, Function Calling and Agent Loops Explained

How can a language model that only produces text check a calendar, search a database or edit a file? Through tool calling: the model asks, your program acts. This article explains function calling, the Model Context Protocol and the agent loop, with a runnable toy loop that shows allowed tools, step limits and what the model never does itself.

On this page

Key takeaways

  • A language model produces text. Tool calling lets it request an action in a structured form, and your application decides whether to run it and sends the result back.
  • The model decides, and the application executes. Permissions, validation and limits therefore live in your code, not in the model.
  • An agent loop repeats: decide, act, observe, until the goal is met or a limit is reached. Step limits, budgets and allowed-tool lists are essential.
  • The Model Context Protocol is an open standard for connecting AI applications to tools and data. It makes connecting easier, which makes vetting what you connect more important.
  • Good tools are narrow, clearly described, validated, least-privilege and, for risky actions, subject to human approval. Treat tool results as untrusted input.

Ask a plain language model, "What is the weather in Chennai right now?" and it cannot tell you. It has no window, no clock and no connection to a weather service. It can only produce text. But connect it to a weather service in the right way and the same model can answer correctly, and even compare two cities, book a reminder or file a report.

The step in the middle is called tool use, and understanding it demystifies most of what people call "AI agents".

What you will learn

#
  • How tool calling (function calling) works, step by step.
  • What the Model Context Protocol is.
  • What an agent loop is, with a runnable toy example.
  • How to design safe tools.
  • Where the risks sit.

The core idea: the model asks, your program acts

#

A language model cannot run code, send an email or query a database. What it can do is write text, including text in a strict, structured shape such as "call the function get_weather with the argument city = Chennai". Tool calling builds on this.

OpenAI's documentation describes the flow in five high-level steps:

  1. Make a request to the model, with the tools it could call.
  2. Receive a tool call from the model.
  3. Execute code on the application side, with the input from the tool call.
  4. Make a second request to the model, with the tool output.
  5. Receive a final response from the model (or more tool calls).

The sentence to remember: the application executes the functions, not the model. The model examines the request and decides whether it needs external data or functionality. If so, it returns a tool call, a structured request naming the tool and its arguments. Your program then runs the real function, gets the result, and sends it back to the model, which writes the final answer.

This is the same pattern across providers, even if the names differ ("function calling", "tool use").

The pieces

#

Piece

What it is

Example

Tool definition

A name, a plain-language description and a schema for the arguments, given to the model

get_weather(city: string): "Returns current weather for a city"

Tool call

The model's structured request to use a tool

{"tool": "get_weather", "args": {"city": "Chennai"}}

Your code

The actual function, plus checks

Calls a weather service, handles errors

Tool result

What your code returns to the model

"34C, humid"

Final answer

The model's reply to the user, using the result

"It is 34C and humid in Chennai."

Two consequences matter for safety:

  1. All real power lives in your code. If a tool can delete files, the model can ask for it. Whether it happens is up to you.
  2. The model's request is just text, and can be wrong. It might choose the wrong tool, give bad arguments or be steered by hostile content it read. Your code should validate everything.

The Model Context Protocol (MCP)

#

If every AI application had to connect to every tool in its own way, it would be a mess. The Model Context Protocol is an open standard for connecting AI applications to external systems. Its introduction describes how AI applications like Claude or ChatGPT can use it to connect to data sources (such as local files and databases), tools (such as search engines and calculators) and workflows (such as specialised prompts), and compares it to a USB-C port for AI applications: a standard way to connect things. It says that many assistants and development tools support it.

For a user, MCP means that the "connectors" and "tools" an assistant offers may be built on a shared standard, so there are many of them, built by many people.

The agent loop

#

A single tool call answers one question. An agent repeats the cycle until a goal is met. The loop looks like this:

Code
goal  |  vdecide  ->  act (call a tool)  ->  observe (read the result)  ^                                      |  +--------------------------------------+  (repeat until: done, step limit, budget used, or a human stops it)

Anthropic's article describes agents as systems where the model dynamically directs its own process and tool use. In practice, at each turn the model sees the goal and everything that has happened so far, and picks the next action or declares it is finished.

Real products wrap this in more machinery, such as planning, memory and sub-agents. GitHub's documentation describes the agent mode in Copilot, for example, as one where you describe a goal and the tool can work through multiple steps, including researching a repository, proposing a plan, editing files and preparing a pull request, while stating that you remain responsible for reviewing and approving. The principle is the same: decide, act, observe, repeat, with a human at the boundary.

A runnable toy loop

#

The program below is a toy. Its "model" is a scripted function, so the output is the same every run. A real model chooses its actions itself. What the toy shows accurately is the loop around the model: the allowed-tool list, the arguments, the observation fed back and the step limit.

Python
# File: agent_loop.py# A toy agent loop. The "model" is a scripted function so the output is the same every run.# In a real system the model is a language model; the loop around it works the same way.def get_weather(city):    return {"Chennai": "34C, humid", "Pune": "27C, clear"}.get(city, "unknown city")def add(a, b):    return a + bTOOLS = {"get_weather": get_weather, "add": add}  # the only actions this agent may takedef scripted_model(history):    """Pretend model: decides the next step from what it has seen so far."""    results = [m["content"] for m in history if m["role"] == "tool"]    if len(results) == 0:        return {"action": "call", "tool": "get_weather", "args": {"city": "Chennai"}}    if len(results) == 1:        return {"action": "call", "tool": "get_weather", "args": {"city": "Pune"}}    if len(results) == 2:        return {"action": "call", "tool": "delete_files", "args": {"path": "/"}}  # not allowed    return {"action": "finish", "answer": "Chennai: " + results[0] + "; Pune: " + results[1]}def run_agent(goal, max_steps=6):    history = [{"role": "user", "content": goal}]    for step in range(1, max_steps + 1):        decision = scripted_model(history)        if decision["action"] == "finish":            print(f"step {step}: finish")            return decision["answer"]        tool = decision["tool"]        if tool not in TOOLS:            print(f"step {step}: model asked for '{tool}' -> blocked, not in allowed tools")            history.append({"role": "tool", "content": "error: tool not allowed"})            continue        result = TOOLS[tool](**decision["args"])        print(f"step {step}: ran {tool}({decision['args']}) -> {result}")        history.append({"role": "tool", "content": result})    return "stopped: step limit reached"print(run_agent("Compare the weather in Chennai and Pune"))print("---")print(run_agent("Compare the weather in Chennai and Pune", max_steps=2))
Code
step 1: ran get_weather({'city': 'Chennai'}) -> 34C, humidstep 2: ran get_weather({'city': 'Pune'}) -> 27C, clearstep 3: model asked for 'delete_files' -> blocked, not in allowed toolsstep 4: finishChennai: 34C, humid; Pune: 27C, clear---step 1: ran get_weather({'city': 'Chennai'}) -> 34C, humidstep 2: ran get_weather({'city': 'Pune'}) -> 27C, clearstopped: step limit reached

Read the output as a story:

  • Steps 1 and 2: the "model" requests the weather for each city. The loop runs the real function and feeds the observation back.
  • Step 3: the "model" asks for a tool, delete_files, that is not on the allowed list. The loop blocks it and tells the model it failed. The model cannot do what the code does not permit.
  • Step 4: having both results, it finishes.
  • Second run: with max_steps=2, the loop stops before the model could finish. A step limit ensures that a confused or stuck agent cannot run forever, spending money or taking actions without end.

What the code does not show: a real model can pick wrong tools, supply bad arguments, loop pointlessly, misread results or be steered by text in the results. The real work of building reliable agents is containing those behaviours.

Designing safe tools

#

If you build tools, or choose which to connect, these principles help.

Principle

In practice

Narrow

A tool does one thing. get_order_status(order_id) is safer than run_sql(query)

Clear description

The model chooses tools by their descriptions, so state what a tool does and does not do

Validate arguments

Check types, ranges and allowed values in code. Never pass model output straight into a shell, query or file path

Least privilege

Give each tool the minimum access, such as read-only database credentials where reads suffice

Separate read from write

Reading is lower risk. Put writes behind extra checks

Approval for risky actions

Sending, deleting, paying, publishing or changing permissions requires a human to confirm

Safe by default

Dry-run modes, drafts instead of sent messages, a trash folder instead of permanent deletion

Useful errors

Return clear messages, so the model can correct course without guessing

Concise results

Huge outputs eat the context window. Return what is needed

Logging

Record every call, argument and result so you can audit and debug

Limits

Caps on steps, time, spending and the number of items touched

Where the risks sit

#
  • Wrong choices. The model picks a poor tool, or the right tool with a wrong argument.
  • Runaway loops. Without limits, an agent can repeat costly actions.
  • Prompt injection. Tool results are content too, such as a web page, an email or a file. If it contains instructions, the model may follow them. OWASP lists prompt injection as the top risk for LLM applications, with indirect injection through external content as a main route, and recommends least-privilege access, human approval for high-risk actions and segregating external content. Treat every tool result as untrusted input.
  • Excessive permissions. The broader the tools, the greater the damage from any mistake or attack.
  • Data exposure. Results flow back into the model's context, and may then flow into later calls or outputs.
  • Silent failure. An agent may report success when it has not achieved the goal. Verify outcomes independently.
  • Cost and latency. Many model calls add up.

A useful habit when judging any agent setup: ask what is the worst thing it could do with the access it has, and whether you would be comfortable if it did that on its worst day.

What agent products do in practice

#

Under the branding, most agent products combine the pieces above: a language model, a set of tools (file access, search, code execution, browser control, connectors to apps), a loop with limits and a user interface that shows what it is doing and asks for approval. The differences that matter for you are practical:

  • What can it see and do? (Permissions.)
  • Does it ask before acting? (Approvals.)
  • Can I see the steps it took? (Transparency.)
  • Can I undo what it did? (Reversibility.)
  • Where does it run, and who has my data? (Environment and privacy.)

Common mistakes

#
  • Thinking the model runs the tool. Your code does.
  • Passing model output straight into a command or query.
  • Giving one tool broad powers ("run any command").
  • No step or spending limit.
  • Connecting a third-party connector without checking it.
  • Trusting a "done" message without verifying the result.
  • Letting an agent read untrusted content while it holds powerful tools.

Exercises

#

Exercise 1

Who does what?

#

In the five-step tool-calling flow, say which steps the model performs and which your application performs.

Exercise 2: Extend the toy

#

In the toy loop, you want to add a tool multiply(a, b). List the changes you would make, and say what you would change to add a limit of at most 3 weather lookups per run.

Exercise 3: Judge the tool

#

A company wants to give its support agent a single tool execute_sql(query) connected to the production database with full permissions. Explain the risks and propose a safer design.

Exercise 4: Read the log

#

An agent's log shows 14 calls to search_web with nearly identical queries, then a call to send_email. List what you would investigate, and what controls would have helped.

Show solutionHide solution

Model: step 2 (decides to call a tool and produces the structured tool call) and step 5 (writes the final response, or requests more tool calls). Your application: step 1 (sends the request with the tool definitions), step 3 (executes the function) and step 4 (sends the result back to the model). The model never runs the function. That is why validation, permissions and limits belong in your code.

Exercise 2

Show solutionHide solution

To add multiply: write the function, add it to the TOOLS dictionary, and (in a real system) describe it to the model. The loop needs no change, because it looks tools up in the dictionary.

To limit weather lookups to 3 per run: keep a counter per tool inside run_agent. Before executing get_weather, check whether the counter is already 3, and if so add an error observation ("lookup limit reached") instead of running it. This is the same pattern as the allowed-tools check and the step limit: policy enforced in code around the model.

Exercise 3

Show solutionHide solution

Risks: the model, or an attacker who injects instructions through a ticket or an email, could run queries that read, change or delete any data, including other customers' records. Mistakes in generated SQL could also cause damage or heavy load. Full permissions on production mean any error is severe.

Safer design: several narrow tools such as get_order_status(order_id) and get_customer_tickets(customer_id), each running a fixed, parameterised query with read-only credentials, validated arguments and limits on result size. Writes (such as issuing a refund) are separate tools requiring human approval, with their own limits. Log all calls, and use a replica or restricted view rather than the production database where possible.

Exercise 4

Show solutionHide solution

Investigate: why it repeated near-identical searches (a stuck loop, poor results, a failing parse), what it did with the results, and why it decided to send an email, to whom, with what content, and whether that action was part of the user's request or was triggered by something it read (possible injection). Check what the email contained and whether any sensitive data left.

Controls that would help: a step or repeat limit, detection of repeated calls, requiring approval before send_email, an allowlist of recipients, logging with review, and keeping untrusted content apart from instructions.

Where to go next

#

Sources & further reading

  1. developers.openai.com
  2. modelcontextprotocol.io
  3. anthropic.com
  4. docs.github.com
  5. genai.owasp.org
  • Guide · Technology

    Writing Better AI Prompts: A Practical Guide

  • Guide · Technology

    Using AI Tools at Work Without Getting Into Trouble

  • Course · Career

    Off-Campus Placements With AI: From Zero to Offer