Skip to main content
This page helps you decide if you need Brussle. It compares Brussle with an AI column that you build in your own database.

An AI column in your own database

Your own database can already keep an AI answer in a column:
  1. A trigger runs when a record changes.
  2. A worker sends the record to an AI model.
  3. The worker writes the answer back to the column.
If the answer reads only its own record, this column is enough. Use it. Each answer costs less than in Brussle. In Brussle, a judgment is a column that an engine fills in. The engine is the AI model that makes the answers. A document is your copy of one record in Brussle.

Where that column breaks

Your database assumes that a computed value is instant, free and always the same. An AI answer takes seconds. It costs money each time. It changes when the AI model changes. Thus, an AI column breaks on four problems: You can build the four solutions yourself. For the first problem alone, you need a map of which records read which other records, a queue, a debounce for bursts of writes, a check that skips unchanged inputs, and a cap on cost. See the four problems.

Who Brussle is for

Brussle is for teams whose AI answers depend on more than one record and must stay correct. For example:
  • matching records to each other, such as a payment to the open invoice that it settles;
  • checking a record against the records that it must agree with;
  • detecting what changed, such as a contract section against its earlier revision;
  • keeping counts current that your process depends on.
The fit is strongest for teams that serve many customers of their own, and that do not have the people to build this system. Brussle is not for these cases:
  • one-off batch jobs;
  • answers that read one record;
  • teams that will build this system themselves.

What it costs

Each answer costs more than a direct call to an AI model. You pay for the work around the call: the relations, the freshness, the versions and the outcomes. If your answers do not have these four problems, call an AI model directly. See pricing.

Move a column across

These steps move an AI column whose answer reads other records. For example, a worker sends each new payment to an AI model, with the open invoices of the same customer. The model names the invoice that the payment settles. The worker writes the invoice’s id to a column.

1. Turn the prompt into a judgment

Most prompts match one of the judgment types: Then do these steps:
  1. Move the prompt’s instructions into question and criteria.
  2. Move the fields of the record that the prompt reads into a context recipe.
  3. Move the records that your worker fetched into a relation. For the payment, a blocking relation reads the open invoices that share the payment’s key. See match one record to another.
If your prompts sent the same record for several questions, make one judgment for each question, with one shared recipe. Brussle answers judgments that share a recipe together. In one request, the first question counts in full. Each question after the first costs a quarter of a judgment, and a quarter more for each further 500 tokens of question text. The engine cannot answer “none”. Instead, each choice judgment gets an extra option, none_of_the_above. Its probability is in escape_p. Use this option where your prompt said “otherwise, answer none”.

2. Mirror your writes

Send each create, update and delete from your system of record to the write API. Send the payments and the invoices to the same namespace. A relation reads only one namespace. After each change, upsert the whole record, as in keep your data in sync. Writes are idempotent. Thus, your sync can retry a write at any time. Your database stays your system of record. Brussle holds a copy. To load the records that you already have, see import existing data. Choose the freshness policy of each judgment:
  • If you filter on the answers, or a new invoice must change a payment’s answer, use on_change.
  • If you show the answer only on a detail page, you can use on_read. An on_read judgment costs nothing until someone reads the answer.

3. Backfill with the estimate in front of you

Your existing payments have no answers yet. A backfill judges them. Ask for the estimate of the backfill first:
The estimate shows the duration next to the cost. Engine rate limits can make a large backfill take days.
  1. Read the estimate.
  2. Set a namespace budget.
  3. Send the backfill again with confirm=True.

4. Compare the two columns side by side

  1. Run your AI column and Brussle side by side on live traffic.
  2. Find the payments where the two answers disagree.
  3. Open some of these payments in the dashboard. You see the exact context that the engine read, including the invoices, and its raw output.
  4. Post the match that your team confirms for each payment as an outcome. On the Team plan and above, an outcome rule can make these outcomes from your own writes.
  5. Change the thresholds before you change the question.
With 100 or more outcomes, 20 of each kind, the threshold recommender picks a threshold for a precision or recall target. The recommender is on the Team plan and above. Whether the answers are good enough on your data is yours to decide, from your outcomes.

5. Cut over, then keep versions apart

To cut over, read answers from queries or from a get of the document. Do not make a user’s request wait for a new answer. wait_for on a write is for scripts and tests. See tradeoffs. Then turn off the old column. From then on, each answer records its judgment_version and its engine_version. Brussle keeps each answer with the context that made it. When you change the question later, create a new version of the judgment:
  1. Activate the new version. Brussle starts a shadow report that compares the two versions on a sample of documents.
  2. Confirm once the report looks right.
  3. Run a backfill to judge the documents again. The backfill shows its cost before you confirm it.
Until Brussle judges a document again, its answer from the old version reads stale, with the reason older_version. A query with answers: "fresh_only" leaves it out. See versions.