Klaussa-8B: replacing four API calls with one model

A Llama-3.1-8B specialization trained to do in one pass what four chained Gemini Flash calls did before, taking the projected cost of answering a legal question from USD 0.09 to USD 0.0012. Written from the middle of the work rather than after it.

Role Co-founder and founding engineer, Klaussa AI. Period 2026. Scope Led the Klaussa-8B work: problem framing, the training data pipeline, the training recipe, the benchmark, and the serving path.

$0.09
PER QUESTION, BEFORE
Four chained Gemini Flash calls, billed per token, charged again every time
$0.0012
PER QUESTION, PROJECTED
One model we own, running on hardware already paid for
1.27B
TOKENS OF INDONESIAN LAW
50k+ regulations, 8.8k court decisions, 2.4k journals, cleaned and chunked
16
RTX 5090s, DISTRIBUTED RUN
Development on a single RTX PRO 6000

Summary

Klaussa answers questions about Indonesian regulation. Every answer used to require four separate calls to Google’s Gemini Flash API, costing about nine cents a question. I trained a single 8-billion-parameter model to do all four steps at once, which brings the projected cost down to roughly a tenth of a cent.

At a hundred thousand questions a month, that is the difference between a 9,000 dollar bill and a 120 dollar one. What matters more than the size of the saving is that it changes the kind of cost: from a fee charged every time somebody uses the product, into a fixed cost on hardware we already own.

COST PER QUERY, DRAWN TO SCALE Four call chain $0.09 Klaussa-8B $0.0012 projected. That sliver is the whole second bar, at the same scale as the first. THE SAME NUMBERS AT 100,000 QUERIES A MONTH $9,000 becomes $120 which is the difference between a line item that ends the runway and one that does not.
Unit economics at true scale. The volume figure is an illustration at an assumed 100,000 queries per month, not a measured traffic number.

The model is a specialization of Meta’s Llama-3.1-8B-Instruct, trained in three stages on 1.27 billion tokens of Indonesian legal text, then scored against an internal benchmark built before the model existed. Stage one is scaffolded and has not completed a full run, so the cost figure above is arithmetic from measured pricing rather than something I have observed.

The rest of this page is the reasoning as it actually happened, including the part I got wrong.


Where it started, the bill

The project starts with a number rather than an idea.

Somebody asks whether a 2019 ministerial regulation still binds after a Constitutional Court ruling, and four separate calls go out: one to break the question into parts, one to find and rank the relevant regulations, one to draft an answer, one to walk every citation back to its source. Four billed requests, priced by the volume of text passing through them, and the meter resets on the next question.

I want to be fair to that design, because it was ours and it worked. Four narrow calls are debuggable in a way one wide call is not. Every intermediate result is text you can read. When an answer is wrong you know which step caused it. If you do not yet know what a good answer looks like in your domain, that visibility is worth paying real money for.

What made it untenable was not the size of the number. It was that the number is charged per unit of text, per call, again and again, and is immune to the engineering getting better. A small team, seed money, a runway that reaches four years only because everything else is fixed. This was the one cost that grew when things went well.

Deciding the cheap fixes were not enough

The first real decision was whether the easy optimizations were enough, and it took longer than it should have because the easy optimizations work a little.

Shorter prompts help. Caching retrieval helps. Merging the planner into the drafter helps. We did all of it, got a genuine discount, and at the end still had a cost proportional to usage that would stay that way no matter how good the system became.

That is the whole decision in one line: a discount changes the constant, and I needed to change the shape. Which means one model, running in-house, doing all four jobs on hardware already paid for.

BEFORE: one query, four API calls 1. Plan decompose the question 2. Retrieve, rank pick regulations 3. Draft compose the answer 4. Cite check verify each source $0.09 per query 4 x Gemini Flash, billed per token, every single time Klaussa-8B one weight set, all four steps, self hosted $0.0012 The projected unit cost falls by roughly 75x. Serving cost moves from per token to per GPU hour, which is the change that actually matters at a fixed monthly budget.
The four call chain collapsed into one model. Each box was a separate billed request; the replacement is a single forward pass on hardware already paid for.

The corpus, which is most of the work

This is the longest and least interesting stretch, and it is where the majority of the effort went.

An 8-billion-parameter instruct model does not know Indonesian regulation. It does not know that a ministerial regulation sits below a statute, or that a Constitutional Court ruling reaches back and changes what a statute has meant since it was written. You can put the hierarchy into an instruction and watch the model agree and then contradict itself two paragraphs later. The knowledge is not in there, and prompting does not put it there.

So: 1.27 billion tokens. Stratified extraction across more than 50,000 regulations, 3,800 Constitutional Court decisions, 5,000 Supreme Court decisions and 2,400 law journals. Scraping, cleaning, chunking on the model’s own tokenizer, publishing as training datasets. I built that pipeline end to end.

The volume figure is the part people quote, and it is the least interesting number here. What actually consumed the time is that a scraped regulation is mostly not the regulation. It arrives wrapped in navigation, page furniture, table markup and viewer scripts, and the useful text has to be separated from all of it before a token count means anything at all.

1. RAW SCRAPE <div class="isi-peraturan"> <p>&nbsp;</p><table border=0> PERATURAN MENTERI NOMOR ... <br/><span style="font:..."> Pasal 1 </td><td>&nbsp;&nbsp; Dalam Peraturan ini yang ... [halaman 3 dari 47] <footer> <script>pdfViewer.init() </div><!-- iklan --> 2. CLEANED PERATURAN MENTERI NOMOR ... TENTANG ... Pasal 1 Dalam Peraturan ini yang dimaksud dengan ... Pasal 2 (1) Setiap orang yang ... boilerplate, nav, page furniture and markup removed 3. CHUNKED ON THE TOKENIZER chunk 001 · 1,024 tokens chunk 002 · 1,024 tokens chunk 003 · 1,024 tokens ... boundaries respect Pasal breaks written out as HuggingFace datasets Repeated across every source, at these volumes 50,000+ regulations 3,800 Constitutional Court 5,000 Supreme Court 2,400 journals Stratified so the mix is not dominated by whichever source happened to scrape most easily. Total after cleaning: about 1.27 billion tokens.
What one document goes through. The scraped source is mostly page furniture; the useful text has to be separated from it before the volume figures mean anything.

No screenshot, no graph that goes up. I have come to think it is also the most durable output here. The model will be superseded within a year. A cleaned and legally stratified corpus of Indonesian law will not, and as far as I know nobody else has assembled one.

Teaching one model a four step procedure

With vocabulary in place, the next problem is format: getting one model to perform a sequence that four models used to perform between them.

I used Claude Opus, a far larger model, to generate three to five thousand worked examples of the four step process with its reasoning left visible, then trained the small model on those. The larger model demonstrates the procedure and the smaller one learns its shape.

PHASE STAGE 1 Continued pretraining 1.27B tokens of Indonesian law 50k+ regulations, 3.8k MK and 5k MA decisions, 2.4k journals STAGE 2 Supervised finetuning 3k to 5k tool call traces generated by Claude Opus, chain of thought retained STAGE 3 RLVR via GRPO reward = did the tool call actually execute and return the right regulation WHAT THE STAGE BUYS Vocabulary and priors It stops guessing at legal Indonesian Format and procedure It learns the shape of the four steps Grounding under pressure It is scored on execution, not on style Why the order is not negotiable Stage 2 teaches a format the model can only fill correctly if stage 1 gave it the vocabulary. Stage 3 can only reward a tool call that stage 2 taught it to emit at all.
The three stage recipe. The top row is what runs; the middle row is what each stage is actually purchasing; the bottom states why they cannot be reordered.

Worth naming why the order is fixed rather than convenient. Stage two teaches a format the model can only fill correctly if stage one gave it the words, and stage three can only reward a lookup that stage two taught it to emit. Getting this backwards produces a model that formats beautifully and says nothing true.

The honesty problem

The hardest part of the project, and the one I did not see coming.

Collapsing four calls into one destroys the property that made the original system trustworthy. In the chain, the retrieved regulations existed as plain text before anything was drafted. Fold it into a single forward pass and a fabricated citation comes out fluent, correctly formatted, in exactly the right register, and indistinguishable from a real one.

Cheap and confidently wrong is a worse product than expensive and checkable. If the project had no answer here it would deserve to be abandoned, and for something people might use to understand their legal obligations, that is not a rhetorical flourish.

The answer is that this domain permits a mechanical check. The final training stage uses reinforcement learning where the reward is whether the regulation lookup the model produced actually executed and actually returned the document it claimed to cite. No credit for sounding right. Either the retrieval ran and returned the correct regulation, or the reward is zero.

Above that sits KlaussaBench, three to five thousand Indonesian legal question and answer pairs built by a multi-agent pipeline running Claude Opus, Perplexity and NotebookLM against each other through the Claude Agent SDK, one group of agents generating candidate items and another verifying them. It was written before the model existed, so the standard was fixed by someone with nothing invested in where it landed.

What it runs on

LoRA and QLoRA adapters, mixed precision, gradient accumulation and checkpointing, data parallelism. Development on a single RTX PRO 6000, with the distributed run targeting a 16 GPU RTX 5090 cluster. Serving prototyped on Cloudflare Workers AI LoRA adapters and Modal serverless.

None of these techniques are novel, and that is the point. The interesting decisions on this project were about what to train and how to check it, not about the training loop.

Where the work currently stands

Stage one is scaffolded and has not completed a full run. Stages two and three are designed and unstarted. The seventy-five-fold reduction is arithmetic from measured pricing, not something I have watched happen. No post-training quality numbers appear on this page because none exist yet.

I am publishing at this point on purpose. A writeup produced after a successful run gets to arrange the evidence around the result, and every decision in it looks inevitable in hindsight. Written from here, the decisions are still bets: that continued pretraining is worth weeks with nothing to show, that a mechanical correctness check will hold up once the regulation index changes shape, that a small team should own model operations at all.

If any of those turn out wrong, this page should say so rather than quietly disappear.

What I would do differently

We built the four call chain first and only later asked what it cost per question. The honest sequence would have been to write down the unit economics on day one, because the answer changes which experiments are worth running.

A quality gain of two points is interesting. A quality gain of two points that costs nine cents a question is a different object entirely, and I did not have the language to tell them apart until the invoice made it obvious.