Backed by
Generate Typesafe Output from LLMs with Zero Boilerplate
BAML is a programming language that does the heavy lifting for you.
Guarantees type-safe LLM outputs
Works with Python & Typescript
VSCode LLM Playground
Type-safe observability
1. Install BAML
brew install boundaryml/baml/baml
# Add BAML to your project
cd my-project
baml init
baml test run
2. Setup VSCode
Trusted by developers at
aer
Haven AI
PMMI
Vetrec
Zenfetch
Defining LLM functions is much nicer when everything isn't a string
See our docs
Often used to pick one or more categories from a list
Scenario 1: Classifying a customer message with BAML
// 1. Define the categories
enum MessageType {
  Refund
  Cancel @alias("cancel-order")
  TechnicalSupport @description("generic technical issue")
  AccountIssue @description("account-login or account-creation")
  Question
}

// 2. Define the function
function ClassifyMessage { 
  input string
  output MessageType[]
}

// 3. Implement the function
impl<llm, ClassifyMessage> v1 {
  client GPT4
  prompt #"
    Classify the following INPUT into any of
    the following:
    {#print_enum(MessageType)}

    INPUT: {#input}

    Output in this JSON format:
    {#print_type(output)}

    JSON:
  "#
}
BAML guarantees your function's output type
Our built-in JSON parser patches many mistakes LLMs make. If we can't parse it, we raise an exception. We do this locally, with 0 additional LLM calls.
Raw LLM string response
```json
"cancel-order"
```
Parsed into MessageType[]
[
0: "MessageType.Cancel"
]
What our parser did to find MessageType[]:
Automatically found a json parseable object in the text
Converted the string ("cancel-order") to an enum (`MessageType.Cancel`)
Wrapped the response in a list even though the LLM only returned a single string
Import your BAML functions in Python & TypeScript
Use your auto-generated type-safe interface for your BAML function ClassifyMessage. It automatically calls the LLM, handles retries, and parses the response into MessageType[].
from baml_client import baml as b
from baml.baml_types import MessageType

async def main():
  categories = await b.ClassifyMessage("I don't want this order anymore")
  
  # category is an Enum, not a plain string
  for category in categories:
    assert isinstance(category, MessageType)
  assert MessageType.CancelOrder in categories

Our compiler generates `baml_client` in milliseconds with 0 LLM calls
If you use the wrong function or input type, get compile-time errors, not at runtime
All prompts, model settings, and retry policies are isolated to BAML files
Iterating on prompts is much faster when you stay in VSCode
Testing: so easy, it's fun
  • Open VSCode Playground
  • Add a test
  • Run and watch results stream in
Compare different models and prompts
BAML generates all the pytest/jest boilerplate testing code
Coming soon
AI-generated test cases
Asserts using LLMs
See the full prompt before calling the LLM
The BAML VSCode Playground shows you the full prompt, like a Markdown preview, in real time.

No need to dig through some library code or logs to figure it out.

One of our core design principles is making prompt engineering transparent.
And when you're ready to deploy,
Boundary Studio gives you the visibility you need
Turn an error in production into a test case with 1 click
Make a test case. Fix the prompt. Redeploy.
Analyze your pipeline
If enabled, all BAML function inputs and outputs are logged (in a type-safe way) to Boundary Studio.
See the entire flow of data
Metrics for latency, cost, and error rates
Pipeline Integration
Share feedback with your team
Leave comments and ratings on every logged BAML function call

Coming soon
React components to collect high quality, type-safe feedback from your users
Leave comments and ratings on every logged event

Frequently asked questions

Does BAML use LLMs to generate code?
No, BAML uses a custom-built compiler.
What does BAML stand for?
Basically, A Made-up Language
What is the BAML compiler written in?
Mostly Rust 🦀
What models do you support?
Openai, Anthropic, Gemini, Mistral, or you can bring your own! We also have plans to support non-generative models.
How do I deploy with BAML?
BAML files are only used to generate Python or Typescript code. You don’t need to install the BAML compiler in your actual production servers. Just commit the generated code as you would any other python code, and you're good to go
Is BAML secure?
Your BAML-generated code never talks to our servers. We don’t proxy LLM APIs -- you call them directly from your machine. We only publish traces to our servers if you enable it explicitly.
How do you make money?
BAML and the VSCode extension will always be 100% free and open-source.

Our paid capabilities only start if you use Boundary Studio, which focuses on Monitoring, Collecting Feedback, and Improving your AI pipelines. Contact us for pricing details at contact@boundaryml.com
Why not use Pydantic / Instructor or Langchain?
Here’s our detailed comparison vs Pydantic and other frameworks.
TL;DR: BAML is more than just a data-modeling library like Pydantic.
1) Everything is typesafe. 2) The prompt is also never hidden from you. 3) It comes with an integrated playground, and 4) can support any model.
Why make a new programming language?
We started building SDKs for TypeScript and Python (and even experimented with YAML), and they were simply not sufficient. Inspired by technologies by Prisma and Terraform, we set out to build a better DX for AI.
Have a different question or want to learn more about integrating BAML for your team?
Join our community onDiscord
Built by former engineers from
deshaw
microsoft
amazon