C# Simple history using Semantic Kernel

If your using Semantic Kernel connect it to your local Ollama models instead of feeling like you must be locked into a pay to play model. You can use all of your local AI resources for testing for free before pushing into a paid for virtual machine platform or just for your own local custom agents and toolset.

This is a changing landscape, as semantic kernel is being replaced by what will now be Microsoft agent framework. While this is very old code it gives a simple idea of how to make a basic agent using Semantic Kernel that can run on any device, lets get into it.

// See https://aka.ms/new-console-template for more information
using Microsoft.SemanticKernel.ChatCompletion;
using OllamaSharp;

//probably no longer necessary as this is very old 
# pragma warning disable SKEXP0010
# pragma warning disable SKEXP0070
# pragma warning disable SKEXP0001

//add the chatService. This can also be created through using a  kernel.buiulder like Kernel.CreateBuilder().AddOpenAIChatCompletion or .AddOllamaChatCompletion
IChatCompletionService chatService = new OllamaApiClient(new Uri("your ollama url"), "your model").AsChatCompletionService();
//here we make the history object
ChatHistory history = new ChatHistory();
// adding a system message
string systemMessage = @"You are an AI programming assistant
and you only answer questions related to computer science. 
For politically sensitive questions, 
security and privacy issues, 
and other non-computer science questions, 
you will answer by saying I cant do that.
";
//now we add the system message as the first in history
history.AddSystemMessage(systemMessage);
string exitMsg = "exit";
int tokens = 0;

//loop over questions until exit command
Console.WriteLine("hello");
while (true)
{
    string input = "";
    input = Console.ReadLine();
    if(exitMsg.Equals(input.ToLower()))
    {
        Console.WriteLine("Ok, goodbye.");
        return 0;
    }
    history.AddUserMessage(input);
    var response = await chatService.GetChatMessageContentAsync(history);
    //now we have the chat history and will persist until ending the program. /
    // checking the token cost in innerContent but can change based on different models /
    // so this might be empty or just not a ChatDoneResponse so should maybe try catch
    try
    {
        if (response.InnerContent is OllamaSharp.Models.Chat.ChatDoneResponseStream onDone)
        {
            Console.WriteLine($"PromptEval: {onDone.PromptEvalCount}");
            Console.WriteLine($"Response: {onDone.EvalCount}");
            history.AddAssistantMessage(onDone.Message.Content);
            Console.WriteLine(response.Content);
        }
    }
    catch(Exception x)
    {
        Console.WriteLine(x.Message);
    }
}

So testing our output using phi4:14b as a model we get

System: hello: ask me something
Prompt: do you like chicken

System: I can't do that.
PromptEval: 69
Response: 26
I can't do that. However, if you have any questions related to computer science or programming, feel free to ask!

Prompt: I asked you for chicken dont play with me

System: PromptEval: 115
Response: 35
I'm here to assist with computer science-related queries. If there's anything else within my scope of knowledge that you'd like to know about, please let me know!

Prompt: I asked you for chicken dont play with me

System: PromptEval: 170
Response: 50
I apologize if it seems that way; I’m just programmed to focus on computer science topics. If you have any questions or need assistance related to programming, algorithms, data structures, software engineering, or anything similar, please feel free to ask!

Prompt: I just really want some chicken

System: PromptEval: 237
Response: 46
I understand your interest in food, but as an AI focused on computer science, I'm unable to assist with that. If you have any questions about programming, technology, or related topics, I'd be happy to help!

This is a very simple rough example of Semantic Kernel history with A local model setup this can be easily expanded on as a starting point. As Semantic Kernel is being replaced this is at best temporary but a good way to get a grounding in what could look like similar tooling for agent framework. Hope it Helps.