AI Tools #Semantic Kernel#Microsoft#AI SDK

Semantic Kernel: Build AI Apps With Microsoft's SDK

Use Semantic Kernel's plugins, memory, and planners in C# and Python. Connect to local Ollama models and Azure OpenAI for production AI application development.

7 min read

Building a useful AI application requires more than a single chat.completions.create() call. Real applications need memory so the AI remembers context across sessions, tools so it can take actions in the world, and planning capabilities so it can break down complex goals into steps. Microsoft Semantic Kernel is an open-source SDK that provides all of this in a production-ready framework for C# and Python, with first-class support for Azure OpenAI, OpenAI, and local models via Ollama.

This guide covers the core concepts — plugins, memory, and planners — with working code examples in both languages, and shows how to connect Semantic Kernel to a local Ollama server for fully offline development.

Core Concepts

Plugins (formerly Skills)

A plugin in Semantic Kernel is a class that exposes one or more functions the AI can call. Functions can be native code (regular Python or C# methods) or semantic functions (LLM prompts with input variables). The kernel discovers these functions and makes them available to the AI as tools.

Memory

Semantic Kernel’s memory system provides vector-based semantic search over stored information. You can store facts, documents, or conversation history and retrieve the most relevant pieces for a given query. This is the foundation of RAG-style applications built within the framework.

Planners

A planner takes a high-level goal and uses the AI to create a step-by-step plan that executes the goal using available plugins. Rather than hardcoding a pipeline, you describe the objective and let the AI figure out which functions to call in what order.

Installation

Python

pip install semantic-kernel

C#

<!-- In your .csproj file -->
<PackageReference Include="Microsoft.SemanticKernel" Version="1.21.1" />

Or via the Package Manager Console:

Install-Package Microsoft.SemanticKernel

Connecting to Ollama (Local Models)

Ollama provides an OpenAI-compatible API, and Semantic Kernel supports OpenAI-compatible endpoints. This means you can develop entirely offline without an API key.

Start your Ollama server and pull a model:

ollama pull llama3:8b
ollama pull nomic-embed-text

Python — Connect to Ollama

from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.ollama import OllamaChatCompletion, OllamaTextEmbedding

kernel = Kernel()

# Add chat completion service
kernel.add_service(
    OllamaChatCompletion(
        service_id="ollama-chat",
        ai_model_id="llama3:8b",
        host="http://localhost:11434",
    )
)

# Add embedding service for memory
kernel.add_service(
    OllamaTextEmbedding(
        service_id="ollama-embed",
        ai_model_id="nomic-embed-text",
        host="http://localhost:11434",
    )
)

C# — Connect to Ollama

using Microsoft.SemanticKernel;

var builder = Kernel.CreateBuilder();

// Ollama via OpenAI-compatible endpoint
builder.AddOpenAIChatCompletion(
    modelId: "llama3:8b",
    apiKey: "ollama",  // Ollama ignores the key but the parameter is required
    endpoint: new Uri("http://localhost:11434/v1")
);

var kernel = builder.Build();

Connecting to Azure OpenAI

For production deployments, Azure OpenAI is the typical choice for enterprise Semantic Kernel applications:

Python — Azure OpenAI

from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion

kernel.add_service(
    AzureChatCompletion(
        service_id="azure-chat",
        deployment_name="gpt-4o",
        endpoint="https://your-resource.openai.azure.com",
        api_key="your-azure-api-key",
        api_version="2024-02-01",
    )
)

C# — Azure OpenAI

builder.AddAzureOpenAIChatCompletion(
    deploymentName: "gpt-4o",
    endpoint: "https://your-resource.openai.azure.com",
    apiKey: "your-azure-api-key"
);

Building a Plugin

Plugins are annotated classes whose methods become tools available to the AI.

Python Plugin Example

from semantic_kernel.functions import kernel_function
from semantic_kernel.plugin_definition import kernel_function_context_parameter

class WeatherPlugin:
    @kernel_function(
        description="Get the current weather for a given city",
        name="get_weather"
    )
    def get_weather(self, city: str) -> str:
        # In a real plugin, call a weather API here
        return f"The weather in {city} is 22°C and partly cloudy."

    @kernel_function(
        description="List cities with extreme weather today",
        name="get_extreme_weather_cities"
    )
    def get_extreme_weather_cities(self) -> str:
        return "Phoenix (45°C), Barrow, AK (-32°C), Dubai (48°C)"

# Register the plugin
kernel.add_plugin(WeatherPlugin(), plugin_name="weather")

C# Plugin Example

using Microsoft.SemanticKernel;
using System.ComponentModel;

public class WeatherPlugin
{
    [KernelFunction("get_weather")]
    [Description("Get the current weather for a given city")]
    public string GetWeather([Description("The city name")] string city)
    {
        // Call your weather API here
        return $"The weather in {city} is 22°C and partly cloudy.";
    }
}

// Register the plugin
kernel.Plugins.AddFromType<WeatherPlugin>("weather");

Memory: Storing and Retrieving Information

Semantic Kernel’s memory allows you to store text with associated metadata and retrieve the most semantically relevant entries for a query.

Python Memory Example

from semantic_kernel.memory import SemanticTextMemory, VolatileMemoryStore

memory = SemanticTextMemory(
    storage=VolatileMemoryStore(),  # In-memory; use ChromaDB or Azure for persistence
    embeddings_generator=kernel.get_service("ollama-embed"),
)

# Store facts
await memory.save_information(
    collection="company_docs",
    id="doc1",
    text="Our refund policy allows returns within 30 days of purchase.",
)

await memory.save_information(
    collection="company_docs",
    id="doc2",
    text="Enterprise customers receive priority support with a 4-hour SLA.",
)

# Retrieve relevant information
results = await memory.search(
    collection="company_docs",
    query="What is the return policy?",
    limit=2,
    min_relevance_score=0.5,
)

for result in results:
    print(f"Relevance: {result.relevance:.2f}{result.text}")

Persistent Memory with ChromaDB

For persistent storage across sessions:

from semantic_kernel.connectors.memory.chroma import ChromaMemoryStore

memory = SemanticTextMemory(
    storage=ChromaMemoryStore(persist_directory="./chroma_data"),
    embeddings_generator=kernel.get_service("ollama-embed"),
)

Planners

The FunctionChoiceBehavior system (the modern replacement for the older StepwisePlanner) allows the AI to automatically select and chain plugin functions to answer a query.

Python — Auto Function Calling

from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import OpenAIChatPromptExecutionSettings

settings = OpenAIChatPromptExecutionSettings(
    function_choice_behavior=FunctionChoiceBehavior.Auto()
)

from semantic_kernel.contents import ChatHistory

history = ChatHistory()
history.add_user_message("What's the weather like in Tokyo and is it an extreme weather city today?")

response = await kernel.invoke_prompt(
    prompt="{{$history}}",
    arguments=KernelArguments(history=history, settings=settings),
)

print(response)

With FunctionChoiceBehavior.Auto(), the kernel will automatically call get_weather("Tokyo") and get_extreme_weather_cities(), synthesize the results, and return a coherent answer — without you writing the orchestration logic.

A Complete Python Application

import asyncio
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.ollama import OllamaChatCompletion
from semantic_kernel.contents import ChatHistory

async def main():
    kernel = Kernel()
    kernel.add_service(
        OllamaChatCompletion(
            service_id="chat",
            ai_model_id="llama3:8b",
        )
    )
    kernel.add_plugin(WeatherPlugin(), plugin_name="weather")

    history = ChatHistory()
    history.add_system_message(
        "You are a helpful assistant. Use available tools to answer questions."
    )

    while True:
        user_input = input("You: ")
        if user_input.lower() in ["exit", "quit"]:
            break

        history.add_user_message(user_input)
        response = await kernel.invoke_prompt(
            prompt="{{$history}}",
            arguments={"history": history},
        )
        print(f"Assistant: {response}\n")
        history.add_assistant_message(str(response))

asyncio.run(main())

When to Use Semantic Kernel

Semantic Kernel makes the most sense when you are building production-grade AI applications that need structured tool use, conversation memory, and multi-step reasoning — especially in enterprise environments where Azure OpenAI, C#, or .NET is already part of the stack. For quick scripts or simple chatbot prototypes, it is more ceremony than you need. For anything that will be maintained, tested, and deployed by a team, the framework’s structure pays for itself quickly.

#Azure OpenAI #Ollama #AI SDK #Microsoft #Semantic Kernel