Function Calling LLM: How It Works and When to Use It
Function calling lets a large language model decide when to invoke a piece of code you've defined, and with what arguments, instead of just returning text. You describe a set of functions (name, description, parameters), the model reads the conversation, and if it decides a function is relevant, it returns a structured request to call it — typically as JSON — rather than a plain-text answer. Your application executes the actual function, then feeds the result back to the model so it can continue the conversation with real data.
This matters because raw LLM output is unstructured and sometimes unreliable for anything that needs to touch a database, an API, or a calculation. Function calling (also called "tool use") is the mechanism that turns a chat model into something that can look up a customer record, run a search, book a meeting, or execute code — reliably enough to build production features on top of it.
How Function Calling Actually Works
The flow is the same across most providers, even if the exact request format differs:
- You send the model a prompt plus a list of available functions, each with a JSON Schema describing its parameters.
- The model decides whether answering requires calling one (or more) of those functions.
- If yes, the model responds with a structured object: the function name and arguments, instead of free text.
- Your code parses that response, runs the actual function, and gets a result.
- You send the result back to the model in a follow-up message.
- The model produces a final natural-language answer, now grounded in real data.
The model never executes anything itself — it only decides what to call and with what arguments. Execution, auth, and side effects are entirely your responsibility, which is actually a safety feature: you control what code can run.
Designing Good Function Schemas
Most reliability problems with function calling come from vague schemas, not from the model being "bad at tools." A few practices that consistently help:
- Write descriptions like documentation, not labels.
"Get the current weather"is worse than"Get current weather conditions for a city. Use this when the user asks about temperature, rain, or forecast." - Constrain types tightly. Use enums for fixed choices,
integervsnumberwhere it matters, and mark required fields explicitly. - Keep the function list short and specific. Ten overlapping functions with similar names confuse the model more than three well-scoped ones.
- Return errors as structured results, not exceptions. If a function call fails, send back something like
{"error": "user_not_found"}so the model can react sensibly instead of hallucinating a fix.
A minimal function definition looks like this:
{
"name": "get_order_status",
"description": "Look up the current status of a customer order by order ID.",
"parameters": {
"type": "object",
"properties": {
"order_id": { "type": "string", "description": "The order ID, e.g. ORD-1234" }
},
"required": ["order_id"]
}
}
Common Pitfalls
- Assuming the model will always call a function when it should. Models sometimes answer from memory even when a tool is available. Prompting explicitly ("Always check order status with the tool, never guess") reduces this.
- Forgetting multi-turn state. If a function call fails or needs clarification, the model needs the full conversation history, including the failed call and its result, to recover gracefully.
- Not validating arguments server-side. The model can hallucinate a plausible-looking but invalid argument (a malformed ID, an out-of-range number). Validate before executing, and return a clear error back to the model rather than crashing.
- Chaining too many tool calls without limits. Set a max number of tool round-trips per request so a confused model doesn't loop indefinitely.
Streaming and Function Calling Together
If you're building a chat UI, you usually want to stream the model's text output while also handling tool calls that may arrive mid-stream. The pattern is: stream tokens to the UI as they come, but buffer and parse tool-call events separately since they arrive as structured chunks rather than plain text. Most SDKs expose distinct event types for "text delta" versus "tool call" so you don't have to guess which is which.
Getting Function Calling in Production Without Managing Infrastructure
If you're already using Claude through a subscription and want to expose function calling as a proper HTTPS API — with your own API keys, usage tracking, and team access — that's exactly what SubToAPI is for. It turns your existing Claude access into an API you can call from any backend, with support for tool use, streaming, and per-key usage metadata, so you don't have to stand up your own proxy or billing layer just to give your app programmatic access.
A basic tool-use request looks like this:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4",
"max_tokens": 1024,
"tools": [
{
"name": "get_order_status",
"description": "Look up order status by order ID.",
"input_schema": {
"type": "object",
"properties": { "order_id": { "type": "string" } },
"required": ["order_id"]
}
}
],
"messages": [
{ "role": "user", "content": "Whats the status of order ORD-1234?" }
]
}'
The response includes a tool-use block with the function name and parsed arguments, which you execute and send back in a follow-up message to get the final answer. Full request and response shapes are in the docs — the tool use guide covers multi-step calls, and messages and streaming cover the rest of the API surface. You can get a key in a few minutes via signup, and pricing details are on the pricing page.
Wrapping Up
Function calling turns an LLM from a text generator into something that can act on real data and real systems, as long as you design clear schemas, validate inputs, and handle failures explicitly. The model's job is to decide what to call — your job is to execute it safely and feed the result back cleanly.
FAQ
Is function calling the same as tool use? Yes, in practice. "Tool use" is the more general term (can include code execution, retrieval, etc.), while "function calling" specifically describes the model returning structured arguments for a named function you defined.
Can a model call multiple functions in one turn? Many models support this, returning several tool-call requests at once. You execute each, return all results, and the model produces one combined answer. Check your provider's docs for exact behavior.
Does function calling guarantee valid output? No. The model can still hallucinate arguments or pick the wrong function. Always validate arguments server-side and handle errors as structured responses the model can react to, rather than assuming correctness.