Skip to content
← Voltar aos artigos

Artigo

Guardrails e Fitness Functions para uma Arquitetura Amigável à IA

Este é o quinto artigo da série sobre arquitetura amigável à IA. Já discutimos como os agentes encontram contexto, usam skills e trabalham com conhecimento especializado.

Agora precisamos responder a duas perguntas:

Dar contexto a um agente não significa dar a ele acesso ilimitado ao sistema.

Instruções não são controles de segurança

Um ponto de partida comum é adicionar uma regra ao prompt ou a uma skill:

Use the production API only for read operations.
Never change data.
Never access admin endpoints.

Essa orientação pode ajudar a direcionar o comportamento do agente, mas não deve ser tratada como uma barreira de segurança.

O agente pode receber novos documentos, combinar informações de fontes diferentes e ler o código da aplicação. Um texto que diz ao agente para seguir uma regra também pode conter instruções conflitantes ou mostrar maneiras de contorná-la.

O mesmo vale para verificações feitas dentro de uma skill ou por meio de uma integração MCP. Se a mesma camada que executa a ação decide se ela é segura com base no contexto fornecido ao agente, esse contexto pode ser alterado ou interpretado de forma inesperada.

O MCP pode ajudar a conectar um agente a sistemas e ferramentas, mas a conexão em si não é um limite de segurança. A autorização deve existir no serviço que protege o recurso.

Até o acesso de leitura pode criar um problema

Imagine que queremos ajudar um agente a investigar um incidente. Para isso, damos a ele um token que permite requisições GET à API de produção.

À primeira vista, isso parece seguro. O agente não pode alterar pedidos, reiniciar serviços ou mudar configurações.

Mas, ao ler o código, a documentação e os contratos da aplicação, o agente pode descobrir outros endpoints disponíveis. Ele pode encontrar rotas administrativas, parâmetros internos, conexões entre recursos ou formas indiretas de obter dados que não deveriam fazer parte da investigação.

O problema não é apenas o método HTTP usado pela requisição. O problema é o conjunto de recursos que o agente consegue alcançar, os dados que recebe e as conexões que pode descobrir.

Por isso, não basta dizer:

GET is allowed.
POST, PUT, and DELETE are not allowed.

Precisamos perguntar:

Como fornecer contexto sem abrir a produção

Existem formas mais seguras de fornecer informações para uma investigação.

Um token com escopo limitado

Em vez de dar ao agente uma credencial de API genérica, podemos criar uma credencial específica para ele:

principal: incident-investigation-agent
resource: orders-observability-api
operations:
  - read:incident-summary
  - read:service-health
  - read:dependency-latency
data_policy:
  - exclude:customer.personal_data
  - exclude:payment.card_data
expiration: 15 minutes

O serviço que recebe essa credencial deve validar seu escopo. Uma descrição no prompt não substitui essa validação.

Dados derivados para investigação

Também podemos manter o agente longe da aplicação de produção. Eventos, métricas, logs sanitizados e informações operacionais podem ser enviados para um local separado de consultas, como uma réplica, um data lake ou um data warehouse.

Context Without Opening Production

Essa camada pode aplicar retenção, anonimização, filtragem de campos e um atraso antes que os dados fiquem disponíveis. O agente recebe contexto suficiente para investigar sem ganhar uma porta de entrada para a aplicação de produção.

O banco de dados com o menor privilégio possível

Quando o acesso direto ao banco for realmente necessário, ele deve ser criado para a tarefa. Não deve reutilizar uma credencial da aplicação:

CREATE ROLE incident_reader LOGIN PASSWORD 'managed-externally';

GRANT CONNECT ON DATABASE operations TO incident_reader;
GRANT USAGE ON SCHEMA incident_data TO incident_reader;
GRANT SELECT ON incident_data.service_health TO incident_reader;
GRANT SELECT ON incident_data.request_summary TO incident_reader;

REVOKE ALL ON SCHEMA billing FROM incident_reader;
REVOKE ALL ON SCHEMA customers FROM incident_reader;

Além de ser somente leitura, esse usuário deve ter acesso apenas às tabelas, views ou schemas necessários para a tarefa. Views de investigação podem ocultar dados sensíveis e limitar a quantidade de informações retornadas.

A ideia é simples: não devemos confiar que o agente evitará tabelas perigosas. O banco deve bloquear o acesso mesmo que o agente tente consultar algo fora do seu escopo.

Guardrails

Guardrails são mecanismos externos às intenções do agente que validam, limitam ou bloqueiam ações. Eles podem existir na identidade, na rede, na API, no banco de dados, no sistema de arquivos ou no processo de aprovação.

Um guardrail realista não é uma instrução if dentro de um prompt. É uma política aplicada pelo serviço que recebe a requisição.

A política pode verificar identidade, recurso, operação, parâmetros, campos solicitados, quantidade de dados e ambiente. Se qualquer condição não for atendida, a requisição é rejeitada antes de chegar ao recurso protegido.

Para mudanças, podemos separar preparação de execução.

O agente não recebe a credencial de execução. Mesmo que crie uma instrução errada, a camada de execução ainda aplica suas próprias regras.

Exemplo: um incidente de CPU

Durante um incidente, a investigação pode mostrar que os pods estão ficando sem CPU. O agente pode conectar os sinais, formular uma hipótese e preparar uma mudança no repositório de infraestrutura.

Ele também pode abrir o pull request e criar a solicitação de mudança. Mas a mudança ainda depende de uma pessoa responsável. Essa pessoa revisa o impacto, aprova a solicitação e faz ou aprova o merge. Depois disso, o pipeline aplica a mudança aos pods.

From Incident to Controlled Change

Guardrails também podem limitar caminhos de arquivos, destinos de rede, tamanho de consultas, tempo de execução, quantidade de registros e tipos de dados retornados.

Fitness functions determinísticas

Fitness functions vêm da arquitetura evolutiva. Elas transformam uma característica arquitetural importante em uma verificação objetiva e contínua.

Uma fitness function não precisa de IA para decidir o resultado. Ela pode ser um teste de arquitetura, uma regra do pipeline, uma análise estática, uma consulta a metadados ou uma verificação periódica. Com o mesmo estado de entrada, o resultado deve ser reproduzível.

O objetivo não é avaliar se a resposta do agente parece boa. O objetivo é verificar se a arquitetura ainda possui as propriedades que consideramos importantes.

Exemplo com Deptrac

Um exemplo real é o Deptrac, uma ferramenta de análise estática para projetos PHP. Ela permite definir camadas arquiteturais e as dependências permitidas entre elas.

Imagine um sistema com dois contextos: Orders e Billing. Uma decisão arquitetural pode determinar que Orders não deve importar diretamente classes internas de Billing. A comunicação deve acontecer por meio de um contrato público.

Essa regra pode ser descrita em uma configuração do Deptrac:

deptrac:
  paths:
    - ./src

  layers:
    - name: Orders
      collectors:
        - type: classLike
          value: .*\\Orders\\.*

    - name: Billing
      collectors:
        - type: classLike
          value: .*\\Billing\\.*

    - name: Shared
      collectors:
        - type: classLike
          value: .*\\Shared\\.*

  ruleset:
    Orders:
      - Shared
    Billing:
      - Shared

Com essa regra, uma classe em Orders que importe diretamente uma classe de Billing cria uma violação. O pipeline pode executar:

vendor/bin/deptrac analyse --config-file=deptrac.yaml

O resultado é determinístico. O Deptrac não precisa entender a intenção do agente, avaliar a qualidade do código gerado ou interpretar um prompt. Ele apenas verifica as dependências no código em relação às regras definidas pela equipe.

Se um agente criar uma nova classe e adicionar uma dependência proibida, o pull request falhará mesmo que o agente tenha sido instruído a respeitar os limites. A fitness function protege a decisão arquitetural à medida que o sistema muda.

Conclusão

Uma arquitetura amigável à IA não é apenas uma arquitetura que permite ao agente fazer mais. É uma arquitetura que fornece contexto sem transformar cada fonte de informação em uma nova superfície de ataque.

Prompts, skills e integrações ajudam a orientar o agente, mas não devem ser a última linha de defesa. As permissões precisam ser aplicadas pelos recursos protegidos, com identidade, menor privilégio, escopo, auditoria e possibilidade de revogar o acesso.

Guardrails limitam ações em tempo de execução. Fitness functions determinísticas verificam se essas proteções continuam presentes à medida que a arquitetura muda.

Para saber mais sobre fitness functions, leia Architectural Fitness Functions, da Yonder e Fitness Function Driven Development, da Thoughtworks.

No próximo artigo, mostraremos como dividir um grande bloco de conhecimento em contextos especializados, organizados por domínio, responsabilidade e objetivo.

Compartilhar LinkedIn WhatsApp X

Receba os novos artigos por e-mail

Um e-mail quando sai artigo novo, em português e inglês. Sem spam, e dá pra sair quando quiser.

Comentários