Skip to main content
A judgment’s context recipe decides which parts of a document the engine sees. Judging is billed in judgment units, one per started 1,000 tokens of compiled context and question together, so the recipe is your biggest lever on cost. It is also a lever on accuracy: an engine given the last three messages and the plan often does better than one given a year of history.
Leaving out context sends the whole state, up to the engine’s limit. That is allowed but not recommended, and creating such a judgment returns a warning. A recipe decides what the engine sees of a document. Which documents a judgment judges at all is applies_to, beside the recipe: {"attributes.kind": "account"} judges, answers and bills only accounts. Each key is an attribute; a value is equality, and a list of values matches any of them. Keys combine with and, up to 8. Other documents have no answer for the judgment. applies_to is part of the definition, so changing it creates a version.

Context size is the cost

Each judgment answered costs one judgment unit per started 1,000 tokens of its compiled context and its question together: 1 unit up to 1,000 tokens, 2 units up to 2,000, and so on, whichever engine answers. The question counts as the engine reads it, with its criteria and every option’s description, so a choice between many long-described options costs more than a yes/no question over the same context. It costs that again every time the document changes. For one judgment whose context and question come to 2,000 tokens: Pricing has the price per unit, which falls as your organization’s monthly volume grows. A recipe that sends the last three messages and the plan, under 1,000 tokens, instead of a 6,000-token history cuts each judgment from 6 units to 1.

Share recipes where you can

All of a document’s judgments that use the same recipe go to the engine in one request, with up to 32 questions. The context is sent once, which makes them faster and lighter on the engine’s rate limit, and that matters most for large backfills. Each judgment answered is still billed as its own units. Each distinct recipe is its own request. Before you give a new judgment its own recipe, check whether one you already have would do. related lets a judgment read the documents that point at the judged one: an account’s tickets and invoices, a user’s posts. The answer is kept current as any of those documents change: see judge a document with its related documents. Start with a small last_n of raw text, or with aggregates; that guide shows what each did in our tests.
  • Up to 4 relations, each with fields, aggregate or both, and each reading the documents that point at the judged one with last_n, window or both.
  • Newest created first. The documents are ordered by created_at, so last_n: 8 is the 8 most recently created. window applies first, then last_n. A relation reads at most the newest 1,000.
  • Aggregates count the relation’s selection. count is how many it selected. sum, min and max skip values that are not numbers; sum of nothing is 0, and min and max of nothing are null. latest is the value in the newest document that has one. To show a few documents and count many, use two relations with the same match.
  • Relations stay in the namespace. A document and everything related to it live in the same namespace.
Each relation becomes one related.<name> entry in the compiled context, after the fields entries. It holds records, the selected documents newest first, keyed by path; one key per aggregate, such as count and sum(state.amount); and capped: true when more than 1,000 documents matched, so the numbers cover only the newest 1,000 (only a relation without last_n can match that many):
Over max_tokens, the compiler drops the last relation’s oldest records first, then the previous relation’s, and only then the fields. Relations are rendered, and cut, in the order of their names. Aggregates are computed before truncation and are never cut. An aggregate is a few tokens where raw text is hundreds, so it is the first thing to try when a question depends on volume rather than wording.

The document the judged one points at

With join: {"theirs": "id", "mine": "attributes.<name>"}, a relation reads the one document whose id the judged document’s own attribute holds: its referenced document. Illustrations across domains: an order line reading its product, a message reading its conversation. Here each item points at its group:
It renders like any relation, with at most one record, so it takes neither last_n nor window. When the attribute is missing, is not a document id, or names a document that does not match match, the relation is empty. A change to what it shows of the referenced document re-judges the judged documents that point at it and are inside the judgment’s re-judge scope, which the judgment’s freshness.fanout settings decide. See judge a document with the document it points at for what that costs and the controls, and fan-out for the settings.

Bands

An entry of a relation’s fields can be an object that shows a number as the band it falls in, rather than the number:
  • bands are 1 to 9 cut points, strictly increasing, and labels has exactly one more entry, each up to 64 bytes.
  • A number renders as the label whose position is how many cut points are at or below it: 0.29 is low, 0.3 is medium, and 0.7 or more is high.
  • A value that is not a number renders unchanged, and a missing one is left out, as for any path.
  • Aggregates always use the raw values.
The engine sees the word, and a move inside a band leaves the context exactly as it was. In a relation that reads the documents pointing at the judged one, that means the answer is kept and nothing is billed. In a relation that reads the document the judged one points at, it means no fan-out at all. Use bands for a number that moves often but matters only past a few thresholds.

Check what the engine saw

Every evaluation stores its compiled context. Fetch it with include=history,context on a get, or open the document in the dashboard, to see the exact text the engine received. context_tokens and context_truncated on each evaluation tell you how close a recipe runs to its cap.

Engine limits

The recipe must fit the engine you pin. Jev takes up to 32,000 tokens for the state plus the longest question. Laya, which is coming, will take at most 512 tokens in total and cut a longer context to fit, so it suits short text such as titles, single messages or search queries. See limits and the engines.