All three run deterministic evaluators only, synchronously, on the hot
path. LLM judges belong in
EvalSuite
and the CI gate.
sengol.instrument()
- Runs
pre_evaluatorson the prompt (default[PIIEvaluator()]). A CRITICAL failure blocks the call before it reaches the model. - Runs
post_evaluatorson the response (default none). Any failure blocks. - Raises
BlockedError; readexc.failure_mode. - Runs
observe_evaluators(default none) afterpost_evaluatorson every call that gets a response. They must beDeterministicEvaluatorinstances with a declaredversion. Their scores go on the call’s record, never block, and never changeoverall_passed. deployment_environment(orSENGOL_DEPLOYMENT_ENVIRONMENT) labels every record the process signs. It must match[a-z0-9_-]{1,40}.- Streams are buffered in full before the post-check runs.
- If the appliance cannot accept the record, the call is refused with
EVIDENCE_UNWRITABLE(on_evidence_failure="refuse", the default).
GuardrailRuntime
Wrap any function that takes a prompt and returns a response. The policy’s
on_failure mode decides what the caller receives:
guard.py
response=""is required on the input; the runtime fills it from your function.- Pre-evaluators score the input exactly as given.
PIIEvaluatorreads theresponsefield, so put it inpost_evaluatorsto check the agent’s answer. - A pre-evaluator failure under
retryis treated asblock. - Each call writes one record. Its last score, from
GuardrailRuntime, names the outcome:GUARDRAIL_BLOCKED,FALLBACK_USED,RETRY_EXHAUSTED, or none when the response passed.
InlineEvaluator
Scores only. It never changes the response:
inline.py
InlineEvaluator refuses LLM evaluators. Its audit write is fire-and-forget
on a running event loop; with no loop, as in this script, it is skipped. Use
EvalSuite or GuardrailRuntime when every verdict must be recorded.