Temenni Değil, Politika
Microsoft Agent Governance Toolkit’i, elle kurduğum sözleşmenin yanına koyarak okumak.
İlk üç yazıda aynı cümlenin etrafında döndüm: modelin verdiği her cevabın arkasında ya doğrulanabilir bir kaynak vardır ya da açık bir refusal vardır.
İlk yazıda problemi koymuştum: chatbot yazmak ile güvenli bir sistem tasarlamak aynı şey değil. İkinci yazıda bu fikri .NET tarafında bir refusal ve citation sözleşmesine çevirdim. Retrieval yoksa cevap yok. Model bozuk JSON döndürürse cevap yok. Model kendisi reddederse bunu bozmuyoruz. Citation varsa da o citation gerçekten retrieval'dan gelen kaynak listesinde olmak zorunda.
Üçüncü yazıda bunu mock dünyasından çıkardım; gerçek Azure AI Search, gerçek Azure OpenAI ve gerçek bir eval akışıyla denedim. Yani mesele artık "böyle tasarladım" seviyesinde kalmadı; sistemin ne yaptığını ölçmeye başladık.
Aslında üç yazı boyunca yaptığımız şey şuydu: model cevabı kullanıcıya gitmeden önce uygulama koduna deterministik bir kapı koymak. "Lütfen kurallara uy" demek yerine, kuralı ihlal eden cevabın dışarı çıkamayacağı bir akış kurmak.
Ben bu kapıyı RAG cevabı için elle yazdım. Microsoft ise aynı fikrin daha genel hâlini açık kaynak olarak yayımladı: Agent Governance Toolkit.
Niyet ile eylem arasında deterministik bir kapı
- İzinÇağrı çalışır
- İnsan onayıÖnce bir insan onaylar
- RetÇağrı hiç gerçekleşmez
# policy.yaml · temsilî
rules: - name: block-destructive-db
when: action.verb in [drop, delete, truncate]
effect: deny - name: external-email-needs-approval
when: tool == send_email and recipient.external
effect: require_approval - name: role-gated-tools
when: tool in supervisor_only and not agent.is(supervisor)
effect: deny - name: allow-read
when: action.kind == read
effect: allowHer karar loglanır
decision { agent: "agentassist", action: search_docs('refund policy'), rule: "allow-read", effect: allow }- effectBu eylem izinli mi?
- agentHangi ajan yaptı?
- decision logNe olduğunu sonradan kanıtlayabilir miyiz?
Repoyu açınca bunun küçük bir demo değil, ciddi bir referans mimari denemesi olduğunu görüyorsunuz (Microsoft'un bu işe sımsıkı sarılması da aslında iddiamızı doğrular nitelikte). Public Preview'da ve v4.1.0 sürümüne gelmiş. Dokümantasyonda 10 formal spec, 992 conformance testi ve 29 ADR görünüyor. Microsoft'un paylaştığı repoda ilk fark ettiğim şey şuydu: kendi repomda AnswerAssistantQueryHandler içinde elle kurduğum kapının daha genel ve daha disiplinli bir versiyonuna bakıyordum.
Bu yazıda toolkit'i "yeni oyuncak çıktı" heyecanıyla değil, kendi kurduğum AgentAssist sözleşmesinin devamı gibi okuyacağım. Nerede aynı şeyi yapıyoruz, nerede toolkit daha geniş, nerede benim elle yazdığım çözüm hâlâ daha sade kalıyor; makalenin asıl konusu bu.
01Prompt bir kontrol katmanı değildir
Bu serinin ana düşüncesi buydu. Agent Governance Toolkit'in çıkış noktası da aynı soruna işaret ediyor: prompt seviyesinde güvenlik istemek, kontrol değil; temennidir.
Sistem prompt'una "kaynaksız konuşma", "şu aracı kullanma", "tehlikeli işlem yapma" yazmak elbette gerekli olabilir. Ama production'da bu tek başına bir güvenlik katmanı değildir. Çünkü model olasılıksal, kesinlik içermeyen bir yapıda çalışıyor: bazen uyuyor, bazen yanlış anlıyor, bazen de adversarial bir girdi karşısında dağılıyor.
Bu sadece bir sezgi değil. Andriushchenko ve arkadaşlarının ICLR 2025 çalışması, kendi deney düzeneklerinde ve benchmark'larında GPT-4o, Claude 3/3.5 ve Llama-3 dahil birçok modelde adaptif jailbreak saldırılarıyla çok yüksek, bazı senaryolarda %100'e varan saldırı başarı oranları raporluyor. Buradaki önemli kelime şu: adaptif. Yani saldırı tek bir "kötü prompt"tan ibaret değil; modele göre şekil değiştiren, deneye deneye zayıf noktayı bulan bir saldırı. O yüzden "prompt'a yazdım, artık güvenliyim" diyemiyoruz.
Toolkit'in cevabı net: ajanın yaptığı kritik eylem, modelin niyeti dışarı çıkmadan önce uygulama seviyesinde yakalanmalı. Araç çağrısı mı? Kontrol et. Mesaj gönderme mi? Kontrol et. Başka bir ajana iş devri mi? Kontrol et. Sonuç ya izin, ya ret, ya da insan onayı. Bu fark küçük görünür, ama mimari olarak her şeyi değiştirir:
Prompt vs. politika
der ki böyle davran.
- Olasılıksal: bazen uyar, bazen yanlış anlar
- Adaptif jailbreak: yayımlanmış bazı düzeneklerde %100’e varan başarı
- Uyulmazsa eylemi durduran bir şey yok
der ki böyle davranmazsan geçemezsin.
- Deterministik, eylem çalışmadan önce değerlendirilir
- Sonuç: izin, ret ya da insan onayı
- Her karar loglanır
Benim refusal/citation sözleşmesinde yaptığım şey de tam olarak bu. Modelin iyi niyetine güvenmedim. Cevap verirken kaynak yoksa ya da citation listesi doğrulanamıyorsa akışı durdurdum. Toolkit aynı refleksi RAG cevabının dışına çıkarıp ajanın bütün eylemlerine yayıyor. Kendileri bunu üç soruyla özetliyorlar:
- Bu eyleme izin var mı?
- Bunu hangi ajan yaptı?
- Ne olduğunu sonradan kanıtlayabiliyor muyuz?
Bu üç soru, güvenli agent mimarisinin omurgası.
02Toolkit'in en basit hâli: mevcut aracı politikayla zorlamak
Toolkit'in giriş seviyesi kullanımı bilerek basit tutulmuş. Var olan bir tool fonksiyonunu govern() ile işaretleyip yanına bir policy dosyası veriyorsunuz. Bundan sonra her çağrı politikaya göre değerlendiriliyor, karar loglanıyor, ihlal varsa çağrı duruyor.
Politika tarafında YAML ile başlanabiliyor. OPA Rego ve Cedar desteği de var, ama ilk okuma için YAML yeterli. Basit örnekler:
drop,delete,truncategibi yıkıcı veritabanı aksiyonlarını engelle.- Dışarıya e-posta gönderimini insan onayına bağla.
- Belirli bir role sahip olmayan ajanların belli tool'ları çağırmasını kapat.
Burada ister istemez kendi koduma döndüm. AzureSearchFilterBuilder içinde yaptığım şey de aynı mantığın daha kısıtlı bir hâliydi. Kullanıcıdan gelen rolü olduğu gibi sorguya basmıyordum; önce izin verilen, doğrulanmış rol listesine sokuyordum. Ayrıca her sorguya isActive eq true filtresi ekliyordum.
Aradaki fark şu: ben bunu C# içinde if ve builder mantığıyla yazdım; toolkit aynı fikri bir policy dosyasına taşıyor.
Bu ayrım önemli. Çünkü kural kodun içine gömülü kaldığında, onu okumak için uygulama kodunu bilmek gerekiyor. Kural bir policy dosyasına taşındığında ise ayrı versiyonlanabiliyor, lint edilebiliyor, CI'da kontrol edilebiliyor ve denetçiye "bizim kural setimiz bu" diye gösterilebiliyor.
Her sistem için bu şart mı? Hayır. Ama ajan tool çağırmaya başladığında, hele dış sistemlere yazma yetkisi varsa, bu ayrım lüks olmaktan çıkıp ihtiyaç hâline geliyor.
03Toolkit'in katmanları: hepsini almak zorunda değilsiniz
Toolkit'in sevdiğim tarafı şu: tek parça, yutulması zor bir framework gibi davranmıyor (Microsoft bu yaklaşımı yaklaşık 10 yıl önce .NET Core ile benimsemeye başlamıştı). Katman katman tasarlanmış; ihtiyacınız olan yerden başlayabiliyorsunuz.
Toolkit’in katmanları: sadece ihtiyacın olanı al
- L6Agent HypervisorYürütme denetimi, audit ve commitment anchoring. Daha ileri kontroller.
- L5Agent ComplianceOWASP doğrulaması, policy linting ve evidence üretimi.
- L4Agent SREKill switch, SLO, chaos, circuit breaker: üretim güvenilirliği.
- L3Agent RuntimePrivilege ring ile yürütme sınırları: ajanın neye dokunabileceği.
- L2Agent MeshAjanlar arası keşif, yönlendirme, kimlik ve güven.
- L1Agent OSPolitika motoru, agent lifecycle ve governance gate. Çekirdek.çekirdek · buradan başla
Ayrıca dikkat çekenler
- MCP Security Gatewaytool poisoning, drift, typosquatting, gizli talimatlar
- PromptDefense Evaluator12 vektörlü prompt injection değerlendirmesi
- Shadow AI Discoverykurum içindeki kayıtsız ajanları bulma
- Governance Dashboardkararlar, ihlaller, ajan sağlığı
AgentAssist için bugün policy + audit tek başına bile değerli. Hepsini birden almak hata olur.
Benim şu anki AgentAssist senaryom için bunların tamamına ihtiyacım yok; hatta hepsini birden almak yanlış olur. Ama policy ve audit katmanı tek başına bile değerli.
Bence bu iyi bir tasarım. Çünkü gerçek sistemlerde güvenlik katmanları "ya hep ya hiç" diye geldiğinde çoğu zaman benimsenmiyor. Burada en azından küçük başlayıp büyütmenin bir yolu var.
04"Güvenli" demek yetmez, kanıt üretmek gerekir
Bu seride en çok önemsediğim cümlelerden biri şuydu: kanıtlanamayan sözleşme, sözleşme değildir. Toolkit tarafında beni en çok çeken kısım da CLI ve evidence üretimi oldu. Öne çıkan komutlar:
agt verify
agt verify --evidence ./agt-evidence.json --strict
agt red-team scan ./prompts/ --min-grade B
agt lint-policy policies/Bunların değeri şu: güvenlik iddiasını sadece dokümana yazmıyorsunuz, CI'da ölçülebilir hâle getiriyorsunuz. Örneğin agt verify --evidence --strict dediğinizde, OWASP Agentic Top 10 kapsamı için evidence üretip eksik varsa build'i düşürme fikrine geliyorsunuz.
Bu, benim iki katmanlı eval yaklaşımıma çok yakın duruyor. Ben Katman 1'de sözleşme davranışını ölçmüştüm: kaynak yoksa refusal geliyor mu, yetkisiz doküman modele hiç gidiyor mu, model uydurma citation döndürürse sistem bunu durduruyor mu? Toolkit bunu daha genel bir agent governance kapsamına taşıyor.
Standartlarla eşleştirme de bu yüzden önemli: OWASP Agentic Top 10, NIST AI RMF, EU AI Act ve SOC 2 gibi çerçeveler için eşleştirme ve evidence üretimi anlatılıyor. Burada dikkatli olmak lazım: bu, "bu sistemi kullandım, otomatik olarak regülasyona uyumlu oldum" demek değil. Ama denetim konuşmasında elinizdeki malzemeyi güçlendirir.
Regüle bir alanda çalışan herkes bilir: "biz güvenli yaptık" cümlesi tek başına bir şey ifade etmez. Denetçi şunları ister:
- Hangi kural aktifti?
- Hangi aksiyon istendi?
- Neye göre izin verildi ya da reddedildi?
- Bu karar sonradan değiştirilemeyecek şekilde saklandı mı?
Toolkit'in audit ve compliance tarafı bu sorulara cevap üretmeye çalışıyor.
05.NET tarafı: var, ama beklentiyi doğru kurmak lazım
Burada .NET'le çalışan biri olarak özellikle dürüst olmam lazım. Toolkit çok dilli geliyor: Python, TypeScript, .NET, Rust ve Go. README'de beş dilin de çekirdek governance tarafını (policy, identity, trust ve audit) desteklediği yazıyor. .NET tarafında Microsoft.AgentGovernance paketi ve MCP için Microsoft.AgentGovernance.Extensions.ModelContextProtocol paketi görünüyor.
Ama full stack hâlâ Python tarafında. Runtime sandboxing, SRE ve bazı ileri katmanlar için Python ekosistemi daha dolu.
.NET bugün: beklentiyi doğru kur
| Yetenek | .NET | Python |
|---|---|---|
| Policy değerlendirme | Var | Var |
| Agent / tool çağrısı governance | Var | Var |
| MCP entegrasyonu | Var | Var |
| Audit ve temel güven katmanı | Var | Var |
| Runtime sandboxing | Python’da daha dolu | Var |
| Agent SRE | Python’da daha dolu | Var |
| İleri katmanlar | Python’da daha dolu | Var |
Microsoft.AgentGovernanceMicrosoft.AgentGovernance.Extensions.ModelContextProtocolBu kötü bir şey değil; sadece mimari karar verirken bunu baştan yazmak gerekiyor. Bunu AgentAssist gibi bir .NET mimarisine ekleyecek olsam, ADR'ye şu notu düşerdim:
Agent Governance Toolkit Public Preview durumunda. .NET tarafında çekirdek governance ve MCP entegrasyonu kullanılabilir; full-stack yetenekler Python tarafında daha geniş. Bu yüzden ilk kullanım CI/evidence ve policy gate ile sınırlı tutulacaktır.
Bu cümle önemli; çünkü teknoloji doğru olsa bile, olgunluk seviyesi mimari kararın bir parçasıdır.
06AgentAssist ile yan yana koyunca
Bu yazının asıl sebebi burası. Toolkit'i okudukça şunu fark ettim: AgentAssist'te aslında bu yaklaşımın dar, elle yazılmış bir versiyonunu kurmuşum. Aynı felsefe var, sadece kapsam farklı.
Benim sistemim tek akışlı bir RAG/agent-assist senaryosu. Tool-calling yok, multi-agent yok, dış sisteme yazma yok. Bu yüzden elle yazılmış sözleşme hâlâ çok okunabilir ve çok kontrollü. Yan yana koyunca tablo şöyle çıkıyor:
AgentAssist → Agent Governance Toolkit
Elle yazılmış sözleşmenin toolkit tarafındaki karşılığı
Rica değil, politika: model cevabı ya da ajan eylemi deterministik bir kapıdan geçer.
- 01Orchestrator içindeki refusal kurallarıYAML policy + policy engineKural koddan ayrılır; lint edilebilir, CI’da kontrol edilir
- 02Rol allow-list + isActive filtresiPolicy condition’larıYetki ve görünürlük kuralları merkezîleşir
- 03Citation whitelist kontrolüdeny kararıSözleşme ihlali bir governance kararı olarak loglanır
- 04Azure SQL audit + App InsightsTamper-evident audit + Decision BOMDenetim ve provenance tarafı güçlenir
- 05Tekil adversarial prompt injection testiPromptDefense + red-team scanInjection ölçümü sistematik hâle gelir
- 06Contract eval + quality evalagt verify --evidence --strictGovernance kapsamı CI’da evidence’a bağlanır
Aynı disiplin, farklı seviye. AgentAssist sözleşmeyi tek bir RAG akışında kuruyor; toolkit bunu ajan eylemlerine genelliyor.
Bu tabloyu yapınca iki şey hissettim. Birincisi, doğru yeri yakalamışım; çünkü toolkit benim kurduğum yaklaşımı reddetmiyor, onu daha genel bir hâle getiriyor. İkincisi, benim çözümümün sınırı da daha görünür hâle geliyor. Elle yazılmış if'ler tek akışta çok net; ama ajan sayısı, tool sayısı ve dış sistem sayısı arttığında aynı yöntem bir yerden sonra dağılır.
07Benimki nerede daha dar ama daha kontrollü?
Burada "hemen toolkit'e geçelim" demek bana doğru gelmiyor.
AgentAssist bugün tek akışlı bir sistem. Retrieval yapıyor, yetki filtresi uyguluyor, modeli çağırıyor, citation doğruluyor, gerektiğinde refusal dönüyor. Bu kadar. Bu sadelikte elle yazılmış sözleşmenin ciddi bir avantajı var: herkes kodu okuyup akışı anlayabilir. Hangi durumda refusal döndüğünü, hangi durumda citation'ın geçersiz sayıldığını doğrudan görebilirsiniz.
Genel bir framework ise bu basitlikte her zaman avantaj getirmeyebilir; bazen sadece bir soyutlama katmanı ekler. Mimari dilde bunun adı çok basit: over-engineering.
Ama sistem büyürse tablo değişir. Ajan tool çağırmaya başlarsa, örneğin:
- SQL sorgusu çalıştırırsa,
- dışarıya e-posta gönderirse,
- CRM'de kayıt açarsa,
- başka bir ajana iş devrederse,
- MCP server'lar üzerinden yeni tool'lar keşfederse,
o noktada elle yazılmış kontrolleri takip etmek zorlaşır. Çünkü artık sadece "cevap doğru mu?" sorusu yoktur; "bu aksiyon yapılabilir mi?" sorusu da vardır. İşte toolkit'in asıl parladığı yer burası.
RAG cevabı için sözleşme yeterli olabilir. Ajan eylemi için politika gerekir.
08Ben bunu nasıl entegre ederdim?
Bugün AgentAssist'e uygulayacak olsam büyük bir geçiş planı yapmazdım; küçük başlardım.
Küçük başla: üç adımlık plan
- 01ŞimdiCI’a evidence ekle
En düşük risk. Uygulama akışına dokunulmaz.
agt verify --evidence ./agt-evidence.json --strict - 02SonraSözleşmeyi politika olarak modelle
Application katmanında orchestrator’ın bir adımı. Anlamı Domain taşır, uygulayan policy engine olur.
denyretrieval boş dönersedenycitation id retrieved set’te yoksarequire_approvalsoru yüksek riskliysedenyaraç eylemi yıkıcıysa
- 03GerekirseMCP ve tool calling gelirse genişlet
Ajan eylem yapmaya başlayınca MCP Security Gateway ve agent identity anlam kazanır.
“Bu kadar araç ve ajanla, politika olmadan hiçbirine nasıl güveneceğiz?”
Çubuklar = her adımın çalışan sisteme ne kadar dokunduğu
İlk adım: CI'a evidence eklemek. En düşük riskli adım bu. Uygulama akışına dokunmadan agt verify ve mümkünse agt verify --evidence --strict denemek. Buradaki amaç "toolkit'i production akışına soktum" demek değil; mevcut güvenlik anlatısını OWASP Agentic Top 10 gibi bir çerçeveyle yan yana koymak. Bu, serinin üçüncü yazısındaki eval mantığına da uyuyor: önce ölç, sonra enforcement'ı düşün.
İkinci adım: refusal/citation sözleşmesini politika olarak modellemek. Daha sonra bazı kuralları YAML policy'ye taşımak denenebilir. Örneğin:
- retrieval sonucu yoksa
deny, - citation ID'si retrieval set'inin içinde değilse
deny, - sorgu yüksek riskliyse
require_approvalya da escalation, - tool aksiyonu yıkıcıysa
deny.
Bunu Clean Architecture içinde Application katmanındaki orchestrator'ın bir adımı olarak konumlandırırdım. Domain hâlâ sözleşmenin anlamını taşır; policy engine ise enforcement mekanizması olur.
Üçüncü adım: MCP ve tool-calling gelirse genişletmek. Bugün için erken. Ama AgentAssist ileride MCP server'lara, tool-calling'e ya da multi-agent senaryolarına giderse, MCP Security Gateway ve agent identity katmanı ciddi şekilde anlam kazanır. O noktada soru "toolkit kullanalım mı?" olmaz. Soru şu olur: bu kadar çok tool ve ajan varken, politikasız nasıl güveneceğiz?
Kapanış
Bu serinin başında "chatbot değil, sistem tasarlamak" demiştim. Dört yazı sonra anlatmaya devam ettiğim şey şu: güvenli bir yapay zekâ sistemi kurmanın püf noktası model seçimi değil, kontrol noktası tasarımı. Model cevap üretir; ama kararı sistem verir. Nerede konuşacağını, nerede susacağını, hangi aksiyonu yapabileceğini ve bunu nasıl kanıtlayacağını sistem belirler.
Microsoft Agent Governance Toolkit bu yüzden ilgimi çekti. Çünkü anlattığı şey, benim üç yazıdır savunduğum çizgiyle aynı yere çıkıyor:
Dört cümlede çizgi
- 01Prompt’a yazma.
- 02Politika koy.
- 03Kararı logla.
- 04Kanıt üret.
Kendi elle yazdığım sözleşmeyi yarın tamamen bu toolkit'e taşır mıyım? Bugün için hayır. Tek akışlı bir RAG senaryosunda mevcut sözleşme daha sade ve daha okunabilir. Ama sistem tool-calling'e, MCP'ye ya da multi-agent yapıya doğru büyürse cevap değişir. O noktada elle yazılmış kapılar yetmez; merkezî policy, agent identity ve audit katmanı mimari bir ihtiyaç hâline gelir.
Önemli olan araç değil. Önemli olan kural koymuş olmak.
Kaynaklar
- Microsoft Agent Governance Toolkit — GitHub README
- Agent Governance Toolkit dokümantasyon sitesi
- Microsoft Open Source Blog: Introducing the Agent Governance Toolkit
- Agent Governance Toolkit sürümleri
- .NET Blog: Agent Governance Toolkit MCP Extensions for .NET
- Andriushchenko ve diğerleri, Jailbreaking Leading Safety-Aligned LLMs with Simple Adaptive Attacks, ICLR 2025