TypeBuilder API enables runtime type modification, allowing you to adapt your output schemas dynamically based on database content, user input, or other runtime conditions.
When to Use Dynamic Types
Use dynamic types when:- Categories or classifications come from a database
- Schema fields are user-configurable
- You need to subset available tools based on context
- Output structure varies by request
Dynamic Enums
Mark an enum as dynamic to add values at runtime.Basic Dynamic Enum
Define the enum with@@dynamic in BAML:
main.baml
Database-Driven Categories
A real-world example loading categories from a database:Dynamic Classes
Add properties to classes at runtime using@@dynamic.
Basic Dynamic Class
main.baml
Advanced Patterns
Dynamic Tool Selection
Add a subset of available tools to a response type:main.baml
Creating New Types at Runtime
Create entirely new classes and enums without defining them in BAML:TypeBuilder API
Type Methods
| Method | Returns | Description | Example |
|---|---|---|---|
string() | FieldType | String type | tb.string() |
int() | FieldType | Integer type | tb.int() |
float() | FieldType | Float type | tb.float() |
bool() | FieldType | Boolean type | tb.bool() |
literal_string(value) | FieldType | Literal string | tb.literal_string("hello") |
literal_int(value) | FieldType | Literal integer | tb.literal_int(123) |
literal_bool(value) | FieldType | Literal boolean | tb.literal_bool(true) |
list(type) | FieldType | List type | tb.list(tb.string()) |
union(types) | FieldType | Union of types | tb.union([tb.string(), tb.int()]) |
map(key, value) | FieldType | Map type | tb.map(tb.string(), tb.int()) |
optional() | FieldType | Makes type optional | tb.string().optional() |
Registry Methods
| Method | Returns | Description |
|---|---|---|
add_class(name) | ClassBuilder | Create new class |
add_enum(name) | EnumBuilder | Create new enum |
MyClass.type() | FieldType | Reference existing BAML class |
Using BAML Syntax for Dynamic Types
For complex type modifications, use raw BAML syntax:Testing Dynamic Types
Testing Return Types
Use thetype_builder block in tests:
test.baml
Testing Parameter Types
Pass dynamic values directly in test args:test.baml
JSON Schema Integration
BAML supports converting JSON schemas to dynamic types. This feature is functional but awaiting user feedback before merging. See the blog post and examples for implementation details. Please comment on GitHub issue #771 if this interests you.
Best Practices
- Base Types: Define base structure in BAML, use dynamic only for runtime variations
- Validation: Validate dynamic values before adding them to avoid LLM confusion
- Caching: Cache TypeBuilder instances when using the same dynamic structure across calls
- Documentation: Use
.description()extensively to help the LLM understand dynamic fields - Testing: Test dynamic types thoroughly with various combinations of runtime additions