Canlı Ortamda Kontrolden Çıkan Yapay Zeka Ajanları Nasıl Durdurulur? Agentic Rollback Stratejileri
Geleneksel mikroservisler çöktüğünde ne yapacağımızı çok iyi biliyoruz: OOMKilled logunu görürüz, Kubernetes pod’u yeniden başlatır, en kötü ihtimalle bir önceki kararlı imaja geri döneriz. Peki ya canlı ortamda kendi kendine tool çalıştıran, veritabanı şemalarını manipüle eden veya üçüncü parti API limitlerinizi saniyeler içinde eriten bir agentic ai sistemi kontrolden çıkarsa? LLM tabanlı otonom ajanların üretim ortamında yer aldığı bu yeni çağda, klasik incident response süreçleri yetersiz kalıyor. Bu yazıda, kontrolden çıkan otonom sistemleri anında dizginlemek için uygulayabileceğimiz pratik rollback strategies ve ai agent observability mimarilerini doğrudan kod ve konfigürasyon örnekleriyle ele alıyoruz.
Ajan Kaosu: Klasik Rollback Neden İşe Yaramaz?
Klasik bir deployment’ta rollback yaptığınızda, uygulamanın durumunu (state) değil, uygulamanın çalıştırdığı kodu geri alırsınız. Ancak ajanlarda durum farklıdır. Bir ajan kontrolden çıktığında sorun kodun kendisinde değil, ajanın o anki “çalışma belleğinde” (context/memory), aldığı otonom kararlarda ve bu kararlar doğrultusunda tetiklediği harici tool’lardadır.
Örneğin, bir müşteri ilişkileri ajanı düşünün. Bir prompt injection veya beklenmedik bir API yanıtı yüzünden sonsuz bir döngüye (hallucination cascade) girdi ve her döngüde veritabanına yeni kayıtlar ekleyip müşterilere SMS gönderiyor. Bu ajanın pod’unu restart etmek hiçbir işe yaramaz; çünkü ajan ayağa kalktığında veritabanındaki kirli state’i veya mesaj kuyruğundaki bekleyen görevleri okuyup kaldığı yerden çılgınlığına devam edecektir. Bize kod tabanlı değil, state ve ağ tabanlı müdahale mekanizmaları gerekiyor.
1. AI Agent Observability: Felaketi Erken Teşhis Etmek
Bir ajanın raydan çıktığını anlamak için geleneksel CPU/Memory metrikleri tek başına yetersizdir. CPU %10’dayken de bir ajan şirket kredi kartını limitsiz API çağrılarıyla eritiyor olabilir. İzlememiz gereken metrikler ajana özel olmalıdır:
- Token Velocity (Saniyede Tüketilen Token): Beklenmedik bir şekilde tavan yapan token tüketimi, ajanın bir döngüye girdiğinin en net göstergesidir.
- Tool Execution Depth (Araç Çağrı Derinliği): Bir ajanın tek bir kullanıcı isteğini çözmek için ardışık olarak çağırdığı araç (tool) sayısı sınırı aşmalıdır.
- Semantic Drift (Anlamsal Sapma): Ajanın LLM’e gönderdiği sistem prompt’u ile LLM’den dönen yanıtların anlamsal benzerliğinin (cosine similarity) hızla düşmesi.
Aşağıdaki Prometheus metrik tanımı ve bir Python middleware örneğiyle, ajanın her tool çağrısını nasıl takip edebileceğimizi ve limiti aşanları nasıl engelleyeceğimizi görelim:
# Prometheus metriklerini expose etmek için örnek bir Python izleme katmanı
from prometheus_client import Counter, Histogram, Gauge
import time
# Metriklerin tanımlanması
AGENT_TOOL_CALLS = Counter('agent_tool_calls_total', 'Total number of tool executions', ['agent_id', 'tool_name'])
AGENT_LOOP_DEPTH = Gauge('agent_loop_depth', 'Current execution steps for a single task', ['agent_id', 'session_id'])
LLM_TOKEN_USAGE = Counter('llm_token_usage_total', 'Total tokens consumed', ['agent_id', 'token_type'])
class AgentSupervisor:
def __init__(self, agent_id: str, max_allowed_steps: int = 10):
self.agent_id = agent_id
self.max_allowed_steps = max_allowed_steps
def verify_step(self, session_id: str, current_step: int, tool_name: str):
# Derinlik kontrolü
AGENT_LOOP_DEPTH.labels(agent_id=self.agent_id, session_id=session_id).set(current_step)
AGENT_TOOL_CALLS.labels(agent_id=self.agent_id, tool_name=tool_name).inc()
if current_step > self.max_allowed_steps:
# Kritik eşik aşıldı, alarm üret ve akışı kes
raise RuntimeError(f"LIMIT_EXCEEDED: Agent {self.agent_id} exceeded maximum step depth of {self.max_allowed_steps} in session {session_id}!")
2. Acil Müdahale: Network Isolation ve Kill-Switch
Eğer bir ajan döngüye girdiyse ve veritabanını bozuyorsa, ilk yapılması gereken şey ajanın dış dünya ve LLM sağlayıcıları (OpenAI, Anthropic vb.) ile olan bağını kesmektir. SRE ekipleri için en hızlı aksiyon, Kubernetes seviyesinde uygulanacak dinamik bir acil durum ağ politikasıdır (NetworkPolicy).
Aşağıdaki Kubernetes NetworkPolicy örneği, etiketlenmiş ajan pod’larının dış dünyadaki LLM API’lerine (Egress) erişimini saniyeler içinde engellemek için kullanılabilir:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: isolate-rogue-agent
namespace: production
spec:
podSelector:
matchLabels:
app: agentic-worker
status: quarantine # Acil durumda bu etiketi set edeceğiz
policyTypes:
- Egress
egress:
# Sadece cluster içi DNS çözümlemesine izin ver, dış dünyaya giden tüm HTTP/HTTPS trafiğini engelle
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
Bir olay anında (incident response sırasında), SRE mühendisi tek bir komutla ajanı karantinaya alabilir:
kubectl label pods -l app=agentic-worker status=quarantine --overwrite -n production
Bu komut çalıştırıldığı an, kural devreye girer. Ajanın LLM API’leri ile olan iletişimi kesilir. Ajan artık yeni kararlar alamayacağı için güvenli bir şekilde durma noktasına (halt state) gelir.
3. State Rollback: Event Sourcing Yaklaşımı
Ajanı durdurduk. Peki ya ajanın veritabanında yaptığı tahribat ne olacak? Örneğin, son 5 dakika içinde 100 farklı kullanıcının yetki tablosunu güncellediyse?
İşte bu yüzden, otonom kararlar alan ajan sistemlerinde doğrudan “State Mutation” yapmak yerine Event Sourcing kullanılması şarttır. Ajan doğrudan veritabanına yazmamalı; bunun yerine yapmak istediği eylemleri birer “Event” olarak fırlatmalıdır. Bu mimari bize olay anında Saga Pattern veya Compensating Transactions (Telafi Edici İşlemler) uygulama şansı verir.
Örnek bir Redis tabanlı event loglama ve geri alma mekanizması kurgulayalım:
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
def execute_agent_action(session_id: str, action_type: str, payload: dict):
# Ajanın yaptığı her işlemi logla (Saga Log)
event_id = r.incr(f"session:{session_id}:event_counter")
event_data = {
"event_id": event_id,
"action_type": action_type,
"payload": payload,
"status": "executed"
}
# Event listesine ekle
r.rpush(f"session:{session_id}:events", json.dumps(event_data))
# Gerçek işlemi simüle et
print(f"Executing: {action_type} with {payload}")
def rollback_session(session_id: str):
# Geriye doğru telafi işlemlerini çalıştır (LIFO order)
events = r.lrange(f"session:{session_id}:events", 0, -1)
for event_raw in reversed(events):
event = json.loads(event_raw)
action_type = event["action_type"]
payload = event["payload"]
print(f"CRITICAL ROLLBACK: Reversing {action_type} for payload {payload}")
if action_type == "CREATE_USER":
# Kullanıcıyı sil veya pasife al
print(f"Compensating: Deleting user {payload['user_id']}")
elif action_type == "UPDATE_BALANCE":
# Bakiyeyi eski haline getir
print(f"Compensating: Restoring balance for account {payload['account_id']} by -{payload['amount']}")
# Temizlik
r.delete(f"session:{session_id}:events")
4. Dynamic Prompt Rollback (Sıcak Prompt Değişimi)
Bazen sorun sistem altyapısında değil, ajanın LLM’e gönderdiği “Sistem Prompt’u” üzerindeki mantık hatasıdır. Canlı ortamda ajanın kodunu yeniden deploy etmek (CI/CD pipeline beklemek) yerine, prompt’ları dinamik bir konfigürasyon deposundan (örneğin Consul, Spring Cloud Config veya Redis) beslemek gerekir.
Kritik bir hata anında, prompt versiyonunu saniyeler içinde eski haline (rollback) getirebilmeliyiz:
# Consul veya benzeri bir K/V store üzerinden prompt versiyonunu rollback etme
curl --request PUT \
--data '{"version": "v1.2.0", "prompt": "You are a helpful assistant. Do NOT execute any DB mutations without direct human approval."}' \
http://localhost:8500/v1/kv/agents/customer-support/system-prompt
Ajan kodunuz her yeni oturum açılışında bu dinamik değeri okuyacak şekilde tasarlanmalıdır. Böylece tek bir API çağrısıyla tüm ajanın davranış şemasını anında değiştirebilirsiniz.
Özet ve SRE Yol Haritası
Geleceğin DevOps dünyası, sadece statik kodların değil, kendi kararlarını veren dinamik ajanların yönetimi üzerine kuruluyor. Canlı ortamda huzurlu uyumak istiyorsanız, şu adımları üretim mimarinize şimdiden dahil edin:
- Ajanlarınızı izole namespace’lerde çalıştırın ve acil durumlar için ağ seviyesinde NetworkPolicy hazır bulundurun.
- Ajanların veritabanlarına doğrudan SQL çalıştırmasına asla izin vermeyin; bunun yerine gated tool calling (onay mekanizmaları) ve event-driven mimariler kullanın.
- Token-rate limits uygulayarak bütçenizi ve altyapınızı sonsuz döngülerden koruyun.
- Prometheus üzerinde
agent_loop_depthmetriği için acil durum alarmları kurun.