IoT e IA

Agente LLM para Dispositivos IoT: Arquitetura, Ferramentas e Proteções de Segurança

Como projetar um agente LLM que lê o estado dos dispositivos via MQTT e envia comandos com segurança, usando cache de estado, ferramentas com schema restrito, camada de políticas, aprovação humana e trilha de auditoria completa.

Diagrama de arquitetura de um agente LLM para dispositivos IoT lendo telemetria MQTT e enviando comandos aprovados por um gate de políticas
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

Um agente LLM para dispositivos IoT pode responder perguntas sobre equipamentos, identificar problemas e executar ações de rotina, mas somente se for projetado de forma que um palpite errado nunca se transforme em um comando perigoso. Este guia apresenta uma arquitetura pensada para produção, em que o agente lê o estado dos dispositivos via MQTT, age apenas por meio de ferramentas estreitas e validadas por schema, e encaminha ações arriscadas para aprovação humana antes que qualquer coisa chegue a um dispositivo.

O que um agente de IoT realmente faz

Um modelo de linguagem sozinho apenas produz texto. Ele se torna um agente quando você lhe dá ferramentas: funções que ele pode pedir ao seu código para executar, como "ler a temperatura mais recente da caldeira 2" ou "definir a velocidade do ventilador na AHU-3". O ciclo funciona assim:

  1. Um usuário ou um gatilho (um alerta, um agendamento) dá um objetivo ao agente.
  2. O modelo decide qual ferramenta chamar e com quais argumentos.
  3. Seu código executa a ferramenta e devolve o resultado.
  4. O modelo raciocina sobre o resultado e chama outra ferramenta ou responde.

Em IoT, as ferramentas tocam o mundo físico. Isso muda completamente as prioridades do projeto: correção e contenção importam muito mais do que esperteza. Um chatbot que alucina dá uma resposta errada; um agente que alucina um setpoint pode superaquecer um processo em uma usina ou na câmara fria de um frigorífico.

Arquitetura de referência

A arquitetura separa o que o modelo pode sugerir daquilo que o sistema vai de fato fazer.

Componente Responsabilidade Comunica-se com
Frota de dispositivos Publica telemetria e estado, executa comandos, envia confirmações Broker MQTT
Broker MQTT Roteia telemetria, comandos e confirmações Todos
Cache de estado Assina os topics de estado e guarda o valor mais recente por dispositivo Broker, ferramentas do agente
Runtime do agente Executa o ciclo do LLM e expõe um pequeno conjunto de ferramentas LLM, cache de estado, gate de políticas
Gate de políticas Valida cada comando proposto contra schema, limites e permissões Runtime do agente, serviço de aprovação
Serviço de aprovação Pede a um humano que aprove ações arriscadas Operadores via dashboard ou chat
Log de auditoria Registra prompts, chamadas de ferramentas, decisões e confirmações dos dispositivos Tudo

O broker é a espinha dorsal. Os dispositivos nunca falam diretamente com o agente, e o agente nunca mantém um socket aberto com um dispositivo. Tudo flui por topics, o que significa que você pode observar, reproduzir e restringir cada interação. Se quiser relembrar o que um broker MQTT faz, ajuda imaginá-lo como a central telefônica pela qual toda mensagem precisa passar.

Organização dos topics

Uma estrutura de topics clara facilita tanto as permissões quanto o raciocínio:

plant1/hvac/ahu-3/state          retained, latest device state (JSON)
plant1/hvac/ahu-3/telemetry      periodic sensor readings
plant1/hvac/ahu-3/cmd            commands addressed to the device
plant1/hvac/ahu-3/cmd/ack        device acknowledgements with result codes
agent/approvals/request          pending approvals for humans
agent/approvals/decision         approve or reject decisions
agent/audit                      every tool call and outcome

Topics de estado com retained message são especialmente valiosos: quando o cache de estado do agente inicia, o broker entrega imediatamente o estado mais recente de cada dispositivo, de modo que o agente nunca raciocina sobre um mundo vazio.

Projetando as ferramentas

A medida de segurança mais eficaz é uma superfície de ferramentas pequena e sem surpresas. Não dê ao modelo uma ferramenta genérica publish(topic, payload). Dê a ele ferramentas no nível de intenção, com parâmetros rigidamente restritos:

{
  "name": "set_fan_speed",
  "description": "Set the supply fan speed of an air handling unit. Speed is a percentage.",
  "parameters": {
    "type": "object",
    "properties": {
      "device_id": { "type": "string", "enum": ["ahu-1", "ahu-2", "ahu-3"] },
      "speed_pct": { "type": "integer", "minimum": 20, "maximum": 90 },
      "reason": { "type": "string", "maxLength": 200 }
    },
    "required": ["device_id", "speed_pct", "reason"],
    "additionalProperties": false
  }
}

Repare nos IDs de dispositivo enumerados, na faixa de inteiros que corresponde ao que o equipamento consegue fazer com segurança e no motivo obrigatório, que acaba indo para o log de auditoria. As ferramentas de leitura seguem o mesmo princípio: get_device_state(device_id) e get_recent_readings(device_id, metric, minutes) são melhores do que dar ao modelo acesso bruto aos topics. Nosso tutorial sobre function calling de LLM para IoT mostra como definir e validar esses schemas de ponta a ponta.

O gate de políticas

Os schemas enviados ao modelo são uma dica, não uma garantia. Modelos podem emitir, e de fato emitem, argumentos fora do schema; por isso, cada chamada de ferramenta precisa ser validada novamente no seu próprio código antes que qualquer coisa seja publicada. O gate abaixo classifica cada comando proposto como rejeitado, aprovado automaticamente ou dependente de aprovação humana.

import json
import time
import uuid
from dataclasses import dataclass

LIMITS = {
    "set_fan_speed": {"devices": {"ahu-1", "ahu-2", "ahu-3"}, "min": 20, "max": 90,
                       "auto_max_step": 10},
}


@dataclass
class Decision:
    status: str          # "rejected", "auto", "needs_approval"
    reason: str
    command: dict | None = None


def evaluate(tool_name: str, args: dict, current_state: dict) -> Decision:
    rule = LIMITS.get(tool_name)
    if rule is None:
        return Decision("rejected", f"unknown tool {tool_name}")
    device = args.get("device_id")
    speed = args.get("speed_pct")
    if device not in rule["devices"]:
        return Decision("rejected", f"device {device!r} not allowed")
    if not isinstance(speed, int) or not rule["min"] <= speed <= rule["max"]:
        return Decision("rejected", f"speed {speed!r} out of range")
    command = {
        "id": str(uuid.uuid4()),
        "action": "set_fan_speed",
        "device": device,
        "value": speed,
        "reason": str(args.get("reason", ""))[:200],
        "issuedAt": int(time.time() * 1000),
    }
    current = current_state.get(device, {}).get("fan_speed_pct")
    if current is None:
        return Decision("needs_approval", "current state unknown", command)
    if abs(speed - current) <= rule["auto_max_step"]:
        return Decision("auto", "small change within policy", command)
    return Decision("needs_approval", f"change of {abs(speed - current)} points exceeds auto limit", command)


def dispatch(client, decision: Decision):
    audit = {"decision": decision.status, "reason": decision.reason, "command": decision.command}
    client.publish("agent/audit", json.dumps(audit), qos=1)
    if decision.status == "auto":
        topic = f"plant1/hvac/{decision.command['device']}/cmd"
        client.publish(topic, json.dumps(decision.command), qos=1)
    elif decision.status == "needs_approval":
        client.publish("agent/approvals/request", json.dumps(decision.command), qos=1, retain=False)
    return audit

O resultado do gate é devolvido ao modelo como saída da ferramenta, para que ele possa dizer ao usuário "esta alteração precisa de aprovação do operador" em vez de afirmar que ela já aconteceu.

Aprovação humana via MQTT

O serviço de aprovação assina agent/approvals/request, mostra a um operador o comando proposto com seu motivo e o estado atual do dispositivo, e publica a decisão. Um pequeno serviço que escuta agent/approvals/decision encaminha os comandos aprovados ao topic do dispositivo, e somente esse serviço possui credenciais com permissão para publicar ali. Aprovações pendentes devem expirar: um pedido para mudar a velocidade de um ventilador com base em condições de uma hora atrás já não é válido. A expiração de mensagens do MQTT 5 se encaixa naturalmente aqui, porque um pedido não atendido simplesmente desaparece do broker ao fim do seu tempo de vida.

Fechando o ciclo com confirmações

Um agente nunca deve presumir que um comando funcionou. Os dispositivos publicam em .../cmd/ack com o ID do comando e um resultado como applied, rejected_local_limit ou device_busy. A ferramenta do agente aguarda a confirmação correspondente com um timeout e relata o resultado com veracidade. Os dispositivos também devem aplicar seus próprios limites: o gate de políticas é uma segunda linha de defesa, não a primeira. Um dispositivo que recusa por conta própria um valor inseguro protege você até mesmo de bugs no gate.

Checklist de segurança para um agente LLM para dispositivos IoT

  1. Apenas ferramentas no nível de intenção; nada de ferramentas de publish bruto ou de shell.
  2. Schemas rígidos com enums, faixas e additionalProperties: false.
  3. Validação independente no código antes de qualquer publish.
  4. Autonomia em níveis: leitura livre, pequenas mudanças automáticas, mudanças grandes ou incomuns com aprovação humana, sistemas críticos de segurança nunca.
  5. Credenciais separadas: o agente pode ler o estado e solicitar ações; somente o dispatcher pode publicar comandos.
  6. Limites no próprio dispositivo e confirmações com códigos de resultado.
  7. Limites de taxa de comandos por dispositivo e por janela de tempo.
  8. Trilha de auditoria completa de prompts, chamadas de ferramentas, decisões e confirmações.
  9. Atenção a prompt injection: campos de texto vindos de dispositivos ou chamados são dados, nunca instruções.

O item 9 merece destaque. Se o nome de um dispositivo, uma mensagem de alarme ou uma nota de manutenção contiver um texto como "ignore as instruções anteriores", um agente ingênuo pode obedecer. Mantenha esses campos claramente marcados como dados no prompt e, mais importante, confie no gate de políticas para que nem mesmo um modelo manipulado consiga ultrapassar suas permissões. Abordamos esse modelo de ameaças em profundidade em controle seguro de dispositivos IoT com IA.

Onde o broker entra em produção

O padrão de agente adiciona mais clients e mais tipos de tráfego ao seu broker: caches de estado, serviços de aprovação, consumidores de auditoria e dashboards. Executar tudo isso em um broker MQTT gerenciado significa que TLS, autenticação e escalabilidade ficam por conta do provedor. O ConnectMQ vincula cada client ID às credenciais emitidas para ele, então você pode dar identidades separadas ao runtime do agente e ao dispatcher de comandos e ver cada um deles no portal. Como a plataforma não oferece regras de acesso por topic, aplique a separação entre leitura e ação nos seus serviços e mantenha as credenciais do dispatcher fora do host do agente.

Para prototipar, execute o ciclo completo no servidor MQTT público (gratuito), pensado para testes e protótipos e não para dados de produção, com dispositivos simulados e um prefixo de topic exclusivo, como connectmq/demo/c42b7e/..., e depois migre para credenciais privadas antes de conectar equipamentos reais. Se preferir manter o modelo on-premises, veja como executar um LLM local com Ollama e MQTT e, para um panorama mais amplo de IA em dispositivos conectados, leia nosso guia de IA e IoT.

Comece com o ConnectMQ

Dê ao seu agente uma espinha dorsal de mensagens confiável. O ConnectMQ oferece MQTT 3.1.1 e 5.0 com TLS, WebSockets, retained messages e expiração de mensagens. Crie um broker Serverless gratuito, sem cartão de crédito, e comece hoje mesmo a construir o ciclo do seu agente com dispositivos simulados.

Perguntas frequentes

Um agente LLM deve algum dia controlar equipamentos críticos de segurança?

Não. Funções de segurança pertencem a sistemas de segurança certificados e a intertravamentos locais. Um agente pode recomendar ações ou ajustar setpoints não críticos dentro de limites estreitos, mas não deve fazer parte de uma cadeia de segurança.

Por que não deixar o modelo publicar mensagens MQTT diretamente?

Uma ferramenta genérica de publish permite que o modelo escreva em qualquer topic com qualquer payload, o que torna a validação quase impossível. Ferramentas no nível de intenção com schemas rígidos mantêm o espaço de ações pequeno e verificável.

Como o agente sabe o estado atual do dispositivo?

Um cache de estado assina os topics de estado com retained message e guarda o valor mais recente por dispositivo. O agente o consulta por meio de ferramentas de leitura, em vez de assinar os topics ele mesmo.

O que acontece se o dispositivo rejeitar um comando?

O dispositivo publica uma confirmação com um código de motivo, e o agente relata esse resultado ao usuário em vez de presumir sucesso.

Artigos relacionados

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.