<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Topics tagged with tutorial]]></title><description><![CDATA[A list of topics that have been tagged with tutorial]]></description><link>https://forum.androidiani.net/tags/tutorial</link><generator>RSS for Node</generator><lastBuildDate>Fri, 01 May 2026 00:33:52 GMT</lastBuildDate><atom:link href="https://forum.androidiani.net/tags/tutorial.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 26 Apr 2026 10:08:16 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Classificazione documenti in C# senza AI: approccio deterministico, spiegabile e pronto per la produzione]]></title><description><![CDATA[Classificare automaticamente i documenti aziendali è uno di quei problemi che, a prima vista, sembra un caso d’uso ideale per i modelli AI. Ma in ambienti di produzione, la stabilità, la tracciabilità e la prevedibilità del comportamento spesso contano più della flessibilità. In questo articolo vediamo come implementare un classificatore di documenti rule-based, ponderato e completamente spiegabile in C# .NET, senza toccare un singolo modello di machine learning.Perché non partire dall’AI?I modelli AI per la classificazione di testo sono potenti, ma introducono una serie di criticità in contesti enterprise:Non-determinismo: lo stesso documento può ricevere classificazioni diverse a seconda della versione del modello, del wording del prompt o di aggiornamenti interni del provider.Opacità: spiegare a un responsabile compliance perché il modello ha classificato un contratto come “fattura” è praticamente impossibile.Dipendenza da pipeline di dati: aggiornare il classificatore richiede raccolta di dati, rietichettatura, riaddestramento e deployment.Un approccio deterministico e rule-based risolve tutti e tre i problemi: stesso input, stesso output, sempre. Ogni decisione è tracciabile e modificabile senza toccare il codice, solo aggiornando un file di configurazione JSON.Architettura del classificatoreIl sistema segue una pipeline chiara:Caricamento dei profili di classificazione da file JSONApertura del documento .docx con TX Text ControlEstrazione del testo da corpo, intestazioni e piè di paginaRilevamento delle regioni strutturali (titolo, heading, corpo, header, footer)Matching delle regole per categoria con strategie configurabiliCalcolo degli score ponderati per categoriaRestituzione della categoria vincente con confidence score e spiegazione dettagliataL’elemento chiave è che tutta la logica di classificazione vive nel file JSON, non nel codice. Questo significa che un domain expert (non un developer) può modificare e migliorare il classificatore semplicemente editando la configurazione.Il file di configurazioneOgni categoria è descritta da un insieme di regole. Ogni regola specifica:term: il termine o la frase da cercareweight: il peso del contributo di questa regola allo scorematchMode: la strategia di matching (Phrase, WholeWord, Contains)strength: la forza del segnale (Strong, Weak)Esempio per la categoria “Resume”:{   "name": "Resume",   "rules": [     {       "term": "work experience",       "weight": 3.0,       "matchMode": "Phrase",       "strength": "Strong"     },     {       "term": "email",       "weight": 1.0,       "matchMode": "WholeWord",       "strength": "Weak"     }   ] }La distinzione tra segnali forti e deboli è cruciale. “Work experience” in un documento è un indicatore molto specifico di un CV, mentre “email” può apparire praticamente ovunque e deve pesare di meno. Questa granularità evita i falsi positivi che affliggono i classifier naïve basati su semplice keyword counting.Estrazione strutturata con TX Text ControlIl classificatore non tratta il documento come un blocco di testo piatto. Usando TX Text Control .NET Server, estrae il contenuto per regioni strutturali:using var textControl = new ServerTextControl(); textControl.Create(); textControl.Load(docxPath, StreamType.WordprocessingML);Vengono estratti separatamente:textControl.Paragraphs → testo del corpotextControl.Sections → HeadersAndFooters → intestazioni e piè di pagina di ogni sezioneQuesta distinzione è fondamentale: nelle fatture, i termini identificativi come “FATTURA N.” appaiono tipicamente all’inizio del documento o nel titolo. Nei report, il tipo di documento è spesso incorporato nell’header. Ignorare queste regioni significherebbe perdere segnali classificatori di primo livello.Structure Awareness: non tutto il testo vale ugualeIl miglioramento più significativo rispetto al semplice keyword matching è la consapevolezza della struttura. Il classificatore assegna pesi diversi agli stessi termini a seconda della regione in cui appaiono:Un termine nel titolo del documento ha peso massimo: è quasi certamente indicativo del tipo di documentoUn termine in un heading H1/H2 ha peso altoLo stesso termine nel corpo del documento ha peso standardNel footer (tipicamente template boilerplate) il peso è ridottoQuesto approccio riflette come un essere umano leggerebbe effettivamente il documento: prima si guarda il titolo, poi le intestazioni principali, infine il corpo.Scoring, confidence e spiegabilitàAl termine dell’analisi, il sistema restituisce non solo la categoria vincente, ma anche:Il confidence score (rapporto tra lo score della categoria vincente e la somma degli score di tutte le categorie)Una spiegazione dettagliata: quali regole hanno fatto match, in quale regione, con quale pesoQuesta tracciabilità è essenziale per scenari di audit e compliance. Se un documento viene classificato erroneamente, il problema è sempre identificabile e correggibile: si modifica la regola nel JSON e si riclassifica. Nessun riaddestramento, nessuna nuova pipeline di dati.Quando usare questo approccio (e quando no)L’approccio deterministico è ottimale quando:Il set di categorie è definito e stabile (fatture, contratti, report, CV, ecc.)La compliance e l’auditability sono requisiti primariIl volume di documenti è alto e la velocità di classificazione è criticaNon si dispone di dataset etichettati sufficienti per addestrare un modelloDove l’AI rimane superiore è nei casi con categorie ambigue, linguaggio naturale molto variabile, o quando il set di categorie evolve rapidamente e non si vuole aggiornare manualmente le regole. Un’architettura ibrida – classificazione rule-based come primo filtro, AI solo per i casi borderline – è spesso la soluzione migliore in produzione.ConclusioneLa classificazione documentale senza AI non è un’alternativa di ripiego: è una scelta ingegneristica deliberata per sistemi che richiedono stabilità, spiegabilità e controllo. Il pattern rule-based, ponderato e configuration-driven descritto in questo articolo è già in uso in ambienti di produzione enterprise e offre vantaggi concreti in termini di manutenibilità e trasparenza.Se il vostro stack include la gestione di documenti .docx in C#, questo approccio vale la pena di essere valutato prima di introdurre la complessità di un modello ML.Fonte: Document Classification Without AI: Deterministic, Explainable, and Built for Production in C# .NET – Bjoern Meyer, TX Text Control Blog]]></description><link>https://forum.androidiani.net/topic/0aa5c73a-f7b6-4d82-9d50-53d0272001cd/classificazione-documenti-in-c-senza-ai-approccio-deterministico-spiegabile-e-pronto-per-la-produzione</link><guid isPermaLink="true">https://forum.androidiani.net/topic/0aa5c73a-f7b6-4d82-9d50-53d0272001cd/classificazione-documenti-in-c-senza-ai-approccio-deterministico-spiegabile-e-pronto-per-la-produzione</guid><dc:creator><![CDATA[blog@spcnet.it]]></dc:creator><pubDate>Sun, 26 Apr 2026 10:08:16 GMT</pubDate></item><item><title><![CDATA[Azure Developer CLI: scrivere gli hook in Python, TypeScript e .NET]]></title><description><![CDATA[L’Azure Developer CLI (azd) è lo strumento open-source di Microsoft pensato per accompagnare lo sviluppatore dall’ambiente locale fino al deployment su Azure. Tra le sue funzionalità più apprezzate, il sistema degli hook permette di iniettare logica personalizzata nei punti chiave del ciclo di vita: prima del provisioning, dopo il deployment, e così via. Fino a poco tempo fa, però, questa logica doveva essere scritta esclusivamente in Bash o PowerShell, costringendo chi lavora in Python o TypeScript a un cambio di contesto non sempre gradito.Con il rilascio più recente di azd, questo limite è stato rimosso: gli hook possono ora essere scritti in Python, JavaScript, TypeScript e .NET, oltre ai già supportati Bash e PowerShell. La selezione del linguaggio avviene automaticamente in base all’estensione del file, senza configurazione aggiuntiva.Cosa sono gli hook in azdGli hook sono script eseguiti automaticamente da azd in corrispondenza di eventi specifici nel workflow:preprovision: prima che venga eseguito il provisioning dell’infrastrutturapostprovision: dopo il provisioningpredeploy / postdeploy: prima e dopo il deployment dell’applicazioneSi definiscono nel file azure.yaml con il blocco hooks:, specificando il percorso allo script da eseguire. azd si occupa autonomamente di rilevare il runtime appropriato, installare le dipendenze e lanciare lo script.Come usare gli hook in PythonPer un hook Python, è sufficiente creare il file .py e, nella stessa directory o in una directory padre, un file requirements.txt o pyproject.toml. azd individuerà automaticamente il file di dipendenze, creerà un virtual environment e installerà i pacchetti necessari prima di eseguire lo script.Struttura tipica:hooks/
├── setup.py
└── requirements.txt
Configurazione in azure.yaml:hooks:
  preprovision:
    run: ./hooks/setup.py
È possibile personalizzare il nome del virtual environment tramite il blocco config:hooks:
  preprovision:
    run: ./hooks/setup.py
    config:
      virtualEnvName: .venv
Hook in JavaScript e TypeScriptPer gli hook JavaScript e TypeScript, azd cerca un file package.json nella stessa directory o in una directory padre. Esegue automaticamente npm install (o il package manager specificato nella configurazione) e lancia lo script.Per TypeScript, la novità più interessante è che non serve un tsconfig.json né una fase di compilazione separata: azd utilizza npx tsx per eseguire il file TypeScript direttamente.hooks/
├── seed.ts
└── package.json
hooks:
  postdeploy:
    run: ./hooks/seed.ts
    config:
      packageManager: pnpm   # npm | pnpm | yarn
Hook in .NET e C#Per i progetti .NET sono supportate due modalità distinte:Project mode: se nella directory dello script (o in una padre) è presente un file .csproj, .fsproj o .vbproj, azd esegue automaticamente dotnet restore e dotnet build.Single-file mode: a partire da .NET 10, i file .cs standalone vengono eseguiti direttamente con dotnet run script.cs, senza necessità di un progetto.hooks/
├── migrate.cs
└── migrate.csproj   # opzionale su .NET 10+
hooks:
  postprovision:
    run: ./hooks/migrate.cs
    config:
      configuration: Release   # Debug | Release
      framework: net10.0
Funzionalità avanzateOverride della directory di lavoroSe la root del progetto e la posizione dello script differiscono, si può usare il campo dir per specificare la working directory:hooks:
  preprovision:
    run: main.py
    dir: hooks/preprovision
Override esplicito del linguaggioSe l’estensione è assente o ambigua, è possibile forzare il runtime con il campo kind:hooks:
  preprovision:
    run: ./hooks/setup
    kind: python
Formato misto e override per piattaformaSi possono combinare hook in linguaggi diversi e specificare script differenti per Windows e sistemi POSIX:hooks:
  preprovision:
    run: ./hooks/setup.py
  predeploy:
    windows:
      run: ./hooks/build.ps1
    posix:
      run: ./hooks/build.sh
  postdeploy:
    run: ./hooks/seed.ts
  postprovision:
    run: ./hooks/migrate.cs
Come aggiornare azdPer assicurarsi di avere questa funzionalità disponibile, è sufficiente aggiornare azd all’ultima versione:azd update
Per una nuova installazione, è possibile seguire la guida ufficiale di installazione.ConclusioniIl supporto multi-linguaggio per gli hook di azd rappresenta un miglioramento concreto per i team che lavorano con stack tecnologici eterogenei. Non dover più mantenere script shell separati per la logica di deployment è un risparmio reale di complessità, soprattutto nei progetti .NET o Python dove gran parte della base di codice esistente può essere riutilizzata direttamente negli hook.La gestione automatica delle dipendenze (virtual env per Python, npm install per JS/TS, dotnet restore per .NET) elimina ulteriore boilerplate, rendendo l’integrazione trasparente. Chi già usa azd nel proprio workflow troverà questa novità immediatamente utile; chi non lo ha ancora esplorato può partire dalla documentazione ufficiale e dalla galleria di template.Fonte: Write azd hooks in Python, JavaScript, TypeScript, or .NET – Azure SDK Blog]]></description><link>https://forum.androidiani.net/topic/673b6796-781d-4080-b8f9-f5996d4b7836/azure-developer-cli-scrivere-gli-hook-in-python-typescript-e-.net</link><guid isPermaLink="true">https://forum.androidiani.net/topic/673b6796-781d-4080-b8f9-f5996d4b7836/azure-developer-cli-scrivere-gli-hook-in-python-typescript-e-.net</guid><dc:creator><![CDATA[blog@spcnet.it]]></dc:creator><pubDate>Fri, 24 Apr 2026 09:03:20 GMT</pubDate></item><item><title><![CDATA[Primary Constructor e Dependency Injection in C# 12: vantaggi, insidie e quando usarli]]></title><description><![CDATA[Con C# 12, Microsoft ha introdotto i primary constructors per tutte le classi e le struct — non solo per i record come in precedenza. Per chi lavora quotidianamente con ASP.NET Core e il pattern di dependency injection, questa feature merita attenzione: riduce il boilerplate in modo significativo, ma nasconde un'insidia che è bene conoscere prima di adottarla sistematicamente.Il problema: il boilerplate del costruttore classicoChi ha scritto servizi ASP.NET Core sa bene come appare il costruttore tradizionale con dependency injection:public class OrderService
{
    private readonly IOrderRepository _orderRepository;
    private readonly ILogger&lt;OrderService&gt; _logger;
    private readonly IEventBus _eventBus;
    private readonly IValidator&lt;Order&gt; _validator;

    public OrderService(
        IOrderRepository orderRepository,
        ILogger&lt;OrderService&gt; logger,
        IEventBus eventBus,
        IValidator&lt;Order&gt; validator)
    {
        _orderRepository = orderRepository;
        _logger = logger;
        _eventBus = eventBus;
        _validator = validator;
    }
}Per ogni dipendenza: una dichiarazione di campo, un parametro nel costruttore, un'assegnazione nel corpo. Con quattro dipendenze, sono già dodici righe di puro scaffolding. In un servizio con sei o sette dipendenze, il costruttore diventa il blocco di codice più lungo della classe — senza contenere logica.La soluzione con primary constructorsCon i primary constructors di C# 12, lo stesso servizio si scrive così:public class OrderService(
    IOrderRepository orderRepository,
    ILogger&lt;OrderService&gt; logger,
    IEventBus eventBus,
    IValidator&lt;Order&gt; validator)
{
    public async Task&lt;Order?&gt; GetOrderAsync(Guid id)
    {
        logger.LogInformation("Fetching order {OrderId}", id);
        return await orderRepository.GetByIdAsync(id);
    }

    public async Task PlaceOrderAsync(Order order)
    {
        await validator.ValidateAndThrowAsync(order);
        await orderRepository.SaveAsync(order);
        await eventBus.PublishAsync(new OrderPlacedEvent(order.Id));
    }
}I parametri del primary constructor diventano direttamente disponibili in tutta la classe senza dichiarazioni esplicite di campo. Il risultato è codice più snello, con meno rumore visivo e il focus immediato sulla logica di business.L'insidia della mutabilità: perché Milan Jovanović era inizialmente scetticoIl motivo di resistenza di molti sviluppatori esperti è legittimo: i parametri del primary constructor non sono campi readonly. Il compilatore non impedisce la riassegnazione accidentale:public class OrderService(IOrderRepository orderRepository)
{
    public void SomeMethod()
    {
        orderRepository = null!;  // Compila senza warning
    }
}Con i campi privati readonly tradizionali, questo codice causa un errore di compilazione. Con i primary constructors, il compilatore lo accetta silenziosamente. In un servizio DI dove le dipendenze non dovrebbero mai essere rimpiazzate a runtime, questo è un rischio concreto in team di grandi dimensioni.Mitigazione: assegnazione esplicita a readonly fieldQuando la garanzia di immutabilità è critica, si può assegnare esplicitamente il parametro a un campo readonly:public class CriticalService(IRepository repository)
{
    private readonly IRepository _repository = repository;

    // Da qui in poi si usa _repository, mai repository direttamente
}Questo reintroduce parte del boilerplate, ma mantiene la sintassi più compatta per la firma del costruttore e garantisce l'immutabilità a livello compilatore.Quando usare i primary constructorsLa valutazione pragmatica è che i primary constructors offrono il massimo vantaggio nelle classi di servizio DI tipiche di ASP.NET Core, dove i parametri vengono usati ma raramente riassegnati. In questi scenari, il rischio di mutabilità accidentale è basso e i benefici di leggibilità sono immediati.Vale la pena usarli anche per entity e value object dove i parametri di costruzione diventano proprietà read-only:public class Order(Guid customerId, Money total)
{
    public Guid Id { get; } = Guid.NewGuid();
    public Guid CustomerId { get; } = customerId;
    public Money Total { get; } = total;
    public DateTime CreatedAt { get; } = DateTime.UtcNow;
}Quando evitarliTre scenari in cui i primary constructors non sono la scelta giusta:Logica di validazione nel costruttore: se il costruttore deve eseguire guard clause o validazioni prima dell'assegnazione, il corpo esplicito del costruttore tradizionale è necessario.Multiple signature di costruttore: i primary constructors supportano una sola firma. Con overload multipli (es. per serializzazione), la sintassi tradizionale è l'unica opzione.Cinque o più dipendenze: se una classe richiede molte dipendenze, il problema non è la sintassi del costruttore ma il design della classe. Il segnale che suggerisce un refactoring verso interfacce più coese o il pattern Facade.Conclusione: adottarli con consapevolezzaI primary constructors di C# 12 non sono una rivoluzione, ma un'evoluzione pragmatica del linguaggio. Per la maggior parte delle classi di servizio in ASP.NET Core, il tradeoff è favorevole: meno boilerplate, codice più leggibile, rischio di mutabilità basso nel contesto DI. L'importante è conoscere il comportamento del compilatore e scegliere consapevolmente quando la garanzia di readonly è effettivamente necessaria.Come sempre con le feature di C#, il consiglio è adottarle dove migliorano la leggibilità del codice reale, non per seguire una moda sintattica.Fonte originale: Why I Switched to Primary Constructors for DI in C# di Milan Jovanović.]]></description><link>https://forum.androidiani.net/topic/ed9059e2-0ab3-4ef4-a625-36f90606443b/primary-constructor-e-dependency-injection-in-c-12-vantaggi-insidie-e-quando-usarli</link><guid isPermaLink="true">https://forum.androidiani.net/topic/ed9059e2-0ab3-4ef4-a625-36f90606443b/primary-constructor-e-dependency-injection-in-c-12-vantaggi-insidie-e-quando-usarli</guid><dc:creator><![CDATA[blog@spcnet.it]]></dc:creator><pubDate>Tue, 21 Apr 2026 13:28:35 GMT</pubDate></item><item><title><![CDATA[Agent Skills in .NET: tre paradigmi di composizione per gli agenti AI]]></title><description><![CDATA[Introduzione: L’evoluzione dei skill negli agent .NETGli 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 skill1. 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.md con metadati nel frontmatter YAMLUna sottocartella opzionale scripts/ con il codice eseguibileUna sottocartella opzionale references/ con documentazione di supportoQuesto 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&lt;T&gt; e si usano attributi di reflection per marcare le risorse e gli script:public sealed class BenefitsEnrollmentSkill : AgentClassSkill&lt;BenefitsEnrollmentSkill&gt;
{
    [AgentSkillResource("available-plans")]
    public string AvailablePlans =&gt; "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) =&gt; 
    {
        // Logica runtime
        return $"Giorni rimanenti: {remaining}";
    });
I skill inline supportano anche risorse dinamiche:.AddResource("policies", () =&gt; PolicyRepository.GetActivePolicies());
Questa capacità di aggiungere risorse come delegate è cruciale: le politiche possono aggiornarsi senza ricompilare l’applicazione.Composizione flessibile con AgentSkillsProviderBuilderLa 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 disponibiliLa classe BenefitsEnrollmentSkill registra i suoi metodi annotatiLo skill inline timeOffSkill aggiunge capacità runtimeIl framework astrae completamente il “come” carica ogni tipo di skill; l’agent li vede come una superficie unificata.Funzionalità avanzateApprovazione degli scriptPer 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 sicurezzaQuando si condividono directory di skill tra team, il filtraggio garantisce che solo gli skill approvati siano disponibili:.UseFilter(skill =&gt; approvedSkills.Contains(skill.Frontmatter.Name))
Iniezione di dipendenzeI 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&lt;IEmailService&gt;();
    return emailService.SendAsync(userId, "Notification");
}
ConclusioneIl 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]]></description><link>https://forum.androidiani.net/topic/cd793990-3175-4b79-b45d-0f25c7036e88/agent-skills-in-.net-tre-paradigmi-di-composizione-per-gli-agenti-ai</link><guid isPermaLink="true">https://forum.androidiani.net/topic/cd793990-3175-4b79-b45d-0f25c7036e88/agent-skills-in-.net-tre-paradigmi-di-composizione-per-gli-agenti-ai</guid><dc:creator><![CDATA[blog@spcnet.it]]></dc:creator><pubDate>Wed, 15 Apr 2026 13:16:15 GMT</pubDate></item></channel></rss>