# Guardrails

The Guardrails block validates and protects your AI workflows by checking content against multiple validation types. Ensure data quality, detect PII, and enforce format requirements before content moves through your workflow.

![Guardrails Block](https://docs.steelengine.com/static/blocks/guardrails.png)

## Validation Types

### JSON Validation

Validates that content is properly formatted JSON. Perfect for ensuring structured LLM outputs can be safely parsed.

**Use Cases:**

* Validate JSON responses from Agent blocks before parsing
* Ensure API payloads are properly formatted
* Check structured data integrity

**Output:**

* `passed`: `true` if valid JSON, `false` otherwise
* `error`: Error message if validation fails (e.g., "Invalid JSON: Unexpected token...")

### Regex Validation

Checks if content matches a specified regular expression pattern.

**Use Cases:**

* Validate email addresses
* Check phone number formats
* Verify URLs or custom identifiers
* Enforce specific text patterns

**Configuration:**

* **Regex Pattern**: The regular expression to match against (e.g., `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` for emails). Patterns longer than 500 characters are rejected. The AI wand can write a pattern from a description

**Output:**

* `passed`: `true` if content matches pattern, `false` otherwise
* `error`: Error message if validation fails

### Hallucination Detection

Checks whether AI-generated content is supported by your knowledge base. It splits the content into claims, retrieves the closest chunks for each claim, and asks TypeSafe's Jev model whether the retrieved text supports, contradicts, or says nothing about each claim.

The hallucination check needs a TypeSafe API key under **Settings** → **Bring Your Own Keys** (provider: TypeSafe). Without one it returns `passed: false` with `errorCode: no_key` and does not error.

**How It Works:**

1. Splits the content into claims on sentence boundaries and newlines (up to 20 claims are judged; the rest count as unchecked)
2. Retrieves the top chunks from your knowledge base for each claim
3. Sends the claims and their excerpts to Jev in one request and classifies each claim as supported, contradicted, or unresolved
4. Any contradiction fails the check. Otherwise the score is 10 × (supported claims ÷ all claims) and the check passes when the score is at or above the threshold

**Configuration:**

* **Knowledge Base**: Select from your existing knowledge bases
* **Confidence**: Minimum score to pass (0-10, default: 7). A score of 7 passes when at least 70% of claims are supported; lower it for thin knowledge bases, raise it to 10 when every claim must be grounded
* **Number of Chunks to Retrieve** (Advanced): Chunks retrieved per claim (1-20, default: 3)

The model picker and API key field have been removed: the check always runs on Jev with the workspace or organization TypeSafe key. Saved workflows that still carry a model value load normally; the value is ignored.

**Output:**

* `passed`: `true` when no claim is contradicted and the score meets the threshold
* `score`: Share of claims supported, times ten (0-10). Absent on configuration failures
* `reasoning`: How many claims were supported, contradicted, unresolved, and not checked, naming any contradicted claim
* `errorCode`: Set only on a configuration failure, never on a real verdict:

| `errorCode`         | Meaning                                                                                                                                                                     |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `no_key`            | No TypeSafe key on the workspace or organization                                                                                                                            |
| `no_knowledge_base` | No knowledge base selected, or it was not found                                                                                                                             |
| `retrieval_empty`   | The knowledge base returned no chunks for any claim                                                                                                                         |
| `no_claims`         | The content had nothing to check                                                                                                                                            |
| `low_confidence`    | No claim was confirmed or contradicted above the 0.8 confidence cutoff                                                                                                      |
| `provider_error`    | TypeSafe, retrieval, or authorization failed, or a claim and its excerpts are too long to send (shorten the content and retry); the block does not throw and is not retried |

* `model`, `tokens`, `cost`: The Jev call's usage, attributed to the provider `typesafe`

**Data and Privacy:** The content and the retrieved knowledge-base excerpts are sent to TypeSafe (US-hosted) and stored in execution logs like other AI block inputs. An organization-level key enables this for every workspace in the organization.

**Use Cases:**

* Validate Agent responses against documentation
* Ensure customer support answers are factually accurate
* Verify generated content matches source material
* Quality control for RAG applications

### PII Detection

Detects personally identifiable information using Microsoft Presidio. It supports 41 entity types across multiple countries.

![PII Detection Configuration](https://docs.steelengine.com/static/blocks/guardrails-2.png)

**How It Works:**

1. Pass content to validate (e.g., `<agent1.content>`)
2. Select PII types to detect using the modal selector
3. Choose the action (Block Request or Mask PII)
4. Content is scanned for matching PII entities
5. Returns detection results and optionally masked text

[Video: guardrails.mp4](https://d4h6f8f5tksdw.cloudfront.net/guardrails.mp4)

**Configuration:**

* **PII Types to Detect**: Select from grouped categories via modal selector. Leave every type unselected to scan for all supported entities
  * **Common**: Person name, Email address, Phone number, Location, Date or time, IP address, URL, Credit card number, International Bank Account Number, Cryptocurrency wallet address, Medical license number, Nationality, religious or political group
  * **USA**: Bank account number, Driver license, ITIN, Passport number, Social Security Number
  * **UK**: NHS number, National Insurance Number
  * **Spain**: NIF, NIE
  * **Italy**: Fiscal code, Driver license, VAT code, Passport, Identity card
  * **Poland**: PESEL
  * **Singapore**: NRIC/FIN, Unique Entity Number
  * **Australia**: ABN, ACN, TFN, Medicare
  * **India**: PAN, Aadhaar, Vehicle registration, Voter ID, Passport
  * **Finland**: Personal Identity Code
  * **Korea**: Resident Registration Number
  * **Thailand**: National ID Number
* **Action**:
  * **Block Request**: Only identify PII (default)
  * **Mask PII**: Replace detected PII with masked values
* **Language**: Detection language. Only **English** works today, because the detection engine loads an English model only. Choosing Spanish, Italian, Polish, or Finnish fails the validation with a `PII detection failed` error

**Output:**

* `passed`: `false` if any selected PII types are detected
* `detectedEntities`: Array of detected PII with type, location, and confidence
* `maskedText`: Content with PII masked (only if mode = "Mask")
* `error`: Error message if validation fails

**Use Cases:**

* Block content containing sensitive personal information
* Mask PII before logging or storing data
* Compliance with GDPR and other privacy regulations
* Sanitize user inputs before processing

## Configuration

### Content to Validate

The input content to validate. This typically comes from:

* Agent block outputs: `<agent.content>`
* Function block results: `<function.result>`
* API responses: `<api.data>`
* Any other block output

### Validation Type

Choose from four validation types:

* **Valid JSON**: Check if content is properly formatted JSON
* **Regex Match**: Verify content matches a regex pattern
* **Hallucination Check**: Validate claims against a knowledge base with TypeSafe Jev
* **PII Detection**: Detect and optionally mask personally identifiable information

## Outputs

All validation types return:

* **`<guardrails.passed>`**: Boolean indicating if validation passed
* **`<guardrails.validationType>`**: The type of validation performed
* **`<guardrails.input>`**: The original input that was validated
* **`<guardrails.error>`**: Error message if validation failed (optional)

Additional outputs by type:

**Hallucination Check:**

* **`<guardrails.score>`**: Share of claims supported, times ten (0-10); absent on configuration failures
* **`<guardrails.reasoning>`**: Supported, contradicted, unresolved, and unchecked claim counts
* **`<guardrails.errorCode>`**: Configuration failure code (see the table above); absent on a real verdict
* **`<guardrails.model>`*&#x2A;, &#x2A;*`<guardrails.tokens>`*&#x2A;, &#x2A;*`<guardrails.cost>`**: Jev usage for the check

**PII Detection:**

* **`<guardrails.detectedEntities>`**: Array of detected PII entities
* **`<guardrails.maskedText>`**: Content with PII masked (if mode = "Mask")

## Example Use Cases

**Validate JSON Before Parsing** - Ensure Agent output is valid JSON

```
Agent (Generate) → Guardrails (Validate) → Condition (Check passed) → Function (Parse)
```

**Enforce an Output Format** - Check that an extracted value matches a pattern

```
Agent (Extract Email) → Guardrails (Regex Match) → Condition (passed) → Gmail (Send) or Agent (Retry)
```

**Block PII in User Inputs** - Sanitize user-submitted content

```
Input → Guardrails (Detect PII) → Condition (No PII) → Process or Reject
```

## Best Practices

* **Chain with Condition blocks**: Use `<guardrails.passed>` to branch workflow logic based on validation results
* **Use JSON validation before parsing**: Always validate JSON structure before attempting to parse LLM outputs
* **Choose appropriate PII types**: Only select the PII entity types relevant to your use case for better performance
* **Set reasonable confidence thresholds**: For hallucination detection, the score is the share of claims supported times ten, so raise the threshold toward 7 or 10 when every claim must be grounded
* **Branch on errorCode**: Treat `<guardrails.errorCode>` as a configuration problem to fix, not as a hallucination
* **Mask PII for logging**: Use "Mask" mode when you need to log or store content that may contain PII
* **Test regex patterns**: Validate your regex patterns thoroughly before deploying to production
* **Monitor validation failures**: Track `<guardrails.error>` messages to identify common validation issues

Guardrails validation happens synchronously in your workflow. JSON, regex, and PII checks run in-process without calling a model.

## Common Questions

**Can I run multiple validation types on the same content?**

Each Guardrails block performs one validation type at a time. To apply multiple validations, chain several Guardrails blocks in sequence — for example, first validate JSON format, then check for PII.

**What does the hallucination confidence score mean?**

The score ranges from 0 to 10. It is the share of claims your knowledge base supports, times ten: 0 means no claim is supported and 10 means every claim is. Any contradicted claim fails the check regardless of the score. Otherwise validation passes when the score meets or exceeds your configured threshold (default: 7).

**How many knowledge base chunks are retrieved for hallucination detection?**

By default, 3 chunks are retrieved for each claim. You can adjust this from 1 to 20 in the Advanced settings using the 'Number of Chunks to Retrieve' slider. More chunks provide broader context but increase latency and token usage.

**What PII detection engine is used?**

PII detection is powered by Microsoft Presidio. It supports 41 entity types across multiple countries including the US, UK, Spain, Italy, Poland, Singapore, Australia, India, Finland, Korea, and Thailand. If you select no types, the block scans for all supported entities.

**What is the difference between Block and Mask modes for PII?**

Block mode fails the validation (passed = false) if any selected PII types are detected. Mask mode also detects PII but replaces it with masked values in the output, making the content safe to use downstream. Both modes return the list of detected entities.

**Which languages does PII detection support?**

English only. The Language dropdown also lists Spanish, Italian, Polish, and Finnish, but the detection engine loads an English model only. Those selections fail with a 'PII detection failed' error rather than detecting anything.

**Does JSON validation check schema structure or just syntax?**

JSON validation only checks that the content is syntactically valid JSON (i.e., it can be parsed without errors). It does not validate against a specific schema. For schema validation, use a Function block after the Guardrails check.
