{"id":2674,"date":"2024-05-14T06:53:10","date_gmt":"2024-05-14T13:53:10","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/semantic-kernel\/?p=2674"},"modified":"2024-05-14T06:53:10","modified_gmt":"2024-05-14T13:53:10","slug":"using-semantic-kernel-to-create-a-time-plugin-with-net","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/using-semantic-kernel-to-create-a-time-plugin-with-net\/","title":{"rendered":"Using Semantic Kernel to create a Time Plugin with .NET"},"content":{"rendered":"<p><span data-contrast=\"auto\">Plugins are one of the most powerful features of Semantic Kernel and in this demo <\/span><span data-contrast=\"auto\">we show how you can easily use Plugins with the power of Auto Function Calling from AI Models.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<p aria-level=\"2\"><strong>A Glimpse into the Demonstration\u00a0<\/strong><\/p>\n<p aria-level=\"3\"><strong>Time Information Plugin\u00a0<\/strong><\/p>\n<p><span data-contrast=\"auto\">In the demo we implement a simple class TimeInformantionPlugin with one function to retrieve the UTC time in string format.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">public class TimeInformationPlugin\u00a0\r\n{\u00a0\r\n\u00a0\u00a0\u00a0 [KernelFunction]\u00a0\r\n\u00a0\u00a0\u00a0 [Description(\"Retrieves the current time in UTC.\")]\u00a0\r\n\u00a0\u00a0\u00a0 public string GetCurrentUtcTime()\u00a0=&gt; DateTime.UtcNow.ToString(\"R\");\u00a0\r\n}<\/code><\/pre>\n<p><span data-contrast=\"auto\">C# functions that can be imported to Plugins are marked with KernelFunction that will instruct the Kernel what are going to be imported into Plugins using Description attribute will be used on how those functions will be detailed to the AI Model for calling so it will have a better understanding on when to use your functions.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">When implementing functions in your plugins you can use many different signatures, including asynchronous tasks and different types, check our [Concept \u2013 Method Function Types]( <\/span><a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/blob\/main\/dotnet\/samples\/Concepts\/Functions\/MethodFunctions_Types.cs\"><span data-contrast=\"none\">semantic-kernel\/dotnet\/samples\/Concepts\/Functions\/MethodFunctions_Types.cs at main \u00b7 microsoft\/semantic-kernel (github.com)<\/span><\/a><span data-contrast=\"auto\">) sample for more details.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<ul>\n<li data-leveltext=\"\uf0d8\" data-font=\"Wingdings\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Wingdings&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0d8&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Info: Is very important providing descriptions to your functions and arguments when using them against the AI for best results.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:279}\">\u00a0<\/span><\/li>\n<\/ul>\n<p aria-level=\"2\"><strong>Configuring the Kernel\u00a0<\/strong><\/p>\n<p><span data-contrast=\"auto\">In the code below we use the configuration extensions from .Net to get the current OpenAI configuration details to setup and initialize the kernel with an OpenAI connector and our TimeInformationPlugin ready to use.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">var config = new ConfigurationBuilder()\u00a0\r\n\u00a0\u00a0\u00a0 .AddUserSecrets&lt;Program&gt;()\u00a0\r\n\u00a0\u00a0\u00a0 .AddEnvironmentVariables()\u00a0\r\n\u00a0\u00a0\u00a0 .Build()\u00a0\r\n\r\nvar kernelBuilder = Kernel.CreateBuilder().AddOpenAIChatCompletion(\u00a0\r\n\u00a0\u00a0\u00a0 modelId: config[\"OpenAI:ChatModelId\"]!,\u00a0\r\n\u00a0\u00a0\u00a0 apiKey: config[\"OpenAI:ApiKey\"]!);\u00a0\r\n\r\nkernelBuilder.Plugins.AddFromType&lt;TimeInformationPlugin&gt;();\u00a0\r\n\r\nvar kernel = kernelBuilder.Build();<\/code><\/pre>\n<p aria-level=\"2\"><strong>Using Auto Function Calling\u00a0<\/strong><\/p>\n<p><span data-contrast=\"auto\">With the kernel instance is possible to get the completion service and use it to call the AI. Is important to configure your execution settings to enable AutoInvocation as this is not a default configuration and won\u2019t expose your plugins inadvertently to AI.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">var chatCompletionService = kernel.GetRequiredService&lt;IChatCompletionService&gt;();\u00a0\r\n\r\nOpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()\u00a0\r\n{\u00a0\r\n\u00a0\u00a0\u00a0 \/\/ Enable auto function calling\u00a0\r\n\u00a0\u00a0\u00a0 ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions\u00a0\r\n};<\/code><\/pre>\n<p><span data-contrast=\"auto\">Is also important to create and pass the chat history so it keeps the track of the conversation with the AI in a loop and it improves the overall results.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:240}\">\u00a0<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">chatHistory.AddUserMessage(input);\u00a0\r\n\r\nvar chatResult = await chatCompletionService.GetChatMessageContentAsync(chatHistory, openAIPromptExecutionSettings, kernel);\u00a0\r\nConsole.Write($\"\\nAssistant &gt; {chatResult}\\n\");<\/code><\/pre>\n<p><span data-contrast=\"auto\">For each iteration in this loop, the assistant will get an instruction from the user, and whenever the instruction suggest a need to get the current time, it will be invoked by the AI automatically.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<p aria-level=\"2\"><b><span data-contrast=\"none\">Dive Deeper<\/span><\/b><span data-contrast=\"none\">\u202f<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:160,&quot;335559739&quot;:80,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Please reach out if you have any questions or feedback through our <a class=\"Hyperlink SCXW128429093 BCX8\" href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/discussions\/categories\/general\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW128429093 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW128429093 BCX8\" data-ccp-charstyle=\"normaltextrun\">Semantic Kernel GitHub Discussion Channel<\/span><\/span><\/a><\/span><span class=\"TextRun SCXW236774567 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW236774567 BCX8\" data-ccp-charstyle=\"normaltextrun\">. We look forward to hearing from you!<\/span><span class=\"NormalTextRun SCXW236774567 BCX8\" data-ccp-charstyle=\"eop\" data-ccp-charstyle-defn=\"{&quot;ObjectId&quot;:&quot;a76df39c-72df-4e55-b0d4-80f5cc09615e|3&quot;,&quot;ClassId&quot;:1073872969,&quot;Properties&quot;:[201342446,&quot;1&quot;,201342447,&quot;5&quot;,201342448,&quot;3&quot;,201342449,&quot;1&quot;,469777841,&quot;Aptos&quot;,469777842,&quot;Arial&quot;,469777843,&quot;\uff2d\uff33 \u660e\u671d&quot;,469777844,&quot;Aptos&quot;,201341986,&quot;1&quot;,469769226,&quot;Aptos,Arial,\uff2d\uff33 \u660e\u671d&quot;,268442635,&quot;24&quot;,335559704,&quot;1025&quot;,335559705,&quot;1041&quot;,335551547,&quot;1033&quot;,335559740,&quot;279&quot;,201341983,&quot;0&quot;,335559739,&quot;160&quot;,469775450,&quot;eop&quot;,201340122,&quot;1&quot;,134233614,&quot;true&quot;,469778129,&quot;eop&quot;,335572020,&quot;1&quot;,469778324,&quot;Default Paragraph Font&quot;]}\">\u202f<\/span><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Plugins are one of the most powerful features of Semantic Kernel and in this demo we show how you can easily use Plugins with the power of Auto Function Calling from AI Models.\u00a0\u00a0 A Glimpse into the Demonstration\u00a0 Time Information Plugin\u00a0 In the demo we implement a simple class TimeInformantionPlugin with one function to retrieve [&hellip;]<\/p>\n","protected":false},"author":149071,"featured_media":2365,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[78,2,1],"tags":[79,48,63,9],"class_list":["post-2674","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-samples","category-semantic-kernel","tag-net","tag-ai","tag-microsoft-semantic-kernel","tag-semantic-kernel"],"acf":[],"blog_post_summary":"<p>Plugins are one of the most powerful features of Semantic Kernel and in this demo we show how you can easily use Plugins with the power of Auto Function Calling from AI Models.\u00a0\u00a0 A Glimpse into the Demonstration\u00a0 Time Information Plugin\u00a0 In the demo we implement a simple class TimeInformantionPlugin with one function to retrieve [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/2674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/149071"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=2674"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/2674\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/2365"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=2674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=2674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=2674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}