An LLM-as-Judge guardrail that rates whether content is supported by a reference text, typically the documents a RAG answer was built from.
What it evaluates: the judge is given referenceContext and asked to rate the content's factual claims against it: 1.0 when all claims are supported by the context, 0.5 when some are supported and others cannot be verified, 0.0 when claims directly contradict it. It is told to evaluate factual claims only and to ignore stylistic differences. It checks the content against the text you supply, not against the world: by the prompt's rubric a claim the context does not mention is one that "cannot be verified", not one that contradicts it. The rubric gives such claims the middle score only beside supported ones; for content none of whose claims the context supports it names no score, so the judge may rate it anywhere below 1.0, and a lenient threshold such as 0.5 does not reliably pass it.
When to use it: to catch answers that drift from retrieved documents. No rule-based guardrail can compare meaning with a source text. The RAG-specific guardrails in org.llm4s.agent.guardrails.rag are the alternative to look at first for retrieval pipelines.
Cost and side: every validation makes one extra llmClient.complete call whose prompt contains the whole of referenceContext as well as the content, so cost and latency grow with the context size, and both go to the provider of llmClient. It is an output guardrail only. The scoring rules and the other limits are described on org.llm4s.agent.guardrails.LLMGuardrail.
One context per instance:referenceContext is fixed when the guardrail is built. A guardrail built once for an agent judges every later answer against that same text, so build a new one when the context changes (for example per retrieval). Its description embeds the first 50 characters of the context followed by ..., so keep secrets out of the start of the context.
Failure:Left with a org.llm4s.error.ValidationError on field output, for example LLM judge score (0.40) below threshold (0.70) for LLMFactualityGuardrail. It does not quote the unsupported claim. An unreadable reply or a failing llmClient is a Left too, never a pass.
Value parameters
llmClient
the client that makes the judge call; it can be the agent's own or a separate model
referenceContext
the text the content is checked against; it is inserted into the prompt as is
threshold
the lowest score that passes (a score equal to it passes), between 0.0 and 1.0 or validate fails; default 0.7
Attributes
Example
import org.llm4s.agent.Agent
import org.llm4s.agent.graph.middleware.GuardrailMiddleware
import org.llm4s.agent.guardrails.builtin.LLMFactualityGuardrail
val context = "Paris is the capital of France. It has a population of 2.1 million."
val guardrail = LLMFactualityGuardrail(client, context, threshold = 0.8)
val agent = Agent
.builder("assistant", client)
.withMiddleware(new GuardrailMiddleware(Nil, Seq(guardrail)))
.build()
The options of the judge call. The default is temperature 0.0, which makes the judge as repeatable as the model allows, and a maximum of 10 tokens, enough for a bare number. Override to give a judge model more room or to set other options.
The options of the judge call. The default is temperature 0.0, which makes the judge as repeatable as the model allows, and a maximum of 10 tokens, enough for a bare number. Override to give a judge model more room or to set other options.
Judges value with one LLM call and compares the score with threshold.
Judges value with one LLM call and compares the score with threshold.
Value parameters
value
the text to judge, typically the agent's final answer
Attributes
Returns
Right(value) unchanged when the score reaches the threshold; otherwise Left: a org.llm4s.error.ValidationError on field threshold when the threshold is not between 0.0 and 1.0 (no judge call is made), on field output when the score is too low, on field llm_response when the reply has no readable score, or the client's own error when the call fails
The evaluation criteria in natural language. It is sent after Evaluation criteria: and before the content, which goes between triple quotes. The fixed system message already asks for a bare number between 0 and 1; say in the criteria what 0 and 1 mean, because a reply on any other scale is refused as unreadable and fails the guardrail (see the scoring notes on the trait).
The evaluation criteria in natural language. It is sent after Evaluation criteria: and before the content, which goes between triple quotes. The fixed system message already asks for a bare number between 0 and 1; say in the criteria what 0 and 1 mean, because a reply on any other scale is refused as unreadable and fails the guardrail (see the scoring notes on the trait).
Attributes
Example
"Rate if this response is professional in tone. Return only a number between 0 and 1."
The client that makes the judge call. It can be the agent's own client or a different one; a separate, cheaper model is a common choice. Every validation makes one blocking complete call on it.
The client that makes the judge call. It can be the agent's own client or a different one; a separate, cheaper model is a common choice. Every validation makes one blocking complete call on it.
The lowest score that passes (a score equal to it passes). The default is 0.7. It must be between 0.0 and 1.0, both included: validate returns a org.llm4s.error.ValidationError on field threshold, without calling the judge, for a value outside that range (including infinities) or NaN. It is checked when validate runs, not when the guardrail is built, so the constructors and factories keep their signatures and a subclass that overrides it is checked too. A threshold of 0.0 passes every reply that parses as a score. It is not a probability or a confidence: it is a cut-off on whatever number the judge returns.
The lowest score that passes (a score equal to it passes). The default is 0.7. It must be between 0.0 and 1.0, both included: validate returns a org.llm4s.error.ValidationError on field threshold, without calling the judge, for a value outside that range (including infinities) or NaN. It is checked when validate runs, not when the guardrail is built, so the constructors and factories keep their signatures and a subclass that overrides it is checked too. A threshold of 0.0 passes every reply that parses as a score. It is not a probability or a confidence: it is a cut-off on whatever number the judge returns.