Agent Harness ile Claw’u Üretime Hazırlamak
Microsoft Agent Framework’ün “Build your own claw” serisinin dördüncü ve son bölümü, geliştirme aşamasında olgunlaşmış bir kişisel finans ajanını gerçek kullanıcıların önüne çıkarmaya odaklanıyor. Üç bölüm boyunca planlama yapan, portföy okuyan, işlem öncesi onay isteyen, hafıza tutan, becerileri talep üzerine yükleyen, kabuk üzerinden dosya düzenleyen, CodeAct ile hesap yapan ve arka planda araştırma ajanları çalıştıran bir claw inşa edildi. “Benim makinemde çalışıyor” ile “başkaları için de çalışıyor” arasındaki mesafe ise tam bu son adımda kapatılıyor.
Wes Steyn’in yazısı bu geçişi dört eksende ele alıyor: gözlemlenebilirlik, yönetişim, dağıtım ve değerlendirme. Yol boyunca mimariye kritik bir yapısal değişiklik de giriyor.
Tek tanım, üç farklı host
Şimdiye kadar her adım tek bir program olarak yazılmıştı. Üretim ortamındaki bir ajan ise genellikle birden fazla biçimde çalıştırılır: geliştirme sırasında etkileşimli konsol, gerçek kullanım için bulutta host edilmiş servis ve CI içindeki eval harness. Yazı, claw’u paylaşılan bir agent factory ile onu tüketen üç ince host katmanına ayırıyor: console, hosted ve evals. Ajan tek yerde tanımlanıyor, yalnızca etrafındaki host değişiyor.
.NET tarafında factory, oluşturulmuş ajanı ve host’un dispose etmesi gereken kaynakları dönduruyor:
await using ClawAgentBuild build = await ClawAgentFactory.CreateAsync(new ClawAgentFactoryOptions
{
Log = Console.WriteLine,
});
Python tarafında ise async context manager döndüren bir async factory kullanılıyor; kabuk ve MCP skill oturumları böylece temiz biçimde kapatılıyor:
agent = await build_claw_agent(credential=AzureCliCredential())
async with agent:
# … ajanı çalıştır …
Tek bir tanım tüm host’ları beslediği için gözlemlenebilirlik, yönetişim, dağıtım ve değerlendirme aynı ajan üzerinde uygulanıyor; üç ayrı ve birbirinden hafifçe farklılaşmış kopya söz konusu olmuyor.
Gözlemlenebilirlik: OpenTelemetry ile ne yaptığını görmek
Dosya okuyan, kod çalıştıran ve araç çağıran bir ajan aslında küçük bir dağıtık sistem. Bir skill hatalı tetiklenirse, bir araç döngüye girerse veya bir yanıt beklenenden çok daha pahalıya mal olursa bunu görmek gerekir. Harness zaten model çağrıları, araç çağrıları ve token kullanımı için OpenTelemetry span, metrik ve log üretiyor; geriye yalnızca uygun exporter’ı bağlamak kalıyor.
Ajan tek bir OpenTelemetry source name taşıyor..NET tarafında bu, harness üzerindeki tek bir seçenek:
AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
OpenTelemetrySourceName = ClawAgentFactory.OpenTelemetrySourceName,
// … dosya erişimi, skills, shell, CodeAct, arka plan ajanları …
});
OTEL_EXPORTER_OTLP_ENDPOINT ortam değişkeni set edildiğinde konsol host’u bu kaynağa yönelik tracer ve metric provider’ları ayağa kaldırıyor ve telemetriyi yapılandırılmış OTLP collector’a gönderiyor. Python tarafında ise instrumentation varsayılan olarak açık; configure_otel_providers() çağrısı ortam değişkenlerinden provider’ları otomatik bağlıyor.
Kritik ayrım şurada: harness telemetriyi üretiyor, siz nereye gideceğine karar veriyorsunuz. Yerelde exporter’ları elle bağlıyorsunuz, Foundry üzerinde host edildiğinde ise hiçbir şey bağlamıyorsunuz. Hosting runtime exporter pipeline’ını kaydediyor ve Foundry APPLICATIONINSIGHTS_CONNECTION_STRING‘i otomatik enjekte ediyor.
Yönetişim: Microsoft Purview ile denetim altında tutmak
Finans alanında çalışan bir asistan hassas materyalle temas ediyor. Düzenlemeye tabi bir bağlamda kredi kartı numaraları, gizli portföy bilgileri ve izin verilmeyen içerikler gibi durumların organizasyon politikasına göre taranması ve denetim izinin bırakılması gerekiyor. Microsoft Purview tam olarak bu işi yapıyor ve entegrasyon chat client’ın etrafına sarılan ince bir katman olduğu için claw’un diğer tüm yetenekleriyle bir arada çalışıyor.
Entegrasyon opt-in; PURVIEW_CLIENT_APP_ID set edildiğinde factory Purview’ü ekliyor, aksi halde davranış değişmiyor..NET tarafında chat client üzerinde bir builder adımı olarak ekleniyor:
if (!string.IsNullOrWhiteSpace(purviewClientAppId))
{
chatClient = chatClient
.AsBuilder()
.WithPurview(browserCredential, new PurviewSettings("Claw"))
.Build();
}
Python tarafında ise FoundryChatClient‘a verilen bir chat middleware olarak çalışıyor. Bu sayede her prompt modele ulaşmadan, her yanıt da kullanıcıya ulaşmadan kontrol ediliyor; engellenen içerik politika mesajıyla değiştiriliyor ve etkileşim denetim için loglanıyor. Purview’ün doğru Graph izinlerine sahip bir Microsoft 365 E5 tenant’ına ihtiyacı olduğu belirtiliyor; tam kurulum için AgentWithPurview ve purview_agent örneklerine yönlendiriliyor.
Dağıtım: Foundry Hosted Agent olarak yayına almak
Ajan tek yerde tanımlandığı için host etmek büyük ölçüde yeniden yazmak değil, kablolamak demek. Hosted host aynı build.Agent‘ı alıyor ve Responses protokolü üzerinden Foundry’nin çalıştırabileceği biçimde açıyor..NET tarafında tüm host, ince bir ASP.NET uygulamasından ibaret; AddFoundryResponses hem Responses API host’unu kaydediyor hem de OpenTelemetry’yi otomatik uyguluyor. Python tarafında karşılığı ResponsesHostServer.
Riskli özellikleri kapatmak
Hosted ajanda dosya erişimi ve shell kapatılıyor. Bu, konsoldan bilinçli olarak ayrışılan tek nokta. Paylaşımlı ve host edilmiş bir ortamda modele container dosya sistemine keyfi okuma/yazma hakkı vermek ya da shell komutu çalıştırma izni tanımak; veri sızıntısı, tahrifat ve kalıcılık gibi ciddi güvenlik riskleri doğuruyor. Bu nedenle hosted build EnableFileAccess = false ve EnableShell = false ile geliyor. Arka plan ajanları ise açık kalıyor.
Host edilmiş bir ortamda gerçekten dosya erişimine ihtiyaç duyulursa yazarın önerisi, container diskine değil harici bir AgentFileStore‘a başvurmak: örneğin Azure Blob Storage tabanlı bir store. Dosyalar bu sayede yönetilebilir, kalıcı ve paylaşılabilir bir katmanda tutuluyor.
Container içinde CodeAct
İkinci bilinçli ayrışma CodeAct tarafında. Yerelde CodeAct, konuk kodu VM tabanlı mikro-sandbox’ta izole eden Hyperlight üzerinde çalışıyor. Hosted build için ise LocalCodeAct destekli bir CodeActProvider geçiliyor; bu, üretilen Python kodunu bir çocuk süreçte çalıştırıyor ve host edilmiş container’ı sandbox olarak kullanıyor. Yazı burada net bir uyarı düşüyor: LocalCodeAct kendi başına bir sandbox değildir; yalnızca hosted-agent container’ı gibi dışarıdan sandbox’lanmış bir ortamda kullanılmalıdır. CodeAct’i tamamen devre dışı bırakmak için EnableCodeAct = false seçilebiliyor.
Manifest, agent tanımı ve dağıtım
Her iki host da bir agent.manifest.yaml ve bir agent.yaml ile geliyor, ama iki dosyanın işlevleri farklı. Manifest, azd ai agent init‘e geçilen şablondur ve ajanın adını, meta verilerini, protokolünü ve yapılandırılabilir parametrelerini taşır. Agent tanımı ise Foundry’nin ne çalıştıracağını anlatır: Responses protokolü, CPU ve bellek ihtiyaçları ve container’ın gerek duyduğu ortam değişkenleri.
Dağıtım yolu dile göre ayrışıyor. Python, Foundry’nin varsayılan kod (ZIP) dağıtımını kullanıyor; azd örnek klasörünü yükleyip requirements.txt‘i kuruyor ve hosted.py‘yi başlatıyor..NET örneği ise Agent Framework depo kaynağına ProjectReference ile bağlandığı ve depo düzeyinde Central Package Management kullandığı için container image olarak dağıtılıyor. Sunucu tarafında restore, klasör dışı referansları ve Directory.Packages.props‘u çözümleyemediği için önce yerelde dotnet publish yapılıp ardından azd‘nin image’ı build edip push etmesi öneriliyor..NET Dockerfile’ı, önceden publish edilmiş out/ klasörünü python3 yüklü bir aspnet:10.0 image’ının üstüne kopyalıyor.
Kaliteyi ölçmek: local ve hosted evals
Dağıtım öncesinde ve sonrasında claw’un gerçekten iyi olup olmadığını değerlendirmek gerekiyor. Değişikliklerin regresyona yol açmadığından emin olmak ya da farklı prompt varyantlarını karşılaştırmak da bu adımın parçası. evals host’u ajanı build ediyor ve küçük bir finans sorguları setiyle iki katmanlı kontrol çalıştırıyor.
Yerel kontroller sade fonksiyonlardan oluşuyor: hızlı, ücretsiz ve CI içinde çalıştırılabilir..NET tarafında FunctionEvaluator ile örneğin “MSFT’yi değerlemesi istendiğinde yanıtta sayı geçmeli” gibi bir kural kolayca yazılabiliyor; Python tarafında aynı fikir @evaluator decorator’ı ile ifade ediliyor.
Hosted Foundry değerlendirmeleri ise model tarafından skorlanan kalite metriklerini (relevance, coherence) ve paylaşılabilir bir raporu ekliyor. Bu bölüm FOUNDRY_PROJECT_ENDPOINT‘in varlığına bağlı; lokal kontroller her koşulda çalışıyor, hosted evals ise opsiyonel katman olarak devreye giriyor. Yazının vurgusu net: her değişiklikte bu değerlendirmeleri çalıştırdığınızda yeni bir talimat, araç ya da becerinin işi iyileştirip iyileştirmediğini skorlardan görürsünüz; dağıtılmış bir ajanı dürüst tutan ince ayar döngüsü budur.
Çalıştırma ve ortam değişkenleri
.NET tarafında ClawAgent.Console, ClawAgent.Evals ve ClawAgent.Hosted projeleri ayrı ayrı çalıştırılabiliyor. Python tarafında karşılıkları console.py, evals.py ve hosted.py. Konsol host’u üçüncü bölümdeki claw ile aynı davranıyor; tek fark, telemetrinin artık seçtiğiniz collector’a akıyor olması.
Yazının derlediği pratik anahtarlar şöyle: trace’leri yerelde izlemek için OTEL_EXPORTER_OTLP_ENDPOINT‘i bir collector’a yönlendirin (Python’da alternatif olarak ENABLE_CONSOLE_EXPORTERS=true). Yönetişimi açmak için PURVIEW_CLIENT_APP_ID‘yi set edin. Host edilmişken Application Insights’a telemetri göndermek için APPLICATIONINSIGHTS_CONNECTION_STRING‘i tanımlayın. Trace içinde prompt ve yanıt içeriğini yakalamak için (varsayılanda kapalıdır).NET’te OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true, Python’da ENABLE_SENSITIVE_DATA=true. Dağıtılmış ajan, Foundry Agent playground üzerinden de çağrılabiliyor.
Bileşenleri kendi ajanınızda kullanmak
Yazının önemli bir vurgusu, dört yeteneğin hiçbirinin harness’ın içine kilitlenmemiş olması. Gözlemlenebilirlik için.NET’te herhangi bir AIAgent, agent.AsBuilder().UseOpenTelemetry(sourceName).Build() ile dekore edilebiliyor; Python’da configure_otel_providers çağrısı yeterli. Yönetişim için.NET’te WithPurview bir ChatClientBuilder uzantısı; Python’da ise PurviewChatPolicyMiddleware chat client’a ekleniyor. Hosting tarafında.NET, AddFoundryResponses ve MapFoundryResponses ile ASP.NET uzantısı olarak sunuluyor; Python’da ResponsesHostServer(agent) ile aynı iş yapılıyor. Değerlendirme için.NET’te LocalEvaluator, FunctionEvaluator ve FoundryEvals; Python’da ise LocalEvaluator, evaluate_agent, @evaluator ve FoundryEvals aynı işlevi görüyor.
Hepsini birbirine bağlayan örüntü paylaşılan agent factory. Ajanı bir kez tanımlayıp aynı yapıyı konsolda, hosted serviste ve evals harness’ında yeniden kullanmak; üretim ortamına geçişi büyük bir mimari kırılım olmaktan çıkarıp beslenmesi kolay bir omurgaya dönüştürüyor.
Kaynaklar ve İleri Okuma
- Agent Harness: Making your claw production-ready — Wes Steyn (Microsoft DevBlogs)
- Build your own claw and agent harness with Microsoft Agent Framework
- .NET örneği: Claw_Step04_ProductionReady
- Python örneği: claw_step04_production_ready
- .NET agent.manifest.yaml
- .NET agent.yaml
- Python agent.manifest.yaml
- Python agent.yaml
- AgentWithPurview.NET örneği
- purview_agent Python örneği
- AgentOpenTelemetry.NET örneği
- Agent Harness: Kıskacı Büyütmek ve Yetenekleri Kuşanmak
- Agent Harness ile Ajana Veri Vermek: Onay ve Hafıza Dahil
- Agent Framework ile Claw Mimarisi: İlk Ajanı Üç Adımda Kurmak
- Microsoft Agent Framework’te Asıl Değişim: Harness, Hosted Agents ve CodeAct
- Microsoft Agent Framework v1.0: Lokal’den Prod’a Geçiş
- Microsoft Agent Framework ve AGT: Ajanları Üretimde Güvende Tutmak







3 comments