Skip to main content
Choose the smallest extension point that expresses your policy.

Return a status-first result

For a Boolean policy, return Judgment.pass(reasoning), Judgment.fail(reasoning), or begin with Judgment.verdict(boolean) when you also need checks or metadata. Do not store 1.0 or 0.0 merely to repeat the status. For a real measurement, begin with Judgment.scored(normalizedScore) and finish by declaring the passing threshold. For a categorical policy, set an optional label in addition to the required status. Use Judgment.abstain(reasoning) when the judge is not applicable or lacks required evidence. Use Judgment.error(reasoning) when evaluation could not complete, and log the originating exception where it was caught.

Start with a lambda

The complete compiled lambda examples live in tutorial module 06. They cover a three-line file rule, a named wrapper, jury participation, and error conversion. A plain lambda has no discoverable identity. Wrap it with Judges.named when verdicts and logs need a stable name, description, and JudgeType.

Build a reusable deterministic judge

Extend DeterministicJudge when the rule has constructor configuration, helper methods, or granular checks. Its constructor supplies JudgeMetadata; the subclass implements only judge(JudgmentContext). PackageStructureJudge.java is the canonical compiled example. It resolves paths from the context workspace, records three Check values, derives the overall status with Judgment.verdict, and converts file-reading failures to a reasoned ERROR.

Compose a model-backed judge

ModelBackedJudge keeps three concerns independent.
  1. JudgePromptTemplate renders evaluation inputs from a context.
  2. JudgeModel invokes a backend.
  3. JudgmentClassifier converts the response into a normalized judgment.
ModelBackedJudgeDemo.java compiles and runs this pipeline with a stub model. Production adapters include SpringAiJudgeModel and AgentClientJudgeModel. LabelJudgmentClassifier requires an explicit label-to-status policy. Assign a normalized score only when the label policy genuinely declares a measurement. Unknown labels produce a reasoned ABSTAIN with the raw judge output in metadata and neither a label nor a score.

Keep metadata portable

Judgment metadata may contain only portable primitives, arrays, and string-keyed objects. Convert SDK objects to stable fields before attaching them. Keep live exceptions and framework-native objects in logs or JudgmentContext, not in the result.

Test all outcome paths

A custom judge test should cover at least its passing, failing, abstaining, and error paths when those paths exist. Assert the status first, then assert optional score, label, checks, reasoning, and portable metadata that the policy intentionally produces.