LLM function calling lets a model request an operation through a structured interface. The model selects a tool and proposes arguments. Application code validates the request, executes an allowed operation and returns an observation.
The model does not gain direct authority over the underlying service merely because it can name a function. The execution layer decides what the request is permitted to do.
Design a tool around a specific task
A tool definition usually includes a name, description and parameter schema. Names should distinguish operations, while descriptions explain when the tool applies and what it returns.
Compare “get_data(query)” with this contract:
lookup_order(order_id)
Purpose: Read the current status of one order for the signed-in customer.
Input: An order reference obtained from the customer or an authorised lookup.
Output: Order ID, status, status timestamp and permitted next actions.
Errors: not_found, permission_denied, temporarily_unavailable.
Side effects: None.
The runtime should bind customer identity from the authenticated session. Asking the model to supply an arbitrary customer ID can create an avoidable authorisation risk.
Anthropic's tool design guidance discusses clear descriptions, useful response content and evaluation. Those principles apply regardless of the tool protocol.
Balance narrow tools and broad tools
Narrow tools can make intended operations easy to validate. A tool for looking up an order exposes less capability than unrestricted database access.
Broad tools can be appropriate in controlled environments, such as a sandboxed coding task. Their safety depends on permissions, isolation, parsing and execution controls. SQL can be constrained with read only roles, approved views and query validation; it is inaccurate to claim that a query string can never be checked.
Choose the interface based on the task and consequences. Too many overlapping tools can also impair selection. Evaluate whether the model chooses the right operation when several plausible tools are available.
Validate before execution
The execution boundary should check the tool name, argument schema, resource ownership, allowed state transition and any required confirmation.
An order ID that matches a pattern still needs an existence and ownership check. A valid refund amount still needs policy approval. These checks should use authoritative application data.
For consequential actions, bind approval to the exact action and arguments. A general approval to investigate an account does not authorise an arbitrary later change.
Return useful observations and explicit errors
A tool result should contain enough information for the next decision without dumping unrelated records or secrets. Include status, source identity and freshness when relevant.
{
"status": "ok",
"order_id": "A-4471",
"order_status": "dispatched",
"observed_at": "2026-09-25T14:30:00Z"
}
Distinguish no results from a failed search. An empty list caused by a timeout must not become evidence that an account has no orders.
Errors should indicate whether retry is appropriate and whether an action's outcome is known. Avoid exposing stack traces, credentials or internal implementation details to the model when they do not help recovery.
Test the tool contract with realistic cases
Include a valid request, a missing identifier, an unauthorised resource, a temporary failure and a duplicate action attempt. Check both the model's request and the execution layer's response.
For write operations, implement idempotency and recovery. For all tools, preserve enough trace information to explain what was requested, what was allowed and what actually happened.