ctx.output_format
{{ ctx.output_format }} generates output schema instructions for the LLM based on the function's return type.
Basic Usage
class Resume {
name string
education Education[]
}
function ExtractResume(resume_text: string) -> Resume {
prompt #"
Extract this resume:
---
{{ resume_text }}
---
{{ ctx.output_format }}
"#
}
Rendered prompt:
Extract this resume
---
Aaron V.
Bachelors CS, 2015
UT Austin
---
Answer in JSON using this schema:
{
name: string
education: [
{
school: string
graduation_year: string
}
]
}
Parameters
prefix
Custom instruction prefix before the schema.
{{ ctx.output_format(prefix="If you use this schema correctly I'll tip $400:\n") }}
Default prefixes by return type:
| Return Type | Default Prefix |
|---|---|
string | (none) |
int | Answer as an |
| Other primitives | Answer as a |
enum | Answer with any of the categories:\n |
class | Answer in JSON using this schema:\n |
| Array | Answer with a JSON Array using this schema:\n |
| Union | Answer in JSON using any of these schemas:\n |
| Optional | Answer in JSON using this schema:\n |
always_hoist_enums
Whether to print enum definitions above the schema or inline them.
Default: false
{{ ctx.output_format(always_hoist_enums=true) }}
Inlined (default):
Answer in this json schema:
{
categories: "ONE" | "TWO" | "THREE"
}
Hoisted:
MyCategory
---
ONE
TWO
THREE
Answer in this json schema:
{
categories: MyCategory
}
BAML always hoists enums if any value has a @description attribute.
or_splitter
Separator for union and optional types.
Default: or
{{ ctx.output_format(or_splitter=" | ") }}
BAML uses or because some LLMs interpret | incorrectly.
hoist_classes
Controls which classes are hoisted in the prompt.
Default: "auto"
Options:
| Value | Behavior |
|---|---|
"auto" | Only hoist recursive classes |
false | Same as "auto" |
true | Hoist all classes |
["ClassName"] | Hoist specific classes plus recursive ones |
Example with recursive class:
class Node {
data int
next Node?
}
class Example {
a string
c NestedClass
d Node
}
"auto" output:
Node {
data: int,
next: Node or null
}
Answer in JSON using this schema:
{
a: string,
c: {
m: int,
n: int,
},
d: Node,
}
true output:
Node {
data: int,
next: Node or null
}
Example {
a: string,
c: NestedClass,
d: Node,
}
NestedClass {
m: int,
n: int,
}
Answer in JSON using this schema: Example
Requires BAML Version 0.89+
hoisted_class_prefix
Prefix for hoisted class definitions.
Default: (none)
{{ ctx.output_format(hoisted_class_prefix="interface") }}
Without prefix:
Node {
data: int,
next: Node or null
}
Answer in JSON using this schema:
{
head: Node or null,
len: int
}
With hoisted_class_prefix="interface":
interface Node {
data: int,
next: Node or null
}
Answer in JSON using this interface:
{
head: Node or null,
len: int
}
Why Not JSON Schema?
BAML uses "type definitions" format instead of JSON Schema because:
- 4x more efficient - fewer tokens
- More readable - by humans and models
- Better performance - especially on nested objects and smaller models
See the full comparison article.