Tool Use & Function Calling Best Practices
Ten practices for naming, describing, scoping, validating, and operating tools so agents select them correctly and fail safely.
How to Use This List
- Use items 1-4 when designing or reviewing a tool surface (selection quality).
- Use items 5-7 when implementing the host loop (execution safety).
- Use items 8-10 in production ops and iteration (evidence and scale).
- Jump to deeper pages when an audit item fails; this list is a control checklist, not a full design doc.
-
Keep the tool list small and non-overlapping. Prefer a handful of sharp tools over a kitchen sink of near-duplicates. Merge tools that always run together; split opposite side effects. Overlap is the leading cause of wrong-tool calls. See Writing Tool Descriptions the Model Will Actually Use Correctly.
-
Name tools as clear verb_noun actions. Use
get_order_status,create_refund,search_orders_by_email. Avoid vague names (helper,handle,data). Stable names are part of your public contract with prompts, evals, and MCP clients. -
Write descriptions with triggers and non-goals. Lead with what the tool does and when to use it; add what it is not for and which sibling to use instead. Put shared policy in the system prompt; keep tool text local and scannable.
-
Constrain parameters with conservative JSON Schema. Root
type: object, explicitrequired, enums for closed sets, bounds on numbers/arrays, andadditionalProperties: falsewhen supported. Validate the same rules in host code. See JSON Schema for Tool Parameters. -
Remember: the model proposes, the host executes. Allowlist dispatch by name, authorize before side effects, and never
evalfree-form code from the model. Function calling is not a sandbox by itself. See How Function Calling Actually Works Under the Hood. -
Return structured observations for success and failure. Use a uniform envelope (
ok,data/error_type,retryable, shortmessage). Always bind a tool result to each call id. Empty failures invite hallucinations. See Handling Tool Errors Gracefully Inside an Agent Loop. -
Bound retries, parallelism, and run cost in the host. Cap max model turns, max tool calls, per-signature retries, concurrent executions, and result size. Disable or serialize parallel calls when tools write or share state. See Parallel Tool Calls.
-
Defer large catalogs with tool search. Keep a small always-on core; load full schemas on demand via search/retrieval. Do not treat hiding a write tool behind search as authorization. See Tool Search: Loading Tool Definitions On Demand.
-
Log trajectories with call ids, redacted args, and latency. Debug wrong selection, bad args, and slow upstreams from traces, not from final prose alone. Track wrong-tool rate and error-type histograms as product metrics.
-
Regression-test tool use with stubbed backends. Golden prompts should assert which tool is called, argument shapes, behavior on tool errors, and that read-only sessions cannot activate writes. Re-run the suite on every description or schema change.
FAQs
Why only ten practices?
This section summary is an operational set. Deeper pages cover protocol mechanics, schema reference, parallel calls, deferred loading, and error envelopes.
What's the highest-ROI habit for wrong tool selection?
Delete or merge overlapping tools, then rewrite triggers/non-goals. Schema tweaks alone will not fix two tools that claim the same job.
Do frameworks replace these practices?
Frameworks supply loop helpers and adapters. You still design names, schemas, authz, budgets, and evals for your product.
Should every agent expose write tools?
No. Default to read-only tools; gate writes with policy, approval, and separate risk levels.
How often should tool descriptions be reviewed?
On every add/rename/deprecate and whenever production wrong-tool or invalid-args rates move.
Is native function calling enough for security?
No. Pair it with least-privilege credentials, output size limits, network egress controls, and treating tool outputs as untrusted context.
When should we turn off parallel tool calls?
When tools have side effects, shared mutable state, or when you are isolating selection bugs. Pure multi-read fan-out is the best case for parallelism.
How do these practices map to MCP?
MCP standardizes discovery and invocation transport. Naming, schema quality, host validation, and budgets still apply to every tool the client exposes to the model.
Related
- How Function Calling Actually Works Under the Hood
- Tool Use & Function Calling Basics
- Writing Tool Descriptions the Model Will Actually Use Correctly
- JSON Schema for Tool Parameters: A Reference Guide
- Parallel Tool Calls: When and How Models Call Multiple Tools at Once
- Tool Search: Loading Tool Definitions On Demand Instead of Upfront
- Handling Tool Errors Gracefully Inside an Agent Loop
- Agent Loop Best Practices
- Custom Tools Best Practices
- The Principle of Least Privilege Applied to Agent Tools
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.