BAML Launch Week Day 3
Developer Spotlights
Launch Week isn't just about us - it's also about the incredible engineering work of amazing companies building with BAML!

Gus Trigos
What does your company do?
Mentum streamlines supply chain sourcing with AI, turning unstructured data into actionable insights for faster decisions and cost savings. We automate workflows like RFQs, PO tracking, and invoice reconciliation.
How has BAML helped you?
BAML enabled a reliable Agentic pipeline for Mentum. Transitioning from LangChain to BAML reduced our prompt complexity by 50%, making our code cleaner and more efficient. We built a high-confidence image-to-text document classification in just one day.


Dex Horthy
What does your company do?
HumanLayer is an API for AI Applications to request human help, feedback, and approvals. Customers use HumanLayer to build agents that perform risky workflows, like terraform applies and database migrations.
How has BAML helped you?
BAML helps us quickly classify/categorize/structure unstructured input from Slack, emails, and etc. Strategically, we're also focused on defining reference architectures for next-gen AI agents, where we think BAML plays a key role.


Gus Trigos
What does your company do?
Mentum streamlines supply chain sourcing with AI, turning unstructured data into actionable insights for faster decisions and cost savings. We automate workflows like RFQs, PO tracking, and invoice reconciliation.
How has BAML helped you?
BAML enabled a reliable Agentic pipeline for Mentum. Transitioning from LangChain to BAML reduced our prompt complexity by 50%, making our code cleaner and more efficient. We built a high-confidence image-to-text document classification in just one day.


Dex Horthy
What does your company do?
HumanLayer is an API for AI Applications to request human help, feedback, and approvals. Customers use HumanLayer to build agents that perform risky workflows, like terraform applies and database migrations.
How has BAML helped you?
BAML helps us quickly classify/categorize/structure unstructured input from Slack, emails, and etc. Strategically, we're also focused on defining reference architectures for next-gen AI agents, where we think BAML plays a key role.

Beyond Strings: Type System for LLMs with BAML
Imagine if you could guarantee the shape of every response you get from a language model. No more parsing messy strings, no more unpredictable outputs. With BAML, that's no longer a dream; it's our new reality.
Many of you are already familiar with the power of structured prompting — the idea that specifying the format of LLM output significantly improves downstream reliability and user experiences. If you're new to this, think of it as designing a conversation where you precisely define what you expect to get back.
Let's see this in action. Look at the recipe for one of my favorite dishes — saag paneer.
In the example on the left, we're using a general-purpose LLM, and ask it to return any string in natural language. It gives back a recipe that we can use but nothing about it is guaranteed. On the right, same model, but using BAML's type system — will always return the data in a shape that our frontend can consume.
The difference is clear: One is freeform, and the other is highly predictable.
As your prompting pipelines become more sophisticated, so does the need for reliability and structure. Our latest release of BAML allows you to build rock-solid LLM interactions by leveraging a purpose-built type system.
We've moved beyond asking language models in plain English. By leveraging types we gain a few specifications:
- Unambiguous Communication: Types are much less vague than natural language.
- Efficiency: Types offer a more compact token representation.
- Clarity: Types are far easier to read and understand, making your code more maintainable.
- Debugging: With types, it's easier to spot inconsistencies and debug.
- Consistency: Type compilers will catch a lot of unexpected bugs before they reach production.
While type systems may require more upfront design and are less flexible than free-form text, their maintainability, reliability, and clarity far outweigh these limitations. We believe this is a worthwhile trade-off.
Introducing BAML's Powerful Type System
BAML's type system now supports a comprehensive set of features, designed specifically for language models:
- Primitives: string, float, int, bool, literal, null
- Composite: map<k, v>, list<v>
- User-defined: classes, enums
- Recursive types
- Type aliases
// You can literally define any type in BAML (including arbitrary JSON).
type JSON = string | int | float | null | JSON[] | map<string, JSON>;
- @alias to rename fields for the LLM without affecting your data storage. For example, use
establishment_name
for the LLM but consume it asname
in a database or UI Components.
class Invoice {
name string @alias("establishment_name")
}
- @assert to add runtime metadata validations, ensuring data integrity.
class Resume {
// if the LLM gives an empty this,
// this is not a valid name or Resume
name string @assert(not_empty, {{ this|length > 0 }})
education string[]
}
or
type NonEmptyString = string @assert(not_empty, {{ this|length > 0 }})
class Resume {
name NonEmptyString
education string[]
}
- @check to plumb metadata validations, letting you know if a response isn't valid:
class Contact {
name string
email string @assert(valid_email, {{ this|regex_matches(".+@.+\..+") }}) @check(not_gmail, {{ !this|regex_matches(".+@gmail.com") }})
}
// BAML transforms the above into this in Typescript and returns the computed @check
// values in the response
interface Contact {
name: string
email: {
value: string
checks: {
not_gmail: boolean
}
}
}
or even cleaner
type ValidEmail = string @assert(valid_email, {{ this|regex_matches(".+@.+\..+") }})
type NotGmail = ValidEmail @check(not_gmail, {{ !this|regex_matches(".+@gmail.com") }})
class Contact {
name string
// alias to work_email for the llm
email NotGmail @alias("work_email")
}
- Dynamic Types: Create types at runtime based on user input or external data, for example, a list of colors loaded from a database.
// BAML code
class ColorCategory {
@@dynamic
}
function GetMoodColor(text: string) -> ColorCategory {
client "openai/gpt-4o"
prompt #"..."#
}
# Python code
valid_categories = ["red", "blue", ...]
tb = TypeBuilder()
for value in valid_categories:
tb.ColorCategory.add_value(value).alias(value.upper())
# Call the baml function
result = b.GetMoodColor("I'm feeling sad", { "tb": tb})
# this will always be true!
assert result in valid_categories
Real-World Example
Let's look at a real use case from one of our users: Invoice Processing.
Instead of this:
You are an expert accountant, extract all the line items from this invoice.
EXTRACT EVERY ITEM. DO NOT SKIP.
Track the quantity and unit price and total for each item.
Extract any fees applied.
Here is the user's invoice.
{{ invoice_content }}
You can do this:
class Invoice {
items Item[]
subtotal float
fees map<string, float>
tax float
total float
}
class Item {
description string
quantity float
unit_price float
total float
}
prompt:
Parse an Invoice.
{{ invoice_content }}
Notice how concise and easy to understand the later approach is using type systems!
Explore this example in depth over at: https://mercoa.com/blog/building-invoice-ocr-in-three-days-with-type-safe-llm-calls
Try BAML Today
If you want to try BAML online (without any installs), visit promptfiddle.com (Yes, we made a full online editor just so you could try BAML!)
If you're ready to experience BAML fully and start using LLMs faster and more reliably than ever before, go on over to our docs to get started today - BAML Guide
But that's not all! We're not slowing down! Tomorrow, prepare for an even bigger update to our type system. It will redefine the way you think about Agentic UX, and you don't want to miss it.
(You might even get a sneak peek of people already talking about it in our Discord community!)
P.S. If you're curious why we created a new programming language for LLMs, check this post out!