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 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 üretim ortamına girdikçe klasik incident response süreçleri yetersiz kalıyor. Bu yazıda kontrolden çıkan otonom sistemleri anında dizginlemek için uygulayabileceğimiz rollback stratejilerini ve ajan gözlemlenebilirliği (observability) mimarilerini kod ve konfigürasyon örnekleriyle ele alıyoruz.
Ajan kaosu: klasik rollback neden işe yaramaz?
Klasik bir deployment’ta rollback yaptığınızda uygulamanın durumunu (state) değil, çalıştırdığı kodu geri alırsınız. 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 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 yetmez. CPU %10’dayken bile bir ajan şirket kredi kartını limitsiz API çağrılarıyla eritiyor olabilir. İzlememiz gereken metrikler ajana özel olmalı:
- Token Velocity (Saniyede Tüketilen Token): Beklenmedik ş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şmamalı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üşmesidir.
Aşağıdaki Prometheus metrik tanımı ve Python middleware örneğiyle ajanın her tool çağrısını nasıl takip edeceğ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
Bir ajan döngüye girdiyse ve veritabanını bozuyorsa ilk yapılacak şey, ajanın dış dünya ve LLM sağlayıcıları (OpenAI, Anthropic vb.) ile 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
Komut çalıştığı an kural devreye girer ve ajanın LLM API’leriyle iletişimi kesilir. Ajan 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? Örneğin son 5 dakika içinde 100 farklı kullanıcının yetki tablosunu güncellediyse?
Bu yüzden otonom kararlar alan ajan sistemlerinde doğrudan “State Mutation” yapmak yerine Event Sourcing kullanmak şart. Ajan doğrudan veritabanına yazmamalı; yapmak istediği eylemleri birer “Event” olarak fırlatmalı. Bu mimari olay anında Saga Pattern veya Compensating Transactions (Telafi Edici İşlemler) uygulama şansı verir.
Örnek bir Redis tabanlı event loglama ve geri alma mekanizması kuralı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ındadı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ı. Böylece tek bir API çağrısıyla ajanın tüm davranış şemasını anında değiştirebilirsiniz.
Özet ve SRE yol haritası
Geleceğin DevOps işi yalnızca statik kodları değil, kendi kararlarını veren dinamik ajanların yönetimini de kapsayacak. 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.