When splitting helps
We tested splitting on two human-labelled datasets. Every number below is accuracy on held-out documents, half of them positive.- On clickbait, splitting helped. Every split set beat the tuned single question. The best sets asked whether the post states the news, where a yes means “not clickbait”, the half of the definition the single question left implicit. The one LLM-proposed set without that question scored lowest. With 50 labels, the combiner got within about 2 points of what 1,000 labels gave.
- On argument quality, it did not. No split set did better than the tuned single question. Every part measured much the same thing as the question itself, so combining them added nothing. What helped was fitting the cut-off: it lifted the single question from 61.1% to 67.8%, a gain of 6.7 points. The split sets also needed about 300 labels just to match the single question.
Try the threshold recommender first
On argument quality, fitting the cut-off was worth more than any split, and it is cheaper. It costs nothing per document, needs no new version, and takes one call. If your judgment has outcomes, pick a threshold with the recommender first. Reach for a composite when a well-chosen threshold still gets too many documents wrong.Define the parts
A composite is abool judgment with parts. Post it like any other definition. On an existing name it is version n+1:
- 2 to 8 parts, each a narrow yes/no question with a name unique within the judgment.
- Parts share the judgment’s context recipe and engine. On Jev they go in one request with the judgment’s other questions, and each part counts toward the engine’s limit of questions per request.
questionis not sent to the engine. It documents what the combination means. The engine is asked the parts.- Parts are part of the version. Changing one creates a new version, like any other change to the definition.
- One level only. A part is a question, never another judgment, so composites never nest.
- Only
bool. There are no compositechoiceorscorejudgments, and all parts use the same context recipe.
Activate it, measured on your labels
A composite version is never active when it is created, not even as a judgment’s first version, andactivate: true is refused with invalid_request. It cannot answer until its combiner is fitted on your labels. Post labelled examples for the judgment, then activate the version with POST /namespaces/{ns}/judgments/clickbait/activate:
202 with a shadow job in awaiting_confirm, even with force: true: a composite cannot answer without a combiner, so there is nothing to skip to. The job:
- Judges up to 1,000 documents that have outcomes for this judgment, asking each part.
- Fits the combiner with 5-fold cross-validation, so every document is scored by a fit that never saw its label.
- Scores a baseline the same way: the active version, or for a first version the composite’s
questionasked on its own. The baseline’s cut-off is fitted by the same folds on the same labels, never left at 0.5, so splitting gets no credit for what a fitted threshold alone would give.
report compares them. For the two-part first version of clickbait above:
compositeandbaselinegive the cross-validated accuracy with its 95% interval, and the ROC AUC.baseline.thresholdis the cut-off fitted for it.differenceis the composite’s accuracy minus the baseline’s, with its 95% interval over the same documents.verdictisbetteronly when the composite beats the baseline by more than that interval. Otherwise it isnot_better, and the threshold recommender on the baseline is the cheaper fix.partsgives each part’s weight in the combiner fitted on all the documents, on a common scale, so sizes compare. A negative weight means a yes points tofalse. A part with a weight near 0 adds cost and little else.recomputeestimates backfilling every document under the new version. Each part is billed as a judgment, so it is several times a single question’s estimate.
type, so "type" in report tells it apart from the report of an ordinary version change:
POST /jobs/{id}/confirm activates the version with the combiner fitted on all the labelled documents, whatever the verdict. POST /jobs/{id}/cancel leaves the active version as it is. The shadow job is free.
Labels. The job needs at least 50 labelled documents, and at least 10 of each answer. With fewer it fails: status is failed, and error starts with insufficient_labels. Post more labels and activate again.
Answers
A composite’s answer hasp, the combined probability, and parts, each part’s raw p from the engine:
- There is no
calibratedobject. The combiner is already fitted to your outcomes, so there is nothing left to calibrate. combinersays whatpcame from:outcomes, the labelled documents it was fitted on, andfrom_previous_epoch.- The combiner is fitted per version and per engine epoch, and refitted nightly along with calibration. After a Jev drift, answers under the new epoch use the previous epoch’s combiner, marked
"from_previous_epoch": true, until the new epoch has 50 outcomes, at least 10 of each answer, and the nightly refit has run. - The calibration report measures the combined
pper epoch. For a composite,method,fitted_atandcalibratedarenull, because there is nothing to calibrate.
p; the combined p is computed when the answer is read. To see what the engine returned, and how long it took, read the evaluation by its id:
Thresholds, filters and ranking
Everything that readsp reads the combined p: thresholds, filters such as ["answers.clickbait.p", "Gte", 0.8], rank_by, and threshold recommendations. A part’s p is in the answer for you to read, but you cannot filter or rank on it.
Suggested parts
Vainona can ask a general-purpose LLM to propose parts from your labelled examples. On clickbait, LLM-proposed sets scored between 75% and 81%, above the hand-written set’s 73.3%, but on argument quality they did no better than one question. A suggestion is a starting point for a composite, not a sign that one will help. It is off by default, because it sends your labelled examples to an LLM provider, which is then a subprocessor, listed in the data processing agreement. An org admin turns on Suggestions in the organization’s settings in the dashboard. Until then the call is refused withforbidden.
POST /namespaces/{ns}/judgments/{name}/suggest_parts with the number of parts to propose, 2 to 8:
- What the LLM sees: the judgment’s
questionandcriteriafrom its newest version, and up to 30 of the namespace’s labelled examples for the judgment, balanced betweentrueandfalseand compiled with the judgment’s context recipe.exampleslists the documents it saw. - It never creates a version. Review the parts, edit or drop any, then post a new version with them.
partshas the shape a definition’spartstakes. - It needs labels: at least 10 labelled examples of each answer, or it is refused with
insufficient_labels. - It is free, and limited to 20 calls per judgment and 50 per organization a day (
rate_limited, withdetails.limit, the limit reached, 20 or 50, anddetails.resets_at, the next midnight UTC). Each call shows the LLM at most 100,000 tokens of examples, so long documents are cut. When the LLM is unavailable it returnsengine_unavailablewithRetry-After, which the SDKs wait out and retry. A call that fails this way before the LLM ran does not count toward the day’s calls; one that timed out, or failed after the LLM replied, does.