Semantic Kernel - Native plugins
Published: 2023-11-08 18:43:01

---
title: Semantic Kernel - Native plugins
published: true
date: 2023-11-07 00:00:00 UTC
tags: 
canonical_url: 
---

 ![Featured image of post Semantic Kernel - Native plugins](https://www.developerscantina.com/p/semantic-kernel-native-plugins/cover.png)

[In the previous post](https://www.developerscantina.com/p/semantic-kernel-functions/), we learned how to create a semantic function plugin for Semantic Kernel. A semantic function is just a prompt, however, by including it in a function inside a plugin, we made it easier to reuse and test it.

In this post, we’re going to explore another type of plugins: native functions. As the name suggests, these plugins are native to the platform you’re using, so they can be written in C#. Python or Java. Since they support native code, they can perform more than just executing a prompt; we can virtually execute any operation which is supported by the platform.

## Creating a native plugin

For this sample, we’re going to build a plugin which is able to retrieve the information about the United States population in a given year. This might be a peculiar scenario, but there’s a reason why we’re using it: a platform called [DataUSA](https://datausa.io/) provides a set of free APIs that we can use to retrieve various data about the United States, like the population number, the number of universities, etc. The APIs are free to use and they don’t require any authentication, so they’re perfect for our sample.

These APIs behave like any other REST APIs. As such, this is the type of operation that requires using native APIs: we need to perform a GET request to a given URL, then we need to parse the response and extract the information we need. We can’t perform this operation just with a prompt.

The first step to create the native function is the same as we have seen [in the previous post](https://www.developerscantina.com/p/semantic-kernel-functions/): we create a folder, called **Plugins** and, inside it, we create a subfolder for our plugin. We’re going to call it **UnitedStatesPlugin**. Inside this folder, we’re going to add a new class, which will host our function, called **UnitedStatesPlugin.cs**. This is how the project looks like:

![A project with a plugin with a native function](https://www.developerscantina.com/p/semantic-kernel-native-plugins/plugin.png)

Inside the class, we can define one or more functions, which will be exposed as Semantic Kernel functions. From a code perspective, these functions are just normal C# functions, so we can use any C# feature we want. The only requirement is that we must decorate the function with the `[SKFunction]` attribute, which is defined in the `Microsoft.SemanticKernel` namespace. This way, Semantic Kernel will know that the plugin exposes a function, whose name will match the name of the method. Let’s take a look at the following sample:

```
public class UnitedStatesPlugin
{
    [SKFunction, Description("Get the United States population for a specific year")]
    public async Task<string> GetPopulation([Description("The year")]int year)
    {
        string request = "https://datausa.io/api/data?drilldowns=Nation&measures=Population";
        HttpClient client = new HttpClient();
        var result = await client.GetFromJsonAsync<UnitedStatesResult>(request);
        var populationData = result.data.FirstOrDefault(x => x.Year == year.ToString());
        string response = $"The population number in the United States in {year} was {populationData.Population}";
        return response;
    }
}

```


As you can see, the function is just a normal C# method, which returns a `string` (using a `Task`, since the method is asynchronous). The only difference is that it’s decorated with the `SKFunction` attribute. This attribute accepts a parameter, which is the description of the function. We have also added a `[Description]` attribute also to the `year` parameter. These two attributes replace the information that, in a semantic function, we were storing in the **config.json** file. We’ll come back to the importance of providing this information when we’re going to introduce the planner.

The rest of the code is easy to understand: we use the `HttpClient` class to perform a GET request to the DataUSA API. By using the `GetFromJsonAsync<T>()` method, we can deserialize the response into a C# class, which maps the content of the JSON response (you can see it [here](https://datausa.io/api/data?drilldowns=Nation&measures=Population]). Finally, we filter the resulting collection to extract only the data for the year we’re interested in and we return the result.

## Testing the plugin

Now that we have created the plugin, we can test it. To do so, we need to add it to the Semantic Kernel configuration. First, we create a new instance of the kernel as usual:

```
string apiKey = "my-api-key";
string deploymentName = "deployment-name";
string endpoint = "endpoint-url";

var kernelBuilder = new KernelBuilder();
kernelBuilder.
    WithAzureChatCompletionService(deploymentName, endpoint, apiKey);

var kernel = kernelBuilder.Build();

```

Then, we can add the plugin to the kernel, this time using the `ImportFunctions()` method:


```
kernel.ImportFunctions(new UnitedStatesPlugin(), "UnitedStatesPlugin");

```

As parameters, we supply first a new instance of the class we have previously created, then we provide a name for the plugin.

Finally, we can retrieve the function defined in the plugin in the same way we did for the semantic function plugin:


```
var function = kernel.Functions.GetFunction("UnitedStatesPlugin", "GetPopulation");

```


The first parameter is the name of the plugin, the second one is the name of the method declared in the `UnitedStatesPlugin` class.

Finally, we execute the plugin in the usual way: we create a `ContextVariables` collection with the input, then we call `RunAsync()` on the kernel passing the collection and the function as parameter:


```
ContextVariables variables = new ContextVariables
{
    { "input", "2015" }
};

var result = await kernel.RunAsync(
    variables,
    function
);

Console.WriteLine(result.GetValue<string>());
Console.ReadLine();

```


In this case, we are supplying as input 2015, so we’re expecting to get back the population number of United States in 2015. If we did everything correct, this is exactly the information we’re going to get back:


```
The population number in the United States in 2015 was 316515021

```

## Wrapping up

In this post, we have seen another type of plugins: native ones. Compared to the semantic functions, they are slightly more complex to define, since we need to create a real class with real code. On the other side, however, they are more powerful, since they can perform any operation we want, not just executing a prompt.

In the next post, we’re going to explore the last type of plugins: OpenAI plugins. Stay tuned!

In the meantime, you can find the full source code of the sample on [GitHub](https://github.com/qmatteoq/SemanticKernel-Demos), in the **SemanticKernel.NativeFunction** project.