A programming language for AI models to write.
Brevi reads like Python and compiles to Rust. Models finish tasks in fewer tokens than in Python, the programs run at native speed, and every compiler error comes back as one short line the model can act on.
Status: preview. The compiler, written in Rust, opens under the Apache-2.0 license with the first public release.
# Three most common words on stdin counts = {} for w in stdin().lower().words(): counts[w] += 1 top = counts.pairs().sort_by(p => (-p.1, p.0)).take(3) for w, n in top: print("{w}: {n}")
the: 3 and: 2 bat: 1
Why Brevi
Built for the model in the loop, not for a person at a keyboard.
Every language in common use was designed for people. People type slowly, read error messages once, and remember the libraries they know. A model works differently. It pays for every token it writes, it rereads every error message in full, and each failed attempt costs another round of both. Brevi is designed around that cost.
What a finished task really costs
- The code it writes. Fewer lines and fewer tokens for the same program. Brevi has no semicolons, braces, lifetimes or import lines, and the common tasks (CSV, JSON, dates, money, regular expressions) need no setup code.
- The errors it reads. An error message goes back into the model's context and is paid for in full. Brevi's errors are one short line. In the examples below they are 42% to 86% shorter than the same mistake reported by Python or Rust.
- The retries it needs. Each failed attempt adds another edit and another error. Brevi accepts the Python habits models fall back on, fixes small typos itself, and points to the exact line to change, so fewer attempts fail and each fix is small.
The benchmark counts all three together, with exact token counts. On that measure models finish tasks with up to 21% fewer tokens in Brevi than in Python. On the hard tasks, writing the same programs in Rust, the language Brevi compiles to, takes about 2.4 times as many tokens as Brevi.
The same task in both languages
A sales report from a CSV file: skip bad rows, total revenue by region and month with exact cents, and find the top product. This is one of the held-out tasks, written after the language was tuned. Both programs below are Claude Haiku's own passing solutions, unedited.
rows = csv(stdin())
valid = 0
skipped = 0
region_tot = {}
prod_qty = {}
month_tot = {}
for i in 1..rows.len():
row = rows[i]
if row.join("").trim().is_empty(): continue
ok = row.len() == 5 and row[0].re_full("\d{4}-\d{2}-\d{2}").len() > 0 and row[3].re_full("\d+").len() > 0 and row[4].re_full("\d+(\.\d{1,2})?").len() > 0
if not ok:
skipped += 1
continue
valid += 1
rev = row[4].dec() * row[3].int()
region_tot[row[1]] += rev
prod_qty[row[2]] += row[3].int()
month_tot[row[0].slice(0, 7)] += rev
print("rows {valid}")
print("skipped {skipped}")
if valid > 0:
print("regions")
for rp in region_tot.pairs().sort_by(rp => (-rp.1, rp.0)):
print(" {rp.0} {rp.1.fmt(2)}")
top = prod_qty.pairs().sort_by(pp => (-pp.1, pp.0))
t = top[0]
print("top_product {t.0} {t.1}")
print("months")
for mp in month_tot.pairs().sort_by(mp => mp.0):
print(" {mp.0} {mp.1.fmt(2)}")
import csv
import re
import sys
from collections import defaultdict
DATE_RE = re.compile(r"[0-9]{4}-[0-9]{2}-[0-9]{2}")
QTY_RE = re.compile(r"[0-9]+")
PRICE_RE = re.compile(r"[0-9]+(\.[0-9]{1,2})?")
def to_cents(price):
if "." in price:
whole, frac = price.split(".")
frac = (frac + "00")[:2]
else:
whole, frac = price, "00"
return int(whole) * 100 + int(frac)
def fmt(cents):
return "%d.%02d" % (cents // 100, cents % 100)
def main():
reader = csv.reader(sys.stdin)
rows = 0
skipped = 0
region_rev = defaultdict(int)
product_qty = defaultdict(int)
month_rev = defaultdict(int)
first = True
for row in reader:
if first:
first = False
continue
if not row or (len(row) == 1 and row[0].strip() == ""):
continue
if len(row) != 5:
skipped += 1
continue
date, region, product, qty, price = row
if not DATE_RE.fullmatch(date) or not QTY_RE.fullmatch(qty) or not PRICE_RE.fullmatch(price):
skipped += 1
continue
q = int(qty)
revenue = q * to_cents(price)
rows += 1
region_rev[region] += revenue
product_qty[product] += q
month_rev[date[:7]] += revenue
out = ["rows %d" % rows, "skipped %d" % skipped]
if rows > 0:
out.append("regions")
for region, rev in sorted(region_rev.items(), key=lambda kv: (-kv[1], kv[0])):
out.append(" %s %s" % (region, fmt(rev)))
best = min(product_qty.items(), key=lambda kv: (-kv[1], kv[0]))
out.append("top_product %s %d" % (best[0], best[1]))
out.append("months")
for month in sorted(month_rev):
out.append(" %s %s" % (month, fmt(month_rev[month])))
sys.stdout.write("\n".join(out) + "\n")
if __name__ == "__main__":
main()
- Exact money is built in.
row[4].dec()is an exact decimal, so the Brevi program adds up prices directly. The Python program writes its ownto_centsandfmthelpers to avoid floating-point errors in the totals. - No setup code. CSV parsing and regular expressions are part of the language, so there are no imports, no compiled patterns and no
main()wrapper. - Missing map keys read as zero.
region_tot[row[1]] += revjust works, with nodefaultdictor.get(k, 0). - And it runs as native code. The Brevi version compiles to a Rust binary, with the speed that comes with it.
Brevi against the usual choices
Python is what models write best today, and Rust is what you would pick for speed and safety. Brevi aims to keep the strengths of both.
| Python | Rust | Brevi | |
|---|---|---|---|
| Tokens to finish a task | Baseline | About 2.4 times Brevi (hard tasks) | Up to 21% fewer than Python |
| Run time (Dijkstra, 100k nodes) | 2.90 s | 0.30 s | 0.47 s |
| Type mistakes found | When the line runs | Before running | Before running |
| Size of the two errors in the next section | 76 to 80 tokens | 106 to 159 tokens | 44 tokens, or none |
| Memory management | Garbage collector | Written by hand: lifetimes and borrows | Worked out by the compiler |
| Exact decimals, CSV, JSON, dates | Imports and helpers | Crates and setup | Built in |
Less to write, less to read
Counted end to end, including errors read and retries, models used fewer tokens in Brevi than in Python on five of six task sets and the same on the sixth, including tasks written after the language was tuned.
Errors a model can act on
No file paths, columns or pages of notes. Each error is one JSON line with the Brevi line number and a suggested fix. Small typos of known names are fixed during the build.
Rust speed and safety underneath
Brevi compiles to Rust and builds a native binary. The model never writes lifetimes, borrows or semicolons; ownership is worked out by the compiler.
Python habits are accepted
Models write Python by reflex, so Brevi accepts the common spellings instead of rejecting them. Indented blocks, comprehensions, len(), sorted() and ", ".join(xs) all work.
The whole language in one short guide
A model reads one page before writing Brevi. The guide is built into the compiler, and brevi guide WORD prints only the lines about one name.
Programs that work the first time
On the 18 small tasks, Claude Sonnet's Brevi programs passed on the first attempt every time, against 35 of 36 in Python. A first-try pass means no error to read and no retry to pay for.
Errors
One line per mistake, with the fix.
Brevi runs its own checks before Rust sees the code, in about 3 ms. Anything Rust still rejects is mapped back to the Brevi line and rewritten in Brevi's own type names, so the model never reads generated Rust.
n = stdin().ints().sum()
print("total: " + n)
{"line":2,"msg":"cannot add str and int","fix":"turn the number into text with str(x), or write \"{x}\""}
The same two mistakes in three languages
Tokens the model has to read before it can fix each mistake, counted with Anthropic's tokenizer.
| Mistake | Python | Rust | Brevi |
|---|---|---|---|
| Adding a number to text | 76 | 106 | 44 |
| Misspelled variable name | 80 | 159 | 22, and the program runs |
Python reports the first mistake only when that line runs. Brevi fixes the misspelling during the build and prints a one-line note instead of failing, so no retry is needed.
Benchmarks
Tokens per finished task, against Python.
Each figure is everything a model spends to finish every task in a set: the code it writes, the error output it reads, and each retry counted as the lines it changed. Counts are exact, from Anthropic's token counter, averaged over two or more runs. Lower is better.
| Task set | Model | Brevi | Python | Saved |
|---|---|---|---|---|
| 6 held-out big tasks | Haiku | 4,604 | 5,847 | 21% |
| 6 held-out big tasks | Sonnet | 4,020 | 4,220 | 5% |
| 18 small tasks | Sonnet | 4,488 | 5,052 | 11% |
| 18 small tasks | Haiku | 5,306 | 5,794 | 8% |
| 8 big tasks | Haiku | 10,382 | 10,556 | 2% |
| 8 big tasks | Sonnet | 8,721 | 8,721 | level |
Held-out tasks were written after the language was tuned and never used to change it. Big tasks are programs of 50 to 200 lines. Full method and logs: bench.md.
| Run time, seconds | Python | Brevi | Rust |
|---|---|---|---|
| Word counts | 0.35 | 0.18 | 0.09 |
| Dijkstra | 2.90 | 0.47 | 0.30 |
| Prime sieve | 1.33 | 0.05 | 0.02 |
| Group records | 0.76 | 0.31 | 0.12 |
Best of three runs. On the hard tasks, models spend about 2.4 times as many tokens writing Rust as writing Brevi.
For agents
Ready for coding agents from the first call.
The compiler ships with the pieces an agent needs to write, check and fix Brevi without a human setting anything up.
MCP server
brevi mcpservesguide,check,run,testandpatchover stdio. Each tool takes the program as text, so the agent needs no files.Agent skill
An Agent Skills package with setup and the write, check, fix loop: skill.md.llms.txt
Machine-readable entry points at /llms.txt and /llms-full.txt, with the guide as plain Markdown at /guide.md.Edit by name
brevi patch f.bv p.bvreplaces each function, type or test by name, so a fix costs only the lines that changed.Fast checks
brevi check f.bv --fastruns Brevi's own checks in about 3 ms without invoking rustc.
Coming next
brevi.run: compile, run and test in the cloud.
A hosted service for agents that need to run Brevi without installing a Rust toolchain. Send a program, get the output or the error lines back. It opens after the public release of the compiler.