# Guard agents with inspectors

**Inspectors** guard an agent while it runs. Each one checks the agent's input, its steps or its final answer, and when it finds a problem it stops the run, runs the agent again, rewrites the content or only logs it. This article explains how inspectors work, the guards that come built in, how to add a guard, a rule or a Python check, how to keep inspectors fast, and how to read what an inspector did in a run's trace and in Dashboard.

> Inspectors work on every aixplain agent, on every plan. You add guards and rules in aixplain Desktop, in the agent's **Configure** tab, and any kind with the Agents SDK. A guard or judge that calls a model uses credits from your workspace balance on each check.

## How inspectors work

An inspector has three parts: what it checks, how it judges, and what it does when it finds a problem.

### What it checks

| Target | What the inspector sees |
| --- | --- |
| **Input** | The person's request, before the agent starts on it |
| **Steps** | Each step's result, including tool results and subagent answers |
| **Output** | The agent's final answer |

One inspector can check more than one target.

### How it judges

- **A guard:** a guardrail model from the Marketplace, such as prompt-attack detection or sensitive-information redaction.
- **A rule:** a sentence in plain words that a judge model checks, such as "The answer must cite a source for every price." The judge answers pass or fail.
- **A Python check:** a function that returns `True` when it finds a problem. It runs in a sandbox and has 10 seconds.

### What it does when it finds a problem

| Action | What happens |
| --- | --- |
| **Stops the run** | The run ends. Its answer is the inspector's reason, or "Request was blocked by an inspector." |
| **Runs again** | The agent tries again with the inspector's feedback, up to the number of retries you set (2 by default). After the last retry, it stops the run or continues, as you choose. |
| **Rewrites it** | The content is replaced, for example with sensitive information masked, and the run goes on. |
| **Only logs it** | Nothing changes. The finding is recorded in the run's trace. |

### Order and severity

Inspectors run in the order you list them, and the first one that finds a problem acts. Each inspector also has a **Severity**: Low, Medium, High or Critical. Severity is a label for sorting and reporting. The action decides what happens.

> **Important:** If an inspector itself fails, for example its guard doesn't answer within 30 seconds or a Python check raises an error, the run continues as if it passed. A judge reply that can't be read counts as a problem, and the content is blocked.

## Built-in guards

aixplain comes with three guards, each with a sensible default. You can change the target and the action after you add one.

| Guard | Checks | Default action | What it does |
| --- | --- | --- | --- |
| **Detect Prompt Attacks** | Input | Stops the run | Catches prompt attacks before they steer the agent |
| **Sensitive Information** | Input | Rewrites it | Masks personal information in the request |
| **Contextual Grounding Check** | Output | Runs again, 2 times, then stops | Checks the final answer against the agent's steps and the request |

aixplain also runs its own checks on every run, which you don't add or remove: it stops runs that loop, enforces the agent's time and credit limits, and pauses for your approval before a tool that needs it.

## Add a guard in aixplain Desktop

1. Open the agent in Omni, or ask Omni to build one, and select **Configure**.
2. Scroll to **Inspectors** and select **Add inspector**.
3. Under **Ready-made guards**, select **Add** next to the guard you want.
4. Save the agent. A new inspector goes into the draft and takes effect when you save.

![The Add inspector list in aixplain Desktop, with three guards under Ready-made guards and Write a rule under Your own rule](https://www.aixplain.com/support/images/guard-agents-with-inspectors/add-inspector.png)

The guard appears in the list with what it checks, what it does and its severity. Select **⋯** on an inspector to edit or remove it.

![Two inspectors in order: Detect Prompt Attacks checks the input and stops the run, Contextual Grounding Check checks the output and runs again twice, then stops](https://www.aixplain.com/support/images/guard-agents-with-inspectors/inspectors-list.png)

## Add a rule inspector

A rule is a check you write in plain words, and a judge model decides whether content breaks it.

1. In **Configure**, select **Add inspector**, then **Write a rule**.
2. Give it a **Name**, unique in this agent.
3. Under **What it checks**, choose **Input**, **Steps** or **Output**.
4. Write the **Rule**: what good content looks like, and when the judge should fail it.
5. Under **Judge**, keep **Default judge** or pick a model. A small, fast model is usually enough. See **[Keep inspectors fast](#keep-inspectors-fast)**.
6. Choose what happens **When it fails**: **Stops the run**, **Runs again**, **Rewrites it** or **Only logs it**. For **Runs again**, set **Retries** and what happens **After the last retry**. For **Rewrites it**, write a **Rewrite rule** that says how to fix the content.
7. Choose a **Severity**, then select **Add inspector** and save the agent.

![The New inspector form with a name, Output selected under What it checks, a rule, Default judge, the When it fails choices and severity](https://www.aixplain.com/support/images/guard-agents-with-inspectors/write-rule.png)

### Example rules

- "Every bullet ends with a link to its source. Fail the answer if a bullet has no link."
- "The answer must not promise a refund or a delivery date."
- "The answer is in the same language as the request."
- "No step sends an email to an address outside our company."

Write the rule as a correction when the action is **Runs again**: the judge's feedback goes to the agent's next try as written.

> **Note:** Start a new rule with **Only logs it**. Check in its runs that it catches what you meant, then switch it to **Runs again** or **Stops the run**.

## Add a Python inspector

A Python check is a function you write, for rules that code can decide exactly, such as a pattern, a length or a required field. Add it with the Agents SDK. aixplain Desktop shows it as **Python · view only**: you can keep it or remove it there, and change it in code.

The function must be named `evaluator_fn`, take the text and return `True` when it finds a problem. Put any imports inside the function.

```python
from aixplain import Aixplain

aix = Aixplain(api_key="YOUR_API_KEY")

def evaluator_fn(text: str) -> bool:
    import re
    bullets = [line for line in text.splitlines() if line.strip().startswith("-")]
    return any(not re.search(r"https?://", line) for line in bullets)

source_check = aix.Inspector(
    name="source-for-every-story",
    severity="high",
    targets=["output"],
    action={"type": "rerun", "max_retries": 2, "on_exhaust": "abort"},
    metric=evaluator_fn,
)

agent = aix.Agent(
    name="Weekly Topic News Brief",
    description="Finds this week's news on a topic and sums it up in five linked bullets.",
    instructions="Search the web for this week's news on the topic and return five bullets, each with a source link.",
    inspectors=[source_check],
).save()
```

- **To rewrite instead of block:** set `action="edit"` and add `editor=edit_fn`, a function named `edit_fn` that returns the new text.
- **To write a rule in code:** pass `metric={"assetId": JUDGE_ID, "prompt": "..."}`, where `JUDGE_ID` is the ID of the model that judges.
- **To add a guard in code:** get it with `aix.Inspector.get()`, for example `aix.Inspector.get("aws/detect-prompt-attacks-guardrail/aws")`.

Define the function in a `.py` file: aixplain sends its source code, and code typed into an interactive shell can't be read, so the check is skipped. Avoid slow network calls inside it. An inspector added after `save()` does nothing until you save again. See **[Inspectors](https://docs.aixplain.com/assets/agents/inspectors/)** in the docs for every option.

## Keep inspectors fast

Every inspector runs on every run, and a rule or a guard is a model call. Too many, or slow ones, make the agent slower and cost more.

- **Use a small model to judge.** A rule asks a simple pass-or-fail question, so a small, fast model is usually as good as a large one, and quicker and cheaper.
- **Prefer Python for exact rules.** A pattern or a length check in Python takes milliseconds and uses no credits.
- **Check only what you need.** An inspector on **Steps** runs after every step. Use **Input** or **Output** when that's enough.
- **Put the cheapest checks first.** The first inspector that finds a problem acts, so a fast check can save a slow one.
- **Keep retries low.** Each retry runs the agent again. Two is usually enough.

## Test an inspector

Test the agent on a request the inspector should catch. On the **Test** tab, a run an inspector stopped reads **Blocked by** and the inspector's name, with its reason, and each run shows what every inspector did: **Stopped the run**, **Ran again**, **Rewrote** or **Logged it**.

![The Test tab with a completed run and a run blocked by Detect Prompt Attacks, with its reason](https://www.aixplain.com/support/images/guard-agents-with-inspectors/blocked-run.png)

> **Note:** Omni can add inspectors or make them stricter, but it can't remove one, loosen one or change its rule. Only you can do that, in the panel.

## Read what an inspector did

### In the run's result

A run an inspector stopped still finishes with the status `SUCCESS`, and its answer is the inspector's reason. The run's **governance** record says what happened:

| Status | Meaning |
| --- | --- |
| `ALLOWED` | No inspector or limit stopped the run |
| `BLOCKED_BY_INSPECTOR` | An inspector stopped the run |
| `BLOCKED_BY_BUDGET` | The run hit its time, credit or step limit |
| `BLOCKED_BY_POLICY` | A policy stopped the run |
| `REQUIRES_HUMAN_REVIEW` | The run is waiting for a person to approve a step |

**Source** says who decided: `INSPECTOR` for your inspectors, `SYSTEM` for aixplain's own limits.

### In the trace

Each inspector appears in the run's steps under its own name, with the action it took. A guard reports `NONE` when the content passed and `GUARDRAIL_INTERVENED` when it flagged it. A stopped run carries the code `INSPECTOR_ABORT`.

### In Dashboard

Open **Dashboard** and pick the agent. **Failure intelligence** lists the most common codes, including `INSPECTOR_ABORT` for runs an inspector stopped and `BUDGET_EXCEEDED` for runs that hit a limit.

![Dashboard for one agent, with Failure intelligence listing RUN_TIMEOUT, BUDGET_EXCEEDED and INSPECTOR_ABORT](https://www.aixplain.com/support/images/guard-agents-with-inspectors/dashboard-failures.png)

Select a run to open its trace. **Governance** shows **Blocked by inspector**, **Codes** shows `INSPECTOR_ABORT`, and the timeline shows the inspector that stopped it.

![A run trace with status Success, governance Blocked by inspector, the code INSPECTOR_ABORT and the Detect Prompt Attacks step](https://www.aixplain.com/support/images/guard-agents-with-inspectors/run-trace-blocked.png)

See **[Monitor your agents](https://www.aixplain.com/support/articles/monitor-your-agents)** for the rest of Dashboard.

## Limits and codes

When a run hits one of its limits, the agent stops planning and answers from the steps it finished. The run returns `SUCCESS` with the status `BLOCKED_BY_BUDGET`, and the limit's code says which one:

| Code | Limit reached |
| --- | --- |
| `RUN_LIMIT_COST` | The run's credit limit |
| `RUN_LIMIT_DURATION` | The run's time limit |
| `RUN_LIMIT_ITERATIONS` | The maximum number of steps |
| `RUN_LIMIT_CONTEXT` | The model's context window |
| `RUN_LIMIT_OUTPUT_TOKENS` | The maximum answer length |

The run warns at 80% of a limit and starts wrapping up at 95%, so it can still give an answer. Because the last answer step still runs, the credits used can end slightly above the credit limit.

## Limitations

- An agent can have up to 20 inspectors, each with a unique name.
- Severity doesn't change what an inspector does.
- Python checks are added and changed in code, not in aixplain Desktop.
- An inspector that errors lets the run continue.

## Frequently asked questions

### Why did a blocked run return SUCCESS?

The run finished: the inspector ended it on purpose and its reason is the answer. Read the governance status to tell a blocked run from a normal one.

### Does an inspector slow the agent down?

Yes, each check adds time, and a rule or guard adds a model call. Use a small model to judge, prefer Python for exact rules and keep the list short. See **[Keep inspectors fast](#keep-inspectors-fast)**.

### Can I see how often my inspectors fire?

Yes. In **Dashboard**, **Failure intelligence** counts `INSPECTOR_ABORT` among the agent's codes, and each run's trace shows its governance status.

## Get help

- **Build an agent:** see **[Build and deploy agents with Omni](https://www.aixplain.com/support/articles/build-and-deploy-agents-with-omni)**.
- **Report a problem:** email **care@aixplain.com** with the agent, the run and what you expected. Remove credentials and private data first.
