Defining Tool Schemas

Describe each tool's name, purpose, and parameters so the model can use it.

To offer a tool, you give the model a schema: the tool's name, a clear description, and the parameters it accepts (usually as JSON Schema). The description is effectively a prompt — write it well.

A good tool definition has

  • A precise name.
  • A description that says exactly when to use it.
  • Typed parameters with descriptions and which are required.

The model reads these definitions and decides which tool (if any) fits the user's request, then produces the arguments.

Example

Example · json
{
  "name": "get_weather",
  "description": "Get the current weather for a city. Use when the user asks about current conditions.",
  "parameters": {
    "type": "object",
    "properties": {
      "city": {"type": "string", "description": "City name, e.g. 'Tokyo'"},
      "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
    },
    "required": ["city"]
  }
}

When to use it

  • An API team writes precise JSON Schema tool definitions so the model always passes correctly typed arguments and never sends a string where an integer is needed.
  • A data tool marks 'table_name' as required in its schema so the model cannot call the query function without specifying which table to read.
  • A developer adds 'enum' constraints to a tool parameter so the model can only pass one of the valid sort-order values the API accepts.

More examples

Well-formed tool schema definition

Shows a complete tool schema with a required string, optional number, and an enum-constrained sort parameter.

Example · json
{
  "type": "function",
  "function": {
    "name": "search_products",
    "description": "Search the product catalogue by keyword and optional filters.",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "description": "Search keyword, e.g. \"blue running shoes\""
        },
        "max_price": {
          "type": "number",
          "description": "Maximum price in USD. Omit to return all prices."
        },
        "sort": {
          "type": "string",
          "enum": ["price_asc", "price_desc", "relevance"],
          "description": "Sort order for results."
        }
      },
      "required": ["query"]
    }
  }
}

Schema with array and nested object

Demonstrates an array parameter and a nested object parameter, both marked as required.

Example · json
{
  "type": "function",
  "function": {
    "name": "send_emails",
    "description": "Send an email to one or more recipients.",
    "parameters": {
      "type": "object",
      "properties": {
        "recipients": {
          "type": "array",
          "items": {"type": "string", "format": "email"},
          "description": "List of recipient email addresses."
        },
        "message": {
          "type": "object",
          "properties": {
            "subject": {"type": "string"},
            "body":    {"type": "string"}
          },
          "required": ["subject", "body"]
        }
      },
      "required": ["recipients", "message"]
    }
  }
}

Validate model's arguments against schema

Uses the jsonschema library to validate that the model's generated arguments conform to the tool's parameter schema.

Example · python
import json
import jsonschema
from openai import OpenAI

client = OpenAI()

param_schema = {
    'type': 'object',
    'properties': {
        'city': {'type': 'string'},
        'units': {'type': 'string', 'enum': ['celsius', 'fahrenheit']}
    },
    'required': ['city']
}
tools = [{'type':'function','function':{'name':'get_weather','description':'Weather.','parameters':param_schema}}]

r = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role':'user','content':'Weather in Berlin in celsius?'}],
    tools=tools
)
args = json.loads(r.choices[0].message.tool_calls[0].function.arguments)
jsonschema.validate(instance=args, schema=param_schema)
print('Valid args:', args)

Discussion

  • Be the first to comment on this lesson.