← Master Index
Vol. 15 Module 15.1 Lecture

Tool Calling

Agent Fundamentals

How This Lesson Fits the Module & Volume

Tools are how an AI agent leaves the chat box: search, databases, tickets, calculators, RAG retrievers from LangChain / Haystack, even other agents. Tool calling is the product concept—typed capabilities with names, descriptions, and arguments. The next lecture, function calling, is the common API shape (OpenAI-style) used to implement it.

Module 15.3 then standardizes discovery and invocation via the Model Context Protocol (MCP tools). Design tools well here; MCP will transport them later.

Learning Objectives

By the end of this lesson, students should be able to:

  • Define a tool as a typed, permissioned capability—not just “an API wrapper.”
  • Write clear names, descriptions, and JSON schemas that models can select.
  • Contrast tools with RAG retrieval and with raw prompt-injected JSON.
  • Apply allowlists, timeouts, and argument validation before execution.
  • Decide how many tools to expose (small, orthogonal sets beat giant menus).
  • Preview MCP as a standard way to publish the same tools across apps.
Definition

A tool is a model-invocable function with a machine-readable schema (name, description, parameters) and a host-side implementation that performs a side effect or lookup, then returns an observation string or structured result. Tool calling is the loop of selecting, executing, and feeding back those results.

What Makes a Good Tool

PropertyGoodBad
Nameget_order_statusdo_stuff
DescriptionWhen to use + what it returns“Helper”
ParametersEnums, required fields, unitsOne giant query string
ScopeOne job (read order)God-tool that does everything
FailureStructured error the model can act onEmpty / stack trace dump

Tool Registry Sketch

Keep a registry the agent loop can consult. Schemas go to the model; implementations stay on the server with auth. This is the same split MCP servers will use.

import json from typing import Callable, Any ToolFn = Callable[[dict], str] SCHEMAS = [ { "type": "function", "function": { "name": "search_kb", "description": "Search internal policy docs. Use for refund/SLA/how-to questions, not live order state.", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "Natural language search query"}, "k": {"type": "integer", "minimum": 1, "maximum": 8, "default": 3}, }, "required": ["query"], }, }, }, { "type": "function", "function": { "name": "get_order_status", "description": "Fetch live commerce order state by ID. Use when the user mentions an order number.", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "pattern": "^ORD-[0-9]+$"}, }, "required": ["order_id"], }, }, }, ] def search_kb(args: dict) -> str: return "Refunds: 5–7 business days after approval." def get_order_status(args: dict) -> str: return json.dumps({"id": args["order_id"], "state": "shipped"}) REGISTRY: dict[str, ToolFn] = { "search_kb": search_kb, "get_order_status": get_order_status, } def run_tool(name: str, raw_args: str) -> str: if name not in REGISTRY: return json.dumps({"error": "unknown_tool", "name": name}) try: args = json.loads(raw_args) except json.JSONDecodeError: return json.dumps({"error": "invalid_json"}) return REGISTRY[name](args)

Tools vs RAG vs Prompted JSON

RAG retriever-as-tool

  • Read-only knowledge
  • Agent chooses when to retrieve
  • Vol. 14 skills still apply

Side-effect tools

  • Writes, emails, deploys
  • Need autonomy gates
  • Idempotency matters

Prompted JSON only

  • Model emits JSON in text
  • Fragile parsing
  • Prefer native function calling

Strengths

  • Grounds the agent in real systems
  • Composable capabilities
  • Clear audit trail
  • Portable to MCP later

Tradeoffs

  • Too many tools confuse selection
  • Bad descriptions → wrong calls
  • Latency per hop
  • Security if validation is weak
Common Misconception

“Give the agent every API in the company; it will figure it out.” Tool selection degrades as the menu grows. Ship a small, orthogonal set with sharp descriptions. Add tools when eval shows a coverage gap—not when a new microservice appears.

Knowledge Check

  1. Short Answer: What three schema pieces should every tool expose? Answer: Name, description, parameters (types/required).
  2. True/False: Tool calling and function calling are identical layers of the stack. Answer: False—tool calling is the concept; function calling is a common API.
  3. Multiple Choice: Unknown tool names should: (a) eval() anyway, (b) return a structured error / deny, (c) reboot. Answer: (b).
  4. Short Answer: Why prefer enums and patterns on parameters? Answer: They constrain hallucinated arguments and simplify validation.
  5. True/False: A RAG retriever can be exposed as a tool. Answer: True.
  6. Multiple Choice: MCP (15.3) mainly standardizes: (a) CNNs, (b) how tools/resources are published to models, (c) CSS. Answer: (b).
  7. Short Answer: What goes wrong with a giant tool menu? Answer: Worse selection accuracy, more tokens, more risk.
  8. Short Answer: Where should implementations run? Answer: On the host/server with auth—not inside the model.
  9. Multiple Choice: Write tools additionally need: (a) autonomy/HITL gates, (b) extra pooling layers, (c) WordPiece. Answer: (a).
  10. True/False: Empty tool errors are better than structured error JSON. Answer: False.

Key Takeaways

  • Tools are typed, permissioned capabilities with schemas the model can select.
  • Keep sets small and orthogonal; validate args; fail closed on unknown names.
  • RAG, writes, and calculators are all tools—scope and gates differ.
  • MCP will standardize publishing the same tools across clients.
  • Next: function calling—the OpenAI-style wire format.
Trainer’s Guide

Whiteboard: Split a messy “support_api” god-tool into 4 sharp tools. Rewrite descriptions so a model knows when not to call each.

Lab: Add timeout + argument regex for order_id. Log every invocation to an episode list (memory preview).

Recap: Tool calling is typed action. Continue with Function Calling.