♨️Damien
04/25/2026, 1:02 AM♨️Damien
04/25/2026, 1:02 AMbaml
// Step 1: Detect what fields exist in the document
class FieldDefinition {
name string @description("Snake_case field name, e.g. invoice_number")
description string @description("What this field represents")
field_type "string" | "int" | "float" | "bool" | "list" | "class" | "enum" | "literal_string" | "literal_int" | "literal_bool" | "union" | "map" | "my_class" @description("Best type for this field. Use 'class' for nested objects, 'list' for arrays, 'enum' for categorical values, 'literal_*' for exact constant values, 'union' for one-of-many types, 'map' for key-value pairs, 'my_class' for an existing BAML class.")
properties FieldDefinition[]? @description("Required if field_type is 'class'. Defines the nested properties of this object.")
item_type FieldDefinition? @description("Required if field_type is 'list'. Defines the type of items in the list.")
enum_values string[]? @description("Required if field_type is 'enum'. List of allowed values.")
literal_value string | int | bool? @description("Required if field_type is 'literal_string', 'literal_int', or 'literal_bool'. The exact constant value.")
union_types FieldDefinition[]? @description("Required if field_type is 'union'. The types that form the union.")
key_type FieldDefinition? @description("Required if field_type is 'map'. The type of map keys.")
value_type FieldDefinition? @description("Required if field_type is 'map'. The type of map values.")
optional bool? @description("Whether this field is optional. Defaults to false (required).")
}
class DetectedFields {
fields FieldDefinition[] @description("All distinct data fields detected in the document, including nested structures and lists")
}♨️Damien
04/25/2026, 1:03 AMbaml
function DetectFields(document: string) -> DetectedFields {
client "openai/gpt-4o-mini"
prompt #"
Analyze the document below and identify ALL distinct data fields present in it.
Return a hierarchical schema (meta-model) describing the document's structure.
For each field, decide if it is:
- A simple primitive value (string, int, float, boolean)
- A list of items (use field_type 'list' and define item_type)
- A nested object (use field_type 'class' and define properties)
- An enum/categorical value (use field_type 'enum' and define enum_values)
- An existing BAML class (use field_type 'my_class')
Return only fields that have actual values — skip headers or labels with no data.
Nest related fields together under parent objects when the document structure is hierarchical.
Use lists when the document contains repeating elements.
{{ _.role("user") }}
{{ document }}
{{ ctx.output_format }}
"#
}
// Step 2: Extract values for the detected fields
// @@dynamic allows TypeBuilder to inject properties at runtime
class ExtractedData {
@@dynamic
}
function ExtractData(document: string, field_descriptions: string) -> ExtractedData {
client "openai/gpt-4o-mini"
prompt #"
Extract the following fields from the document.
The field descriptions below describe the expected schema in JSON-like format.
Return null for any field that is not present.
Fields to extract:
{{ field_descriptions }}
{{ _.role("user") }}
{{ document }}
{{ ctx.output_format }}
"#
}