Şimdi yükleniyor

.NET Agent Skills: Üç Yöntem, Tek Sağlayıcı

.NET Agent Skills: Üç Yöntem, Tek Sağlayıcı

Geçen ay bir finans kuruluşundaki müşterimiz için chatbot projesinde çalışırken garip bir durumla karşılaştık. Ekipte üç farklı kişi üç farklı şekilde agent skill’leri yazıyordu — biri dosya tabanlı, biri inline C# ile, biri de NuGet paketi olarak (buna dikkat edin). Ortaya çıkan kaos… neyse, uzatmayalım. Tam da o hafta Microsoft’un Agent Framework ekibinin yayınladığı bu yeni yaklaşım gözüme çarptı. Dedim ki: “Bu tam da bizim derdimize çare.”

Konu şu aslında..NET’te agent skill’lerinizi üç farklı biçimde yazıp hepsini tek bir provider altında birleştirebiliyorsunuz artık (ciddiyim). Dosya tabanlı, inline kod, ya da sınıf tabanlı — hangisini seviyorsanız, o. Üstelik script çalıştırma desteği ve insan onayı mekanizması da var. Kulağa basit geliyor, biliyorum. Ama pratikte bu esneklik, nasıl desem, fena hâlde işe yarıyor — bunu yaşayarak gördüm.

Mesele Ne? Neden Üç Farklı Yöntem?

Bak şimdi, gerçek dünyada bir agent geliştirirken her şey güllük gülistanlık olmuyor. Hiç olmadı zaten. Bir skill dosya olarak başlıyor, sonra başka bir ekip aynı işlevi NuGet paketi olarak yayınlıyor, bir diğeri de “ben hızlıca bir şey yazıp koyayım” diyor — ve sız orada kalıyorsunuz ortada, üç farklı paradigmayla boğuşarak. Bu üç yaklaşımın bir arada çalışabilmesi lazım, yoksa her yeni eklentide tüm mimariyi yeniden yazmak zorunda kalıyorsunuz (bu konuda ikircikliyim). Gerçekten.

Garip gelecek ama, Bir HR self-service agent senaryosu düşünelim. İlk gün yeni çalışan onboarding rehberi lazım — dosya tabanlı bir skill (bu beni çok şaşırttı). İki hafta sonra yan ekip benefits enrollment’ı NuGet paketi olarak yayınlıyor. Ama bir de izin bakiyesi hesaplama skill’i var ki henüz paketlenmemiş, acil lazım, yarın demo var. Ne yapacaksınız? İşte tam o noktada inline kod devreye giriyor.

2024 sonlarında benzer bir senaryo yaşadık Logosoft’ta. Bir telekomünikasyon firmasının destek chatbot’ünü geliştirirken fatura sorgulama modülü başka bir vendor’dan geliyordu, arıza takip modülü bizim ekibin, kampanya bilgilendirme işe müşterinin kendi iç ekibinden — üç ayrı dünya, tek çatı altında toplanması gerekiyor. Aslında tam da bu yazının konusu o.

İşte tam da bu noktada devreye giriyor.

Dosya Tabanlı Skill: Klasik Ama Etkili

En kolay başlangıç noktası bu. Bir klasör yapısı oluşturuyorsunuz, içine SKILL.md dosyası, scriptler ve referans dökümanlar koyuyorsunuz. Basit. Ama “basit” demek “yetersiz” demek değil — özellikle hızlı prototipleme için baya iş görüyor, şaşırdım açıkçası ilk kullandığımda (evet, doğru duydunuz)

Klasör Yapısı

skills/
└── onboarding-guide/
├── SKILL.md
├── scripts/
│   └── check-provisioning.py
└── references/
└── onboarding-checklist.md

SKILL.md dosyasının içi bir markdown — name, description ve instructions bölümleri var. Agent bu dosyayı okuyor ve adımları takip ediyor (ben de ilk duyduğumda şaşırmıştım). Mesela “çalışanın adını. Başlangıç tarihini sor”, “provisioning script’ını çalıştır”, “checklist’teki maddeleri gözden geçir” gibi talimatlar (bizzat test ettim). Gayet okunabilir, teknik olmayan ekip üyeleri bile düzenleyebiliyor — bu önemli bir avantaj.

Ha, burada önemli bir nokta var. Script çalıştırma. SubprocessScriptRunner.RunAsync ile Python veya başka bir script’i doğrudan agent üzerinden tetikleyebiliyorsunuz. Güzel özellik, ama — dur bir saniye — bunu production’da kontrolsüz kullanmak gerçekten riskli. Birazdan insan onayı mekanizmasına geleceğim, oraya kadar bekleyin.

Evet, doğru duydunuz.

var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
SubprocessScriptRunner.RunAsync);
AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
.GetResponsesClient()
.AsAIAgent(new ChatClientAgentOptions
{
Name = "HRAgent",
ChatOptions = new() { Instructions = "You are a helpful HR self-service assistant." },
AIContextProviders = [skillsProvider],
},
model: deploymentName);

Dikkat ederseniz DefaultAzureCredential kullanılıyor — (ciddiyim). Managed identity, environment variables, VS Code credential vs. hepsini otomatik deniyor. AZ-500 sınavına hazırlanırken bu konuyu defalarca işlemiştim, her seferinde “production’da connection string hardcoded koyma” diye vurguluyorlardı. Haklılarmış. Çok haklılarmış.

Sınıf Tabanlı Skill: NuGet’ten Gelen Güç

Gel gelelim ikinci yönteme. Diyelim ki başka bir ekip benefits enrollment skill’ını güzelce paketlemiş, test etmiş, NuGet’e koymuş. Sız de bunu alıp projenize ekliyorsunuz. Hepsi bu kadar — ciddi ciddi.

Sınıf tabanlı skill’lerde AgentSkill sınıfından türetiyorsunuz. GetSkillContent ile GetTools metodlarını override ediyorsunuz. Skill’in ne yapacağı, hangi tool’ları sunacağı burada tanımlanıyor. Temiz, derli toplu, versiyonlanabilir.

public class BenefitsEnrollmentSkill : AgentSkill
{
public override string Name => "benefits-enrollment";
public override string Description => "Help employees enroll in or change their benefits plans.";
public override SkillContent GetSkillContent()
{
return new SkillContent
{
Instructions = "Guide the employee through available benefit plans..."
};
}
public override IEnumerable<AITool> GetTools()
{
// Benefits API çağrıları burada tanımlanıyor
yield return AIFunctionFactory.Create(GetAvailablePlans);
yield return AIFunctionFactory.Create(EnrollInPlan);
}
}

Size bir şey söyleyeyim, Bunu provider’a eklemek mi? Tek satır:

skillsProvider.AddSkill(new BenefitsEnrollmentSkill());

Bitti. Mevcut dosya tabanlı skill’ınız de dürüyor, yeni eklenen sınıf tabanlı skill de. İkisi yan yana çalışıyor, birbirini etkilemiyor, birbirinden haberi bile yok (şaşırtıcı ama gerçek). Bir arkadaşım geçen ay buna benzer bir yapıya geçti kendi projesinde — “skill ekleme çıkarma işini beş dakikaya indirdik” dedi. Ben inanamadım açıkçası. Ama doğruymuş, denedim, gördüm (ben de ilk duyduğumda şaşırmıştım)

Inline Kod Skill: Acil Durumlarin Kurtaricisi

Şimdi gelelim en “pratik” ama aynı zamanda en “tehlikeli” yönteme. Inline kod tanımlı skill’ler. Neden tehlikeli diyorum? Çünkü insanlar bunu bir kere kullanınca bırakamıyor. Geçici çözüm diye başlıyor, kalıcı hâle geliyor. Maalesef.

Hmm, bir düşüneyim… Evet, senaryo şöyleydi: izin bakiyesi hesaplama skill’i henüz paketlenmemiş ama hemen lazım. O zaman direkt C# ile tanımlıyorsunuz:

skillsProvider.AddInlineSkill(
name: "time-off-balance",
description: "Check remaining PTO balance for an employee.",
instructions: "Ask for employee ID, then call the balance check function.",
tools: new[]
{
AIFunctionFactory.Create((string employeeId) =>
{
// Geçici mock veya gerçek API çağrısı
return $"Employee {employeeId} has 12 days remaining.";
}, "check_balance", "Returns remaining PTO days")
});

Güzel, hızlı, pratik. Ama açık konuşayım: bunu uzun vadeli tutmayın. NuGet paketi geldiğinde hemen değiştirin. 2019’da kendi hosting sunucularımda “geçici” diye yazdığım bir script 3 yıl boyunca production’da kaldı — kimse dokunmaya cesaret edemedi (inanın bana). Aynı hataya düşmeyin. Tahmin eder mısınız? Düşersiniz çünkü çok kolay düşülüyor.

Uc Yöntemi Bir Arada Kullanmak

İşin güzel tarafı şu: bu üç yöntem birbirini dışlamıyor. Hepsini tek bir AgentSkillsProvider altında topluyorsunuz (yanlış duymadınız). Agent hangi skill’in nasıl yazıldığını bilmiyor bile — sadece kullanıyor, sormuyor, merak etmiyor.

Yöntem Ne Zaman Kullanmalı? Avantaj Dezavantaj
Dosya tabanlı Prototipleme, sık değişen içerik Kod bilgisi gerektirmiyor, markdown yeterli Karmaşık lojik için yetersiz
Sınıf tabanlı (NuGet) Production, paylaşılan modüller Test edilebilir, versiyonlanabilir Paketleme/yayınlama süreci var
Inline kod Acil ihtiyaçlar, geçici köprüler Çok hızlı, sıfır overhead Bakımı zor, kalıcı hâle gelme riski

Bir bankacılık projesinde — 2024 Kasım’dı galiba, kesin hatırlamıyorum ama sonbahardı — tam olarak bu üçlü yapıyı kullandık. KYC (Know Your Customer) doğrulama dosya tabanlıydı çünkü compliance ekibi markdown’u anlıyordu. Sık güncelleme yapıyordu, kod bilgisi yoktu kimsede. Kredi limit sorgulama NuGet paketiydi, başka projeler de kullanıyordu. Döviz kuru bildirimi işe inline’dı — merkez bankası API’si değişene kadar geçici bir çözümdü. Değişti mi sonra? Valla değişti, ama o ayrı bir hikâye.

Skill’lerin nasıl yazıldığı önemli değil — önemli olan hepsinin aynı provider altında, birbirinden habersiz şekilde çalışabilmesi. Bu modülerlik, kurumsal projelerde hayat kurtarıyor.

Script Çalıştırma ve Insan Onayı: Kritik Güvenlik Katmanı

Bak bir de şunu söyleyeyim, bu kısımı atlamamanızı tavsiye ederim. Agent’ınız bir Python script’i çalıştırabiliyorsa, bu güzel bir kabiliyet — ama aynı zamanda ciddi bir güvenlik riski. “Provisioning check” script’i zararsız olabilir, peki ya birisi o script’i değiştirirse? Ya da agent yanlış parametrelerle çalıştırırsa? Düşündünüz mü hiç? Daha fazla bilgi için Copilot CLI Metrikleri Artık Birleşik: Ne Değişti? yazımıza bakabilirsiniz.

Ve işler burada ilginçleşiyor.

İşte burada human-in-the-loop mekanizması devreye giriyor. Script çağrılarına onay mekanizması ekleyebiliyorsunuz:

var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
async (scriptPath, args, cancellationToken) =>
{
Console.WriteLine($"Script çalıştırılacak: {scriptPath}");
Console.WriteLine($"Argümanlar: {string.Join(", ", args)}");
Console.Write("Onaylıyor musunuz? (y/n): ");
var input = Console.ReadLine();
if (input?.ToLower() != "y")
return "Script execution denied by operator.";
return await SubprocessScriptRunner.RunAsync(scriptPath, args, cancellationToken);
});

Production ortamında bu tabii ki console’dan onay olmaz — Slack entegrasyonu, Teams approval flow, ya da bir admin dashboard üzerinden yapılıyor genelde. Ama konsept aynı: agent bir script çalıştırmadan önce bir insana soruyor. Basit ama etkili. Bu konuyla ilgili ChatGPT ile Araştırma: Search ve Deep Research … yazımıza da göz atmanızı tavsiye ederim. Bu konuyla ilgili agent konusundaki yazımız yazımıza da göz atmanızı tavsiye ederim. Bu konuyla ilgili PowerShell’de MSI Dönemi Bitiyor: MSIX’e Geçiş … yazımıza da göz atmanızı tavsiye ederim.

💡 Bilgi: İnsan onayı mekanizması sadece script çalıştırma için değil — herhangi bir “yüksek riskli” tool çağrısına da uygulanabilir. Mesela veritabanı silme, kullanıcı deaktive etme gibi işlemler için de aynı pattern kullanılabiliyor.

AZ-500 güvenlik sertifikasına hazırlanırken “least privilege” ve “just-in-time access” kavramlarını çok işlemiştik. Bu insan onayı mekanizması da aslında aynı felsefenin agent dünyasına uyarlanmış hali — agent’a güveniyorsun. Yine de kritik işlemlerde kontrol sende kalıyor. Bu ne anlama geliyor? Bu denge önemli, çok önemli.

Küçük Startup vs Enterprise: Hangisi Için Ne Mantıklı?

İşin garibi, Küçük bir startup için muhtemelen sadece dosya tabanlı skill’ler yeterli olacak. Hızlı prototipleme, markdown düzenleme, git’e commit atma — bitti. Fazla mühendislik yapmaya gerek yok, gerçekten. Hani ne farkı var diyorsunuz, değil mi? Over-engineering burada düşmanınız.

Ama enterprise seviyede iş değişiyor. Farklı ekipler farklı skill’ler üretiyor, versiyon yönetimi lazım, test pipeline’ları lazım, approval flow’ları lazım — liste uzuyor (ben de ilk duyduğumda şaşırmıştım). O zaman sınıf tabanlı skill’ler ağırlıkta oluyor, dosya tabanlılar da config-driven senaryolar için kalıyor. Yanı iki dünyanın da yeri var, birini seçmek zorunda değilsiniz.

Ha bu arada, Azure MCP Server 2.0: Kendi Sunucunuzda Ajan Otomasyonu yazımda ajan otomasyonunun sunucu tarafını ele almıştım — bu skill meselesi de o mimarinin doğal bir uzantısı aslında, bağlantılı konular bunlar.

Şöyle söyleyeyim, Bir de şunu ekleyeyim: AG-UI ile Çoklu Ajan Arayüzü: Gerçek Zamanlı Demo yazısında çoklu agent arayüzlerinden bahsetmiştim. Bu skill provider yapısı, o tür multi-agent senaryolarda da gayet kullanışlı — her agent kendi skill set’ını taşıyabiliyor, bağımsız hareket edebiliyor. GitHub Copilot CLI Nedir ve Nasıl Kurulur: İlk … yazımızda bu konuya da değinmiştik.

Hayal Kiriklığım ve Beklentilerim

Açık konuşayım: bu framework’ün şu anki hali “iyi” ama “mükemmel” değil. Birkaç şey beni rahatsız etti, lafı gevelemeyeyim.

Birincisi, skill discovery mekanizması yok (evet, doğru duydunuz). Yanı agent hangi skill’lerin mevcut olduğunu biliyor ama dinamik olarak yeni skill keşfetme gibi bir özellik yok — her şeyi baştan tanımlamanız gerekiyor (inanın bana). İkincisi, skill’ler arası bağımlılık yönetimi eksik. Onboarding skill’i benefits skill’ine bağımlıysa ne olacak? Şu an bunu sız manuel yönetiyorsunuz, framework size yardımcı olmuyor bu konuda.

Üçüncüsü — ve bu beni en çok rahatsız eden — debugging deneyimi. Dosya tabanlı bir skill hata verdiğinde, hatanın nereden geldiğini bulmak bazen çok zor oluyor. Markdown parse hatası mı, script hatası mı, yoksa agent’ın yanlış yorumlaması mı? Bilemiyorsunuz hemen. Loglama biraz daha olgunlaşması lazım, kesinlikle.

Küçük bir detay: Kağıt üstünde süper bir model ama pratikte birkaç sprint daha pişmesi gerekiyor. Yine de mevcut alternatiflere kıyasla bayağı iyi durumda — bunu da belirteyim, haksızlık etmeyeyim. Doğru yönde gidiyorlar en azından.

Sıkça Sorulan Sorular

Agent skill nedir ve neden birden fazla yazma yöntemi var?

Bunu yaşayan biri olarak söyleyeyim, Agent skill, bir yapay zekâ ajanının belirli bir görevi yerine getirmek için kullandığı yetenek modülü. Birden fazla yazma yöntemi olmasının sebebi gerçek dünya ihtiyaçları — farklı ekipler farklı hızlarda çalışıyor, bazı skill’ler sık değişiyor, bazıları paketlenip paylaşılıyor. İlginç, değil mi? Tek bir yöntem herkesi tatmin etmiyor.

Dosya tabanlı skill’lerde script çalıştırmak güvenli mi?

Tek başına güvenli değil — mutlaka insan onayı mekanizması eklemeniz gerekiyor. SubprocessScriptRunner’ı doğrudan kullanmak yerine, arada bir approval katmanı koymanız şiddetle tavsiye edilir. Production ortamında kontrolsüz script çalıştırma ciddi güvenlik açıklarına yol açabilir.

Bu yapı sadece Azure OpenAI ile mi çalışıyor?

Hayır. AgentSkillsProvider yapısı AI provider’dan bağımsız çalışıyor. Örneklerde Azure OpenAI kullanılıyor ama herhangi bir OpenAI uyumlu endpoint ile kullanabilirsiniz. Provider pattern sayesinde AI backend değişikliği skill’leri etkilemiyor.

Inline skill ne zaman tercih edilmeli?

İşte, size bir şey söyleyeyim, Sadece geçici çözümler için. Bir skill’in resmî paketi henüz hazır değilse veya hızlı bir PoC yapıyorsanız inline kullanın. Ama production’da kalıcı inline skill tutmayın — bakımı zorlaşır ve test edilemez hâle gelir.

Mevcut bir skill’i başka bir yöntemle değiştirmek agent’ı etkiler mi?

İlginç olan şu ki, Hayır, bu modelin en güzel tarafı bu. Inline bir skill’i kaldırıp yerine NuGet paketli sınıf tabanlı skill koyduğunuzda, agent açısından hiçbir şey değişmiyor. Aynı işim ve açıklama korunduğu sürece geçiş sorunsuz oluyor (inanın bana)

Hmm, bunu nasıl anlatsamdı…

Kaynaklar ve İleri Okuma

Bence, Agent Skills in.NET: Three Ways to Author, Öne Provider to Run Them — Microsoft DevBlogs (kendi tecrübem)

Azure OpenAI Service Resmî Dokümantasyonu

Microsoft Agents Framework — GitHub Repository

İçeriği paylaş:

📬 Bu yazıyı faydalı buldunuz mu?

Azure, DevOps ve bulut teknolojileri hakkında güncel içerikler için beni takip edin!

📨

Haftalık Bülten

Her pazar en iyi yazılar ve teknoloji haberleri e-postanıza gelsin.

Yorum gönder

Microsoft Azure Çözüm Uzmanı | Bulut Bilişim, Yapay Zekâ, DevOps ve Kurumsal Güvenlik alanlarında 15+ yıl deneyim. Azure, Kubernetes, AI/ML ve modern altyapı mimarileri üzerine yazılar yazıyorum.

Haftalık Bülten

Azure, DevOps ve Yapay Zeka dünyasındaki en güncel içerikleri her hafta doğrudan e-postanıza alın.

Spam yok. İstediğiniz zaman iptal edebilirsiniz.
📱
Uygulamayı Yükle Ana ekrana ekle, çevrimdışı oku
Paylaş
İçindekiler
    ← ChatGPT ile Araştırma: Search ...
    GitHub Pages ile Ücretsiz Site... →
    📩

    Gitmeden önce!

    Her pazar özenle seçilmiş teknoloji yazıları ve AI haberleri doğrudan e-postanıza gelsin. Ücretsiz, spam yok.

    🔒 Bilgileriniz güvende. İstediğiniz zaman ayrılabilirsiniz.

    📬 Haftalık bülten: Teknoloji + AI haberleri