Construindo um guardrail
O guardrail verifica cada chamada de ferramenta que um agente de LLM propõe, antes de ela ser executada, e responde
permitir, confirmar (perguntar à pessoa) ou recusar, citando a regra que decidiu. Nada numa decisão é
adivinhado por um modelo de linguagem: a mesma chamada, conversa e regras sempre dão a mesma resposta e o mesmo
decision_id.
Dá para construir um de dois jeitos, pelos mesmos passos: em Python, ou pedindo ao seu próprio assistente de IA pelo
stalwart mcp.
O que é garantido, e o que não é
Garantido:
- Toda chamada de ferramenta é verificada antes de ser executada, pelas mesmas regras, e a mesma chamada, contexto e regras sempre dão a mesma resposta.
- Uma ferramenta fora da sua lista nunca é executada; uma chamada cujos valores quebram a descrição da própria ferramenta nunca é executada.
- Uma escrita que nenhuma regra permitiu nunca é executada sem o sim de uma pessoa, e esse sim cobre exatamente a chamada mostrada.
- Um valor numa escrita que ninguém disse e nenhuma ferramenta devolveu é perguntado.
- Nada numa decisão é adivinhado por um modelo de linguagem.
Não garantido:
- Ele julga ferramentas, argumentos, rótulos, histórico e regras, não o que uma resposta quer dizer.
- Ele não distingue um valor certo de um errado que alguém de fato disse.
- Suas regras são tão completas quanto você as escreveu: o caçador de falhas procura brechas.
- Uma ferramenta cujo nome e descrição escondem o que ela faz pode ser classificada errado: marque-a.
- Chamadas feitas fora do guardrail não são verificadas.
Passo a passo, em Python
- Instale.
pip install stalwart-agents, e ative a licença (stalwart licence activate). As verificações são respondidas pelo runtime licenciado na sua máquina; se ele não responder, toda chamada é bloqueada, nunca permitida. Dê a ele suas ferramentas. A lista que você entrega ao modelo basta: definições de ferramentas da OpenAI ou da Anthropic, o
tools/listde um servidor MCP, ou ferramentas do LangChain. Um LLM sem ferramentas não faz chamadas de ferramenta, então não há o que verificar.from stalwart_agents.guardrails import Guardrail rail = Guardrail(tools=tools)Diga quais ferramentas escrevem. Cada ferramenta lê, escreve ou envia para fora. A maioria é deduzida pelo nome, pela descrição e pelos argumentos; uma ferramenta que ninguém consegue dizer é tratada como escrita. Escreva as que você conhece em
tool_kinds.yaml(Tipos de ferramenta) e passetool_kinds="tool_kinds.yaml".- Escreva suas regras. Uma planilha de regras em YAML simples (A planilha de regras):
rules="rules.yaml". - Escolha as verificações. Toda verificação vem ligada;
checks=[...]liga só as listadas (As verificações). As que não podem ser desligadas sempre rodam. Verifique cada chamada antes de executá-la.
from stalwart_agents.guardrails import CallRefused context = {"turns": turns, "results": results, "session": sid} try: verdict = rail.check_call(call, context) # uma recusa levanta CallRefused if verdict.decision == "confirm" and ask_person(verdict.confirmation["sentence"]): verdict = rail.check_call(call, {**context, "confirmation": rail.approve(verdict.confirmation)}) if verdict.proceed: results[call["id"]] = run_tool(call) # seu código executa a ferramenta, nunca o guardrail except CallRefused as refused: tell(refused.verdict.reason)Uma chamada alterada depois do sim da pessoa é perguntada de novo.
Teste. Faça chamadas de ensaio que você espera que passem e que sejam barradas, busque as formulações que o leitor verifica (A busca de formulações) e repita as chamadas antigas do seu agente (Avaliando).
- Conecte onde seu agente roda: Python puro, o gateway MCP, Guardrails AI ou NeMo Guardrails (Conectando).
Construa com seu assistente de IA
O stalwart mcp é um servidor MCP na sua máquina. Adicione-o ao seu cliente MCP (Claude Code, Cursor, VS Code) e peça
ao seu assistente para construir o guardrail: o prompt build-guardrail o conduz, nesta ordem:
- ler suas ferramentas:
catalogue_from_server; - os tipos delas:
writes_file, e o promptclassify-tools, que deixa seu assistente propor tipos porset_tool_kinds(registrados comosource: assistant, listados à parte); - rascunhar uma planilha de regras a partir da sua política em palavras simples, com a referência da planilha como recurso;
compile_ruleselint_rules;- ensaios:
check_call; search_wordingsehunt;- o trecho de código para onde ele vai rodar:
snippet.
Quem rascunha as regras é o seu próprio assistente; nosso servidor nunca chama um modelo. O que ele rascunha é compilado, verificado e caçado, e você lê a planilha antes de ela ser usada.
$ claude mcp add stalwart -- stalwart mcp
As respostas e o que fazem
| Resposta | O que acontece | Python | Guardrails AI |
|---|---|---|---|
| permitir | a chamada pode rodar | verdict.proceed é verdadeiro |
PassResult |
| confirmar | a pessoa é perguntada; com o sim, a mesma chamada passa | ConfirmationNeeded, ou action == "ask" |
FailResult com stalwart_confirm |
| recusar | nada roda; a frase da regra diz por quê | CallRefused, ou action == "refrain" |
FailResult com a frase |
on_fail escolhe o que uma falha faz: {"refuse": "exception" | "refrain" | "noop", "confirm": "ask" | "exception" |
"refrain"}. noop registra a falha e deixa a chamada rodar, só para uma verificação que pode ser desligada.
Por que uma chamada foi barrada
Cada decisão é guardada, por padrão, num arquivo JSON lines por dia em ~/.stalwart/decisions/ (record=False não
guarda nada; STALWART_DECISIONS muda o lugar): o decision_id, a resposta, a verificação e sua regra, a ferramenta,
os nomes dos argumentos e seus digests, de onde veio o tipo da ferramenta e o que a verificação leu. Nunca o valor de
um argumento e nunca uma palavra do que a pessoa disse. explain_decision(decision_id) no stalwart mcp lê de volta.