Skip to Content
DocumentationEdge SDKAndroidConstrained Generation

Constrained Generation with Kotlin Annotations

Setting the jsonSchemaConstraint field in GenerationOptions will enable constrained generation. While it is possible to directly set the constraint with raw JSON Schema strings, we recommend to create the constraints with the Generatable annotation.

Generatable annotation

package ai.liquid.leap.structuredoutput annotation class Generatable(val description: String) annotation class Guide(val description: String)

Only Kotlin data classes can be annotated with Generatable, and all the fields of the data class should be declared in the parameter of the constructor. Guide annotation can be used to add further descriptions to the fields.

For example, here is a generatable data class for holding information of a city:

@Generatable(description="Facts about a city") data class CityFact( @Guide(description="Name of the city") val name: String, @Guide(description="State/province of the city") val state: String, @Guide(description="Country name") val country: String, @Guide(description="Place of interests in the city") val placeOfInterests: List<String>, )

Apply Generatable data class in GenerationOptions

Then we can use setResponseFormatType() in GenerationOptions to set up the constraint.

val options = generationOptions { // Set the response format to follow `CityFact` setResponseFormatType(CityFact::class) // Example of other parameters minP = 0.0f temperature = 0.7f } conversation.generateResponse("Show the city facts about Tokyo", options)

If you want to add the JSON Schema into the prompt to help the generation, you can get the raw JSONSchema with JSONSchemaGenerator:

val jsonSchema = JSONSchemaGenerator.getJSONSchema(CityFact::class) conversation.generateResponse( "Show the city facts about Tokyo following this JSON Schema: $jsonSchema", options )

With these settings, the model will generate a JSON string following the schema as its output.

If the JSON Schema cannot be created from the provided data class, a LeapGeneratableSchematizationException will be thrown.

Deserialize Generatable data class

Finally, you can use GeneratableFactory.createFromJSONObject() to deserialize the JSON string generated by the model into the generatable data class:

import ai.liquid.leap.structuredoutput.GeneratableFactory conversation.generateResponse( "Show the city facts about Tokyo.", options ).onEach { if (it is MessageResponse.Complete) { val message = it.fullMessage val jsonContent = (message.content.first() as ChatMessageContent.Text).text // Deserialize the content as a `CityFact` object. val cityFact: CityFact = GeneratableFactory.createFromJSONObject( JSONObject(jsonContent), ) } }.collect()

If the JSON string generated by the model is not valid for creating instances of the generatable data class, a LeapGeneratableDeserializationException will be thrown.

Supported data types

Not all Kotlin data types are supported in Leap Android SDK constrained generation. Here is the list of supported JSON Schema types:

  • String (String in Kotlin)
  • Integer (Int and Long in Kotlin)
  • Number (Float and Double in Kotlin)
  • Boolean (Boolean in Kotlin)
  • Enum (Enum class in Kotlin. The plain name string will be used as values)
  • Object (Any data classes annotated with [Generatable])
  • Array (List and MutableList of any other supported data types, and arrays of integer, float numbers and boolean in Kotlin)

Only if the data types of the fields of object types and the items of array types are supported, these composition data types can be supported.

Last updated on