← Workbook
Dossier Print
sequential

Agent Tool Use: Calling Functions

Agent Tool Use

Function calling turned large language models from talking heads into system operators. The shift happened quietly β€” a specification update, a new parameter in an API β€” but its implications are only now being worked through by developers, security researchers, and regulators.

Salt Security 2024-03-13 legal

ChatGPT Plugin Vulnerabilities Discovered by Salt Security: OAuth Hijacking, Unauthorized Access

Security researchers from Salt Labs identified three critical vulnerability classes in ChatGPT plugins: malicious plugin installation without user confirmation, account takeover through the PluginLab.AI framework, and OAuth redirect manipulation. The vulnerabilities allowed attackers to compromise users' private chat data, credentials, and access to third-party services including GitHub. All issues were disclosed to affected vendors in 2023 and remediated before public announcement.

"You gave it permission. You just didn't know which vendors that permission could reach."

Source β†—
arXiv (Security Research) 2025-09-05 economic

Red Team Report: Coding Agents Vulnerable to Tool-Invocation Attacksβ€”Claude Code, Copilot, Cursor All Exploitable

A comprehensive security assessment evaluated multiple coding agents (Claude Code, GitHub Copilot, Cursor, Windsurf, Cline, Trae) for vulnerabilities in how they invoke external tools. Researchers documented systematic weaknesses: agents invoke unintended tools when given ambiguous instructions, tool parameters can be redirected to execute unauthorized commands, and system prompts provide insufficient protection. Attack vectors included supply-chain compromise of tools, parameter injection, and name spoofing.

"The agent followed instructions. They were just instructions the attacker planted."

Source β†—
Anthropic Engineering Blog 2025-06-01 economic

Anthropic Tool Use Advances Accuracy for Complex Parameters to 90%β€”Cuts Token Usage 37% on Research Tasks

Anthropic's latest tool-use improvements significantly raised accuracy on complex function-call scenarios. Tool use examples improved Claude's accuracy from 72% to 90% on tasks requiring correct parameter handling and tool selection. Programmatic Tool Calling (PTC)β€”a new feature allowing Claude to write orchestration code across multiple tools in one passβ€”cut token usage from 43,588 to 27,297 tokens on complex research tasks, a 37% reduction. Internal knowledge retrieval improved from 25.6% to 28.5%.

"Faster and cheaper. The accuracy gap didn't vanishβ€”the margin shrank."

Source β†—
Embrace The Red (Security Research) 2025-06-13 scientific

Google Jules Agent Falls to Invisible Prompt Injection: Hidden Unicode Characters Trigger Backdoor Code Injection

Security researchers demonstrated a class of prompt injection attacks targeting Google's Jules coding assistant by embedding malicious instructions in GitHub issues using invisible Unicode Tag characters. When Jules processes the issue text, it copies the hidden characters verbatim, allowing attackers to instruct the agent to inject backdoor code, compile malicious functions, or execute arbitrary shell commands. The attack exploits Jules's unrestricted outbound internet access and the fact that Gemini models process hidden instructions transparently. Google acknowledged the vulnerability on June 13, 2025.

"The agent reads what you can't see, executes what you didn't ask for."

Source β†—

The big question

Should AI systems that can call external functions be subject to the same API access controls as human developers, or does the speed of automated tool use require a stricter regime?

passage

Models Need Hands

Why Models Need Hands

The Sealed-Off Problem

A language model is a text-prediction machine. Give it "What is 2 + 2?" and it predicts "is 4" by pattern-matching billions of examples. It works for retrieval β€” questions whose answers live in its training data. It fails for action.

Imagine you're a student in Seoul and you want to book a flight to Busan on June 15. A model can tell you why you'd want to go to Busan, or what to expect when you get there. But it cannot buy the ticket. It has no hands. It cannot call the airline API, read the response, adjust the booking, and confirm the purchase. It can only predict the next word that a human who had already bought a ticket would type in a forum post.

When we ask a model to accomplish a real task β€” "Book me a flight" β€” it either:

  1. Hallucinates: Writes plausible-sounding but fake text like "Booking confirmed. PNR: A8K2X9." The model has no way to know if that PNR exists.
  2. Refuses: Admits it cannot act and asks the human to do it.

Neither solves the problem.

What a Tool Gives the Model

A tool is a contract that says: "Here is a function you can call. Tell me its name, the parameters it needs, and I will run it, give you the result, and you can respond based on what actually happened."

A tool definition has four parts:

  1. Name β€” What the function is called. Example: search_flights. The model reads this name and decides: "I need to search for flights, so I'll call this." If you name it get_random_string, the model will pick it for the wrong reasons.

  2. Description β€” What the tool does and when to use it. Example: "Searches available flights from a departure city to a destination city on a specific date. Returns a list of flights with prices, airlines, and departure times." A vague description like "Does something with flights" leaves the model guessing about when to use it.

  3. Parameter Schema β€” A JSON schema that specifies exactly which inputs the tool accepts: their names, types, constraints, and defaults. Example:

    {
      "type": "object",
      "properties": {
        "from_city": { "type": "string", "description": "IATA code, e.g. ICN" },
        "to_city": { "type": "string", "description": "IATA code, e.g. PUS" },
        "date": { "type": "string", "format": "YYYY-MM-DD", "description": "Departure date" }
      },
      "required": ["from_city", "to_city", "date"]
    }
    

    A schema protects against garbage input. The model cannot pass a person's name where a date belongs. The schema is the guardrail.

  4. Return Type β€” What the tool sends back. Example: "An array of flight objects, each with: airline (string), departure_time (HH:MM 24-hour), arrival_time (HH:MM 24-hour), price_usd (number), stops (integer)." The model needs to know what it will receive so it can parse the result and respond sensibly.

The ReAct Loop

Once the model has tools, a ReAct loop (Reason-Act-Observe) runs like this:

  1. Reason: Model thinks, "I need to book a flight. First, let me search for options."
  2. Act: Model calls the tool: search_flights(from_city="ICN", to_city="PUS", date="2025-06-15").
  3. Observe: The tool runs. It returns: [{"airline": "Asiana", "departure_time": "09:30", "price_usd": 45}, {...}].
  4. Reason (again): Model sees the result and thinks, "There are three options. Asiana at 9:30 for 45 dollars is the cheapest. I should book that."
  5. Act (again): Model calls a second tool: book_flight(airline="Asiana", departure_time="09:30") with the customer's details.
  6. Observe: Tool returns confirmation or error.
  7. Respond: Model tells the human: "Done. Your flight is booked for June 15 at 9:30 AM on Asiana. Your confirmation code is XYZ."

Without tools, step 2 never happens β€” the model just predicts what a booked person would write. With tools, the model can actually do it.

Real Cost: Vague Definitions Trap the Loop

Here's the hard part: the clarity of your tool definition determines whether the agent succeeds or fails.

Example: You write a tool called get_weather with a vague description: "Gets weather data." The schema requires a location (string), but does not say whether it accepts a city name, a latitude/longitude pair, or an IATA airport code.

Now the model sees a task: "What's the weather in Seoul?" It calls get_weather(location="Seoul"). Your tool receives a city name, but your backend expects coordinates. It returns an error or garbage. The model observes the failure. It might retry with a different input, or it might hallucinate a response ("The weather in Seoul is sunny and 22Β°C"), or it might give up.

In contrast, a precise tool definition prevents this:

{
  "name": "get_weather",
  "description": "Retrieves current weather for a location. Always use the city's full Korean name (ν•œκΈ€) or its English name followed by 'Seoul'/'Busan'/'Daegu'.",
  "parameters": {
    "location_name": {
      "type": "string",
      "description": "City name in Korean or English (e.g., μ„œμšΈ, Seoul, Busan). Do not use coordinates."
    }
  }
}

Now when the model calls get_weather(location_name="Seoul"), your tool receives exactly what it expects.

Why This Matters

Tools are how autonomous AI systems work in the real world. A customer-service chatbot is sealed off until you give it tools to look up orders, check inventory, initiate refunds. A research assistant is powerless until you give it tools to query databases, fetch papers, run calculations.

You are not building a chatbot. You are building a reasoner with hands. The clarity of your hand (the tool definition) determines what it can actually do.

doc

React Paper Β· S2 1

Yao, Zhao, Yu, Du, Shafran, Narasimhan, Cao

Yao et al. (ICLR 2023) β€” the reasoning-then-acting loop that defines what a tool call is structurally. Core reading before the anatomy-of-a-tool-call activity.

Open source β†—
title

UNIT 3: THE HANDS

Agent Tool Use: Calling Functions

An AI that can only talk is a chatbot. One that can act is an agent. Learn how models call functions to wire your agent to real actions β€” search the web, write files, query databases, trigger workflows. The difference between a chatbot and a tool-using agent is the model's ability to choose which function to call when.

1 / 8

Loading activity...

Answer key
## Answer Key

### Part A: Matching

1 β†’ **A (Name)**: The tool is called `search_bus_fares`, and the model invoked it by that name.
2 β†’ **B (Description)**: It explains what the tool does and when to use it β€” searching fares and returning operator + time + price info.
3 β†’ **C (Parameter Schema)**: The schema specifies that `from_city` and `to_city` are strings and `return` is a boolean.
4 β†’ **D (Return Type)**: The tool returns an array of objects with fields like `operator`, `departure`, `arrival`, and `price_won`.

### Part B: Schema Violation

**Violation:** The parameter schema says cities must be in Korean only ("Korean name only, e.g., μ„œμšΈ"). The model passed `"Seoul"` (English name), which violates the constraint.

**What happens next:** The tool receives `from_city="Seoul"` in English. Your backend might:
- **Fail to lookup** β€” if it strictly expects Korean, it returns an error or empty result. The model observes the error and may retry or hallucinate.
- **Accidentally match the wrong city** β€” if "Seoul" collides with another city's English name in your database (unlikely here, but possible in other cases). Bad data flows downstream.
- **Silently use the correct city anyway** β€” if your backend normalizes English to Korean internally. But now the tool definition is a lie; it says Korean-only but accepts English. Next time the model tries `"Shanghai"` (another city), it might fail because your backend doesn't auto-translate Mandarin.

**The lesson:** Vague or false schema definitions break the ReAct loop. The model cannot predict the failure. Precise, honest definitions protect the loop.
Task

Define And Test

Task: Write and Test a Tool Definition

You are building an autonomous assistant for a Seoul high-school library. One of its jobs is to help students reserve study rooms. The assistant should be able to call a function to check availability and book a room.

Your task has two parts:

Part 1: Write the Tool Definition

Write a complete tool definition (in JSON format) for a function called reserve_study_room. The tool must specify:

  1. name β€” exact function name

  2. description β€” what the tool does and when to use it (2–3 sentences)

  3. parameters β€” a JSON Schema object with these fields (all required):

    • room_number β€” identifier for the room (e.g., "A1", "B3")
    • date β€” the date requested (format: YYYY-MM-DD)
    • start_time β€” when the reservation begins (format: HH:MM in 24-hour time)
    • duration_minutes β€” how long to reserve (integer, 30–240 minutes)
    • student_id β€” the student's ID number (integer)

    For each parameter, specify:

    • type (string or integer)
    • description (what it accepts and any constraints)
    • Mark all as required
  4. returns β€” a description of what the tool sends back (e.g., success status, confirmation number, error message)

Constraint: Your description and schema must be precise enough that an AI model reading it could call the tool correctly without human intervention. No vague phrasing like "some time" or "any ID".

Part 2: Spot the Weak Point

Consider this scenario: A student asks the assistant, "I want to study in room B3 at 2:30 PM for an hour and a half starting tomorrow."

The assistant processes this and calls your tool with:

{
  "room_number": "B3",
  "date": "tomorrow",
  "start_time": "14:30",
  "duration_minutes": 90,
  "student_id": 20241234
}

Question: Identify the error(s) in the assistant's call given your tool definition. What would happen when your backend receives this call? How would you revise your tool definition's description to prevent this specific error?


What to Hand In

Submit a document with:

  1. Your complete JSON tool definition (formatted and valid JSON)
  2. Your answer to Part 2: the error(s), why they matter, and your revised description language

Test your definition by reading it aloud to a partner: would they be able to call the function correctly based only on your definition?

Open Claude Output Β· project
agent-tool-use Β· content dossier Β· teacher copy