Introduzione: L’evoluzione dei skill negli agent .NET
Gli agent AI richiedono un modo flessibile e modulare di estendere le loro capacità: questo è il ruolo dei skill. Con il framework Agent di Microsoft per .NET, gli sviluppatori dispongono di tre paradigmi complementari per definire e comporre skill, permettendo ai team di scegliere l’approccio più adatto al loro contesto.
I tre paradigmi per creare skill
1. Skill basati su file (File-Based Skills)
L’approccio più dichiarativo parte da una struttura di directory semplice. Ogni skill è organizzato come una cartella contenente:
- Un file
SKILL.mdcon metadati nel frontmatter YAML - Una sottocartella opzionale
scripts/con il codice eseguibile - Una sottocartella opzionale
references/con documentazione di supporto
Questo paradigma è particolarmente vantaggioso per i team che vogliono gestire i skill come assets indipendenti dentro un repository condiviso. Il caricamento è automatico: l’agent scopre e carica i skill quando l’utente ne fa richiesta.
Ecco come si registra un provider file-based:
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
SubprocessScriptRunner.RunAsync);
Il vantaggio decisivo è la separazione tra definizione del skill e implementazione. Non è necessario riconfigurare il codice C# per aggiungere nuovi skill; basta creare una nuova directory.
2. Skill basati su classe (Class-Based Skills)
Per chi preferisce la sicurezza dei tipi e il supporto IDE completo, gli skill basati su classe offrono un’alternativa fortemente tipizzata. Si eredita da AgentClassSkill<T> e si usano attributi di reflection per marcare le risorse e gli script:
public sealed class BenefitsEnrollmentSkill : AgentClassSkill<BenefitsEnrollmentSkill>
{
[AgentSkillResource("available-plans")]
public string AvailablePlans => "Plan A, Plan B, Plan C...";
[AgentSkillScript("enroll")]
private static string Enroll(string employeeId, string planCode)
{
// Logica di iscrizione
return $"Iscrizione di {employeeId} al piano {planCode} completata";
}
}
Questo approccio è ideale per skill complessi che richiedono logica C# sofisticata. Gli attributi [AgentSkillResource] e [AgentSkillScript] permettono al framework di scoprire automaticamente quali metodi e proprietà esporre all’agent.
Un vantaggio cruciale: i team possono sviluppare e distribuire skill indipendentemente come pacchetti NuGet, mantenendo il proprio ciclo di rilascio e permettendo il riuso tra progetti.
3. Skill inline (Inline Code-Defined Skills)
Il terzo paradigma è il più flessibile: skill definiti a runtime usando AgentInlineSkill. Sono perfetti per bridge temporanei, skill generati dinamicamente o implementazioni condizionate dallo stato dell’applicazione:
var timeOffSkill = new AgentInlineSkill(
name: "time-off-balance",
description: "Calcola i giorni di ferie e malattia rimanenti per un dipendente...")
.AddScript("calculate-balance", (employeeId, leaveType) =>
{
// Logica runtime
return $"Giorni rimanenti: {remaining}";
});
I skill inline supportano anche risorse dinamiche:
.AddResource("policies", () => PolicyRepository.GetActivePolicies());
Questa capacità di aggiungere risorse come delegate è cruciale: le politiche possono aggiornarsi senza ricompilare l’applicazione.
Composizione flessibile con AgentSkillsProviderBuilder
La vera potenza del design emerge quando si combinano tutti e tre i paradigmi in un’unica applicazione. Il builder pattern permette una composizione dichiarativa:
var skillsProvider = new AgentSkillsProviderBuilder()
.UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"))
.UseSkill(new BenefitsEnrollmentSkill())
.UseSkill(timeOffSkill)
.UseFileScriptRunner(SubprocessScriptRunner.RunAsync)
.Build();
In questa configurazione:
- I skill nel filesystem vengono caricati e resi disponibili
- La classe
BenefitsEnrollmentSkillregistra i suoi metodi annotati - Lo skill inline
timeOffSkillaggiunge capacità runtime
Il framework astrae completamente il “come” carica ogni tipo di skill; l’agent li vede come una superficie unificata.
Funzionalità avanzate
Approvazione degli script
Per ambienti ad alto rischio, è possibile richiedere una revisione umana prima dell’esecuzione:
.UseScriptApproval(true)
In questo caso, l’agent formula il comando ma non lo esegue autonomamente; un operatore deve approvare.
Filtraggio di sicurezza
Quando si condividono directory di skill tra team, il filtraggio garantisce che solo gli skill approvati siano disponibili:
.UseFilter(skill => approvedSkills.Contains(skill.Frontmatter.Name))
Iniezione di dipendenze
I metodi degli skill possono ricevere IServiceProvider come parametro. Questo consente l’accesso a servizi registrati nel contenitore DI, indipendentemente dal paradigma di skill:
[AgentSkillScript("send-notification")]
private static string SendNotification(string userId, IServiceProvider services)
{
var emailService = services.GetRequiredService<IEmailService>();
return emailService.SendAsync(userId, "Notification");
}
Conclusione
Il design tripartito dei skill in .NET Agent Framework non è una complicazione: è un’architettura di composizione che rispetta gli usi diversi. Gli skill basati su file servono la semplicità e la dinamica; quelli basati su classe offrono sicurezza e riusabilità via NuGet; quelli inline forniscono agilità runtime.
Per i team che costruiscono sistemi agent complessi, questa flessibilità è fondamentale. Permette di iniziare in semplicità (skill inline), evolversi verso la modularità (skill basati su classe in NuGet) e mantenere agilità operativa (skill file-based per aggiustamenti dinamici) — tutto nello stesso agent, senza compromessi architetturali.
Fonte originale: Agent Skills in .NET: Three Ways to Author, One Provider to Run Them — Microsoft Agent Framework Blog