Semantic Kernel Tutorial: Microsoft's AI Orchestration Framework for Building Intelligent Applications

# Tutorial Semantic Kernel: Framework AI Orchestration dari Microsoft untuk Membangun Aplikasi Cerdas Semantic Kernel adalah SDK open-source dari Microsoft yang dirancang untuk mengintegrasikan Large...

By Ruby Abdullah · · tutorial
Semantic KernelMicrosoftAI AgentsPythonLLM

Semantic Kernel Tutorial: Microsoft's AI Orchestration Framework for Building Intelligent Applications

Semantic Kernel is an open-source SDK from Microsoft designed to integrate Large Language Models (LLMs) into applications in a structured and modular way. This framework enables developers to build AI applications that combine prompt engineering, plugin systems, and agentic workflows within a cohesive architecture. In this tutorial, we will learn how to use Semantic Kernel with Python, from installation to building AI agents capable of executing complex tasks autonomously.

Why Semantic Kernel?

Unlike other AI frameworks that focus on simple prompt chaining, Semantic Kernel takes a more enterprise-ready approach. Some of its key advantages include:

  • Plugin Architecture: Separates business logic from prompts, making code more maintainable
  • Multi-Provider Support: Works with OpenAI, Azure OpenAI, Hugging Face, and other providers
  • Automatic Function Calling: LLMs can automatically select and execute available functions
  • Built-in Memory and RAG: Native integration with vector stores for long-term context
  • Planner: Ability to break down complex tasks into executable steps
  • Type Safety: Strongly typed with Pydantic support for input/output validation

Semantic Kernel is widely used in Microsoft products like Microsoft 365 Copilot, making it a framework that has been battle-tested at production scale.

Installation

Prerequisites

Make sure Python 3.10 or later is installed on your system.

python --version

Installing Semantic Kernel

pip install semantic-kernel

For additional features, you can install the extras you need:

# For Azure OpenAI

pip install semantic-kernel[azure]

For Hugging Face

pip install semantic-kernel[huggingface]

For Google AI

pip install semantic-kernel[google]

All providers

pip install semantic-kernel[all]

Configuring Environment Variables

Create a .env file in your project root:

# For OpenAI

OPENAIAPIKEY=sk-your-api-key-here

OPENAICHATMODELID=gpt-4o

For Azure OpenAI

AZUREOPENAIAPIKEY=your-azure-key

AZUREOPENAIENDPOINT=https://your-resource.openai.azure.com/

AZUREOPENAICHATDEPLOYMENTNAME=gpt-4o

Basic Usage

Creating Your First Kernel

The Kernel is the core of Semantic Kernel. It acts as a container for all services, plugins, and configurations.

import asyncio

from semantickernel import Kernel

from semantickernel.connectors.ai.openai import OpenAIChatCompletion

kernel = Kernel()

chatservice = OpenAIChatCompletion(

aimodelid="gpt-4o",

serviceid="chat"

)

kernel.addservice(chatservice)

async def main():

result = await kernel.invokeprompt("Explain what machine learning is in 3 sentences.")

print(result)

asyncio.run(main())

Using Chat History

For multi-turn conversations, use ChatHistory:

import asyncio

from semantickernel import Kernel

from semantickernel.connectors.ai.openai import OpenAIChatCompletion

from semantickernel.contents import ChatHistory

kernel = Kernel()

kernel.addservice(OpenAIChatCompletion(

aimodelid="gpt-4o",

serviceid="chat"

))

chathistory = ChatHistory()

chathistory.addsystemmessage(

"You are an AI assistant helping Python developers. "

"Answer concisely and provide code examples when needed."

)

async def chat(userinput: str):

chathistory.addusermessage(userinput)

result = await kernel.invokeprompt(

userinput,

chathistory=chathistory

)

response = str(result)

chathistory.addassistantmessage(response)

return response

async def main():

print(await chat("What is a decorator in Python?"))

print(await chat("Give me an example of its usage"))

asyncio.run(main())

Prompt Templates

Semantic Kernel has a template system that allows you to create reusable prompts:

import asyncio

from semantickernel import Kernel

from semantickernel.connectors.ai.openai import OpenAIChatCompletion

from semantickernel.prompttemplate import PromptTemplateConfig

kernel = Kernel()

kernel.addservice(OpenAIChatCompletion(

aimodelid="gpt-4o",

serviceid="chat"

))

promptconfig = PromptTemplateConfig(

template="""You are a {{$role}}.

Task: {{$task}}

Provide a detailed and structured answer.""",

inputvariables=[

{"name": "role", "description": "The AI's role"},

{"name": "task", "description": "The task to perform"}

]

)

function = kernel.addfunction(

pluginname="writer",

functionname="generate",

prompttemplateconfig=promptconfig

)

async def main():

result = await kernel.invoke(

function,

role="senior data scientist",

task="Explain the differences between Random Forest and Gradient Boosting"

)

print(result)

asyncio.run(main())

Plugin System

Plugins are a core feature of Semantic Kernel that allow you to define functions that can be automatically called by the LLM.

Creating a Native Plugin

import asyncio

from datetime import datetime

from typing import Annotated

from semantickernel import Kernel

from semantickernel.connectors.ai.openai import OpenAIChatCompletion

from semantickernel.functions import kernelfunction

class UtilityPlugin:

@kernelfunction(description="Gets the current date and time")

def getcurrenttime(self) -> str:

return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

@kernelfunction(description="Calculates discount from original price")

def calculatediscount(

self,

price: Annotated[float, "Original product price"],

discountpercent: Annotated[float, "Discount percentage"]

) -> str:

discounted = price (1 - discountpercent / 100)

savings = price - discounted

return f"Original: ${price:,.2f}, Discount: {discountpercent}%, Final: ${discounted:,.2f}, Saved: ${savings:,.2f}"

@kernelfunction(description="Converts temperature from Celsius to Fahrenheit")

def celsiustofahrenheit(

self,

celsius: Annotated[float, "Temperature in Celsius"]

) -> str:

fahrenheit = (celsius 9/5) + 32

return f"{celsius}°C = {fahrenheit}°F"

kernel = Kernel()

kernel.addservice(OpenAIChatCompletion(

aimodelid="gpt-4o",

serviceid="chat"

))

kernel.addplugin(UtilityPlugin(), pluginname="utility")

async def main():

result = await kernel.invokeprompt(

"What is the price after a 25% discount on $500?"

)

print(result)

asyncio.run(main())

Plugin with Async Functions

import asyncio

import httpx

from semantickernel.functions import kernelfunction

from typing import Annotated

class WeatherPlugin:

@kernelfunction(description="Gets weather information for a city")

async def getweather(

self,

city: Annotated[str, "City name to check weather for"]

) -> str:

async with httpx.AsyncClient() as client:

response = await client.get(

"https://api.open-meteo.com/v1/forecast",

params={

"latitude": 0,

"longitude": 0,

"currentweather": True

}

)

data = response.json()

weather = data.get("currentweather", {})

return (

f"Weather in {city}: "

f"Temperature {weather.get('temperature', 'N/A')}°C, "

f"Wind speed {weather.get('windspeed', 'N/A')} km/h"

)

Plugin from Prompt Files

You can define plugins from prompt files organized in folders:

plugins/

WriterPlugin/

Summarize/

skprompt.txt

config.json

Translate/

skprompt.txt

config.json

File skprompt.txt:

Summarize the following text in {{$targetlength}} sentences:

{{$input}}

Summary:

File config.json:

{

"schema": 1,

"description": "Summarizes long text into a shorter version",

"inputvariables": [

{

"name": "input",

"description": "Text to summarize"

},

{

"name": "targetlength",

"description": "Number of sentences for the summary",

"default": "3"

}

]

}

Loading plugins from a folder:

kernel.addplugin(parentdirectory="./plugins", pluginname="WriterPlugin")

Automatic Function Calling

One of Semantic Kernel's most powerful features is the LLM's ability to automatically select and call the right function based on conversation context.

import asyncio

from semantickernel import Kernel

from semantickernel.connectors.ai.openai import OpenAIChatCompletion

from semantickernel.connectors.ai.openai.promptexecutionsettings import (

OpenAIChatPromptExecutionSettings,

)

from semantickernel.connectors.ai.functionchoicebehavior import FunctionChoiceBehavior

from semantickernel.contents import ChatHistory

from semantickernel.functions import kernelfunction

from typing import Annotated

class MathPlugin:

@kernelfunction(description="Adds two numbers")

def add(

self,

a: Annotated[float, "First number"],

b: Annotated[float, "Second number"]

) -> float:

return a + b

@kernelfunction(description="Multiplies two numbers")

def multiply(

self,

a: Annotated[float, "First number"],

b: Annotated[float, "Second number"]

) -> float:

return a b

@kernelfunction(description="Calculates power")

def power(

self,

base: Annotated[float, "Base number"],

exponent: Annotated[float, "Exponent"]

) -> float:

return base exponent

kernel = Kernel()

kernel.addservice(OpenAIChatCompletion(

aimodelid="gpt-4o",

serviceid="chat"

))

kernel.addplugin(MathPlugin(), pluginname="math")

settings = OpenAIChatPromptExecutionSettings(

serviceid="chat",

functionchoicebehavior=FunctionChoiceBehavior.Auto()

)

chathistory = ChatHistory()

async def main():

chathistory.addusermessage(

"What is the result of (15 + 27) multiplied by 3, then raised to the power of 2?"

)

result = await kernel.invokeprompt(

"{{$chathistory}}",

chathistory=chathistory,

settings=settings

)

print(f"Answer: {result}")

asyncio.run(main())

In the example above, the LLM will automatically:

  • Call add(15, 27) to get 42
  • Call multiply(42, 3) to get 126
  • Call power(126, 2) to get 15876
  • Advanced Usage

    Building AI Agents with Semantic Kernel

    Agents in Semantic Kernel allow you to create AI entities with specific personas, tools, and capabilities.

    import asyncio
    

    from semantickernel import Kernel

    from semantickernel.agents import ChatCompletionAgent

    from semantickernel.connectors.ai.openai import OpenAIChatCompletion

    from semantickernel.contents import ChatHistory

    from semantickernel.functions import kernelfunction

    from typing import Annotated

    class DatabasePlugin:

    @kernelfunction(description="Executes a SQL query and returns results")

    def executequery(

    self,

    query: Annotated[str, "SQL query to execute"]

    ) -> str:

    sampledata = {

    "SELECT COUNT() FROM users": "Total users: 1,247",

    "SELECT AVG(revenue) FROM sales WHERE month='2026-09'":

    "Average revenue September 2026: $12,450"

    }

    for key, value in sampledata.items():

    if key.lower() in query.lower():

    return value

    return f"Query executed: {query}\nRows affected: 0"

    @kernelfunction(description="Gets list of available tables in the database")

    def listtables(self) -> str:

    return "Tables: users, sales, products, orders, inventory"

    @kernelfunction(description="Gets the schema of a table")

    def gettableschema(

    self,

    tablename: Annotated[str, "Table name"]

    ) -> str:

    schemas = {

    "users": "id INT PK, name VARCHAR, email VARCHAR, createdat TIMESTAMP",

    "sales": "id INT PK, productid INT FK, amount DECIMAL, month VARCHAR",

    "products": "id INT PK, name VARCHAR, price DECIMAL, category VARCHAR"

    }

    return schemas.get(tablename, f"Table '{tablename}' not found")

    kernel = Kernel()

    kernel.addservice(OpenAIChatCompletion(

    aimodelid="gpt-4o",

    serviceid="chat"

    ))

    kernel.addplugin(DatabasePlugin(), pluginname="database")

    agent = ChatCompletionAgent(

    kernel=kernel,

    name="DataAnalyst",

    instructions="""You are a data analyst expert in SQL and data analysis.

    Use the available database tools to answer user questions.

    Always explain the queries you run and interpret the results.""",

    )

    async def main():

    history = ChatHistory()

    history.addusermessage("How many total users are registered in the system?")

    async for message in agent.invoke(history):

    print(f"Agent: {message.content}")

    asyncio.run(main())

    Multi-Agent Collaboration

    Semantic Kernel supports agent collaboration through AgentGroupChat:

    import asyncio
    

    from semantickernel import Kernel

    from semantickernel.agents import ChatCompletionAgent, AgentGroupChat

    from semantickernel.agents.strategies import TerminationStrategy

    from semantickernel.connectors.ai.openai import OpenAIChatCompletion

    from semantickernel.contents import ChatMessageContent, AuthorRole

    kernel = Kernel()

    kernel.addservice(OpenAIChatCompletion(

    aimodelid="gpt-4o",

    serviceid="chat"

    ))

    analyst = ChatCompletionAgent(

    kernel=kernel,

    name="Analyst",

    instructions="""You are a business analyst.

    Analyze business problems and identify technical requirements.

    Provide measurable and realistic recommendations."""

    )

    engineer = ChatCompletionAgent(

    kernel=kernel,

    name="Engineer",

    instructions="""You are a senior software engineer.

    Evaluate technical recommendations from the analyst.

    Provide effort estimates, architecture, and potential risks.

    Be specific and technical."""

    )

    reviewer = ChatCompletionAgent(

    kernel=kernel,

    name="Reviewer",

    instructions="""You are a project reviewer.

    Review output from the analyst and engineer.

    Provide approval or feedback for improvement.

    If the output is good enough, end with the word APPROVED."""

    )

    class ApprovalTermination(TerminationStrategy):

    async def shouldagentterminate(self, agent, history):

    if history:

    last = history[-1]

    return "APPROVED" in last.content.upper()

    return False

    chat = AgentGroupChat(

    agents=[analyst, engineer, reviewer],

    terminationstrategy=ApprovalTermination(

    agents=[reviewer],

    maximumiterations=6

    )

    )

    async def main():

    await chat.addchatmessage(

    ChatMessageContent(

    role=AuthorRole.USER,

    content="We want to build a product recommendation system for an e-commerce platform with 100K SKUs and 1M active users."

    )

    )

    async for message in chat.invoke():

    print(f"\n{'='*50}")

    print(f"[{message.name}]: {message.content}")

    asyncio.run(main())

    Memory and Vector Store Integration

    Semantic Kernel supports integration with various vector stores for memory and RAG features:

    import asyncio
    

    from semantickernel import Kernel

    from semantickernel.connectors.ai.openai import (

    OpenAIChatCompletion,

    OpenAITextEmbedding,

    )

    from semantickernel.memory import SemanticTextMemory, VolatileMemoryStore

    kernel = Kernel()

    kernel.addservice(OpenAIChatCompletion(

    aimodelid="gpt-4o",

    serviceid="chat"

    ))

    embeddingservice = OpenAITextEmbedding(

    aimodelid="text-embedding-3-small",

    serviceid="embedding"

    )

    memorystore = VolatileMemoryStore()

    memory = SemanticTextMemory(

    storage=memorystore,

    embeddingsgenerator=embeddingservice

    )

    async def main():

    collection = "companyknowledge"

    await memory.saveinformation(

    collection=collection,

    id="policy1",

    text="Annual leave policy is 12 working days per year. "

    "Leave can be accumulated up to 6 days into the next year."

    )

    await memory.saveinformation(

    collection=collection,

    id="policy2",

    text="Standard working hours are Monday-Friday, 09:00-18:00. "

    "Overtime is calculated after 8 working hours per day."

    )

    await memory.saveinformation(

    collection=collection,

    id="policy3",

    text="Employee benefits include health insurance, employment insurance, "

    "supplementary insurance, and meal allowance of $5 per day."

    )

    results = await memory.search(

    collection=collection,

    query="How many leave days do employees get?",

    limit=2

    )

    context = "\n".join([r.text for r in results])

    result = await kernel.invokeprompt(

    f"""Based on the following information:

    {context}

    Answer the question: How many leave days do employees get and can they be accumulated?"""

    )

    print(result)

    asyncio.run(main())

    Filters and Hooks

    Semantic Kernel provides a filter system for logging, monitoring, and request/response modification:

    import asyncio
    

    import time

    from semantickernel import Kernel

    from semantickernel.connectors.ai.openai import OpenAIChatCompletion

    from semantickernel.filters import (

    FunctionInvocationContext,

    PromptRenderContext,

    )

    kernel = Kernel()

    kernel.addservice(OpenAIChatCompletion(

    aimodelid="gpt-4o",

    serviceid="chat"

    ))

    @kernel.filter(filtertype="functioninvocation")

    async def logfunctionfilter(context: FunctionInvocationContext, next):

    starttime = time.time()

    print(f"[LOG] Calling function: {context.function.name}")

    print(f"[LOG] Arguments: {context.arguments}")

    await next(context)

    elapsed = time.time() - starttime

    print(f"[LOG] Function {context.function.name} completed in {elapsed:.2f}s")

    print(f"[LOG] Result: {str(context.result)[:200]}")

    @kernel.filter(filtertype="promptrender")

    async def modifypromptfilter(context: PromptRenderContext, next):

    await next(context)

    context.renderedprompt += "\n\nPlease provide a clear and well-structured answer."

    print(f"[LOG] Rendered prompt length: {len(context.renderedprompt)}")

    async def main():

    result = await kernel.invokeprompt("What is a neural network?")

    print(f"\nResult: {result}")

    asyncio.run(main())

    Streaming Responses

    For real-time applications, use streaming:

    import asyncio
    

    from semantickernel import Kernel

    from semantickernel.connectors.ai.openai import OpenAIChatCompletion

    kernel = Kernel()

    kernel.addservice(OpenAIChatCompletion(

    aimodelid="gpt-4o",

    serviceid="chat"

    ))

    async def main():

    print("Response: ", end="", flush=True)

    async for chunk in kernel.invokepromptstream(

    "Explain the 5 steps in a machine learning pipeline"

    ):

    print(str(chunk), end="", flush=True)

    print()

    asyncio.run(main())

    Best Practices

    1. Use Dependency Injection

    from semantickernel import Kernel
    
    

    def createkernel(apikey: str, model: str = "gpt-4o") -> Kernel:

    kernel = Kernel()

    kernel.addservice(OpenAIChatCompletion(

    aimodelid=model,

    apikey=apikey,

    serviceid="chat"

    ))

    return kernel

    2. Proper Error Handling

    from semantickernel.exceptions import ServiceResponseException
    
    

    async def safeinvoke(kernel, prompt):

    try:

    result = await kernel.invokeprompt(prompt)

    return str(result)

    except ServiceResponseException as e:

    print(f"Service error: {e}")

    return None

    except Exception as e:

    print(f"Unexpected error: {e}")

    return None

    3. Keep Plugin Scope Focused

    Each plugin should have a single, clear responsibility. Avoid creating monolithic plugins that handle too many functions.

    class FilePlugin:
    

    @kernelfunction(description="Reads file content")

    def readfile(self, path: Annotated[str, "File path"]) -> str:

    with open(path, "r") as f:

    return f.read()

    @kernelfunction(description="Writes content to a file")

    def writefile(

    self,

    path: Annotated[str, "File path"],

    content: Annotated[str, "Content to write"]

    ) -> str:

    with open(path, "w") as f:

    f.write(content)

    return f"File written: {path}"

    4. Use Execution Settings

    from semantickernel.connectors.ai.openai.promptexecutionsettings import (
    

    OpenAIChatPromptExecutionSettings,

    )

    settings = OpenAIChatPromptExecutionSettings(

    serviceid="chat",

    temperature=0.7,

    maxtokens=2000,

    topp=0.9,

    )

    result = await kernel.invokeprompt(prompt, settings=settings)

    5. Test Plugin Functions Independently

    import pytest
    
    

    class TestMathPlugin:

    def setupmethod(self):

    self.plugin = MathPlugin()

    def testadd(self):

    result = self.plugin.add(a=10, b=20)

    assert result == 30

    def testmultiply(self):

    result = self.plugin.multiply(a=5, b=6)

    assert result == 30

    def testpower(self):

    result = self.plugin.power(base=2, exponent=10)

    assert result == 1024

    6. Structured Output with Pydantic

    from pydantic import BaseModel, Field
    

    from semantickernel.functions import kernelfunction

    class AnalysisResult(BaseModel):

    sentiment: str = Field(description="positive, negative, or neutral")

    confidence: float = Field(description="Confidence score 0-1")

    keytopics: list[str] = Field(description="Main topics detected")

    summary: str = Field(description="Brief summary")

    class AnalysisPlugin:

    @kernelfunction(description="Analyzes sentiment and topics from text")

    async def analyzetext(

    self,

    text: Annotated[str, "Text to analyze"],

    kernel: Kernel

    ) -> str:

    result = await kernel.invokeprompt(

    f"""Analyze the following text and provide output in JSON format:

    • sentiment: positive/negative/neutral
    • confidence: score 0-1
    • keytopics: list of main topics
    • summary: brief summary

    Text: {text}

    JSON Output:"""

    )

    return str(result)

    Comparison with Other Frameworks

    | Feature | Semantic Kernel | LangChain | LlamaIndex |

    |---------|----------------|-----------|------------|

    | Plugin System | Native, strongly typed | Tools/Agents | Tools |

    | Multi-Provider | Yes | Yes | Yes |

    | Memory | Built-in | Add-on | Native |

    | Agent Framework | ChatCompletionAgent | AgentExecutor | Agent |

    | Enterprise Ready | Excellent | Good | Good |

    | Learning Curve | Moderate | Low-Moderate | Moderate |

    | Languages | Python, C#, Java | Python, JS | Python, TS |

    Conclusion

    Semantic Kernel is a mature and production-ready AI orchestration framework from Microsoft. With its modular plugin architecture, multi-provider support, and comprehensive agent features, this framework is well-suited for building enterprise AI applications. Its automatic function calling and multi-agent collaboration capabilities make it a strong choice for projects that require structured and scalable LLM integration.

    Key takeaways to remember:

    • Start with the Kernel and add services as needed
    • Use the plugin system to separate business logic from prompts
    • Leverage automatic function calling for more natural workflows
    • Implement filters for logging and monitoring in production
    • Consider multi-agent patterns for complex tasks
    • Always test plugin functions independently before integrating with LLMs

    With a strong foundation from Microsoft and a growing community, Semantic Kernel is a solid investment for developers looking to build robust, enterprise-grade AI applications.

    Related Articles

    Semantic Router Tutorial: Smart Routing for LLM Applications

    Tutorial Semantic Router: Routing Cerdas untuk Aplikasi LLM Semantic Router adalah library Python yang memungkinkan Anda...

    Complete Llama Stack Tutorial: Meta's Official Framework for Building AI Applications with Llama Models

    Tutorial Lengkap Llama Stack: Framework Resmi Meta untuk Membangun Aplikasi AI dengan Model Llama Llama Stack adalah fra...

    CAMEL-AI Tutorial: Building Multi-Agent Systems with Communicative AI Agents

    Tutorial Lengkap CAMEL-AI: Framework Multi-Agent Communication untuk Membangun Sistem AI Kolaboratif Penulis: Ruby Abdul...

    Zep Tutorial: Long-Term Memory for AI Agents with a Temporal Knowledge Graph

    Zep: Bikin AI Agent Punya Memori Jangka Panjang dengan Temporal Knowledge Graph Temen-temen, pernah ngobrol sama chatbot...