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
- BAML — docs — accessed 2026-04-20
- BoundaryML on GitHub — accessed 2026-04-20