Skip to content

Concept map· 6 connected terms

Tool Calling (Function Calling)

Also called: Function calling · Tool use · LLM tool calling

In one line
An LLM feature in which the model replies with a structured request to run one of your functions — such as check_order_status — instead of text.

Reviewed

What is tool calling (function calling)?

Tool calling, also called function calling, is the feature that lets a large language model (LLM) take actions through your software. You describe a set of tools — each with a name, a description and a JSON Schema for its arguments — alongside the conversation. When the model decides it needs one, it returns a structured call, such as check_order_status with {"order_id": "48213"}, instead of a text reply. Your code runs the function, sends the result back, and the model writes its answer from real data.

The model only proposes; your application disposes. Nothing is executed by the model, which is what makes tool calling safe enough to build on: your code can validate the arguments, check that this WhatsApp user may perform the action, ask for confirmation, rate-limit, log or refuse. One turn can involve several calls, in sequence or in parallel, and an AI agent is essentially this loop run repeatedly until a task is done.

Tool calling is often confused with two neighbours. Structured output (JSON mode) also returns JSON, but as the final answer rather than as a request for your code to act. The Model Context Protocol (MCP) sits a layer above: an open standard for packaging tools in servers so any compatible application can discover and use them, while tool calling is the model-level mechanism that actually invokes a tool, wherever it came from.

Key takeaways

  • Tool calling lets an LLM ask your code to run a named function with JSON arguments, then answer from the result.
  • The model never executes anything itself; your code decides whether and how each proposed call runs.
  • Authorise every call against the verified WhatsApp sender, never against identifiers the model supplies.
  • Make side-effecting tools idempotent and confirm irreversible actions with the customer first.
  • MCP standardises how tools are packaged and shared; tool calling is the model-level mechanism that invokes them.

Inspect one tool call, from definition to reply

8 / 8
{
"tools": [
{
"name": "check_order_status",
"description": "Get delivery status for one of this customer's orders.",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string"
}
},
"required": [
"order_id"
]
}
}
],
"customer_message": "48213 kab tak aayega?",
"model_turn": {
"tool_calls": [
{
"id": "call_01",
"name": "check_order_status",
"arguments": {
"order_id": "48213"
}
}
]
},
"tool_result": {
"tool_call_id": "call_01",
"content": {
"status": "out_for_delivery",
"eta": "today, 6–8 pm"
}
},
"final_reply": {
"text": "Aapka order 48213 out for delivery hai — aaj 6–8 pm ke beech pahunch jayega. 🚚"
}
}
A provider-neutral record of a single tool-calling round trip on WhatsApp: the tool definition, the model's proposed call, your code's result and the final reply. Field names vary slightly between LLM providers.

Field 8: final_reply.text — The model's answer, written from real data, sent to the customer through the Cloud API.

Tool calling (function calling) in code

const tools = [{
name: "check_order_status",
description: "Get delivery status for one of THIS customer's orders.",
parameters: {
type: "object",
properties: { order_id: { type: "string", pattern: "^[0-9]{5,10}$" } },
required: ["order_id"],
},
}];
async function reply(conv, waId) {
for (let round = 0; round < 5; round++) { // hard cap on tool rounds
const res = await llm.generate({ system: SYSTEM_PROMPT, messages: conv, tools });
if (!res.toolCalls?.length) return res.text; // final answer for WhatsApp
conv.push(res.assistantMessage);
for (const call of res.toolCalls) {
const result = await runTool(call.name, call.arguments, waId);
conv.push({ role: "tool", tool_call_id: call.id, content: JSON.stringify(result) });
}
}
return "Sorry, I couldn't finish that. Connecting you to our team.";
}
async function runTool(name, args, waId) {
if (name !== "check_order_status") return { error: "unknown_tool" };
const order = await orders.find(args.order_id);
if (!order || order.waId !== waId) return { error: "order_not_found" }; // same error for both
return { status: order.status, eta: order.eta }; // only what the customer may see
}

A provider-neutral loop: the model proposes calls, your code authorises and runs them, and results go back tagged with the call ID.

How does tool calling (function calling) work?

  1. Describe the tools

    Send each tool's name, a description of when to use it, and a JSON Schema for its arguments with every request. Clear descriptions matter more than clever names: the model chooses tools from them.

  2. The model returns a call

    When a tool is needed, the response contains one or more calls — each with an ID, the tool name and JSON arguments — instead of, or before, any text for the customer.

  3. Your code validates and runs it

    Parse the arguments against the schema, authorise the action for the sender's wa_id from the webhook, attach an idempotency key to anything that writes, and execute with a timeout.

  4. Return the result

    Send the result back tagged with the matching call ID — data on success, a short machine-readable error otherwise — so the model can answer, retry with different arguments or call another tool.

  5. Send the final reply

    When the model responds with text, send it through the Cloud API. Cap the loop — say five tool rounds per message — so a confused model cannot spin forever.

Why does tool calling (function calling) matter?

Tool calling is what turns a bot that talks about orders into one that can look them up, book a service slot or raise a return — the difference between sending a customer to a website and resolving the request in the chat. It is also where most of the risk lives: every tool is a capability a manipulated or confused model might try to use, through prompt injection or a plain misunderstanding. Designing tools well — narrow, validated, authorised and idempotent — is most of the work of building a trustworthy WhatsApp bot that acts.

Common wrong turns

Common mistakes with tool calling (function calling)

  • Trusting the arguments

    Arguments are model output, shaped by whatever the customer typed. Validate types and formats, and authorise against the verified sender — never accept a phone number or customer ID from the model as proof of identity.

  • Tools that do too much

    A generic run_sql or update_order(fields) tool hands the model your database. Expose narrow, task-shaped tools with only the fields they need.

  • No idempotency on writes

    Retries and repeated calls can book two slots or raise two returns. Give every side-effecting call an idempotency key derived from the conversation and the request.

  • Silent slowness

    Several tool rounds plus model time can take many seconds. Acknowledge the webhook immediately, show a typing indicator, and set a timeout on every tool.

  • Leaking raw errors and data

    Returning stack traces or whole customer records gives the model — and through it the customer — more than they should see. Return small, purpose-built results and generic error codes.

Key facts at a glance

Tool calling (function calling): key facts and limits

Who executes the function
Your code — the model only proposes calls
Tool definition
Name + description + JSON Schema for the arguments
Call shape
Call ID, tool name, JSON arguments
Calls per turn
None, one, several in sequence or several in parallel
Tool choice
Let the model decide, force a tool, or disable tools
Typical loop cap
A few rounds per customer message (for example 5)
WhatsApp typing indicator
Shown until you reply or for up to 25 seconds

Example: Booking an AC service visit in Ahmedabad

An appliance-service company in Ahmedabad gives its WhatsApp bot three tools: get_open_slots(pincode, date), book_slot(slot_id) and create_ticket(summary). A customer writes "AC not cooling, can someone come tomorrow? 380015". The model calls get_open_slots with the PIN code and tomorrow's date and offers three slots as reply buttons. When the customer taps one, it calls book_slot — which the server runs only after checking the slot is still free and the booking is for the sender's own wa_id, with an idempotency key so a double tap books once. The bot then confirms the technician's time window in the chat.

Tool Calling (Function Calling) FAQs

Does the LLM run the function itself?+
No. The model only returns the function name and arguments it wants; your application decides whether to run it, runs it and sends back the result. That separation is where security and business rules are enforced.
What is the difference between tool calling and MCP?+
Tool calling is how a model requests a function; MCP is a standard for packaging and exposing tools to applications. An MCP server can supply the tools, but the model still invokes them through tool calling.
Is function calling the same as structured output?+
Both return JSON, but for different purposes. A function call asks your code to act and return a result; structured output is the model's final answer delivered in a fixed shape.
How do I stop a bot from calling tools it shouldn't?+
Send only the tools a conversation needs, and enforce permissions in code. Even if the model is manipulated into proposing a call, your server should refuse anything the verified sender is not allowed to do.

Good practice

Best practices for tool calling (function calling)

  • Write tool descriptions as instructions: when to use it, when not to, and what each argument means.
  • Return errors the model can act on, such as slot_taken or order_not_found, rather than free text.
  • Log every call with its arguments, result, latency and the conversation's wamid for audits.
  • Start with read-only tools, and add tools that write once your authorisation layer has been tested.

See InfiQ pricing

Try it on the official WhatsApp Business API

InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.