https://github.com/algunion/describedtypes.jl
LLM-friendly annotated Julia types.
https://github.com/algunion/describedtypes.jl
julia julialang llms structured-output
Last synced: 4 months ago
JSON representation
LLM-friendly annotated Julia types.
- Host: GitHub
- URL: https://github.com/algunion/describedtypes.jl
- Owner: algunion
- License: mit
- Created: 2025-02-08T15:34:35.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2026-02-14T14:44:09.000Z (4 months ago)
- Last Synced: 2026-02-14T22:34:07.170Z (4 months ago)
- Topics: julia, julialang, llms, structured-output
- Language: Julia
- Homepage:
- Size: 249 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# DescribedTypes
[](https://github.com/algunion/DescribedTypes.jl/actions/workflows/CI.yml?query=branch%3Amain)
[](https://codecov.io/gh/algunion/DescribedTypes.jl)
[](https://algunion.github.io/DescribedTypes.jl/stable/)
[](https://algunion.github.io/DescribedTypes.jl/dev/)
This package provides a way to annotate Julia types with descriptions, which are
then used to generate JSON Schemas compatible with LLM provider APIs (for
structured-output functionality).
OpenAI uses JSON Schema in two different places, and the package supports both:
- **`OPENAI`** — for [structured output via `response_format`](https://developers.openai.com/api/docs/guides/structured-outputs)
(the model's direct response). Wraps the schema under a `"schema"` key.
- **`OPENAI_TOOLS`** — for [function / tool calling](https://developers.openai.com/api/docs/guides/function-calling)
(arguments the model passes to your code). Wraps the schema under a `"parameters"` key.
## Example — Response Format (`OPENAI`)
```julia
using DescribedTypes
using JSON
struct Person
name::String
age::Int
end
DescribedTypes.annotate(::Type{Person}) = Annotation(
name="Person",
description="A schema for a person.",
parameters=Dict(
:name => Annotation(name="name", description="The name of the person", enum=["Alice", "Bob"]),
:age => Annotation(name="age", description="The age of the person")
)
)
schema_dict = schema(Person, llm_adapter=OPENAI)
println(JSON.json(schema_dict, 2))
```
Output *(generated automatically by [`docs/generate_readme.jl`](docs/generate_readme.jl))*:
```json
{
"name": "Person",
"description": "A schema for a person.",
"strict": true,
"schema": {
"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
}
}
```
## Example — Tool / Function Calling (`OPENAI_TOOLS`)
```julia
DescribedTypes.annotate(::Type{Person}) = Annotation(
name="get_person",
description="Fetches information about a person.",
parameters=Dict(
:name => Annotation(name="name", description="The name of the person", enum=["Alice", "Bob"]),
:age => Annotation(name="age", description="The age of the person")
)
)
schema_dict = schema(Person, llm_adapter=OPENAI_TOOLS)
println(JSON.json(schema_dict, 2))
```
Output:
```json
{
"type": "function",
"name": "get_person",
"description": "Fetches information about 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
}
}
```
## Optional Fields
Both `OPENAI` and `OPENAI_TOOLS` modes enforce that all fields are listed in
`"required"`. Optional fields (`Union{Nothing, T}`) are represented as
`["type", "null"]`, following the
[OpenAI structured-output requirement](https://developers.openai.com/api/docs/guides/structured-outputs):
> 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.
**Standard schema** (optional field excluded from `required`):
```json
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"nickname": {
"type": "string"
}
},
"required": [
"name"
]
}
```
**OpenAI schema** (optional field uses `["type", "null"]`):
```json
{
"name": "PersonOpt",
"description": "A person with an optional nickname.",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Full name"
},
"nickname": {
"type": [
"string",
"null"
],
"description": "Optional nickname"
}
},
"required": [
"name",
"nickname"
],
"additionalProperties": false
}
}
```
---
*Output blocks in this README were generated by running `julia docs/generate_readme.jl`.*