The tool use vs function calling difference is mostly a naming collision, but the distinction matters when you wire LLMs into production systems. OpenAI coined “function calling” for models that emit structured JSON to invoke a named function; the broader ecosystem now calls the same pattern “tool use” when it spans multi-turn agent loops. Understanding both saves you from rewriting orchestration code when you switch providers.
Definitions that hold up in code
Function calling entered the lexicon with OpenAI’s functions parameter in 2023. The model returned a function_call object containing a name and arguments. Later, OpenAI deprecated that in favor of a tools array where each tool is a function. Anthropic, Google, and others adopted the tools concept but describe the runtime behavior as “tool use”: the model produces a tool_use block, you execute it, and you return a tool_result.
The mechanistic core is identical: the model predicts a structured invocation; your code runs it; you feed the result back. The terminology diverges because “tool use” implies an agentic loop with multiple round-trips, while “function calling” originally meant a single predicted call.
Minimal wire example
# OpenAI-compatible tools request (current standard)
import openai
client = openai.OpenAI()
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Ping the status API"}],
tools=[{
"type": "function",
"function": {
"name": "check_status",
"description": "Hit the internal status endpoint",
"parameters": {
"type": "object",
"properties": {"service": {"type": "string"}},
"required": ["service"]
}
}
}],
tool_choice="auto"
)
print(resp.choices[0].message.tool_calls)
Anthropic’s Claude returns a tool_use content block with the same name and input fields. The schema translation is mechanical, not semantic.
Capabilities
Both patterns support:
- Structured argument generation against a JSON Schema.
- Forced invocation (
tool_choice/function_call: {"name": ...}). - Streaming of partial arguments (useful for long inputs).
- Parallel calls: OpenAI emits an array of
tool_calls; Anthropic emits multipletool_useblocks in one response.
The real capability gap is historical. Legacy function calling only allowed one call per turn and used a separate role: function message for results. Modern tool use standardizes on role: tool with a tool_call_id, which maps cleanly to parallel execution.
Cost model
There is no separate “tool fee.” You pay per token as with any generation. The tool/function schema lives in the input context, so a large catalog of tools increases prompt tokens linearly. Output tokens cover the generated arguments. A gateway with per-token usage metering reports the same counts whether the provider labels the feature “functions” or “tools.”
Do not expect cost differences between the two terms—any delta comes from schema size and round-trips, not the naming.
Latency and throughput
Adding a tool schema to the context adds a few hundred to a few thousand tokens depending on descriptions. That marginally raises time-to-first-token. The model’s decode step for arguments is comparable to generating a short JSON string. Throughput on the provider side is unaffected by the label.
The only latency win is architectural: if you batch parallel tool calls, you reduce round-trips versus sequential function calls. That is a tool-use-loop advantage, not a wire-format one.
Ergonomics
Function calling in old OpenAI SDKs surfaced as message.function_call. Modern SDKs unify on message.tool_calls. If you maintain legacy code, you will parse a different field. New code should target tools exclusively.
Tool result handling requires discipline:
{
"role": "tool",
"tool_call_id": "call_01",
"content": "{\"status\": \"ok\", \"latency_ms\": 12}"
}
Forgetting tool_call_id breaks parallel execution. Anthropic uses tool_result with a tool_use_id; same idea, different key.
Ecosystem
OpenAI started it; Mistral, Meta (via Ollama), Anthropic, and Google followed. The tool use vs function calling difference is blurred because most vendors now implement the OpenAI tools schema for compatibility. A gateway like n4n.ai exposes one OpenAI-compatible endpoint covering 240+ models and forwards provider cache-control hints, so your tool definitions work unchanged across vendors.
If you stay inside OpenAI’s ecosystem, the terms are interchangeable post-2023. If you target Anthropic or Vertex, “tool use” is the native phrase but the payload is translatable.
Limits
Practical limits, not marketing claims:
- Context window: every tool schema consumes tokens. A catalog of 50 verbose tools can eat 10–20% of a 128k window before the user speaks.
- Parallel calls: supported but bounded by the model’s ability to track IDs. Complex parallel graphs still need orchestration logic.
- Forced choice:
tool_choice: "required"forces a call but not correctness; validate arguments yourself. - Some smaller open-weight models emit malformed JSON more often than frontier models.
Head-to-head summary
| Dimension | Function calling (legacy term) | Tool use (modern term) |
|---|---|---|
| Wire format | functions array, function_call field |
tools array, tool_calls / tool_use blocks |
| Multi-turn loop | Manual role: function (old) / role: tool |
Native role: tool or tool_result |
| Parallel invocations | Later supported via tool_calls |
Supported as multiple blocks |
| Forced invocation | function_call: {"name": ...} |
tool_choice: {"type":"function","function":{"name":...}} |
| Ecosystem | OpenAI-centric, 2023 | Cross-vendor (Anthropic, Google, OpenAI) |
| Cost | Per-token, schema in input | Identical per-token |
| Latency | Same order | Same order |
Which to choose
Single-model OpenAI service with legacy code: Keep using the tools API (the successor to function calling). Do not reach for the deprecated functions parameter in new builds.
Agentic systems with multiple round-trips: Design around tool use. Use role: tool messages, persist tool_call_id, and assume parallel blocks. The loop ergonomics are better and provider support is universal.
Multi-provider routing: Write one tools schema conforming to OpenAI’s shape. Translate only the response wrapper per provider. This neutralizes the tool use vs function calling difference entirely.
Constrained context budgets: Trim tool descriptions aggressively. The cost and latency impact is real regardless of what you call the feature.
Pick the term that matches your runtime, but ship the tools array. The protocol won.