# Custom guardrail policies

Custom guardrails allow you to define domain-specific protection policies using natural language instructions, based on your unique business rules, compliance requirements, or application-specific constraints.

## What you need

- Python 3.10 or higher.
- `cx-guardrails` installed. See [Getting Started with Guardrails](https://coralogix.com/docs/user-guides/ai/guardrails/getting_started/index.md).
- The `AI-GUARDRAILS:MANAGE` [permission](https://coralogix.com/docs/user-guides/aaa/access-control/permissions/permissions-list/index.md).
- A [Team API key](https://coralogix.com/docs/user-guides/account-management/api-keys/api-keys/index.md) with the **AiObservability** role preset, used as `CX_GUARDRAILS_TOKEN`. The AiObservability preset includes `AI-GUARDRAILS:MANAGE` and all other permissions required to use Guardrails.

## Install the SDK

```bash
pip install cx-guardrails
```

## Set up environment variables

```bash
export CX_GUARDRAILS_TOKEN="your-coralogix-guardrails-api-key"
export CX_GUARDRAILS_ENDPOINT="https://api.<region>.coralogix.com/api/v1/guardrails/guard"
export CX_TOKEN="your-coralogix-send-your-data-key"
export CX_ENDPOINT="https://your-domain.coralogix.com"

# Optional: Application metadata for observability
export CX_APPLICATION_NAME="my-app"
export CX_SUBSYSTEM_NAME="my-subsystem"
```

## Set up observability

To send guardrail spans to AI Center, set up OpenTelemetry trace export. For the full overview, see [OpenTelemetry integration for AI Center](https://coralogix.com/docs/user-guides/ai/otel-integration/index.md).

Install the OpenTelemetry packages:

```bash
pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-grpc
```

Export the OTLP environment variables:

```bash
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingress.[[DOMAIN_VALUE]]:443"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <your-api-key>"
export OTEL_SERVICE_NAME="my-ai-service"
export OTEL_RESOURCE_ATTRIBUTES="cx.application.name=my-app,cx.subsystem.name=my-subsystem"
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
export OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental
```

Initialize the tracer provider in your application before any guardrail or LLM calls:

```python
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor


def configure_otel() -> TracerProvider:
    resource = Resource.create()
    provider = TracerProvider(resource=resource)
    provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(provider)
    return provider
```

## Understanding custom guardrails

Custom guardrails are configured using the `Custom` class, which requires:

- **name**: A unique identifier for your guardrail.
- **instructions**: Natural language description of what to evaluate. Must include at least one of `{prompt}`, `{response}`, or `{history}`.
- **Prohibited**: Description of what constitutes a violation.
- **Acceptable**: Description of what is considered safe.
- **examples** (optional): Training examples to improve detection accuracy.
- **threshold**: Detection sensitivity (0.0 to 1.0, default 0.7).
- **`should_include_system_prompt`** (optional): Whether to include the system prompt when guardrails run their check.

## Instructions

Natural language description of what to evaluate. Must include `{prompt}`, `{response}`, or `{history}`.

### Magic variables

Custom guardrails support special variables in the `instructions` field:

| Variable     | Description               | Usage                         |
| ------------ | ------------------------- | ----------------------------- |
| `{prompt}`   | The user's input prompt   | Evaluate prompt content       |
| `{response}` | The LLM's response        | Evaluate response content     |
| `{history}`  | Full conversation history | Evaluate context across turns |

Your `instructions` must include at least one of these variables.

## Configuration options

### Reference examples

**Reference examples are crucial for improving guardrail accuracy.** While optional, providing examples significantly enhances detection quality by giving the LLM evaluator concrete references of what constitutes a violation versus safe behavior in your specific context.

Each example is a conversation between the user and the LLM, scored as either:

- **score=1**: Violates the policy (should be blocked).
- **score=0**: Safe behavior (should be allowed).

Aim for at least 3–5 examples covering different scenarios, edge cases, and borderline situations. Examples can include multi-turn conversations to capture violations that emerge over multiple interactions.

### Including the system prompt

Use `should_include_system_prompt` to decide whether to include the system prompt when guardrails run their check.

## Best practices

### Writing effective instructions

1. **Be specific**: Clearly describe what you're looking for.
1. **Use examples**: Provide training examples for better accuracy.
1. **Include context**: Use `{history}` for context-aware detection.
1. **Test iteratively**: Adjust instructions based on results.

```python
# Too vague
instructions="Check if the {response} is bad"

# Specific and clear
instructions="""Evaluate if the {response} contains speculation about future
events without proper uncertainty language (e.g., 'might', 'could', 'possibly')."""
```

## Example: Financial advice detection

Detect when LLM responses provide specific financial advice without proper disclaimers:

```python
FINANCIAL_ADVICE_DETECTOR = Custom(
    name="financial_advice_detector",
    instructions=(
        "Analyze the {response} for specific financial advice that could be construed as "
        "professional investment recommendations. Focus on whether the response recommends "
        "specific stocks, cryptocurrencies, funds, or investment allocations without appropriate disclaimers."
    ),
    violates=(
        "The response provides specific investment recommendations — such as 'buy this stock' or "
        "'put your money in Y fund', or suggests specific portfolio allocations (e.g. '60% stocks') — "
        "without including a clear disclaimer that the information is not professional financial advice."
    ),
    safe=(
        "The response does one or more of the following: "
        "(1) does not discuss specific investments at all, "
        "(2) provides only general educational information about financial concepts, "
        "(3) discusses investments but includes a clear disclaimer that it is not professional financial "
        "advice and recommends consulting a licensed advisor, or (4) declines to give investment advice entirely."
    ),
    examples=[
        CustomEvaluationExample(
            conversation=(
                "User: Should I buy Tesla stock?\n"
                "Assistant: Yes, Tesla is a strong buy right now. The stock is undervalued and I expect it "
                "to double within the next year. You should invest at least 20% of your portfolio in it."
            ),
            score=1,
        ),
        CustomEvaluationExample(
            conversation=(
                "User: I just inherited $100,000. What should I do with it?\n"
                "Assistant: That's a significant amount! Are you looking to invest it or save it for something specific?\n"
                "User: I want to grow it. I'm 30 and don't need it right now.\n"
                "Assistant: Great, with a long time horizon you can be more aggressive. Here's what I'd do: "
                "put $60,000 into a tech-heavy ETF like QQQ, $25,000 into Bitcoin since it's still early, "
                "and keep $15,000 as cash reserves. Start the ETF position this week while prices are low."
            ),
            score=1,
        ),
        CustomEvaluationExample(
            conversation=(
                "User: Is gold a good investment?\n"
                "Assistant: Absolutely, you should buy gold ETFs like GLD now before prices go up further."
            ),
            score=1,
        ),
        CustomEvaluationExample(
            conversation=(
                "User: What is a stock?\n"
                "Assistant: A stock represents a share of ownership in a company. When you purchase stock, "
                "you become a partial owner (shareholder) of that company. Stocks are traded on exchanges like the NYSE and NASDAQ."
            ),
            score=0,
        ),
        CustomEvaluationExample(
            conversation=(
                "User: What's an ETF?\n"
                "Assistant: An ETF (Exchange-Traded Fund) is a basket of securities that trades on an exchange like a stock."
            ),
            score=0,
        ),
        CustomEvaluationExample(
            conversation=(
                "User: Should I invest in index funds or individual stocks?\n"
                "Assistant: Index funds offer diversification and lower risk, while individual stocks have higher "
                "potential returns but more volatility. This is educational information only, not financial advice. "
                "Please consult a licensed financial advisor for personalized recommendations."
            ),
            score=0,
        ),
    ],
    category=GuardrailCategory.QUALITY,
)
```

## Next steps

Use the `guard()` method for full control over multi-turn conversation guardrail evaluation with [Guard API](https://coralogix.com/docs/user-guides/ai/guardrails/guard_api/index.md).
