windlass.interfaces.guardrail¶
guardrail
¶
The guardrail interface.
Guardrails inspect what goes into a model and what comes out. Windlass runs them
at two points — input before the prompt is sent, output before the
answer is returned — and lets each guardrail decide between three verdicts:
- allow — nothing objectionable found.
- redact — rewrite the content (mask a credit card, strip a name) and continue. This is the default for PII.
- block — refuse. Raises :class:
~windlass.core.exceptions.GuardrailViolationunless the pipeline was told to return a refusal message instead.
Implementers override one coroutine, :meth:Guardrail.acheck.
Example
from windlass.providers.guardrails.rules import RuleGuardrail g = RuleGuardrail(pii=True, on_violation="redact") g.check("mail me at a@b.com").content 'mail me at [EMAIL]'
Guardrail
¶
Guardrail(
*,
on_violation: str = "block",
stages: tuple[str, ...] = ("input", "output"),
name: str | None = None,
**config: Any
)
Bases: Component
Abstract input/output safety check.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
on_violation
|
str
|
One of |
'block'
|
stages
|
tuple[str, ...]
|
Which stages this guardrail runs at — any of |
('input', 'output')
|
name
|
str | None
|
Component name for traces. |
None
|
**config
|
Any
|
Policy-specific options. |
{}
|
Attributes:
| Name | Type | Description |
|---|---|---|
on_violation |
The configured action. |
|
stages |
The stages this guardrail participates in. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
Implementing a guardrail takes one method::
class NoShouting(Guardrail):
provider_name = "no_shouting"
async def acheck(self, content, *, stage="input", context=None):
if content.isupper():
return GuardrailResult(
allowed=False, content=content,
rule="shouting", stage=stage,
)
return GuardrailResult(allowed=True, content=content, stage=stage)
Source code in src\windlass\interfaces\guardrail.py
acheck
abstractmethod
async
¶
acheck(
content: str, *, stage: str = "input", context: dict[str, Any] | None = None
) -> GuardrailResult
Inspect content and return a verdict.
Implementations should report what they found and leave the policy
decision to :attr:on_violation — that keeps one detector usable in
both blocking and redacting configurations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
str
|
The text to inspect. |
required |
stage
|
str
|
|
'input'
|
context
|
dict[str, Any] | None
|
Extra signals — retrieved chunks, the user id, the tool about to be called. |
None
|
Returns:
| Type | Description |
|---|---|
GuardrailResult
|
The verdict, with |
Source code in src\windlass\interfaces\guardrail.py
avalidate
async
¶
Check content and apply the configured policy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
str
|
The text to check. |
required |
stage
|
str
|
|
'input'
|
context
|
dict[str, Any] | None
|
Extra signals for the check. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The content to use downstream — unchanged, or redacted. |
Raises:
| Type | Description |
|---|---|
GuardrailViolation
|
When a rule fires and |
Example
import asyncio from windlass.providers.guardrails.rules import RuleGuardrail g = RuleGuardrail(banned_words=["secret"], on_violation="redact") asyncio.run(g.avalidate("the secret plan")) 'the [REDACTED] plan'
Source code in src\windlass\interfaces\guardrail.py
validate
¶
Blocking :meth:avalidate.
check
¶
check(
content: str, *, stage: str = "input", context: dict[str, Any] | None = None
) -> GuardrailResult
Blocking :meth:acheck — returns the verdict without enforcing it.
Source code in src\windlass\interfaces\guardrail.py
GuardrailChain
¶
Bases: Guardrail
Runs several guardrails in order, threading redactions through.
Each guardrail sees whatever the previous one produced, so a PII redactor followed by an injection detector inspects the already-masked text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
guards
|
list[Guardrail] | None
|
The guardrails to run. |
None
|
name
|
str | None
|
Component name for traces. |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
guards |
list[Guardrail]
|
The configured guardrails. |
Example
from windlass.providers.guardrails.rules import RuleGuardrail chain = RuleGuardrail(pii=True, on_violation="redact") & RuleGuardrail( ... banned_words=["nope"], on_violation="redact" ... ) chain.validate("a@b.com says nope") '[EMAIL] says [REDACTED]'
Source code in src\windlass\interfaces\guardrail.py
add
¶
acheck
async
¶
acheck(
content: str, *, stage: str = "input", context: dict[str, Any] | None = None
) -> GuardrailResult
Aggregate every child's detections without enforcing them.
Source code in src\windlass\interfaces\guardrail.py
avalidate
async
¶
Run every guardrail's own policy in sequence.