JSON Schema for function calling in Large Language Models.

In our previous posts about function calling with the OpenAI API, we discussed how to specify the format in which we want the model to respond. Sometimes this is based on real-world functions or APIs, and other times it’s just to get a neatly organized piece of data.

To describe this desired data structure, we use a tool known as JSON Schema. It’s not just any JSON structure; think of it as a blueprint for your data.

What is JSON Schema?

JSON Schema outlines how your data should be organized. It specifies the types of data allowed, how data should be nested, the format of certain data (like dates), and which data fields are mandatory. In essence, it sets the rules for your JSON files.

If you’ve read our previous posts on function calling, you should have a basic understanding of JSON Schema. For a quick refresher, you can revisit these posts: Function Calling on GPT API, How to Call Multiple Functions in One API Call.

Today, we’ll dive deeper into JSON Schema, exploring its capabilities and how to make the most of it.

For comprehensive documentation, you can visit the official JSON Schema website. However, this post aims to cover the basics to get you started.

Basic Structure

First things first: a JSON Schema is itself a JSON file. It adheres to the key-value pair structure inherent to all JSON files. For instance, a typical JSON file might look like this:

{
  "name": "John",
  "age": 30,
  "isMarried": false,
  "children": ["Alice", "Bob"]
}

And its corresponding JSON Schema would be:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "integer"
    },
    "isMarried": {
      "type": "boolean"
    },
    "children": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": ["name", "age", "isMarried"]
}

Here, each key-value pair in the JSON file corresponds to a definition in the JSON Schema. This definition specifies the type of value that the key can have.

Basic Data Types

JSON Schema aligns with JSON’s data types to validate the data. Here are the basic types you’ll encounter:

  • String: Text enclosed in double quotes.
  • Number: Any numeric data, either integer or floating-point.
  • Integer: Whole numbers, a subset of the number type.
  • Boolean: Either true or false.
  • Array: An ordered list of values.
  • Object: A collection of key-value pairs.
  • Null: Represents an empty value or “nothing.”

String

Strings can have additional constraints, such as matching a specific format like a date or an email address, or even regular expressions.

Number

The 'integer' type is used for integral numbers. And the 'number' type is used for any numeric type, either integers or floating point numbers.

Note: In JSON, the distinction between integers and non-integers isn’t determined by the presence of a decimal point. For example, both 1 and 1.0 are treated as integers because they represent whole numbers. This means that the type is determined by the value itself, not its notation.

Numbers can also be constrained by range(>, <, >=, or <=) and multiples(a number must be a multiple of another).

Object

An object is essentially a JSON within another JSON. It can have its own properties, defined using the 'properties' keyword.

Note: An object can have zero or more properties, and it’s perfectly valid to have additional properties not defined in the schema.

Required Properties

The 'required' keyword specifies which properties must be present for the JSON to be valid. By default, no property is mandatory.

Array

An array is an ordered list items.

item

Arrays can contain items of different types. However, if all items are of the same type, you can use the 'items' keyword to specify this. For example:

{
  "type": "array",
  "items": {
    "type": "number"
  }
}

prefixItems

If the elements in an array need to be of different types and appear in a specific order, you can use the 'prefixItems' keyword to enforce these constraints. For instance, consider an address composed of ‘address number,’ ‘street name,’ ‘street type,’ and ‘direction.’ The schema could look like this:

{
  "type": "array",
  "prefixItems": [
    { "type": "number" },
    { "type": "string" },
    { "enum": ["Street", "Avenue", "Boulevard"] },
    { "enum": ["NW", "NE", "SW", "SE"] }
  ]
}

This ensures that the first item in the array is a number, the second is a string, the third is one of the specified street types, and the fourth is one of the specified directions.

enum

The 'enum' keyword is used to restrict a value to a fixed set of possible values. This set must be defined as an array with at least one element, and each element must be unique.

The 'enum' keyword is quite versatile; it can even be used to accept values of different types. For example:

{
  "enum": ["red", "amber", "green", null, 42]
}

Annotations

JSON Schema also includes annotation keywords that aren’t used for validation but help in understanding the schema. For instance, adding a 'description' can make the schema more self-explanatory.

Conclusion

This post aims to offer a beginner-friendly overview of JSON Schema, a tool you’ll find invaluable when working with function calling in the GPT API. For a more in-depth understanding, you can refer to the official documentation.

Leave a Reply

Your email address will not be published. Required fields are marked *