Capability · Framework — orchestration

BAML

BAML flips the usual prompt workflow: instead of embedding prompts as strings in application code, you write typed functions in a standalone .baml language, and BAML's compiler generates type-safe clients and handles prompt engineering, retries, and parser logic. The result is prompts treated as code — diff-able, testable, and versioned — with the reliability of static types at the boundary.

Framework facts

Category
orchestration
Language
DSL + Python / TypeScript / Ruby / Go
License
Apache 2.0
Repository
https://github.com/BoundaryML/baml

Install

pip install baml-py
# or npm install @boundaryml/baml
npx baml-cli init

Quickstart

# schema.baml
class Resume { name string @description("full name") skills string[] }

function ExtractResume(text: string) -> Resume {
  client GPT4o
  prompt #"Extract structured data: {{ text }} {{ ctx.output_format }}"#
}

# Python usage
from baml_client import b
resume = b.ExtractResume(text=raw)
print(resume.skills)

Alternatives

  • Instructor — Pydantic-based structured output
  • Outlines — constrained decoding for any LLM
  • Marvin — decorator-based typed AI
  • Guidance — Microsoft's structured generation library

Frequently asked questions

Why a separate language instead of Pydantic?

BAML argues that prompts deserve their own syntax with first-class support for jinja, output shape hints, and provider swapping. In practice teams using BAML report faster iteration and fewer 'LLM returned malformed JSON' incidents compared to ad-hoc Pydantic + OpenAI setups.

Can BAML swap models easily?

Yes — client definitions are separate from function definitions, so you change a client block (GPT-4o → Claude Opus 4.7 → Llama 3.1) without touching the prompt.

Sources

  1. BAML — docs — accessed 2026-04-20
  2. BoundaryML on GitHub — accessed 2026-04-20