Skip to content

algunion/DescribedTypes.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DescribedTypes

Build Status

This package attempts to provide a way to annotate types with descriptions which in turn can be used to generate JSON Schemas compatible with LLM providers APIs (for structured output functionality).

Future versions of this package will provide specialized macros for increased ergonomics and ease of use. The current version emulates the StructTypes.jl functionality (see test file for examples).

Example

using DescribedTypes
using OrderedCollections: OrderedDict
using StructTypes
using JSON3

struct Person
    name::String
    age::Int
end

StructTypes.StructType(::Type{Person}) = StructTypes.Struct()

DescribedTypes.annotate(::Type{Person}) = DescribedTypes.Annotation(
    name="Person",
    description="A schema for a person.",
    parameters=OrderedDict(
        :name => DescribedTypes.Annotation(name="name", description="The name of the person", enum=["Alice", "Bob"]),
        :age => DescribedTypes.Annotation(name="age", description="The age of the person")
    )
)

schema_dict = DescribedTypes.schema(Person, llm_adapter=DescribedTypes.OPENAI)
JSON3.pretty(schema_dict)

This will generate a JSON schema for the Person type with annotations for the fields:

{
    "name": "Person",
    "description": "A schema for a person.",
    "strict": true,
    "parameters": {
        "type": "object",
        "properties": {
            "name": {
                "type": "string",
                "description": "The name of the person",
                "enum": [
                    "Alice",
                    "Bob"
                ]
            },
            "age": {
                "type": "integer",
                "description": "The age of the person"
            }
        },
        "required": [
            "name",
            "age"
        ],
        "additionalProperties": false
    }
}

Advanced Example

using DescribedTypes
using OrderedCollections: OrderedDict
using StructTypes
using JSON3

struct OptionalFieldSchema
    int::Int
    optional::Union{Nothing, String}
end

StructTypes.StructType(::Type{OptionalFieldSchema}) = StructTypes.Struct()
StructTypes.omitempties(::Type{OptionalFieldSchema}) = (:optional,)
DescribedTypes.annotate(::Type{OptionalFieldSchema}) = DescribedTypes.Annotation(
    name="OptionalFieldSchema",
    description="A schema containing an optional field.",
    markdown="Optional field",
    parameters=OrderedDict(
        :int => DescribedTypes.Annotation(name="int", description="An integer field"),
        :optional => DescribedTypes.Annotation(name="optional", description="An optional string field")
    )
)

schema_dict = DescribedTypes.schema(OptionalFieldSchema, llm_adapter=DescribedTypes.OPENAI)
JSON3.pretty(schema_dict)

Output:

{
    "name": "OptionalFieldSchema",
    "description": "A schema containing an optional field.",
    "strict": true,
    "parameters": {
        "type": "object",
        "properties": {
            "int": {
                "type": "integer",
                "description": "An integer field"
            },
            "optional": {
                "type": [
                    "string",
                    "null"
                ],
                "description": "An optional string field"
            }
        },
        "required": [
            "int",
            "optional"
        ],
        "additionalProperties": false
    }
}

This above ensures a JSON schema for the OptionalFieldSchema type, including handling for optional fields in a way that is compatible with OpenAI's LLM API:

Although all fields must be required (and the model will return a value for each parameter), it is possible to emulate an optional parameter by using a union type with null.

About

LLM-friendly annotated Julia types.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages