Lesson 2 of 3 · Mastering Function Calling & Tool Use
Defining Your First Tool
reading14 min
A developer at an e-commerce company defined a tool called "process" with the description "handles stuff." The model called it for everything -- order lookups, refunds, inventory checks -- because the definition was so vague that anything seemed like a match. She renamed it to "get_order_status" with a precise description, and suddenly the model called it only when customers asked about their orders. Nothing else in the code changed. The tool definition was the entire fix.
Tool definition is where you, the developer, have the most leverage over the model's behavior. Get this right and everything downstream works. Get this wrong and no amount of prompt engineering will fix it.
The Tool Object Structure
Every tool definition has three parts:
Python
{ "type": "function", "function": { "name": "get_weather", # 1. Function name "description": "...", # 2. When to use this function "parameters": { # 3. What arguments it needs "type": "object", "properties": {...}, "required": [...] } }}
Let's master each part.
1. Function Name
The name should be a clear, specific verb-noun combination:
Do
Use descriptive verb-noun names: get_order_status, send_email, create_calendar_event, search_products, cancel_subscription. The model reads the name to understand what the function does.
Don't
Use vague names like do_thing, process, handle_request, or utility. The model cannot infer behavior from generic names. Also avoid names that sound similar -- get_user_profile and get_user_preferences will confuse the model.
2. Description: The Most Important Field
The description is how the model decides whether to call your function. Write it like you are explaining to a capable but new colleague when they should use this tool.
Python
# BAD: Too vague"description": "Gets weather data"# BAD: Too technical, no usage guidance"description": "Calls the OpenWeatherMap API endpoint /data/2.5/weather"# GOOD: Clear when-to-use guidance"description": "Get the current weather conditions for a specific city. Use this when the user asks about weather, temperature, rain, snow, or outdoor conditions for a location. Returns temperature in Fahrenheit, conditions (sunny/cloudy/rainy), humidity, and wind speed."
The 'Use this when...' Pattern
Always include a "Use this when..." sentence in your description. This explicitly tells the model the trigger conditions for calling the function. Without it, the model has to infer when to call from context, which leads to both missed calls (should have called but did not) and false calls (called when it should not have).
3. Parameters: JSON Schema
Parameters are defined using JSON Schema, a standard for describing JSON structure. If you have never used JSON Schema before, the core is simple.
Basic Types
Python
"parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "The city name, e.g., 'San Francisco' or 'London'" }, "units": { "type": "string", "enum": ["fahrenheit", "celsius"], "description": "Temperature unit preference. Defaults to fahrenheit if not specified." }, "include_forecast": { "type": "boolean", "description": "Whether to include a 5-day forecast. Defaults to false." }, "days_ahead": { "type": "integer", "description": "Number of forecast days (1-7). Only used when include_forecast is true." } }, "required": ["city"]}
Enums for Constrained Values
When a parameter has a fixed set of valid values, use enum:
The model will only produce values from the enum list. This eliminates an entire class of errors where the model invents values like "critical" or "very high" that your code does not handle.
"tags": { "type": "array", "items": {"type": "string"}, "description": "List of tags to apply, e.g., ['billing', 'urgent']"}
3 fields
make or break your tool definition: name, description, and parameter descriptions
A Complete Real-World Example
Here is a well-defined tool for a CRM system:
Python
tools = [{ "type": "function", "function": { "name": "search_contacts", "description": "Search the CRM for contacts matching given criteria. Use this when the user asks to find, look up, or search for a customer, contact, or lead. Returns up to 10 matching contacts with name, email, company, and last interaction date.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Search query -- matches against name, email, company, and notes. Example: 'John at Acme Corp'" }, "status": { "type": "string", "enum": ["active", "inactive", "lead", "churned"], "description": "Filter by contact status. Omit to search all statuses." }, "sort_by": { "type": "string", "enum": ["relevance", "last_interaction", "name"], "description": "How to sort results. Defaults to relevance." }, "limit": { "type": "integer", "description": "Maximum number of results (1-50). Defaults to 10." } }, "required": ["query"] } }}]