The unified software stack for agents

BAML is a language with a vertically integrated toolchain that helps agents in production. Test and trace code, query data, build alerts, and replace 10+ separate tools.

deploy
BeforeIn production

11 separate products

BAML

Used by engineers at

  • Stitch Fix
  • Feather
  • SAP
  • AMD
  • EY
  • Akamai
  • Vetcove

Iteration loops are fast when everything speaks the same language.

We didn't want to build a programming language.

But agents today wait on slow CI and juggle separate tools to run experiments, check alerts, build dashboards, and work out which version of the code did what.

To make something 100x better, you have to vertically integrate. So we built a virtual machine that runs anywhere, a compiler that knows which errors you're hitting in production, and a data lake that stores every call in a structured way, even with the types you declared.

The layers of the BAML stack drawn as a blueprint, from the virtual machine at the bottom to dashboards, alerts, and feature flags at the top.

Build, deploy, observe, and improve with one CLI.

Build

Build with the best parts of TypeScript, Rust, and Go.

BAML is a fully open-source language designed for agents.

1type Label = "billing" | "bug" | "other";
2
3// 'AI function' syntax for easy extraction
4function classify(ticket: string) -> Label {
5 client: "openai/gpt-6-luna"
6 prompt: `
7 Classify this support ticket.
8 ${ticket}
9 `
10}
11
12function route(ticket: string) -> string {
13 let label = classify(ticket);
14 if (label == "bug") {
15 return "engineering";
16 }
17 return "support";
18}
Syntax like TypeScript.
Unions, generics, and interfaces, in a syntax TypeScript developers already read.
A type system like Rust.
Types hold at runtime, with no any and no unchecked casts. Errors are part of a function's type, and pattern matching is exhaustive.
Compiles as fast as Go.
baml check type-checks 60,000 lines in about 1.4 seconds, and green threads run work concurrently with spawn and await.
AI functions built in.
Declare a model call like any other function, with typed arguments and a typed result. Declare a test anywhere, like in Rust.
Tools for agents.
baml describe finds code by its structure, baml run runs any function from the command line, and baml test runs the tests.
Use it from Python or TypeScript.
Generate an SDK and move one function at a time.

Deploy

Ship faster with built-in tracing.

The BAML runtime records your program as it runs and sends it to Boundary Cloud. There's no SDK to install and no collector to run.

Your app

triage.baml, running on the BAML runtime
program data

boundary cloud

Hosted by us, in your own cloud, or on your machine
SQL

Your terminal

baml querybaml dashboardbaml alerts
triage.baml
1/// baml:$trace=trace.span
2function route(ticket: string) -> string {
3 ...
4}
5
6route(ticket, $trace = trace.span(inputs = true))

Set BOUNDARY_API_KEY to send everything to Boundary Cloud. You can also run Boundary Cloud in your own cloud account, or set BOUNDARY_API_KEY=local to keep it all on your machine.

AI functions are traced automatically.
Every call to an AI function records its arguments, the model's reply, the parsed result, and any error.
Every other function is timed.
Ordinary functions record how long each call took. It costs so little that Boundary Cloud doesn't charge for it.
Errors leave a trace.
When a function throws, the runtime records where the error started and how it moved up the stack.

Observe

Create dashboards and alerts from your data.

Your calls land in Boundary Cloud as typed rows. Read them with SQL from the terminal, chart them, or put a threshold on them.

Calls per minute

SELECT count(*) FROM spans GROUP BY minute

last 4 hours
Labels

SELECT output_value, count(*) FROM spans WHERE span_name = 'classify' GROUP BY hour, output_value

billingbugother
Latency by function

SELECT span_name, p50(duration), p95(duration) FROM spans GROUP BY span_name

route

p50 1.4s
p95 2.9s

classify

p50 1.3s
p95 2.4s
Share labelled other

SELECT avg(output_value = 'other') FROM spans WHERE span_name = 'classify' GROUP BY hour

alert firing on classify

baml query

Look up any call.
Every call is stored with its typed arguments, its result, its latency, and the version of the code that ran.

baml dashboard

Chart any query, live.
A dashboard is a query that keeps running.

baml alerts

Alert on any query.
An alert is a query with a threshold, and it fires on the function it's about, next to its code.

ImproveComing soon

Test and roll out fixes on real traffic.

The calls that went wrong are stored with their real inputs, so you can test a fix against them before you ship it.

Tests from production

31 calls labelled other

Oh great, charged twice again. Love that.other

Wow, the export broke again. Amazing.other

Sure, I will just wait another week.other

Fantastic, another invoice I never asked for.other

27 more

$ baml test add classify --from-query "output_value = 'other'"

31 tests added

Ship to 10% first

Share labelled other, by version

v43

90% of traffic

3.1%

v44

10% of traffic

0.3%

Adopt BAML incrementally.

Start with the language or with production. You don't have to move everything at once.

Start with the language.

Write one function in BAML and call it from your Python, TypeScript, Go, Rust, Java, Swift, or C++ app through a generated client.

Start with production.

Send the OpenTelemetry traces you already have to Boundary, and move code into BAML when you want typed telemetry.

Get access to the BAML stack.

The stack is in private beta. Book a 45-minute call with the founders, and we'll set you up.