featured image

Working with Semantic Kernel in Python

An introduction to the Python version of the Semantic Kernel SDK

Yash Worlikar Yash Worlikar Mon Jul 15 2024 4 min read

With the release Semantic Kernel python V1.0 announced at Microsoft build, it is now generally available for developers with a stable version.

While compared to the current .NET version of the SDK it’s still currently lacking in some features. But it’s just a matter of time when the SDKs will reach a parity along with implementing language specific features.

For more detailed information check out this page containing the latest available features in each SDK. https://learn.microsoft.com/en-us/semantic-kernel/get-started/supported-languages

Setting Up Semantic Kernel

Semantic Kernel provides a structured way to manage prompts and interactions with various AI services. To get started, install the Semantic Kernel package:

pip install semantic_kernel

Import the necessary modules we will be using. We will see their uses one by one.

import asyncio
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai import PromptExecutionSettings
from semantic_kernel.functions import KernelArguments
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion

Next, we will define our kernel and add AI service available through the connectors. Here we are adding Azure OpenAI through the AzureChatCompletion class.

kernel = Kernel()
azureOpenAIService  = AzureChatCompletion("YourCustomServiceID","APIKEY","DeploymentName","Endpoint")
kernel.add_service(azureOpenAIService)

The kernel is the central part of the Semantic-Kernel. Almost all our interactions with the AI Services will be through the kernel.

We can register various supported AI services like OpenAI or huggingface through the kernel or even write custom implementations for custom local models.

In this example, we are registering an AzureOpenAIService, but any other available service would also work with the below example.

Defining a Prompt Template

While the current LLMs can answer any general-purpose query, we often want to limit their responses to a specific task. Though these models are non-deterministic by nature we can steer them towards a desired output through natural language instructions.

Here’s a prompt template that will generate a creative story based on the submitted request.

# define a template 
promptTemplate = """
Generate a creative story:
{{$request}}
"""

Next, we will create a user request and setup some optional parameters before calling the AI service.

# User message that will be replace the {{$request}} param in the above template
request = "Once upon a time in a land far, far away, there lived a brave knight named Sir Lancelot."

# define optional settings like maximun tokens, and temperature for our request
execSettings = PromptExecutionSettings(max_tokens=150);

# combine everything through the Kernelarguments object
arguments = KernelArguments(request=request, settings=execSettings)

Finally, we can use the invoke_prompt() method along with our prompt template and arguments defined above to call the AI service.

result = await kernel.invoke_prompt(
	function_name="CreateStory",
	plugin_name="storyPlugin",
	prompt=promptTemplate,
	arguments=arguments
)
print(result)

Here’s the entire code snippet

import asyncio
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai import PromptExecutionSettings
from semantic_kernel.functions import KernelArguments
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion

kernel = Kernel()
azureOpenAIService  = AzureChatCompletion("YourCustomServiceID","APIKEY","DeploymentName","Endpoint")
kernel.add_service(azureOpenAIService)

promptTemplate = """
Generate a creative story:
{{$request}}
"""

request = "Once upon a time in a land far, far away, there lived a brave knight named Sir Lancelot."
execSettings = PromptExecutionSettings(max_tokens=150)
arguments = KernelArguments(request=request, settings=execSettings)

async def main():
	result = await kernel.invoke_prompt(
		function_name="CreateStory",
		plugin_name="storyPlugin",
		prompt=promptTemplate,
		arguments=arguments
	)
	print(result)

if __name__ == "__main__":
    asyncio.run(main())

That’s it, this is all the code required for intergrating an AI service with our application. Once we run this program we will get a similar output.

Sir Lancelot was known throughout the kingdom for his courage, loyalty, and skill with a sword. He had sworn to protect the land and its people from any dangers that may come their way.

One day, a dark cloud appeared over the kingdom, and a fearsome dragon descended from the skies. The people of the kingdom were terrified, and their crops and livestock were being destroyed by the dragon's fiery breath.

Sir Lancelot knew he had to act quickly. He donned his shining armor, mounted his trusty steed, and set out to face the dragon. As he rode towards the beast, the people of the kingdom cheered for their brave knight.

The battle was fierce, with the dragon breathing fire and lashing its tail

Notice that the last sentence was cut off. This is due to the 150 max-token limit we had set up. The models aren’t aware of the execution settings we have set so we must set our templates and settings according to our expected results.

Conclusion

Semantic Kernel allows us to easily manage and integrate our structured management of prompts and interactions, with the help of the latest available models for generating creative content, answering questions, or any other AI-based tasks. Along with the features like plugins, filters and agents further allow use to build enterprise level applications with minimal overhead.

This blog just provides a basic understanding of how to set up and execute such integrations in Python.

Prev
Building a Simple text Classifier with Semantic Kernel
Next
Building AI Apps with .Net Aspire and Semantic Kernel