IoT ve Yapay Zekâ

IoT Cihazları için LLM Ajanı: Mimari, Araçlar ve Güvenlik Önlemleri

Durum önbelleği, şemayla kısıtlanmış araçlar, bir politika katmanı, insan onayı ve eksiksiz bir denetim kaydıyla MQTT'den cihaz durumunu okuyan ve komutları güvenle gönderen bir LLM ajanı nasıl tasarlanır?

MQTT telemetrisini okuyan ve onaylanmış komutları bir politika kapısından geçirerek gönderen, IoT cihazları için LLM ajanı mimari diyagramı
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

IoT cihazları için bir LLM ajanı ekipmanla ilgili soruları yanıtlayabilir, sorunları fark edebilir ve rutin işlemleri yürütebilir; ancak yalnızca hatalı bir tahminin asla tehlikeli bir komuta dönüşemeyeceği şekilde tasarlanmışsa. Bu rehber, ajanın cihaz durumunu MQTT'den okuduğu, yalnızca dar ve şemayla doğrulanmış araçlar üzerinden hareket ettiği ve riskli işlemleri herhangi bir şey cihaza ulaşmadan önce insan onayına yönlendirdiği, üretim ortamı düşünülerek kurgulanmış bir mimariyi adım adım anlatıyor.

Bir IoT Ajanı Aslında Ne Yapar?

Bir dil modeli tek başına yalnızca metin üretir. Ona araçlar verdiğinizde ajana dönüşür: "kazan 2'nin en son sıcaklığını oku" ya da "AHU-3'te fan hızını ayarla" gibi, kodunuzdan çalıştırmasını isteyebileceği fonksiyonlar. Döngü şöyle işler:

  1. Bir kullanıcı ya da bir tetikleyici (bir alarm, bir zamanlama) ajana bir hedef verir.
  2. Model hangi aracı hangi argümanlarla çağıracağına karar verir.
  3. Kodunuz aracı çalıştırır ve sonucu döndürür.
  4. Model sonuç üzerinde akıl yürütür ve ya başka bir aracı çağırır ya da yanıt verir.

IoT'de araçlar fiziksel dünyaya dokunur. Bu da tasarım önceliklerini tamamen değiştirir: doğruluk ve sınırlama, zekâdan çok daha önemlidir. Halüsinasyon gören bir sohbet botu yanlış bir yanıt verir; bir ayar noktasını halüsinasyonla uyduran bir ajan ise bir prosesi aşırı ısıtabilir.

Referans Mimari

Mimari, modelin önerebileceği şeyi sistemin yapacağı şeyden ayırır.

Bileşen Sorumluluk İletişim kurduğu taraf
Cihaz filosu Telemetri ve durum yayınlar, komutları yürütür, onay (ack) gönderir MQTT broker
MQTT broker Telemetri, komut ve onay mesajlarını yönlendirir Herkes
Durum önbelleği Durum topic'lerine abone olur ve her cihaz için en son değeri tutar Broker, ajan araçları
Ajan çalışma ortamı LLM döngüsünü çalıştırır ve küçük bir araç setini sunar LLM, durum önbelleği, politika kapısı
Politika kapısı Önerilen her komutu şema, limitler ve izinlere göre doğrular Ajan çalışma ortamı, onay servisi
Onay servisi Riskli işlemler için bir insandan onay ister Dashboard veya sohbet üzerinden operatörler
Denetim kaydı Prompt'ları, araç çağrılarını, kararları ve cihaz onaylarını kaydeder Her şey

Omurga broker'dır. Cihazlar ajanla asla doğrudan konuşmaz ve ajan bir cihaza asla soket bağlantısı tutmaz. Her şey topic'ler üzerinden akar; bu da her etkileşimi gözlemleyebileceğiniz, yeniden oynatabileceğiniz ve kısıtlayabileceğiniz anlamına gelir. Bir MQTT broker'ın ne yaptığını hatırlamak isterseniz, onu her mesajın geçmek zorunda olduğu bir santral olarak düşünmek işinizi kolaylaştırır.

Topic Düzeni

Net bir topic yapısı hem izinleri hem de akıl yürütmeyi kolaylaştırır:

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

Retained durum topic'leri özellikle değerlidir: ajanın durum önbelleği başladığında broker her cihazın en son durumunu hemen iletir, böylece ajan asla boş bir dünya üzerinde akıl yürütmez.

Araçları Tasarlamak

En etkili tek güvenlik önlemi küçük ve sıradan bir araç yüzeyidir. Modele genel bir publish(topic, payload) aracı vermeyin. Ona parametreleri sıkı biçimde kısıtlanmış, niyet düzeyinde araçlar verin:

{
  "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
  }
}

Numaralandırılmış (enum) cihaz kimliklerine, ekipmanın güvenle yapabileceği işle eşleşen tam sayı aralığına ve denetim kaydına düşen zorunlu gerekçe alanına dikkat edin. Okuma araçları da aynı ilkeyi izler: get_device_state(device_id) ve get_recent_readings(device_id, metric, minutes), modele ham topic erişimi vermekten daha iyidir. IoT için LLM function calling eğitimimiz bu şemaların uçtan uca nasıl tanımlanıp doğrulanacağını gösteriyor.

Politika Kapısı

Modele gönderilen şemalar bir garanti değil, bir ipucudur. Modeller şemanın dışında argümanlar üretebilir ve üretir de; bu yüzden her araç çağrısı, herhangi bir şey yayınlanmadan önce kendi kodunuzda yeniden doğrulanmalıdır. Aşağıdaki kapı, önerilen her komutu reddedildi, otomatik onaylandı ya da insan onayı gerekiyor olarak sınıflandırır.

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

Kapının sonucu modele araç çıktısı olarak döndürülür; böylece model, değişikliğin zaten yapıldığını iddia etmek yerine kullanıcıya "bu değişiklik operatör onayı gerektiriyor" diyebilir.

MQTT Üzerinden İnsan Onayı

Onay servisi agent/approvals/request topic'ine abone olur, önerilen komutu gerekçesi ve cihazın mevcut durumuyla birlikte bir operatöre gösterir ve kararı yayınlar. agent/approvals/decision topic'ini dinleyen küçük bir servis onaylanan komutları cihaz topic'ine iletir ve oraya yayın yapma yetkisine sahip kimlik bilgilerini yalnızca bu servis tutar. Bekleyen onayların süresi dolmalıdır: bir saat önceki koşullara dayanan bir fan hızı değişikliği talebi artık geçerli değildir. MQTT 5'in mesaj süresi dolumu (message expiry) özelliği buna doğal olarak uyar, çünkü sahiplenilmeyen bir talep ömrü dolduğunda broker'dan kendiliğinden kaybolur.

Onaylarla Döngüyü Kapatmak

Bir ajan, bir komutun işe yaradığını asla varsaymamalıdır. Cihazlar .../cmd/ack topic'ine komut kimliğiyle birlikte applied, rejected_local_limit veya device_busy gibi bir sonuç yayınlar. Ajanın aracı eşleşen onayı bir zaman aşımıyla bekler ve sonucu dürüstçe raporlar. Cihazlar kendi limitlerini de uygulamalıdır: politika kapısı ilk değil, ikinci savunma hattıdır. Güvenli olmayan bir değeri kendi başına reddeden bir cihaz, sizi kapıdaki hatalardan bile korur.

IoT Cihazları için LLM Ajanında Güvenlik Kontrol Listesi

  1. Yalnızca niyet düzeyinde araçlar; ham publish veya shell araçları yok.

  2. Enum'lar, aralıklar ve additionalProperties: false içeren katı şemalar.

  3. Herhangi bir yayından önce kodda bağımsız doğrulama.

  4. Kademeli özerklik: serbestçe okuma, küçük değişiklikler otomatik, büyük veya olağandışı değişiklikler insan onayıyla, güvenlik açısından kritik sistemler asla.

  5. Ayrı kimlik bilgileri: ajan durumu okuyabilir ve işlem talep edebilir; komutları yalnızca dağıtıcı (dispatcher) yayınlayabilir.

  6. Cihaz tarafında limitler ve sonuç kodlu onaylar.

  7. Cihaz başına ve zaman penceresi başına komut hız sınırları.

  8. Prompt'ların, araç çağrılarının, kararların ve onayların eksiksiz denetim kaydı.

  9. Prompt injection farkındalığı: cihazlardan veya kayıtlardan gelen metin alanları talimat değil, veridir.

  10. madde özellikle vurgulanmayı hak ediyor. Bir cihaz adı, bir alarm mesajı veya bir bakım notu "önceki talimatları yok say" gibi bir metin içeriyorsa, saf bir ajan buna uyabilir. Bu tür alanları prompt'ta açıkça veri olarak işaretleyin ve daha da önemlisi, manipüle edilmiş bir modelin bile yetkilerini aşamaması için politika kapısına güvenin. Bu tehdit modelini IoT cihazlarının güvenli yapay zeka kontrolü yazımızda ayrıntılı olarak ele alıyoruz.

Üretimde Broker'ın Yeri

Ajan deseni broker'ınıza daha fazla client ve daha fazla trafik türü ekler: durum önbellekleri, onay servisleri, denetim tüketicileri ve dashboard'lar. Bunu tam yönetilen bir MQTT servisinde çalıştırmak, TLS, kimlik doğrulama ve ölçeklemenin sizin yerinize halledilmesi demektir. ConnectMQ her client ID'yi kendisine verilen kimlik bilgilerine bağlar; böylece ajan çalışma ortamına ve komut dağıtıcısına ayrı kimlikler verebilir ve her birini portalda görebilirsiniz. Platform topic bazında erişim kuralları sunmadığından, okuma/eylem ayrımını servislerinizde uygulayın ve dağıtıcı kimlik bilgilerini ajanın çalıştığı makineden uzak tutun.

Prototipleme için tüm döngüyü simüle edilmiş cihazlarla ve connectmq/demo/c42b7e/... gibi benzersiz bir topic önekiyle herkese açık MQTT test broker'ı üzerinde çalıştırın, ardından gerçek ekipmanı bağlamadan önce özel kimlik bilgilerine geçin. Modeli şirket içinde tutmayı tercih ediyorsanız Ollama ve MQTT ile yerel LLM çalıştırmayı inceleyin; bağlantılı cihazlarda yapay zekanın daha geniş tablosu için de yapay zeka ve IoT rehberimizi okuyun.

ConnectMQ ile Başlayın

Ajanınıza güvenilir bir mesaj omurgası verin. ConnectMQ; TLS, WebSocket, retained message ve mesaj süresi dolumu desteğiyle MQTT 3.1.1 ve 5.0 sunar. Kredi kartı gerektirmeden ücretsiz bir Serverless broker oluşturun ve ajan döngünüzü simüle edilmiş cihazlarla bugün kurmaya başlayın.

Sık Sorulan Sorular

Bir LLM ajanı güvenlik açısından kritik ekipmanı hiç kontrol etmeli mi?

Hayır. Güvenlik fonksiyonları sertifikalı güvenlik sistemlerine ve yerel kilitlemelere (interlock) aittir. Bir ajan işlem önerebilir veya kritik olmayan ayar noktalarını dar limitler içinde ayarlayabilir, ancak bir güvenlik zincirinin parçası olmamalıdır.

Neden modelin MQTT mesajlarını doğrudan yayınlamasına izin vermiyoruz?

Genel bir publish aracı, modelin herhangi bir topic'e herhangi bir payload yazmasına olanak tanır ve bu da doğrulamayı neredeyse imkânsız hâle getirir. Katı şemalara sahip niyet düzeyindeki araçlar eylem alanını küçük ve denetlenebilir tutar.

Ajan cihazın mevcut durumunu nasıl bilir?

Bir durum önbelleği retained durum topic'lerine abone olur ve her cihaz için en son değeri tutar. Ajan kendisi abone olmak yerine bu önbelleği okuma araçları aracılığıyla sorgular.

Cihaz bir komutu reddederse ne olur?

Cihaz bir gerekçe koduyla birlikte bir onay mesajı yayınlar ve ajan başarılı olduğunu varsaymak yerine bu sonucu kullanıcıya bildirir.

İlgili yazılar

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.