Skip to main content
Guardrails validate inputs and outputs to ensure safety, quality, and compliance. All guardrail calls are automatically traced.

Available Guardrails

GuardrailDescription
toxic_languageDetects harmful, offensive, or inappropriate content
biased_languageIdentifies biased or discriminatory language
valid_jsonValidates JSON format and optional schema
contains_stringChecks for required or forbidden strings

Toxic Language Detection

from abvdev import ABV

abv = ABV(api_key="sk-abv-...")

result = abv.guardrails.validate_toxic_language(
    text="You're doing a great job!",
    config={"sensitivity": "high"}  # high, medium, low
)

if result.status == "PASS":
    print("Content is safe")
else:
    print(f"Blocked: {result.reason} (confidence: {result.confidence})")

Biased Language Detection

result = abv.guardrails.validate_biased_language(
    text="The engineer fixed the issue quickly.",
    config={"categories": ["gender", "race", "age"]}
)

if result.status == "FAIL":
    print(f"Bias detected: {result.reason}")

JSON Validation

Validate that output is valid JSON, optionally against a schema.
# Basic JSON validation
result = abv.guardrails.validate_json(
    data='{"name": "Alice", "age": 30}'
)

# With JSON schema
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer", "minimum": 0}
    },
    "required": ["name", "age"]
}

result = abv.guardrails.validate_json(
    data='{"name": "Alice", "age": 30}',
    config={"schema": schema, "strictMode": True}
)

if result.status == "PASS":
    print("Valid JSON matching schema")

Contains String Validation

Check for required or forbidden strings.
# Must contain disclaimer
result = abv.guardrails.validate_contains_string(
    text="This is financial advice. Disclaimer: Not professional advice.",
    config={
        "strings": ["disclaimer", "not professional advice"],
        "matchMode": "any",  # any, all
        "caseSensitive": False
    }
)

# Must NOT contain forbidden content
result = abv.guardrails.validate_contains_string(
    text="Here's the safe response",
    config={
        "strings": ["password", "secret", "api_key"],
        "matchMode": "none",  # Fail if ANY string is found
        "caseSensitive": False
    }
)

Input Validation Before LLM

Validate user input before sending to the LLM.
from abvdev import ABV, observe

abv = ABV(api_key="sk-abv-...")

@observe()
def safe_chat(user_message: str) -> str:
    # Validate input
    validation = abv.guardrails.validate_toxic_language(
        text=user_message,
        config={"sensitivity": "medium"}
    )

    if validation.status == "FAIL":
        return "I can't respond to that message. Please rephrase."

    # Safe to proceed
    response = abv.gateway.complete_chat(
        provider="openai",
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": user_message}]
    )

    return response.choices[0].message.content

result = safe_chat("Tell me about machine learning")

Output Validation After LLM

Validate LLM output before returning to user.
@observe()
def validated_generation(prompt: str) -> str:
    response = abv.gateway.complete_chat(
        provider="openai",
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}]
    )
    output = response.choices[0].message.content

    # Validate output for toxic content
    toxic_check = abv.guardrails.validate_toxic_language(
        text=output,
        config={"sensitivity": "high"}
    )

    # Validate output doesn't leak sensitive patterns
    leak_check = abv.guardrails.validate_contains_string(
        text=output,
        config={
            "strings": ["internal:", "confidential:", "secret:"],
            "matchMode": "none"
        }
    )

    if toxic_check.status == "FAIL" or leak_check.status == "FAIL":
        return "I apologize, but I cannot provide that response."

    return output

Multi-Guard Pipeline

Chain multiple guardrails for comprehensive validation.
from abvdev import ABV, observe
from dataclasses import dataclass
from typing import List

abv = ABV(api_key="sk-abv-...")

@dataclass
class GuardResult:
    passed: bool
    failures: List[str]

def run_guards(text: str) -> GuardResult:
    failures = []

    # Run all guards
    guards = [
        ("toxic", abv.guardrails.validate_toxic_language(text, {"sensitivity": "medium"})),
        ("bias", abv.guardrails.validate_biased_language(text, {})),
        ("forbidden", abv.guardrails.validate_contains_string(text, {
            "strings": ["password", "api_key"],
            "matchMode": "none"
        })),
    ]

    for name, result in guards:
        if result.status == "FAIL":
            failures.append(f"{name}: {result.reason}")

    return GuardResult(passed=len(failures) == 0, failures=failures)

@observe()
def guarded_chat(message: str) -> str:
    # Input guards
    input_result = run_guards(message)
    if not input_result.passed:
        return f"Input blocked: {input_result.failures}"

    # Generate
    response = abv.gateway.complete_chat(
        provider="openai",
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": message}]
    )
    output = response.choices[0].message.content

    # Output guards
    output_result = run_guards(output)
    if not output_result.passed:
        return "Response blocked by safety filters."

    return output

Structured Output Validation

Ensure LLM output matches expected structure.
@observe()
def get_structured_data(query: str) -> dict:
    schema = {
        "type": "object",
        "properties": {
            "answer": {"type": "string"},
            "confidence": {"type": "number", "minimum": 0, "maximum": 1},
            "sources": {"type": "array", "items": {"type": "string"}}
        },
        "required": ["answer", "confidence"]
    }

    response = abv.gateway.complete_chat(
        provider="openai",
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "Respond in JSON with answer, confidence, and sources."},
            {"role": "user", "content": query}
        ]
    )
    output = response.choices[0].message.content

    # Validate structure
    result = abv.guardrails.validate_json(
        data=output,
        config={"schema": schema, "strictMode": True}
    )

    if result.status == "FAIL":
        raise ValueError(f"Invalid output structure: {result.reason}")

    import json
    return json.loads(output)