DescribedTypes.jl
Annotate Julia types/functions and generate JSON Schemas for LLM provider APIs.
Overview
DescribedTypes.jl lets you attach human-readable descriptions to Julia struct types and Julia function methods, then automatically produces JSON Schema dictionaries compatible with LLM structured-output APIs.
For functions, the package also supports argument execution from JSON payloads: function -> schema and JSON -> typed function call.
Supported adapters:
| Adapter | Use case | Wrapper key |
|---|---|---|
STANDARD | Plain JSON Schema (no wrapping) | — |
OPENAI | Structured output via response_format | "schema" |
OPENAI_TOOLS | Function / tool calling | "parameters" |
GEMINI | Google Gemini (placeholder) | — |
Installation
using Pkg
Pkg.add("DescribedTypes")Or in the Pkg REPL:
pkg> add DescribedTypesQuick Start
using DescribedTypes
using JSON
struct Person
name::String
age::Int
end
DescribedTypes.annotate(::Type{Person}) = Annotation(
name="Person",
description="A person.",
parameters=Dict(
:name => Annotation(name="name", description="The person's name", enum=["Alice", "Bob"]),
:age => Annotation(name="age", description="The person's age"),
),
)
# OpenAI structured-output format
schema_dict = schema(Person, llm_adapter=OPENAI)
print(JSON.json(schema_dict, 2)){
"name": "Person",
"description": "A person.",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The person's name",
"enum": [
"Alice",
"Bob"
]
},
"age": {
"type": "integer",
"description": "The person's age"
}
},
"required": [
"name",
"age"
],
"additionalProperties": false
}
}Function tools quickstart:
function ping(city::String; verbose::Bool=false)
return (; city, verbose)
end
tool_schema = schema(ping, llm_adapter=OPENAI_TOOLS)
call_result = callfunction(ping, Dict("city" => "Paris"))
(tool_schema["name"], call_result)("ping", (city = "Paris", verbose = false))See the Guide for more detailed usage and examples.