The hyper-observable programming language

BAML is a programming language with built-in telemetry. Replace 10+ separate tools with one toolchain that helps agents test, trace, query data, build alerts, and more.

CTSGoBAMLBuildTestTraceDashboardsAlertsFeature flagsdeploy
baml checkbaml testbaml querybaml dashboardbaml alertsbaml flags

Each logo past deploy is a separate product with its own SDK.

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 to make something 100x better, you have to vertically integrate. So we built BAML, with a virtual machine that makes it run anywhere,

one that allows us to profile every function at barely any cost,

a compiler that knows about your errors in production,

and a data lake to query your program data: profiles, spans, logs, traces, and blobs.

Raptor 1, Raptor 2, and Raptor 3 engines side by side, drawn as a blueprint. Each one has fewer external parts than the last.

Query traces, analyze errors, and improve your code, with one CLI.

Build

Designed for agents.

BAML is a fully open-source, completely free-to-use language.

1// Tools are ordinary functions.
2/// Look up a customer's plan and billing status.
3function lookup_customer(email: string) -> string {
4 `${email}: pro plan, paid through March`
5}
6
7/// Search past tickets for ones like this one.
8function search_tickets(query: string) -> string[] {
9 ["Charged twice", "Wrong plan on invoice"]
10}
11
12// An agent is an AI function with tools.
13function support_agent(ticket: string) -> string {
14 client: "openai/gpt-6-luna"
15 tools: [classify, lookup_customer, search_tickets]
16 prompt: `
17 Answer this ticket. Look up the customer first.
18 ${ticket}
19 `
20}
  • syntax and readability of TypeScript
  • correctness and tooling of Rust
  • compile times and concurrency of Go
  • dynamism and nothing else of Python

Deploy

Turn your program data into a queryable data lake.

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

AI calls

The provider, model, tokens, and cost of every AI call, next to its arguments and result.

gpt-6-luna1,204 tokens$0.0042
claude-sonnet-5-51,388 tokens$0.0061

Profiles

How long every function took. It costs so little that Boundary Cloud doesn't charge for it.

  • route, 1100ms, starting at 0ms
  • load_ticket, 220ms, starting at 0ms, called by route
  • classify, 660ms, starting at 231ms, called by route
  • notify, 198ms, starting at 902ms, called by route
  • db_get, 132ms, starting at 6ms, called by load_ticket
  • parse_json, 72ms, starting at 143ms, called by load_ticket
  • render_prompt, 77ms, starting at 242ms, called by classify
  • gpt-6-luna, 462ms, starting at 330ms, called by classify
  • parse, 83ms, starting at 803ms, called by classify
  • send_email, 176ms, starting at 913ms, called by notify
  • query, 110ms, starting at 11ms, called by db_get
  • http, 451ms, starting at 336ms, called by gpt-6-luna
  • coerce, 55ms, starting at 809ms, called by parse
  • smtp, 132ms, starting at 924ms, called by send_email
  • stream, 385ms, starting at 396ms, called by http

Errors

Where each error started and how it moved up the stack, without changing code.

ParseError in parse

at classifytriage.baml:14

at routetriage.baml:31

boundary cloud

A data lake hosted by us, in your cloud, or on your machine

Your terminal

$ baml query

SELECT span_name,

p95(duration)

FROM spans

GROUP BY span_name

classify1.2s

route6ms

Observe

Create dashboards and alerts from your traces.

Make custom dashboards that are 100% tied to your product by using the SQL-based query API.

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

ImproveComing soon

Roll out experiments 100x faster than your CI/CD runs.

The BAML runtime can track experiments and A/B test functions securely for you, without having to redeploy.

gpt-6-sol's share of classify's traffic, and what it cost

gpt-6-luna3.1% labelled other, $0.03 per 1k calls

gpt-6-sol0.3% labelled other, $0.65 per 1k calls

gpt-6-sol took 10% of classify's traffic on Monday, 50% on Tuesday, and 100% on Wednesday, replacing gpt-6-luna. The three days cost $6.71, $23.25, $51.58.

Use BAML where the feedback loop matters most.

BAML can be adopted incrementally. You can literally call BAML functions from Python.

Start migrating an AI agent or workflow.

Move one agent or workflow into BAML, and call it from the rest of your app.

# app/tickets.pyfrom baml_sdk import triagedef handle(ticket: Ticket) -> None:    # "billing", "bug", or "other"    label = triage.classify(ticket.body)    if label == "bug":        escalate(ticket)

Keep the rest of your stack.

BAML works alongside Python, TypeScript, Go, Rust, Java, Swift, and C++. baml generate writes a typed client, so your app calls BAML like its own code.

Or send your existing OTEL traces.

Send OpenTelemetry traces to Boundary to get started, and move code into BAML for richer traces and better DX.

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.