Here’s a list of all the types that can be represented in BAML:

Primitive Types

  • bool
  • int
  • float
  • string
  • null

Literal Types

This feature was added in: v0.61.0.

The primitive types string, int and bool can be constrained to a specific value. For example, you can use literal values as return types:

1function ClassifyIssue(issue_description: string) -> "bug" | "enhancement" {
2 client GPT4Turbo
3 prompt #"
4 Classify the issue based on the following description:
5 {{ ctx.output_format }}
6
7 {{ _.role("user")}}
8 {{ issue_description }}
9 "#
10}

See Union(|) for more details.

Multimodal Types

See calling a function with multimodal types and testing image inputs

image

You can use an image like this for models that support them:

1function DescribeImage(myImg: image) -> string {
2 client GPT4Turbo
3 prompt #"
4 {{ _.role("user")}}
5 Describe the image in four words:
6 {{ myImg }}
7 "#
8}

You cannot name a variable image at the moment as it is a reserved keyword.

Calling a function with an image type:

1from baml_py import Image
2from baml_client import b
3
4async def test_image_input():
5 # from URL
6 res = await b.TestImageInput(
7 img=Image.from_url("https://upload.wikimedia.org/wikipedia/en/4/4d/Shrek_%28character%29.png")
8 )
9
10 # Base64 image
11 image_b64 = "iVBORw0K...."
12 res = await b.TestImageInput(
13 img=Image.from_base64("image/png", image_b64)
14 )

audio

Example

1function DescribeSound(myAudio: audio) -> string {
2 client GPT4Turbo
3 prompt #"
4 {{ _.role("user")}}
5 Describe the audio in four words:
6 {{ myAudio }}
7 "#
8}

Calling functions that have audio types.

1from baml_py import Audio
2from baml_client import b
3
4async def run():
5 # from URL
6 res = await b.TestAudioInput(
7 audio=Audio.from_url(
8 "https://actions.google.com/sounds/v1/emergency/beeper_emergency_call.ogg"
9 )
10 )
11
12 # Base64
13 b64 = "iVBORw0K...."
14 res = await b.TestAudioInput(
15 audio=Audio.from_base64("audio/ogg", b64)
16 )

Composite/Structured Types

enum

See also: Enum

A user-defined type consisting of a set of named constants. Use it when you need a model to choose from a known set of values, like in classification problems

1enum Name {
2 Value1
3 Value2 @description("My optional description annotation")
4}

If you need to add new variants, because they need to be loaded from a file or fetched dynamically from a database, you can do this with Dynamic Types.

class

See also: Class

Classes are for user-defined complex data structures.

Use when you need an LLM to call another function (e.g. OpenAI’s function calling), you can model the function’s parameters as a class. You can also get models to return complex structured data by using a class.

Example:

Note that properties have no :

1class Car {
2 model string
3 year int @description("Year of manufacture")
4}

If you need to add fields to a class because some properties of your class are only known at runtime, you can do this with Dynamic Types.

Optional (?)

A type that represents a value that might or might not be present.

Useful when a variable might not have a value and you want to explicitly handle its absence.

Syntax: Type?

Example: int? or (MyClass | int)?

Union (|)

A type that can hold one of several specified types.

This can be helpful with function calling, where you want to return different types of data depending on which function should be called.

Syntax: Type1 | Type2

Example: int | string or (int | string) | MyClass or string | MyClass | int[]

Order is important. int | string is not the same as string | int.

For example, if you have a "1" string, it will be parsed as an int if you use int | string, but as a string if you use string | int.

List/Array ([])

A collection of elements of the same type.

Syntax: Type[]

Example: string[] or (int | string)[] or int[][]

  • Array types can be nested to create multi-dimensional arrays
  • An array type cannot be optional

Map

A mapping of strings or enums to elements of another type.

Syntax: map<string, ValueType>

Example: map<string, string>

Enums and literal strings can also be used as keys.

1enum Category {
2 A
3 B
4 C
5}
6
7// Enum key syntax
8map<Category, string>
9
10// Literal strings syntax
11map<"A" | "B" | "C", string>

❌ Set

  • Not yet supported. Use a List instead.

❌ Tuple

  • Not yet supported. Use a class instead.

Examples and Equivalents

Here are some examples and what their equivalents are in different languages.

Example 1

1int? | string[] | MyClass

Example 2

1string[]

Example 3

1(int | float)[]

Example 4

1(int? | string[] | MyClass)[]

Example 5

1"str" | 1 | false

⚠️ Unsupported

  • any/json - Not supported. We don’t want to encourage its use as it defeats the purpose of having a type system. if you really need it, for now use string and call json.parse yourself or use dynamic types
  • datetime - Not yet supported. Use a string instead.
  • duration - Not yet supported. We recommend using string and specifying that it must be an “ISO8601 duration” in the description, which you can parse yourself into a duration.
  • units (currency, temperature) - Not yet supported. Use a number (int or float) and have the unit be part of the variable name. For example, temperature_fahrenheit and cost_usd (see @alias)