sabato 9 agosto 2025

Creare un Agent in C# con Semantic Kernel

 Ciao a tutti,

In questo post voglio condividere come implementare un agent in c# sfruttando il semantic Kernel.

Ma partiamo dalle basi, cos' è un Agent? e a cosa ci serve?

Cos'è un Agent?

Un agent può essere inteso come un sistema in grado di prendere decisioni in modo autonomo, seguendo obiettivi e regole che gli sono stati dati, sfruttando le informazioni in un suo possesso.

A Cosa ci servono gli Agent?

Gli agent ci possono aiutare ad automatizzare tutta una serie di operazioni e a velocizzare il nostro lavoro quotidiano. 
Il caso più banale è quello dell'operatore di customer care, che deve recuperare e verificare la situazione del cliente, a seguito della richiesta del cliente, bene queste sono operazioni che può eseguire un Agent addestrato a fare ciò.

Cos'è Il Semantic Kernel ?

Il Semantic Kernel è un Framework che permette l'integrazione dell'AI all'interno di vari linguaggi di programmazione questo ci permette appunto di sviluppare agent, ma non solo gli agent sono solo una parte di ciò che possiamo fare con il Semantic Kernel


Costruiamo un semplice agente

Bene a questo punto vi mostro gli step per costruire un agent.

Per sviluppare questo piccolo progetto, ho usato come modello "llama3.2" su un Container con Ollama,

STEP 1 Creazione del progetto e aggiunta dei pacchetti necessari.

Creiamo una console e andiamo ad aggiungere i seguenti pacchetti nuget



Microsoft.SemanticKernel
Microsoft.SemanticKernel.Core
Microsoft.SemanticKernel.Agents.Core
Microsoft.SemanticKernel.Connectors.Ollama  → in pre-release


STEP 2 Creazione dell'agent

Ora possiamo già procedere con la creazione dell'agent,

Andremo a Instanziare l'agent e a dargli le istruzioni, nel mio caso gli ho detto di inventare storie divertenti.


using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;

var builder = Kernel.CreateBuilder();

// Add the Ollama chat completion service
// Ensure you have Ollama running and the model "llama3.2:3b" is available
// You can change the model name and URI as needed
builder.AddOllamaChatCompletion("llama3.2:3b", new Uri("http://localhost:11434"));

var kernel = builder.Build();

ChatCompletionAgent agent = new() // 👈🏼 Definition of the agent
{
    Instructions = "You are an agent who creates funny stories.",
    Name = "Story Agent",
    Description = "This agent can create funny stories based on user input.",
    Kernel = kernel
};

STEP 3 Interazione con l'agent

è il momento di scrivere l'interazione con l'agent, io ho simulato un chatbot botta e risposta giusto per divertirmi un po



string userMessage = string.Empty;

do
{
    Console.WriteLine("What kind of story would you like me to tell you? Type 'exit' to stop the chat.");
    userMessage = Console.ReadLine();

    if (!string.IsNullOrEmpty(userMessage) && userMessage != "exit")
    {
        ChatHistory chat =
        [
            new ChatMessageContent(AuthorRole.User, userMessage)
        ];

        await foreach (var response in agent.InvokeAsync(chat))
        {
            chat.Add(response);
            Console.WriteLine(response.Message.Content);
        }

        userMessage = string.Empty;
    }

}
while (userMessage != "exit");

A questo punto la console può essere eseguita e testata.

Integrazione con Function

Ovviamente per rendere l'agent più centrato sui nostri obiettivi, possiamo definire delle funzioni custom con le quali lui andrà a recuperare le informazioni. 
Ad esempio il recupero delle informazioni relative al cliente stesso, all'interno dei sistemi. Di seguito ho simulato un esempio dell'utilizzo delle funzioni

STEP 4 Definire le funzioni


[Description("Get the residence city from the user")]
string GetCity(string name)
{
    return "Roma";
}

[Description("Get the age of a user")]
int GetUserAge(string name)
{
    return 25;
}

Definite le funzioni le associamo al nostro agent

Andiamo ad aggiungere ai plugin le funzioni che abbiamo scritto sopra, in modo tale che questo possa invocarle quando necessario


agent.Kernel.Plugins.Add(GetCity);
agent.Kernel.Plugins.Add(GetUserAge);

Definire gli arguments nella definizione dell'agent


ChatCompletionAgent agent = new() // 👈🏼 Definition of the agent
{
    Instructions = "You are an agent who creates funny stories. If you find any 
       information related to the user through plugins or tools, include it in 
       the story to make it more personal and engaging.",
    Name = "Story Agent",
    Description = "This agent can create funny stories based on user input.",
    Kernel = kernel,
    Arguments = new KernelArguments(new PromptExecutionSettings
    {
        FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
    }) // 👈🏼 Set the function choice behavior to auto
};

In questo modo abbiamo detto al nostro agent, che può recuperare informazioni tramite le  funzioni che abbiamo definito.

Conclusioni

Con questo post volevo, condividere come implementare un Agent, e le sue potenzialità..  Ovviamente anche io sto ancora studiando e questo progetto di test è in continua evoluzione, per cui vi lascio anche il link al Repository github.

martedì 27 settembre 2011

Log For Sharepoint

Ciao a tutti,

Oggi voglio mostrarvi una feature per i log da me implementata, è abbastanza semplice da utilizzare e spero possa tornarvi utile.

Si occupa di scrivere i log su liste sharepoint cosi eviteremo di andare sempre a guardarci i log che scrive sharepoint in quel file di testo, è ancora in fase di sviluppo ma se magari qualcuno vuole darmi una mano è ben accetto.

Questo è il link per il download del sorgente



E ora ecco la spiegazione di come funziona, e di come installarla

Nel Progetto ci sono 2 feature la prima installa tutto il necessario, mentre la seconda modifica il web.config in modo di inserire l'error module ma io vi consiglio di inserire a mano questa riga nel web.config o se proprio volete usare la feature di farvi un backup del web.config (non dovrebbe succedere niente ma non si sa mai! meglio un backup!)
Questa va sotto
del web. config
Invece questa è la chiamata per scrivere i log

void WriteLogWithException(Exception Ex,string list,string fromPage,string ErrorType)

i parametri più importanti sono l'exception e la lista che corrisponde alla lista dove scrivere i log all'installazione della feature viene creata la seguente lista

LogForSharepoint - LastLogs

Questo è un esempio di chiamata

WriteLog.WriteLogWithException(exception, "LogForSharepoint - LastLogs", HttpModule-" + pageUrl, "Application Error HttpModule Intercept");

se il parametro list è uguale a string.empty o null viene usata la lista di default per scrivere i log

Ora vi spiego in breve come funziona la feature.

Dunque all'installazione vengono create 2 liste e una document library.

Le 2 liste sono

LogForSharepoint - LastLogs : Dove vengono salvati i log è possibile creare anche altre liste per scrivere i log utilizzando il list template "LogForSharepoint - ListLogs" in modo che possiamo dedicare magari ogni lista ad un area del sito oppure inserirli tutti nella stessa lista come preferiamo.

Poi c' è la lista

LogForSharepointConfiguration che come dice il nome stesso non è nient'altro che una lista di configurazione per la feature e sono presenti questi 3 item

<Row>

<Field Name="Title" >MaxNumberItem</Field> Il numero massimo di Item prima che i log vengono archiviati nell'histoty

<Field Name="Value" >3</Field>

</Row>

<Row>

<Field Name="Title" >DefaultSharepointLogList</Field>

<Field Name="Value" >LogForSharepoint - LastLogs</Field> La lista di default dove scrivere i Log quella che viene usata dall'httpmodule

Row>

<Row>

<Field Name="Title" >DefaultSharepointHistoryList</Field>

<Field Name="Value" >HistoryLog</Field> La lista per l'history

</Row>

Poi è presente una document library chiamata history log

Dove ogni X(MaxNumberItem + 1) record tramite un event handler presente nella lista dei log.. tutti i log tranne l'ultimo vengono spostati in un file di testo che viene archiviato nella lista Historylog.

L'httpmodule naturalmente, si occupa di catturare tutti gli errori che non vengono gestiti, e scriverli nella lista di default.

Dovrebbe essere tutto

Resto a disposizione per chiarimenti e suggerimenti


martedì 17 maggio 2011

Overflow Sharepoint Scroolbar

Ciao,

A quanti di voi non è mai capitato che su sharepoint vengono fuori sempre quelle fastidiose scrollbar interne all'interno del div s4-workspace b'è forse finalmente sono riuscito a liberarmene forse in modo definitivo.

Mi è bastato inserire questo all'interno del css

#s4-workspace {
overflow:inherit !important;
}

mercoledì 13 aprile 2011

Certificazione 70-573 Presa


E dopo la 70-576 e la 70-668 sono alla terza su sharepoint 2010...

e alla 4 complessiva

giovedì 30 settembre 2010

Excel Library

Sorgenti

Su un progetto c’è stata la necessità di creare una dll che
permette la lettura di un file excel utilizzando dot.net


La libreria è composta da 2 costruttori

Il primo prende in input il path del file e se la libreria è
usata sotto sharepoint (visto che in questo caso usa un provider differente e
quindi la connection string cambia)


public ReadExcel(string
FileName ,bool useInSharepoint)



Mentre il secondo prende in input solo la connection string.

public ReadExcel(string
connectionString)

Ci sono diversi metodi


Il primo ci permette di tirare fuori dal nostro documento
excel i vari fogli e non ha parametri di imput. E restituira in output una
lista di stringhe contenente l’elenco dei fogli del nostro elenco.


public List<string>
GetExcelSheet()


Poi c’ è un metodo che ci tira fuori dall’excel tutte le
colonne e vuole in input il nome del foglio su cui si vogliono prendere le
colonne

Questo metodo restituisce in output una lista di stringhe
con tutte le colonne del nostro foglio excel


Public List<string> GetExcelFields(string
Sheet)


Poi c’è il metodo che ci tira fuori tutti i valori presenti
sull’excel . questo prende in input il nome del foglio e una lista di stringhe
contenente l’elenco dei campi che verranno selezionati dall’excel. Se questa
lista ha valore null verranno selezionati tutti i campi

public List<ExcelRowItem> readExcelForField(List<string>
selectedItem,string sheet)



In oput avremmo una lista di elementi di tipo ExcelRowItem
anche questo oggetto è definite all’interno della libreria

L’oggetto ExcelRowItem rappresenta una collection di righe
dell’excel ognuna delle quali è composta da N Colonne queste sono rappresentate
con l’elemento ExcelField
il quale ha 2 proprietà Titolo e Valore



Per recuperare un Field da una riga basta chiamare
il metodo questo dato il titolo ci restituisce il valore del campo

public string GetFieldValue(string title)




Per
qualsiasi chiarimento poteti chiedere senza problemi allego anche i sorgenti
naturalmente









Sorgenti

Ciao a Tutti

Benvenuti Nel mio Blog !