Skip to content

Developing and Integrating AI in C# .NET solutions

Published: at 08:00 AM (13 min read)

Table of contents

Open Table of contents

AI and C# and Overview

We are absolutely living in the era of AI. Generative AI capabilities of large language models are genuinely mind-boggling to see. I remember working with QnA maker and LUIS (Language Understanding and Interactive Service, now named CLU - Conversational Language Understanding) services from Microsoft and they were great tools, but compared to the capabilities we see today from a conversational perspective the leap forward is staggering.

I’ve been working with Microsoft’s cognitive service platform and the various resources provided since their inception many years ago. I was also for a number of years part of the AI Inner circle at Microsoft helping provide insight and direction from the perspective of a developer and consumer of these tools. I’ve always appreciated Microsoft’s efforts in bridging the gap between the skills needed to create AI or ML models and providing out-of-the-box capabilities to developers simply wanting to consume those capabilities in their solutions or applications.

With that in mind, this blog post looks at the landscape of interoperability between C# developers and available AI capabilities. I’ll look to highlight a few key frameworks, libraries, and APIs that facilitate this integration, and where possible, showcase practical examples to illustrate how developers can leverage AI in their C# projects.

Integrating AI with C-Sharp

The integration of AI capabilities into C# applications is facilitated by several well-known and well-maintained libraries, frameworks, and APIs, each offering unique features and capabilities. We will explore some of the most prominent tools that C# developers can use to incorporate AI functionalities into their applications in sections below. I also wanted to add in a short list of some of the heavy hitters below.

  1. Azure Cognitive Services
    Azure Cognitive Services provides a suite of APIs and services to add AI capabilities to applications, including vision, speech, language, and decision-making features.

  2. ML.NET
    ML.NET is an open-source and cross-platform machine learning framework for .NET developers, allowing the integration of custom machine learning models for scenarios like classification, regression, and clustering.

  3. OpenAI API
    OpenAI offers a powerful API to access GPT models, enabling advanced natural language processing tasks such as text generation, translation, and summarization.

  4. TensorFlow.NET
    TensorFlow.NET is a .NET binding library for TensorFlow, allowing C# developers to build, train, and deploy machine learning models using the TensorFlow ecosystem.

  5. Accord.NET
    Accord.NET is a .NET machine learning framework that includes libraries for audio and image processing, as well as statistical analysis and machine learning.

  6. CNTK (Microsoft Cognitive Toolkit)
    CNTK is an open-source deep-learning toolkit developed by Microsoft, designed for training and testing neural networks.

  7. Keras.NET
    Keras.NET provides a .NET Standard binding for Keras, enabling the construction and training of deep learning models in C#.

  8. Hugging Face Transformers
    While primarily a Python library, Hugging Face Transformers can be accessed via the OnnxRuntime for C# to utilize state-of-the-art natural language processing models.

  9. NVIDIA cuDNN
    NVIDIA cuDNN is a GPU-accelerated library for deep neural networks, providing highly optimized implementations for standard routines such as forward and backward convolution, pooling, normalization, and activation layers.

  10. DeepAI API
    DeepAI offers a suite of APIs that provide various AI functionalities, including image recognition, text processing, and more, which can be integrated into C# applications using HTTP requests.

  11. IBM Watson
    IBM Watson provides a range of AI services such as language understanding, speech-to-text, and visual recognition, which can be integrated into C# applications via their APIs.

  12. Unity ML-Agents
    Unity ML-Agents allows developers to create AI environments and train agents using reinforcement learning directly within the Unity game engine.

  13. SharpLearning
    SharpLearning is a C# machine learning library that includes algorithms for supervised and unsupervised learning, providing tools for feature selection, cross-validation, and more.

  14. Deedle
    Deedle is a .NET library for data and time series manipulation, often used in conjunction with machine learning tasks for data preparation and analysis.

  15. Accord.NET Extensions
    These extensions enhance the Accord.NET framework with additional machine learning algorithms and data manipulation tools.

  16. XGBoost.NET
    XGBoost.NET provides a .NET wrapper for the popular XGBoost library, enabling the use of gradient boosting algorithms for classification and regression tasks.

  17. SciSharp STACK
    The SciSharp STACK is an ecosystem of .NET libraries that include bindings for TensorFlow, Keras, and other popular machine learning frameworks, facilitating the integration of AI in .NET applications.

  18. AI4E Cognitive Services Repository
    This GitHub repository by Microsoft offers a collection of tools and examples for integrating Azure Cognitive Services into various applications, including those developed in C#.

Developers can leverage any of the above tools in their applications and most can be integrated fairly easily into .NET C# solutions.

Azure Cognitive Services

Azure Cognitive Services is a collection of APIs, SDKs, and services available to developers to make their applications more intelligent, engaging, and discoverable. These services enable developers to easily add cognitive features into their applications without having in-depth knowledge of AI or data science, which, as mentioned previously, is something I genuinely think Microsoft has done very well.

Usefulness:

Azure Cognitive Services provides a wide range of pre-built AI capabilities, such as vision, speech, language, and decision-making. This allows developers to integrate sophisticated AI features quickly and efficiently, reducing development time and costs.

Use Cases:

Example: Text Analytics API

One of the services offered by Azure Cognitive Services is the Text Analytics API, which provides advanced natural language processing over raw text. Here’s a simple example of how to use the Text Analytics API in a C# application:

using System;
using Azure.AI.TextAnalytics;

public class Program
{
    private static readonly AzureKeyCredential credentials = new AzureKeyCredential("<your-key-here>");
    private static readonly Uri endpoint = new Uri("<your-endpoint-here>");

    public static void Main(string[] args)
    {
        var client = new TextAnalyticsClient(endpoint, credentials);
        string inputText = "Hello world, this is a test for the Text Analytics API.";
        DocumentSentiment documentSentiment = client.AnalyzeSentiment(inputText);
        Console.WriteLine($"Document sentiment: {documentSentiment.Sentiment}");
        Console.WriteLine($"Positive score: {documentSentiment.ConfidenceScores.Positive}");
        Console.WriteLine($"Neutral score: {documentSentiment.ConfidenceScores.Neutral}");
        Console.WriteLine($"Negative score: {documentSentiment.ConfidenceScores.Negative}");
    }
}

ML.NET

ML.NET is an open-source and cross-platform machine learning framework for .NET developers. It enables integrating custom machine learning models into .NET applications, covering scenarios like classification, regression, clustering, and more.

Usefulness:

ML.NET democratizes machine learning for .NET developers by providing tools and libraries to create, train, and deploy custom models using C# or F#. It is especially beneficial for those who want to incorporate machine learning without switching to another language or platform.

Use Cases:

Example: Binary Classification

Here’s a basic example of how to create a binary classification model to predict whether an email is spam or not:

using Microsoft.ML;
using Microsoft.ML.Data;

public class EmailData
{
    public bool IsSpam { get; set; }
    public string Message { get; set; }
}

public class SpamPrediction
{
    [ColumnName("PredictedLabel")]
    public bool IsSpam { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var mlContext = new MLContext();
        IDataView dataView = mlContext.Data.LoadFromTextFile<EmailData>("emails.csv", separatorChar: ',', hasHeader: true);
        var pipeline = mlContext.Transforms.Text.FeaturizeText("Features", nameof(EmailData.Message))
            .Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "IsSpam", featureColumnName: "Features"));
        var model = pipeline.Fit(dataView);
        // The model can now be used to predict whether new emails are spam or not
    }
}

OpenAI and C-Sharp

With the increasing popularity of OpenAI’s GPT models, integrating these advanced language models into C# applications has become a sought-after capability. While OpenAI provides an API for accessing its models, the community has developed various libraries and wrappers to facilitate the use of these models in .NET environments.

Usefulness:

OpenAI’s models bring powerful natural language processing capabilities, enabling applications to perform tasks such as text generation, translation, summarization, and more. This enhances the user experience by providing more interactive and intelligent features.

Use Cases:

Example: Using OpenAI with C-Sharp

Personally I prefer using HTTP Client capabilities to connect to OpenAIs API but Microsoft do provide their own Azure OpenAI client library for .Net which I believe can be used to connect to both the Azure deployment of OpenAI and OpenAIs API. Either way, developers can access GPT models by sending HTTP requests to the OpenAI API, handling authentication, and parsing responses accordingly.

using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

public class OpenAIExample
{
    public static async Task Main(string[] args)
    {
        var httpClient = new HttpClient();
        string apiKey = "<your-api-key>";
        httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

        var data = new
        {
            prompt = "Translate the following English text to French: 'Hello, world!'",
            temperature = 0.7,
            max_tokens = 60,
            top_p = 1.0,
            frequency_penalty = 0.0,
            presence_penalty = 0.0
        };

        var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
        var response = await httpClient.PostAsync("https://api.openai.com/v1/engines/davinci/completions", content);
        var responseString = await response.Content.ReadAsStringAsync();

        Console.WriteLine(responseString);
    }
}

The Rise of Small Language Models: Benefits, Risks, and Code Integration

Small language models are gaining traction due to their efficiency and lower resource requirements. Let’s delve into the benefits and risks, supplemented with code snippets for integrating such models. In my mind this is the rise of the ‘Small Language Model’ or SLM. I think the race to the smallest most capable language model is going to have significant impact on how we use AI and the compute requirements needed to use these models in the future. We want more capabilities at smaller sizes; I liken it to Moores Law the prediction that the number of transistors in integrated circuits will double every two years. I believe SLMs will continue to get smaller with greater capabilities over the next 12-24 months.

Benefits

Usefulness:
Small language models are designed to operate efficiently on less powerful hardware, making them more accessible for developers who don’t have access to high-end GPUs or extensive cloud resources.

Use Cases:

Risks

Bias and Non-Censorship:

There’s a risk of generating biased or inappropriate content. Developers may want to consider implementing content filtering mechanisms to mitigate this if they believe there’s the potential for harm or misuse.

Use Cases:

Code Snippet for Content Filtering

Below is a hypothetical example of implementing a simple content filter for the responses generated by the language model. This snippet checks if the generated response contains any predefined inappropriate keywords and filters them out.

static string FilterResponse(string response)
{
    var inappropriateKeywords = new List<string> { "inappropriate1", "inappropriate2" }; // Example keywords to filter out
    foreach (var keyword in inappropriateKeywords)
    {
        response = response.Replace(keyword, "***");
    }
    return response;
}

You would call FilterResponse on the text generated by the language model before displaying it to the user:

await foreach (string text in session.ChatAsync(message, inferenceParams))
{
    string filteredText = FilterResponse(text);
    Console.Write(filteredText);
}

This example demonstrates a basic approach to content filtering. In practice, you might need a more sophisticated solution, potentially involving AI-based content moderation tools, to effectively filter out inappropriate content.

By integrating small language models with thoughtful consideration of their benefits and risks, developers can harness AI’s power more responsibly and inclusively.

Creating a Console App with LlamaSharp and Local Language Models

So off the back of understanding a bit more about Small Language Models this section will guide you through creating a console application using LlamaSharp, a .NET wrapper that facilitates interaction with language models directly from C# applications. The below is from a test console application I created to get my head around this library with the thought to start integrating these capabilities into one of my applications GPT Powertoys.

Setting Up Your Environment

  1. Install LlamaSharp: Ensure that LlamaSharp is added to your project. If LlamaSharp is available as a NuGet package, you can add it via NuGet Package Manager or the Package Manager Console in Visual Studio.

  2. Model Files: Download the desired GGUF model file. The code snippet suggests various models, such as “Phi-3-mini-4k-instruct-q4.gguf”. Place the downloaded model in a directory within your project, typically in a folder named LLMs.

  3. Project Configuration: Make sure your project targets .NET 5.0 or later, as LlamaSharp may rely on features available in these versions.

Implementing the Console Application

The provided code snippet outlines the process of loading a language model, setting up a chat session, and interacting with the user through the console. Here’s a step-by-step breakdown of how the application works:

  1. Load the Model: The application starts by defining the path to the GGUF model file and checking if the file exists. If the file is not found, it notifies the user and exits.

  2. Model Parameters: It sets up model parameters, including context size and GPU layer count, to optimize performance based on the machine’s capabilities.

  3. Create Chat Session: A chat session is initialized with a system message loaded from a text file. This message can guide the AI on how to behave during the interaction.

  4. User Interaction: The application enters a loop, prompting the user for input. The user’s input is then fed into the model, which generates a response based on the loaded language model and the provided parameters.

  5. Displaying Responses: As the model generates responses, they are displayed in the console. The application uses output transforms to customize the appearance of these responses, hiding specific keywords.

  6. Continuous Interaction: The loop continues until the user types “exit”, allowing for ongoing conversation with the AI.

Example Code Implementation

using System;
using System.IO;
using LLama;
using LLama.Common;

class Program
{
    static async Task Main(string[] args)
    {
        // Define the model path
        string modelPath = Path.Combine(Environment.CurrentDirectory, @"LLMs\Phi-3-mini-4k-instruct-q4.gguf");

        // Check if the model file exists
        if (!File.Exists(modelPath))
        {
            Console.WriteLine("Model file not found. Please ensure the model file is correctly placed in the LLMs folder.");
            return;
        }

        // Load the model with parameters
        ModelParams modelParams = new ModelParams(modelPath)
        {
            ContextSize = 4000,
            GpuLayerCount = 5 // Adjust based on your GPU's capabilities
        };

        using LLamaWeights weights = LLamaWeights.LoadFromFile(modelParams);
        using LLamaContext context = weights.CreateContext(modelParams);
        InteractiveExecutor executor = new InteractiveExecutor(context);

        // Initialize chat session with a system message
        ChatHistory chatHistory = new ChatHistory();
        string systemMessage = "This is a system message to guide the AI's behavior.";
        chatHistory.AddMessage(AuthorRole.System, systemMessage);

        ChatSession session = new ChatSession(executor);
        var hideWordsTransform = new LLamaTransforms.KeywordTextOutputStreamTransform(new[] { "User:", "Bot: " });
        session.WithOutputTransform(hideWordsTransform);

        // Set inference parameters
        InferenceParams inferenceParams = new InferenceParams
        {
            Temperature = 0.8f,
            TopP = 0.9f,
            MaxTokens = 256 // Adjust based on desired response length
        };

        // User interaction loop
        string userInput = "";
        while (userInput.ToLower() != "exit")
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write("\nPrompt: ");
            userInput = Console.ReadLine() ?? "";

            // Prepare and process the user input
            ChatHistory.Message message = new ChatHistory.Message(AuthorRole.User, userInput);
            Console.ForegroundColor = ConsoleColor.Yellow;
            await foreach (string text in session.ChatAsync(message, inferenceParams))
            {
                Console.Write(text);
            }
        }
    }
}

Final Thoughts

I think as a developer it’s never been easier than it is today to integrate the various capabilities of AI and ML into your applications. There is a wide variety of Libraries, SDKs and APIs available covering a whole host of different AI capabilities that might be useful to include within your solutions.

You might have guessed that I’m a big fan of the effort being invested into small language models over the last few months and I do genuinely believe that locally deployable and executable language models represent a really interesting advancement that I think will allow developers to create some unique applications.

I hope the code snippets above have helped or given you some inspiration to start working with some of the technologies discussed. If you want to talk through any of the content by all means reach out across my various social platforms.