What is Semantic Kernel?

Semantic Kernel (SK) is Microsoft's open-source SDK for integrating Large Language Models into applications. It's designed for enterprise use cases with first-class support for C#, Python, and Java.

Key features:

  • Plugins: Modular, reusable AI capabilities
  • Planners: AI-powered task orchestration
  • Memory: Built-in semantic memory with vector stores
  • Enterprise-ready: Designed for production workloads
  • Multi-language: C#, Python, and Java support

Why Semantic Kernel?

Enterprise Integration

First-class Azure OpenAI support, designed for corporate environments.

Type Safety

Strong typing in C# and Python, better IDE support and error catching.

Plugin Architecture

Reusable, shareable AI capabilities across projects.

Microsoft Ecosystem

Integrates with Azure, Microsoft 365, and enterprise tools.

Getting Started

Installation (Python)

pip install semantic-kernel

Installation (C#)

dotnet add package Microsoft.SemanticKernel

Basic Setup (Python)

import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion

# Create kernel
kernel = sk.Kernel()

# Add AI service
kernel.add_service(
    OpenAIChatCompletion(
        service_id="chat",
        ai_model_id="gpt-4",
        api_key="your-api-key"
    )
)

# Or use Azure OpenAI
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion

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

Basic Setup (C#)

using Microsoft.SemanticKernel;

// Create kernel builder
var builder = Kernel.CreateBuilder();

// Add OpenAI
builder.AddOpenAIChatCompletion(
    modelId: "gpt-4",
    apiKey: "your-api-key"
);

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

var kernel = builder.Build();

Plugins

Plugins are collections of functions that extend the kernel's capabilities:

Native Functions (Python)

from semantic_kernel.functions import kernel_function

class MathPlugin:
    @kernel_function(
        name="add",
        description="Adds two numbers together"
    )
    def add(self, a: int, b: int) -> int:
        return a + b

    @kernel_function(
        name="multiply",
        description="Multiplies two numbers"
    )
    def multiply(self, a: int, b: int) -> int:
        return a * b

# Register plugin
kernel.add_plugin(MathPlugin(), plugin_name="math")

Semantic Functions (Prompts)

from semantic_kernel.functions import KernelFunction

# Define a semantic function
summarize_function = KernelFunction.from_prompt(
    prompt="""Summarize the following text in 3 bullet points:

{{$input}}

Summary:""",
    plugin_name="text",
    function_name="summarize",
    description="Summarizes text into bullet points"
)

kernel.add_function(summarize_function)

# Use the function
result = await kernel.invoke(
    summarize_function,
    input="Your long text here..."
)

Native Functions (C#)

public class EmailPlugin
{
    [KernelFunction, Description("Sends an email")]
    public async Task SendEmailAsync(
        [Description("Email recipient")] string to,
        [Description("Email subject")] string subject,
        [Description("Email body")] string body)
    {
        // Send email logic
        return $"Email sent to {to}";
    }

    [KernelFunction, Description("Gets unread emails")]
    public async Task> GetUnreadEmailsAsync()
    {
        // Fetch emails logic
        return new List();
    }
}

// Register plugin
kernel.ImportPluginFromType();

Function Calling

Let the AI automatically choose and call functions:

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

# Configure automatic function calling
settings = kernel.get_prompt_execution_settings_class(service_id="chat")()
settings.function_choice_behavior = FunctionChoiceBehavior.Auto()

# Chat with function calling
response = await kernel.invoke_prompt(
    prompt="What is 15 multiplied by 7?",
    settings=settings
)

print(response)  # The AI will call math.multiply and return 105

Planners

Planners let the AI create multi-step plans to accomplish goals:

from semantic_kernel.planners import FunctionCallingStepwisePlanner

# Create planner
planner = FunctionCallingStepwisePlanner(service_id="chat")

# Execute a complex task
result = await planner.invoke(
    kernel,
    question="Research the weather in Tokyo and send a summary email to john@example.com"
)

# The planner will:
# 1. Call weather API
# 2. Summarize the data
# 3. Send the email

Handlebars Planner

from semantic_kernel.planners.handlebars_planner import HandlebarsPlannerOptions

options = HandlebarsPlannerOptions(
    allow_loops=True,
    allow_conditions=True
)

planner = HandlebarsPlanner(options=options)

plan = await planner.create_plan(
    kernel,
    goal="Analyze sales data and create a report"
)

result = await plan.invoke(kernel)

Memory and RAG

Semantic Kernel includes built-in memory capabilities:

from semantic_kernel.memory import SemanticTextMemory
from semantic_kernel.connectors.memory.azure_cognitive_search import AzureCognitiveSearchMemoryStore
from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding

# Setup embeddings
embedding_service = OpenAITextEmbedding(
    ai_model_id="text-embedding-3-small",
    api_key="your-key"
)

# Setup memory store
memory_store = AzureCognitiveSearchMemoryStore(
    search_endpoint="https://your-search.search.windows.net",
    admin_key="your-key"
)

# Create semantic memory
memory = SemanticTextMemory(
    storage=memory_store,
    embeddings_generator=embedding_service
)

# Save information
await memory.save_information(
    collection="company_docs",
    id="doc1",
    text="Our company was founded in 2020...",
    description="Company history"
)

# Search memory
results = await memory.search(
    collection="company_docs",
    query="When was the company founded?",
    limit=3
)

Filters and Middleware

Add cross-cutting concerns like logging and validation:

from semantic_kernel.filters import FunctionInvocationContext

class LoggingFilter:
    async def on_function_invocation(
        self,
        context: FunctionInvocationContext,
        next_handler
    ):
        print(f"Calling: {context.function.name}")
        start = time.time()

        # Call the function
        await next_handler(context)

        elapsed = time.time() - start
        print(f"Completed in {elapsed:.2f}s")

# Add filter
kernel.add_filter("function_invocation", LoggingFilter())

Complete Example: Customer Support Agent

import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.functions import kernel_function

class CustomerSupportAgent:
    def __init__(self):
        self.kernel = sk.Kernel()
        self.kernel.add_service(
            AzureChatCompletion(
                service_id="chat",
                deployment_name="gpt-4",
                endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
                api_key=os.getenv("AZURE_OPENAI_KEY")
            )
        )
        self._setup_plugins()

    def _setup_plugins(self):
        # Add customer support plugin
        self.kernel.add_plugin(CustomerPlugin(), "customer")
        self.kernel.add_plugin(OrderPlugin(), "orders")
        self.kernel.add_plugin(KnowledgePlugin(), "knowledge")

    async def handle_query(self, user_message: str, customer_id: str):
        settings = self.kernel.get_prompt_execution_settings_class("chat")()
        settings.function_choice_behavior = FunctionChoiceBehavior.Auto()

        response = await self.kernel.invoke_prompt(
            prompt=f"""You are a helpful customer support agent.
Customer ID: {customer_id}
Customer Query: {user_message}

Help the customer with their request using available tools.""",
            settings=settings
        )

        return str(response)

class CustomerPlugin:
    @kernel_function(description="Get customer details")
    def get_customer(self, customer_id: str) -> dict:
        # Fetch from database
        return {"name": "John Doe", "tier": "Premium"}

class OrderPlugin:
    @kernel_function(description="Get customer orders")
    def get_orders(self, customer_id: str) -> list:
        return [{"id": "ORD-123", "status": "Shipped"}]

    @kernel_function(description="Track an order")
    def track_order(self, order_id: str) -> dict:
        return {"status": "In Transit", "eta": "Dec 28"}

# Usage
agent = CustomerSupportAgent()
response = await agent.handle_query(
    "Where is my order ORD-123?",
    customer_id="CUST-456"
)

Best Practices

  • Use dependency injection: Configure kernel in DI container for testability
  • Organize plugins: Group related functions into cohesive plugins
  • Add descriptions: Good function descriptions help the AI choose correctly
  • Handle errors: Implement proper error handling in functions
  • Use filters: Add logging, telemetry, and validation as filters
  • Test functions: Unit test plugins independently from the kernel

Build Enterprise AI with Expert Guidance

Our Agentic AI program covers Semantic Kernel and enterprise AI patterns. Learn to build production-ready AI applications for corporate environments.

Explore Agentic AI Program

Related Articles