Core Concepts (v2, Beta)
A short mental model for the v2 API. Five ideas explain almost everything else: evidence vs population, values vs features, links, calibrated probability, and explanations. The queries in the Use Cases all rest on these.
Rows, fields, and collections
Data lives in collections (v2 tables). A collection has typed fields
(Text, String, Int, Decimal, Boolean, String[]/Set, Link,
Vector). A field's type decides how it's treated in inference โ a Text field
is tokenized and BM25-searchable; a Decimal bins into a numeric prior; a Link
resolves to another collection's row. See Schema Design.
Evidence vs population
This is the distinction that makes inference correct rather than approximate.
- Evidence โ the
wherein an inference query. It's what you know about the thing you're asking about ("this invoice's description is 'cloud services'"). Evidence conditions the probabilities. - Population โ who is being compared. By default it's the whole
collection; a nested
fromrestricts it:
{ "from": { "from": "prompts", "where": { "type": "question" } },
"where": { "prompt": { "$match": "how do I return my order" } },
"predict": "answer" }
The nested from masks the population to answered questions, so base rates and
candidate sets are computed over that subset โ the same mechanism that scopes a
multi-tenant model per client. The outer where is still just evidence. Keeping
these separate is what lets one query be both per-tenant and conditioned on the
incoming record.
Values vs features
A prediction ranks candidate values of a field, but it reasons over features.
predict "tags"scores whole tag-sets exclusively;predict "tags.$feature"scores each member label independently (multi-label). The target picks the mode โ there's no flag to misconfigure.- Candidates are values, not rows: a category that appears on a thousand rows is one candidate with the aggregated probability, not a thousand near-duplicate hits. (This is an intentional v2 improvement over v1.)
Links
A Link field is a typed foreign key to another collection. You traverse it with
dot notation in where, select, and predict:
{ "from": "impressions", "where": { "context.user": "larry" },
"get": "product", "select": ["name"] }
context.user walks impression โ context โ user as declared in the schema โ no
join to spell out. On a get/predict over a link, the target row's columns
are selectable (each candidate product resolves its own name).
Probability is calibrated
_predict returns $p as a calibrated probability, not a raw score. E002
at 0.85 means that among cases the model calls 85%, about 85% are right โ so a
threshold like $p > 0.9 โ auto-post behaves the way the number says. This is
what makes "auto-act on the confident ones, queue the rest" a safe policy rather
than a guess.
A related consequence: if a target has many values but only a few examples each
and only diffuse signal, _predict returns a near-uniform distribution rather
than a falsely confident guess โ it declines to overfit. For that shape, retrieve
with ranked _search instead (see Common Errors).
Explanations โ $why
Add "$why" to a prediction's select and each candidate carries a factor
tree: the base rate, calibration, and the lift each piece of evidence
contributed. It's the difference between "the model said so" and an auditable
suggestion โ and the evidence propositions are reusable verbatim as a where to
drill into the supporting rows. See Inference.
Fail-loud
v2 turns ambiguous conditions into typed 4xxs with a message, never a
silent empty result โ an unsupported operator, an unknown config profile, a
missing test set all say so, because an empty result is indistinguishable from
"no match" and hides the real problem. When something's off, read the message;
Common Errors maps the frequent ones.
Related: Quickstart ยท Query Reference ยท Inference ยท Which Query Type?