Writing Tool Definitions for AI Agents
The Three Components of Every Definition
Every tool definition has three required components that work together: the name, the description, and the parameter schema. The name identifies the function to invoke. The description tells the model when and why to use it. The parameter schema defines what input the function accepts. Weakness in any one component degrades the reliability of the entire tool.
Names should be descriptive and follow a consistent convention. "search_products" is better than "sp" or "search" because it immediately communicates what the function operates on. Names should use snake_case or camelCase consistently across all tools in a set. Avoid generic names like "process", "handle", or "do_action" that do not communicate the function purpose. When multiple tools operate on the same entity (like "create_user", "update_user", "delete_user"), consistent naming helps the model distinguish between them.
Descriptions are the most impactful component for model behavior. Models read descriptions to make three decisions: whether this tool is relevant to the current request, whether to call this tool versus another available tool, and how to interpret the parameters. A description that answers these three questions clearly produces reliable tool selection. A description that leaves ambiguity produces inconsistent behavior.
Parameter schemas use JSON Schema syntax to define the structure of the arguments the function accepts. The schema specifies the type of each parameter (string, number, boolean, array, object), which parameters are required, and any constraints like enums, minimum/maximum values, or string patterns. The more precisely the schema defines the expected input, the more accurately the model generates the arguments.
Writing Effective Descriptions
The most common mistake in tool definitions is writing descriptions for human developers rather than for the model. Human developers understand implicit context from code, documentation, and team knowledge. Models have none of this context, they have only the description text and the conversation history. Every piece of information the model needs to use the tool correctly must be explicitly stated in the description.
Start descriptions with a clear action statement: "Retrieves", "Creates", "Updates", "Deletes", "Searches", "Calculates". This immediately tells the model what kind of operation the tool performs. Follow the action with the target: "Retrieves user profile information", "Searches the product catalog", "Calculates shipping costs for an order". Then add context about when to use the tool: "Use this when the user asks about their account details", "Use this for product search queries, not for order lookups".
Include information about what the function returns. Models use return value information to decide whether a tool is appropriate for the current task. "Returns a JSON object with name, email, and subscription_status fields" tells the model exactly what data it will receive. Without this information, the model must guess whether the tool returns the data it needs, which leads to unnecessary tool calls when the return value does not actually contain the needed information.
Negative guidance is often as important as positive guidance. Tell the model when not to use a tool: "Do not use this for historical data older than 90 days, use archive_search instead." Explicit boundaries prevent the model from calling a tool in situations where it will fail or return incorrect results. Without negative guidance, the model may call the closest-matching tool even when it is not appropriate for the specific request.
Parameter Schema Best Practices
Keep required parameters to the minimum necessary. Every required parameter is a potential point of failure. If the function can operate with reasonable defaults, make parameters optional and document the default values in the parameter description. The model should only need to provide arguments that are essential for the function to work or that the user has explicitly specified.
Use enum types wherever a parameter has a fixed set of valid values. Enums eliminate an entire category of errors by constraining the model to only valid options. A "status" parameter with enum ["active", "inactive", "pending"] is far more reliable than a string parameter where the model might generate "Active", "ACTIVE", "on", or any number of variations that the application would need to handle.
Add descriptions to every parameter, not just the function itself. Parameter descriptions should include the expected format (ISO 8601, UUID, email address), valid ranges ("integer between 1 and 100"), and the effect of different values ("higher values return more results but increase latency"). Models use parameter descriptions to generate appropriate values, so the more specific the description, the more accurate the generated arguments.
Avoid deeply nested object schemas. While models can generate nested JSON, accuracy decreases with each level of nesting. A schema with more than three levels of nesting should be restructured. Consider splitting a complex tool into multiple simpler tools, flattening the parameter structure, or using a string parameter with a documented format instead of a deeply nested object.
Common Mistakes and How to Fix Them
Overly broad tools that try to do everything are the most common design mistake. A single "database_query" tool that accepts raw SQL is technically flexible but gives the model no guidance about what data is available or how to structure queries. Breaking this into specific tools like "get_user_by_email", "search_orders_by_date", and "count_active_subscriptions" gives the model clear, well-scoped options that it can use accurately.
Missing parameter descriptions lead to the model guessing at formats and valid values. A parameter named "date" with no description might receive values in any format: "2026-01-15", "January 15, 2026", "01/15/2026", or "yesterday". Adding a description like "date in YYYY-MM-DD format" eliminates this ambiguity.
Inconsistent naming across a tool set confuses the model about which tool does what. If some tools use "user_id" and others use "userId" or "id" for the same concept, the model must infer the mapping from context. Consistent naming across all tools reduces this cognitive load and improves accuracy.
Too many tools overwhelm the model and increase both token costs and error rates. If your system has 100 tools but any given request only needs 5 to 10, implement dynamic tool selection that includes only relevant tools in each request. This reduces the number of tool definitions the model must process and improves its ability to select the right tool from a smaller, more relevant set.
Tool definitions are instructions for the model, not documentation for developers. Write descriptions that explicitly state what the function does, when to use it, and what it returns. Use enums for constrained values, keep required parameters minimal, and describe every parameter with format requirements and valid ranges. The quality of your definitions determines the quality of your agent tool use.