org.llm4s.agent.guardrails
Members list
Packages
Type members
Classlikes
Combines multiple guardrails with configurable validation mode.
Combines multiple guardrails with configurable validation mode.
Supports three modes:
- All: All guardrails must pass (strictest)
- Any: At least one guardrail must pass (OR logic)
- First: First result wins (performance optimization)
Type parameters
- A
-
The type of value to validate
Value parameters
- guardrails
-
The guardrails to combine
- mode
-
How to combine validation results
Attributes
- Companion
- object
- Supertypes
Attributes
- Companion
- class
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
CompositeGuardrail.type
Base trait for all guardrails.
Base trait for all guardrails.
A guardrail is a pure function that validates a value of type A. Guardrails are used to validate inputs before agent processing and outputs before returning results to users.
Type parameters
- A
-
The type of value to validate
Attributes
- Supertypes
-
class Objecttrait Matchableclass Any
- Known subtypes
-
class CompositeGuardrail[A]trait InputGuardrailclass LengthCheckclass PIIDetectorclass PIIMaskerclass ProfanityFilterclass PromptInjectionDetectorclass RegexValidatorclass SecretLeakGuardrailclass TopicBoundaryGuardrailtrait OutputGuardrailclass JSONValidatorclass ToneValidatortrait RAGGuardrailclass GroundingGuardrailtrait LLMGuardrailclass LLMFactualityGuardrailclass LLMQualityGuardrailclass LLMSafetyGuardrailclass LLMToneGuardrailShow all
Actions to take when a guardrail detects a violation.
Actions to take when a guardrail detects a violation.
Guardrails can be configured to respond to violations in different ways depending on the use case and severity of the detected issue.
Example usage:
// Block on prompt injection (security critical)
val injectionGuard = PromptInjectionDetector(onFail = GuardrailAction.Block)
// Fix PII by masking (privacy preserving)
val piiGuard = PIIDetector(onFail = GuardrailAction.Fix)
// Warn on low-severity issues (monitoring)
val lengthGuard = LengthCheck(1, 10000, onFail = GuardrailAction.Warn)
Attributes
- Companion
- object
- Supertypes
-
class Objecttrait Matchableclass Any
- Known subtypes
Attributes
- Companion
- trait
- Supertypes
-
trait Sumtrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
GuardrailAction.type
Result of a guardrail check with action handling.
Result of a guardrail check with action handling.
Extends the basic Result type with information about what action was taken and any warnings that were logged.
Attributes
- Companion
- object
- Supertypes
-
class Objecttrait Matchableclass Any
- Known subtypes
Attributes
- Companion
- trait
- Supertypes
-
trait Sumtrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
GuardrailResult.type
Validates user input before agent processing.
Validates user input before agent processing.
Input guardrails run BEFORE the LLM is called, validating:
- User queries
- System prompts
- Tool arguments
Attributes
- Companion
- object
- Supertypes
- Known subtypes
-
class LengthCheckclass PIIDetectorclass PIIMaskerclass ProfanityFilterclass PromptInjectionDetectorclass RegexValidatorclass SecretLeakGuardrailclass TopicBoundaryGuardrailShow all
Attributes
- Companion
- trait
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
InputGuardrail.type
Base trait for LLM-based guardrails (the LLM-as-Judge pattern).
Base trait for LLM-based guardrails (the LLM-as-Judge pattern).
A judge guardrail asks a language model to rate the content against natural-language criteria and passes the content when the rating reaches a threshold. It suits subjective qualities (tone, factual support, safety in context) that deterministic rules cannot express. For plain word, pattern or length checks prefer the rule-based guardrails (ProfanityFilter, RegexValidator, PIIDetector, LengthCheck): they are free, instant and repeatable.
Side: output only. LLMGuardrail extends OutputGuardrail and not InputGuardrail, so it belongs in the output list of a GuardrailMiddleware, where it judges the agent's final answer.
What one validation does: exactly one synchronous llmClient.complete call, made on the calling thread even when the content is empty. The request holds two messages:
- a fixed system message that asks for a bare number between 0 and 1;
- a user message made of
evaluationPromptand the content between triple quotes.
Cost, latency and privacy: every validation adds one llmClient.complete call to the run. With a plain provider client that is one round trip and its token cost; a wrapping client changes the count - CachingLLMClient first embeds the system and user messages (an embedding request that sends the judged content to its embedding provider, hit or miss) and on a cache hit skips only the completion request, and ReliableClient can retry a failed request or reject the call with its circuit breaker open. Either way these guardrails do not belong on latency-sensitive paths. The content being judged is sent to whichever provider llmClient talks to, including any embedding provider a caching wrapper uses. A cheaper or separate model can serve as judge, which also avoids a model grading its own answer.
Scoring: a reply is a score only when the whole reply is one plain decimal number from 0 to 1, optionally labelled Score:, and the content passes when the score reaches threshold (a score equal to the threshold passes). Any other reply is refused as unreadable and fails the guardrail; a number is never clamped into range, because a clamped value would read as 1.0 for the usual mistakes (a 0 to 100 answer, a fraction, a percentage) and approve the content. The rules, in full:
- Accepted:
0.9,.5,0,1,1.0, with surrounding whitespace or a trailing newline, with markdown emphasis, quotes, brackets or code-fence backticks before or after the number (**0.9**,"0.9",```0.9```), and with aScore:label in any case before it (Score: 0.9,score:0.9,**Score:** 0.9). The wrapping characters before and after the number are read independently and need not match or balance, so((0.9and0.9 *are accepted too; they carry no meaning either way. - Refused, as unreadable: everything else. That includes a number outside 0 to 1 (
85,1.5); a sign, glued or apart (-0.5,- 1,negative 1,+0.5); a percentage, fraction, exponent or any scale, as a sign or in words (85%,1 %,1 percent,1 per ten thousand,100 bps,8/10,0.7 out of 1,1e-3); a decimal comma (0,9); a trailing full stop (0.85.); any other label or sentence (Rating: 0.9,The score is 0.9,0.9, because ...); more than one number; and a reply with no number. The grammar lists what is accepted rather than what is refused, so a scale or sign written in a form no one anticipated is refused too. - The edges of the grammar: the label is strict, so emphasis may wrap
Score:as a whole (**Score:** 0.9) but not split it (**Score**: 0.9is refused); a code fence is accepted only bare, so a fence with a language tag (textafter the opening backticks, on the line before0.7) is refused, the tag being a word the grammar does not admit; and the number is at most 64 characters, so a reply of thousands of digits is refused before it is parsed. - The score is compared at the precision the judge wrote it, and the threshold as the decimal it is written as:
1.0000000000000001is out of range, and0.79999999999999999does not reach a threshold of 0.8, though both would round to the bound as aDouble. - The judge is not asked to be lenient: the fixed system message asks for only a number between 0 and 1. Before this rule the reply was reduced to its digits and dots and clamped, so
85,85%,8/10,1e-3and0,9all read as 1.0 and passed any threshold up to 1.0, and0.7 out of 1read as 0.71.
Failures are always Left; an error never lets content through:
- A threshold outside 0.0 to 1.0, or NaN: a org.llm4s.error.ValidationError on field
threshold, before any judge call:LLM judge threshold must be between 0.0 and 1.0, got <value> for <name>. - Below the threshold: a
ValidationErroron fieldoutputwhose message names this guardrail, the score and the threshold to two decimals:LLM judge score (0.40) below threshold (0.70) for <name>. It does not say why the judge scored the content low. Because of the rounding, a score of 0.69999 against a threshold of 0.7 reads0.70 below 0.70. - An unreadable reply: a
ValidationErroron fieldllm_responsethat quotes the reply. - A failing
llmClient.complete(network, rate limit, authentication): the client's own error, returned unchanged.
Inside an agent run a failing guardrail blocks the run: GuardrailMiddleware reports the name of the first failing guardrail together with the failure messages.
Limits: validate is not pure here, unlike the contract of Guardrail: it performs a network call, and the same content can score differently between calls (the default temperature of 0.0 reduces this but does not remove it). The content is inserted into the prompt as is, without escaping, so text inside it that addresses the judge can sway the score: treat the result as a probabilistic filter, not a security boundary. threshold must be between 0.0 and 1.0: any other value, or NaN, makes validate fail before the judge is called (see threshold). A threshold of 0.0 is accepted and passes every reply that parses as a score.
@note The default completionOptions cap the judge's reply at 10 tokens. Override them if your judge model needs more room than a bare number.
@example
class MyCustomLLMGuardrail(client: LLMClient) extends LLMGuardrail {
val llmClient = client
val evaluationPrompt = "Rate if this response is helpful (0-1)"
override val threshold = 0.7
val name = "HelpfulnessGuardrail"
}
Attributes
- Companion
- object
- Supertypes
- Known subtypes
-
class LLMFactualityGuardrailclass LLMQualityGuardrailclass LLMSafetyGuardrailclass LLMToneGuardrail
Attributes
- Companion
- trait
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
LLMGuardrail.type
Validates agent output before returning to user.
Validates agent output before returning to user.
Output guardrails run AFTER the LLM responds, validating:
- Assistant messages
- Tool results
- Final responses
Attributes
- Companion
- object
- Supertypes
- Known subtypes
-
class JSONValidatorclass LengthCheckclass PIIDetectorclass PIIMaskerclass ProfanityFilterclass RegexValidatorclass SecretLeakGuardrailclass ToneValidatortrait RAGGuardrailclass GroundingGuardrailtrait LLMGuardrailclass LLMFactualityGuardrailclass LLMQualityGuardrailclass LLMSafetyGuardrailclass LLMToneGuardrailShow all
Attributes
- Companion
- trait
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
OutputGuardrail.type
Mode for combining multiple guardrails.
Attributes
- Companion
- trait
- Supertypes
-
trait Sumtrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
ValidationMode.type