> ## Documentation Index
> Fetch the complete documentation index at: /docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Guardrails externos

> Chame o OPA, outros mecanismos de políticas e provedores de guardrails de terceiros a partir de um guardrail ou evaluator em Python.

Um guardrail externo bloqueia uma geração com base em uma decisão tomada fora do **Toqan Router**: um mecanismo de políticas (OPA, Cedar, OpenFGA), uma API de moderação de terceiros ou um serviço interno de compliance. A decisão é executada como um [Python Guardrail](/docs/pt-BR/ai-gateway/configuration/guardrails.md#python-guardrail) que chama o serviço com `requests`. Os [System Guardrails](/docs/pt-BR/ai-gateway/configuration/guardrail-rules.md#system-guardrails) cobrem a detecção de PII e de segredos sem um serviço externo.

## Criar e vincular

| Tipo | Onde |
| - | - |
| Python Guardrail | **AI Gateway** > **Guardrails** > <kbd>+ Guardrail</kbd> > **Python** |
| Python Evaluator | **Evaluators** > <kbd>+ Evaluator</kbd> > **Python**, ou em um projeto ou pasta > <kbd /> > **Evaluator** > **Python** |

O código define uma função chamada `evaluate` que recebe `log` e retorna o veredito; o executor chama `evaluate(log)` pelo nome, portanto o ponto de entrada não pode ser renomeado. Funções auxiliares podem ser definidas em qualquer parte do código.

Vincule a verificação:

| Superfície | Vinculação | Etapa |
| - | - | - |
| **AI Gateway** | Adicione o guardrail a uma [Guardrail Rule](/docs/pt-BR/ai-gateway/configuration/guardrail-rules.md) | Por guardrail na regra: **Input**, **Output** ou **Both** |
| Agents | Vincule o Python Evaluator em Configurar Evaluators e Guardrails | Por entrada: **Input** ou **Output** |
| Deployments | Vincule o Python Evaluator em Evaluators e Guardrails | Por entrada: **Input Guardrail** ou **Output Guardrail** |

| Campo de `log` | Conteúdo |
| - | - |
| `log["input"]` | Última mensagem enviada ao modelo, em uma verificação de entrada |
| `log["output"]` | Resposta gerada pelo modelo, em uma verificação de saída |

Objeto completo: [Python Guardrail](/docs/pt-BR/ai-gateway/configuration/guardrails.md#python-guardrail). Verificações de saída, incluindo as externas, não são executadas em respostas em streaming. Consulte [Comportamento de execução](/docs/pt-BR/ai-gateway/configuration/guardrails.md#execution-behavior).

## Condição de aprovação

O veredito é comparado com a condição de aprovação configurada no guardrail:

| Valor de retorno | Condição de aprovação |
| - | - |
| `True` quando o tráfego é permitido | **Boolean** com **True** |
| Pontuação, quanto maior, mais seguro | **Number** com um limite acima de zero |

Um guardrail reprovado bloqueia a solicitação. O status depende da superfície: `400` no endpoint Responses e no endpoint de chat completions compatível com a OpenAI, e `422` nos endpoints compatíveis com Anthropic e Google e nas superfícies Agents e Deployments. Um guardrail que excede o tempo limite retorna `408` nos endpoints do **AI Gateway** e em Deployments; na superfície Agents, um guardrail que não pode ser executado, inclusive por tempo limite, retorna `502 guardrail_execution_failed`. Consulte Resposta de erro de guardrail.

> [!WARNING]
>
> **Um guardrail que falha na execução bloqueia a solicitação.** Código que lança uma exceção, excede o tempo limite ou não consegue acessar a rede encerra a execução com um erro de execução em vez de liberar o tráfego. Capture os erros de solicitação no código e retorne uma negação, para que o chamador veja o motivo do guardrail em vez de uma execução com falha.

## Requisitos

| Requisito | Detalhe |
| - | - |
| Falhar fechado | Negue quando a verificação não puder ser executada. Trate um erro de solicitação, uma resposta malformada ou um campo ausente como negação; uma exceção que escapa do código é um erro de execução, que bloqueia a solicitação. |
| Tempo limite | Defina um `timeout` explícito bem abaixo do tempo de execução disponível, que por padrão é de 60 segundos e pode ser configurado no evaluator, até 2 minutos. Uma chamada que ultrapassa esse tempo é encerrada, e um guardrail encerrado é um erro de execução: a solicitação é bloqueada e a negação prevista no código nunca é executada. Consulte [Tempo limite do guardrail](/docs/pt-BR/ai-gateway/configuration/guardrails.md#timeout). |
| Acessibilidade | O código é executado em um sandbox do **Toqan Router**, não na máquina que chama a API. Exponha o serviço de decisão onde esse sandbox consiga acessá-lo, atrás de um proxy que aceite apenas tráfego do sandbox. Um servidor vinculado a `localhost` não é acessível. |
| Credenciais | O código do guardrail não tem um armazenamento de segredos separado, portanto uma chave no código pode ser lida por qualquer pessoa com acesso ao evaluator. Coloque as chaves em um proxy na frente de cada serviço de decisão e chame o proxy a partir do código. O proxy guarda a chave e precisa rejeitar qualquer outro chamador; como o código não pode enviar uma credencial, essa restrição precisa ser no nível de rede, por exemplo permitindo apenas os endereços de onde o sandbox faz as chamadas. |
| Publicação | As alterações no código permanecem no rascunho de trabalho até **Publish**. Vincule o guardrail após publicar. |

## Open Policy Agent

O Open Policy Agent (OPA) é um mecanismo de políticas de uso geral: as regras são escritas em Rego, e o servidor retorna uma decisão para a entrada que recebe via HTTP. Consulte a [documentação do OPA](https://www.openpolicyagent.org/docs) para instalação e criação de políticas.

Inicie o servidor e carregue a política. A API de dados escuta na porta 8181 por padrão:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
opa run --server orq/guardrail.rego
```

`opa run --server` aceita gravações não autenticadas em `/v1/policies` e `/v1/data`, portanto um mecanismo de políticas que o sandbox consegue acessar diretamente também pode ser reescrito por qualquer pessoa que consiga acessá-lo, incluindo outros autores de guardrails, cujo código é executado no mesmo sandbox. Execute-o atrás de um proxy que aceite apenas tráfego do sandbox e encaminhe somente a consulta de decisão (`POST /v1/data/orq/guardrail/allowed`), rejeitando qualquer outro caminho e verbo, em particular gravações em `/v1/policies` e `/v1/data`, conforme descrito em [Requisitos](#requirements); o guardrail chama o proxy, que guarda a credencial.

A política nega o texto enviado pelo guardrail quando ele corresponde a um padrão de injeção. `is_string` faz com que uma consulta sem texto seja uma negação, e `default` mantém a consulta respondível quando o corpo da regra é indefinido.

```text orq/guardrail.rego theme={"theme":{"light":"github-light","dark":"github-dark"}}
package orq.guardrail

default allowed = false

allowed if {
    is_string(input.text)
    not contains(lower(input.text), "ignore previous instructions")
}
```

* Os nomes do pacote e da regra correspondem ao caminho da consulta: `data.orq.guardrail.allowed` é servido em `/v1/data/orq/guardrail/allowed`.
* A regra usa a sintaxe do OPA 1.0. Em uma versão anterior, adicione `import future.keywords.if`.

Código do guardrail, chamando o mecanismo de políticas pelo proxy autenticado:

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def evaluate(log):
    import requests

    try:
        text = log["output"] or log["input"]  # output on an output guardrail, input otherwise
        response = requests.post(
            "https://opa-proxy.example/v1/data/orq/guardrail/allowed",
            json={"input": {"text": text}},
            timeout=2,
        )
        response.raise_for_status()
        return response.json()["result"] is True
    except (requests.RequestException, KeyError, ValueError, TypeError):
        return False  # block when the policy cannot be reached
```

Condição de aprovação: **Boolean** com **True**. A geração é bloqueada quando a política retorna `False`.

Qualquer mecanismo que responda via HTTP segue o mesmo formato. Troque a URL, o corpo da solicitação e o campo de onde o veredito é lido.

## Provedores de guardrails de terceiros

Mapeie a resposta do provedor para a condição de aprovação. Um guardrail numérico é aprovado quando atinge ou ultrapassa o limite, portanto uma pontuação de risco, em que um valor maior significa mais risco, precisa ser normalizada para o intervalo de 0 a 1 e depois invertida; uma pontuação de segurança, em que um valor maior significa mais seguro, precisa apenas ser normalizada. Verifique a direção da pontuação do provedor antes de decidir se deve invertê-la. Chame o provedor pelo proxy descrito em [Requisitos](#requirements) e substitua o host do proxy, o corpo da solicitação e o campo de pontuação pelos do provedor.

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def evaluate(log):
    import requests

    try:
        text = log["output"] or log["input"]
        response = requests.post(
            "https://guard-proxy.example/v1/guard",
            json={"text": text, "model": "guard-standard"},
            timeout=2,
        )
        response.raise_for_status()
        score = response.json()["results"][0]["score"]  # this provider scores 0 to 100
        if isinstance(score, bool) or not isinstance(score, (int, float)) or not 0 <= score <= 100:
            return -1.0  # a score outside the provider contract blocks
    except (requests.RequestException, KeyError, ValueError, IndexError, TypeError):
        return -1.0  # below any threshold above zero, so an unreachable provider blocks

    return 1.0 - score / 100.0
```

O proxy anexa a chave de API do provedor, portanto nenhuma credencial fica no código do guardrail.

Condição de aprovação: **Number** com um limite acima de zero, para que o valor de falha `-1.0` bloqueie quando o provedor não puder ser acessado. Um provedor que retorna `True` ou `False` em um campo próprio pode ter esse valor retornado diretamente com uma condição de aprovação **Boolean**.

### Provedores específicos

Cada framework é executado como um serviço, e a verificação o acessa via HTTP. Expanda um framework para ver o que é executado onde, o endpoint que o proxy precisa expor, o código do guardrail e a condição de aprovação a configurar.

> [accordion] Guardrails AI, auto-hospedado com seu servidor de validação
>
> **O que é executado onde.** O framework valida o texto com um Guard, e o servidor Guardrails hospeda guards atrás de uma API HTTP. Execute esse servidor, ou reutilize um já implantado, em um local que o sandbox do **Toqan Router** consiga acessar, e o guardrail o chamará.
>
> **O que o proxy precisa expor.** O próprio endpoint de validação do servidor, com o nome do guard no caminho e o texto em `llmOutput`. O servidor responde com `validationPassed`, um booleano:
>
> | Elemento | Valor |
> | - | - |
> | Método e caminho | `POST /guards/{guardName}/validate` |
> | Corpo da solicitação | `{ "llmOutput": "<text>" }` |
> | Campo da resposta | `validationPassed` |
>
> O proxy guarda a credencial do servidor, portanto o guardrail não envia nenhuma. Consulte a [API REST do servidor Guardrails](https://guardrailsai.com/docs/guardrails_server_api) para ver o schema completo.
>
> **Código do guardrail.** Defina a condição de aprovação como **Boolean** com **True**.
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
> def evaluate(log):
>     import requests
>
>     try:
>         text = log["output"] or log["input"]  # output on an output guardrail, input otherwise
>         response = requests.post(
>             "https://guardrails-proxy.example/guards/toqan_guardrail/validate",
>             json={"llmOutput": text},
>             timeout=2,
>         )
>         response.raise_for_status()
>         passed = response.json()["validationPassed"]  # the guard's outcome for the text
>         if not isinstance(passed, bool):
>             return False  # an outcome outside the expected shape blocks
>     except (requests.RequestException, KeyError, ValueError, TypeError):
>         return False  # block when the guard cannot be reached or answers unexpectedly
>
>     return passed
> ```
>
> **Modos de falha.** Um guard inacessível, uma resposta sem `validationPassed` e um `validationPassed` que não é booleano retornam `False`. O nome do guard faz parte da URL, portanto um guard renomeado transforma todas as chamadas em falhas bloqueantes, em vez de aprovações silenciosas.

> [accordion] Lakera, Guard API hospedada
>
> **O que é executado onde.** Não há nada para implantar: a Guard API é hospedada, e o proxy na frente dela guarda a chave de API. O projeto indicado na solicitação seleciona a política que a analisa.
>
> **Antes de executar o exemplo.** Duas configurações do projeto determinam se o guardrail pode bloquear algo. Com a ação `detect`, a Lakera informa as detecções em `breakdown` e retorna `flagged` como `false` para todas as solicitações, portanto nenhum guardrail pode agir com base nisso. O projeto precisa fazer a análise com a ação `enforce`. A role da mensagem determina quais detectores se aplicam, portanto a saída do modelo é enviada como `assistant` e a entrada como `user`.
>
> | Elemento | Valor |
> | - | - |
> | Método e caminho | `POST /v2/guard` |
> | Corpo da solicitação | `messages: [{ "role": "assistant" \| "user", "content": "<text>" }]`, `project_id` |
> | Campos da resposta | `flagged`, `action` |
>
> Consulte a [referência da Guard API](https://docs.lakera.ai) para ver o schema completo e as configurações do projeto.
>
> **Código do guardrail.** Defina a condição de aprovação como **Boolean** com **True**.
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
> def evaluate(log):
>     import requests
>
>     try:
>         text = log["output"] or log["input"]
>         role = "assistant" if log["output"] else "user"  # screen model output as output
>         response = requests.post(
>             "https://lakera-proxy.example/v2/guard",
>             json={
>                 "messages": [{"role": role, "content": text}],
>                 "project_id": "project_01J...",  # the project whose policy screens this traffic
>             },
>             timeout=2,
>         )
>         response.raise_for_status()
>         verdict = response.json()
>         if verdict.get("action") != "enforce" or not isinstance(verdict["flagged"], bool):
>             return False  # a project in detect mode never flags, so it cannot block
>     except (requests.RequestException, KeyError, ValueError, TypeError):
>         return False  # block when the provider cannot be reached or answers unexpectedly
>
>     return not verdict["flagged"]
> ```
>
> **Modos de falha.** Um projeto que não está no modo `enforce`, um campo `flagged` ausente, um `flagged` não booleano e um proxy inacessível bloqueiam a solicitação. A verificação de `action` é o que mantém o guardrail confiável: sem ela, um projeto alterado para `detect` permitiria silenciosamente tudo o que o provedor detecta.

## Testar

1. Teste o código no painel **Playground** do guardrail.
2. Clique em **Publish**.
3. Vincule o guardrail na superfície de destino.
4. Envie tráfego e inspecione os resultados em [Traces](/docs/pt-BR/ai-studio/observability/traces.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.