All Articles

Article List

Introduction

Large language models have taken the world by storm, changing the ways humans interact with computers. Clicking buttons, searching google, and writing your own emails have all become obsolete. These menial tasks can be bypassed by asking an AI to do it for you in your own natural language. With such great power, every company at every corner in the world is rushing to integrate AI into their products and applications. The question is, how do you quickly and efficiently integrate AI into these products? Microsoft has attempted to answer that with their recently released Semantic Kernel.

What is Semantic Kernel?

Semantic Kernel is Microsoft’s way to directly implement AI in code. With many different functionalities to leverage the power of LLMs, it is a powerful tool that can be utilized when adding AI to your own application.

The main functionality for Semantic Kernel stems from its “Semantic Functions.” These are essentially reusable prompts with an input that allows any kind of text completion model to use it and generate a useful response. Let’s look at one possible use case, where you want to create a Semantic Function that will translate the text from english to spanish.


 translator = kernel.create_semantic_function("""Translate the following text from english to spanish
 English: {{$input}}
 Spanish: """)
 
 
 
 print(translator("Hey there, how are you doing?"))
 
 # output: ¿Hola como estas? 

In this sample code, we are taking advantage of Semantic Kernel’s semantic function in order to create a reusable prompt. Now, anywhere in the code that you need to translate English to Spanish, you can programmatically use a function to do it for you. Essentially, it eliminates the need for the intermediary step in which you call some sort of web API and allows you to focus more on writing the code with the power of LLMs infused right into it.

Skills, Memories, and Connectors

Semantic Functions are the building blocks of a Semantic Kernel, but its true beauty comes out when you combine it with other features.

Skills are an extension of Semantic Functions. Rather, they are a collection of many Semantic Functions that fits into one “skill.” For instance, a WriterSkill may have a Semantic Function for summarizing, brainstorming, creating articles, etc. A TranslatorSkill may have functions for different languages. Microsoft also has built in non-semantic function skills such as a TextSkill for more menial tasks such as capitalizing or truncating. These seem useless at first, but wait until you see the power of Semantic Kernel’s planner.

Memories utilize embeddings to extend the context capability of the kernel. Embeddings allow the kernel to express any kind of data it's given as a vector (a point in an n-dimensional space) which holds the meaning of the text. The closer the two vectors are, the more similar their meaning is. This means that if the kernel needs to recall something that the user had said earlier, it can use these embeddings to find the memory it wants and add it to its context. All in all, this is a powerful tool to add more data to the context of a semantic function or just plain text completion.

Finally, connectors are a way for the kernel to interact with outside APIs and functions. For example, one may add a connection to google’s search API in order to expose the kernel to the endless information of the web. They can also be used to connect databases or other kinds of data storage.

Planner

At this point, all of these features may seem like a disconnected jumble of useful things. And while by themselves they are very powerful, it all comes together with Semantic Kernel’s planner.

The planner is an integral part of the kernel’s pipeline. The planner can take all of these skills, memories, and connections and put them together in order to accomplish whatever task the user inputs as best as possible. Here is an example output of a simple JSON planner:


 [GOAL]
 
 "Tomorrow is Valentine's day. I need to come up with a few date ideas.
 
 She likes Edgar Allen Poe so write using his style.
 
 E-mail these ideas to my significant other. Translate it to French."
 
 
 
 
 [OUTPUT]
 
     {
 
         "input": "Valentine's Day Date Ideas",
 
         "subtasks": [
 
             {"function": "WriterSkill.Brainstorm"},
 
             {"function": "EdgarAllenPoeSkill.Poe"},
 
             {"function": "WriterSkill.EmailTo", "args": {"recipient": "significant_other"}},
 
             {"function": "translate", "args": {"language": "French"}}
 
         ]
 
     } 

The planner takes in the prompt and spits out a series of functions to apply to the input in order to achieve the goal. Each of these functions are Semantic Functions that have been defined. In fact, the planner itself is just a fancier Semantic Function, but its output has been tuned to be a JSON response that can be interpreted by code and run.

Of course, Microsoft isn’t done with just this. Semantic Kernel is still in the early stages of development, and many other types of planners are planned. In addition to the JSON planner, they have also implemented a similar XML planner, plus they may release other types of planners with different kinds of outputs.

Real World Example

These tools unlock an endless amount of possibilities for applications. It can easily create a text summarizer, a customer service bot, a home assistant, etc. As an example, I will show you how to create a simple email assistant bot.

The first step is to create a custom “email” skill so that the Semantic Kernel can have access to sending and receiving emails. Here is a barebone structure of how you would do it with Semantic Kernel:

 class EmailSkill:
 
     @sk_function(description="Send an email to someone")
 
     def email(self, recipient: str) -> str:
 
         return "Email sent to " + recipient
 
 
 
     @sk_function(description="Get the email addresses that most recently sent an email to you")
 
     def get_recent_email_addresses(self) -> str:
 
         return "example@example.com"
 
 
 
 
     @sk_function(description="Get content of latest email from email address")
 
     def get_recent_email(self, email_address: str) -> str:
 
         return "Hello, this is a test email. I like hotdogs, and hamburgers. Also pineapple belongs on pizza." 

Then, we can use this along with Microsoft’s predefined skills in order to create a superpowered kernel. The WriterSkill and SummarizeSkill have been taken off their github and the TextSkill is a built in skill and comes with the library.

 skills_directory = "./skills"
 summarize_skill = kernel.import_semantic_skill_from_directory(skills_directory, "SummarizeSkill")
 writer_skill = kernel.import_semantic_skill_from_directory(skills_directory, "WriterSkill")
 text_skill = kernel.import_skill(TextSkill(), "TextSkill")
 email_skill = kernel.import_skill(EmailSkill(), "EmailSkill") 

Now, we can generate a plan to accomplish something that the user wants. Here is a simple one: “Get my most recent email from Tom and then summarize it and send it to Max.”

 ask = """
 Get my most recent email for Mannan and then summarize it and send it to Puneet"""
 plan = await planner.create_plan_async(ask, kernel)
 print(plan.generated_plan)
 res = await planner.execute_plan_async(plan, kernel)
 print(res)
 
 ### Generated plan:
 
 {
 
         "input": "Tom's Recent Email Summary",
         "subtasks": [
             {"function": "EmailSkill.get_recent_email", "args": {"input": "Tom"}},
             {"function": "SummarizeSkill.Summarize"},
             {"function": "EmailSkill.email", "args": {"input": "Summary", "recipient": "Max"}}
         ]
   } 

All that is left to do is to actually implement the functions in our Email Skill, which I will leave as an exercise to the reader since the point was mostly to showcase the Semantic Kernel part of this. Either way, this showcases how powerful the Kernel is. Without any prompt engineering and with very little work, you can make a fully functional app powered by AI. To give an idea, this took me around 45 minutes to implement all of this, and that was including the research on Semantic Kernel’s docs.

Drawbacks

Since Semantic Kernel just released, it has quite a few drawbacks associated with it. In fact, the fact it just released itself is a drawback. This means lack of documentation, having to update your code on every new release, and even broken releases. This can be pretty annoying especially if you are working on a long term project. It may be more beneficial just to wait for it to mature a bit more so that you can get full use out of it.

Another drawback is the languages it supports. Currently it only supports C# with .NET and python to an extent. C# has had its development start months before and is much more mature than the python branch, however both of them are still lacking in features. Python also doesn’t have all the features they have in C#  since they are still working on updating it, which can be a real pain since their documentation is in C#. There are also Java and Typescript branches in the works, but neither are anywhere near done for it to be released. Right now your best bet would be to use C# if possible. Python also works pretty well, as you can see with the sample, but is still lacking in many areas.

Conclusion

Although Semantic Kernel is still in its infancy, its power is already starting to shine through. Especially now that integrating AI into code is more important than ever, Semantic Kernel can be vital to your success in efficiently incorporating AI code into your applications, website, or program. In conclusion, it will be exciting to see Semantic Kernel progress and become a crucial part of your AI toolset.