Guardrails

Guardrails run in your process, on every LLM span — no proxy, no extra hop. Pass them to instrument() and Peekr applies them to each call automatically.

agent.py
import peekr

peekr.instrument(
    guardrails=[
        peekr.guard.PIIRedact(categories=("email", "phone", "ssn")),
        peekr.guard.Blocklist(
            patterns=peekr.guard.Blocklist.COMMON_SECRETS,
            action="redact",
        ),
        peekr.guard.HallucinationBlock(threshold=0.4),
    ],
)

Note

Call peekr.instrument() before you import your LLM SDK or create a client. Guardrails attach when the SDK class is patched, so the order matters.

Pipeline order

Guards run as a fixed pipeline around each call, regardless of the order you list them in:

1

PIIRedact

Redacts PII from span attributes before anything else sees them.

2

Eval

Evaluators run and write their scores to span.attributes["eval_scores"].

3

Storage

The span is persisted — already redacted, already scored.

4

HallucinationBlock

Reads the hallucination score and raises a GuardrailError if it falls below the threshold. Because it runs last, the violating span is already stored.

PIIRedact

Strips PII from span attributes before they are stored. The LLM still sees the original input — only what Peekr records is redacted.

python
peekr.guard.PIIRedact(
    fields=("output",),                 # which span fields to scan
    categories=("email", "phone"),      # what to redact
)

Supported categories: email, phone, ssn, credit_card, ip_address.

Blocklist

Blocks or redacts terms and regex patterns. Use the built-in COMMON_SECRETS set to catch leaked API keys and credentials, or pass your own.

python
# Redact leaked secrets from stored spans
peekr.guard.Blocklist(
    patterns=peekr.guard.Blocklist.COMMON_SECRETS,
    action="redact",
)

# Hard-block competitor mentions in model output
peekr.guard.Blocklist(
    terms=["CompetitorAI", "RivalCorp"],
    fields=("output",),
    action="raise",
)

# Custom regex patterns
peekr.guard.Blocklist(
    patterns=[r"internal[_-]?api[_-]?key[_-]?\w{8,}"],
    action="redact",
    case_sensitive=False,
)

action can be "raise" (raise a GuardrailError), "redact" (replace the match in the stored span), or "warn" (log it and continue). fields defaults to ("input",).

HallucinationBlock

Raises a GuardrailError when the hallucination score drops below your threshold. It reads the score produced by the Hallucination evaluator, so enable that evaluator too.

python
peekr.instrument(
    evaluators=[peekr.eval.Hallucination()],
    guardrails=[
        peekr.guard.HallucinationBlock(threshold=0.4),
    ],
)

Scores run from 1.0 (fully grounded) to 0.0 (fully hallucinated), so a lower threshold blocks fewer responses. Pass detailed=True for per-claim verdicts.

Catching GuardrailError

Any guard with action="raise" — including HallucinationBlock — throws a GuardrailError around the LLM call. Catch it to serve a fallback. The violating span is already stored before the error propagates.

python
from peekr.guard import GuardrailError

try:
    resp = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": "..."}],
    )
except GuardrailError as e:
    print(e.guardrail_name)   # e.g. "HallucinationBlock"
    print(e.span.trace_id)    # the stored span that tripped the guard
    return fallback_response()

Warning

HallucinationBlock depends on the Hallucination evaluator, which makes a model call after each response. Expect a small latency cost on guarded calls.

Guardrails vs. compliance packs

The guards on this page run in-process and work on every plan, including the free tier. Compliance packs (HIPAA, GDPR, FINRA, and more) are evaluated in Peekr Cloud and require an HTTPExporter plus a Pro plan.