Skip to content

AI/LLM tool use (function calling) JSON Schema generator - a Kotlin multiplatform library

License

Notifications You must be signed in to change notification settings

xemantic/xemantic-ai-tool-schema

Repository files navigation

xemantic-ai-tool-schema

AI/LLM tool use (function calling) JSON Schema generator - a Kotlin multiplatform library which generates JSON Schema for Kotlin @Serializable classes.

Maven Central Version GitHub Release Date license

GitHub Actions Workflow Status GitHub branch check runs GitHub commits since latest release GitHub last commit

GitHub contributors GitHub commit activity GitHub code size in bytes GitHub Created At kotlin version discord users online Bluesky

Important

🤖 Build Your Own AI Agents - Join our one-day Agentic AI & Creative Coding Workshop in Berlin (Spring 2025), led by AI hack Berlin 2024 winner Kazik Pogoda. Learn to create autonomous AI agents using Anthropic's API, engineer advanced prompts, and give your agents tools to control machines. Workshops run Tuesdays (Feb 25 - Mar 25) at Prachtsaal Berlin, limited to 15 participants. 150 EUR contribution supports open source development. All examples use Kotlin (crash course included) but focus on meta-principles of AI agent development. Details: https://xemantic.com/ai/workshops

Why?

This library was created to fulfill the need of agentic AI projects created by xemantic. In particular:

These projects are heavily dependent on tool use (function calling) functionality provided by many Large Language Models. Thanks to xemantic-ai-tool-schema, a Kotlin class, with possible additional constraints, can be automatically instantiated from the JSON tool use input provided by the LLM. This way any manual steps of defining JSON schema for the model are avoided, which reduce a chance for errors in the process, and allows to rapidly develop even complex data structures passed to an AI agent.

In short the xemantic-ai-tool-schema library can generate a JSON Schema from any Kotlin class marked as @Serializable, according to kotlinx.serialization.

Tip

You might be familiar with similar functionality of the Pydantic Python library, however, the standard Kotlin serialization is already fulfilling model metadata provisioning, so this analogy might be misleading.

Usage

In build.gradle.kts add:

plugins {
    kotlin("multiplatform") version "2.1.0" // (or jvm for jvm-only project)
    kotlin("plugin.serialization") version "2.1.0"
}

// ...
dependencies {
    implementation("com.xemantic.ai:xemantic-ai-tool-schema:1.0.0")
}

Then in your code you can define entities like this:

@Serializable
@SerialName("address")
@Title("The full address")
@Description("An address of a person or an organization")
data class Address(
    val street: String,
    val city: String,
    @Description("A postal code not limited to particular country")
    @MinLength(3)
    @MaxLength(10)
    val postalCode: String,
    @Pattern("[a-z]{2}")
    val countryCode: String,
    @Format(StringFormat.EMAIL)
    val email: String? = null
)

And when jsonSchemaOf() function is invoked:

val schema = jsonSchemaOf<Address>()

It will produce a JsonSchema instance, which serializes to:

{
  "type": "object",
  "title": "The full address",
  "description": "An address of a person or an organization",
  "properties": {
    "street": {
      "type": "string"
    },
    "city": {
      "type": "string"
    },
    "postalCode": {
      "type": "string",
      "description": "A postal code not limited to particular country",
      "minLength": 3,
      "maxLength": 10
    },
    "countryCode": {
      "type": "string",
      "pattern": "[a-z]{2}"
    },
    "email": {
      "type": "string",
      "format": "email"
    }
  },
  "required": [
    "street",
    "city",
    "postalCode",
    "countryCode"
  ]
}

And this is the input accepted by Large Language Model APIs like OpenAI API and Anthropic API. When requesting a tool use, these LLMs will send a JSON payload adhering to this schema, therefore immediately deserializable as the original @Serializable Kotlin class.

More details and use cases in the JsonSchemaGeneratorTest.

Note

When calling toString() function on any instance of JsonSchema, it will also produce a pretty printed String representation of a valid JSON schema, which in turn describes the Kotlin class as a serialized JSON. This functionality is useful for testing and debugging.

Serializing Java BigDecimals

For JVM-only projects, it is possible to specify java.math.BigDecimal serialization. It will serialize decimal numbers to strings, and add description and pattern properties to generated JSON Schema of a BigDecimal property.

See JavaBigDecimalToSchemaTest for details.

Serializing BigDecimal/monetary values in multiplatform way

There is an interface called Money defined in the tests of this project. It explains how to define and serialize monetary amounts independently of the underlying decimal number and arithmetics provider.

See also xemantic-ai-money project for a ready solution packaged as a library.

Development

Clone this repo and then in the project dir:

./gradlew build

Non-recommended usage

Warning

Even though this library provides basic serializable representation of a JSON Schema, it is not meant to fully model general purpose JSON Schema. In particular, it should not be used for deserializing existing schemas from JSON.