{"componentChunkName":"component---src-templates-tags-js","path":"/tags/semantickernel/","result":{"data":{"allMarkdownRemark":{"totalCount":3,"edges":[{"node":{"id":"d15262d2-9cb7-58a5-afc0-409f3d9feaa9","html":"<p>In my previous posts, I introduced you to foundational concepts of <a href=\"https://learn.microsoft.com/en-us/semantic-kernel/overview/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Semantic Kernel</a>, offering a glimpse into its potential. Then I showed you how to leverage plugins to communicate to LLMs, and as promised in this part we would review planners and native function plugins to show <em>Semantic Kernel’s</em> full potential.</p>\n<!--more-->\n<p>Semantic Kernel Series:</p>\n<p>✔️ Part one: <a href=\"/blog/2024/04/30/semantic-kernel\">Intro</a>\r\n<br/>\r\n✔️ Part two: <a href=\"/blog/2024/05/13/semantic-kernel-plugins\">Plugins</a>\r\n<br/>\r\n✔️ Part three: <a href=\"/blog/2024/05/27/semantic-kernel-planners/\">Planners and Native Function plugins</a></p>\n<p><a href=\"https://github.com/yashints/semantic-kernel-devops\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">You can find the code on my GitHub repository here</a>.</p>\n<p>In out last two posts we successfully created some prompts for Azure DevOps and GitHub Action workflows and called Azure OpenAI to generate the YAML files and return the result. However, the result had multiple files separated by a special separator and that gives us a great opportunity to get into planners and native function plugins.</p>\n<h2 id=\"native-function-plugins\" style=\"position:relative;\"><a href=\"#native-function-plugins\" aria-label=\"native function plugins permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Native function plugins</h2>\n<p>Previously we learnt how to create a plugin from prompt directory which allowed us to invoke one based on user input to get the desired results. But you don’t always have to use the text based approach, any function can become a plugin if you use a special decorator from the Semantic Kernel library.</p>\n<p>The result we got from our Azure OpenAI model had multiple YAML files separated by a series of characters. Let’s create a plugin which gets that output and creates one file per workflow in a given directory. All we need is to use the <code class=\"language-text\">KernelFunction</code> attribute like following:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"53862969273819370000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`using Microsoft.SemanticKernel;\r\nusing System.ComponentModel;\r\n\r\nclass ExtrcatPipelineFromOutput\r\n  {\r\n    [KernelFunction, Description(@&quot;Saves a pipeline to a file. The pipeline is a YAML file.&quot;)]\r\n    public static bool Extract(string modelOutPut, string separator, string path)\r\n    {\r\n      Console.WriteLine(modelOutPut);\r\n      try\r\n      {\r\n        var chunks = modelOutPut.Split(separator);\r\n\r\n        for (int i = 0; i < chunks.Length; i++)\r\n        {\r\n          if (chunks[i].IndexOf(&quot;FILE: &quot;) >= 0)\r\n          {\r\n            var fileName = chunks[i].Split(&quot;FILE: &quot;)[1].TrimEnd('\\r', '\\n');\r\n            SaveFile.SaveContentToFile(chunks[i + 1], Path.Combine(path, fileName));\r\n            i++;\r\n          }\r\n        }\r\n\r\n        return true;\r\n      }\r\n      catch (Exception e)\r\n      {\r\n        Console.WriteLine(\\$&quot;Error saving the pipeline: {e.Message}&quot;);\r\n        return false;\r\n      }\r\n\r\n    }\r\n  }`, `53862969273819370000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token keyword\">using</span> <span class=\"token namespace\">Microsoft<span class=\"token punctuation\">.</span>SemanticKernel</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">using</span> <span class=\"token namespace\">System<span class=\"token punctuation\">.</span>ComponentModel</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">ExtrcatPipelineFromOutput</span>\r\n  <span class=\"token punctuation\">{</span>\r\n    <span class=\"token punctuation\">[</span><span class=\"token attribute\"><span class=\"token class-name\">KernelFunction</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">Description</span><span class=\"token attribute-arguments\"><span class=\"token punctuation\">(</span><span class=\"token string\">@\"Saves a pipeline to a file. The pipeline is a YAML file.\"</span><span class=\"token punctuation\">)</span></span></span><span class=\"token punctuation\">]</span>\r\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token return-type class-name\"><span class=\"token keyword\">bool</span></span> <span class=\"token function\">Extract</span><span class=\"token punctuation\">(</span><span class=\"token class-name\"><span class=\"token keyword\">string</span></span> modelOutPut<span class=\"token punctuation\">,</span> <span class=\"token class-name\"><span class=\"token keyword\">string</span></span> separator<span class=\"token punctuation\">,</span> <span class=\"token class-name\"><span class=\"token keyword\">string</span></span> path<span class=\"token punctuation\">)</span>\r\n    <span class=\"token punctuation\">{</span>\r\n      Console<span class=\"token punctuation\">.</span><span class=\"token function\">WriteLine</span><span class=\"token punctuation\">(</span>modelOutPut<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n      <span class=\"token keyword\">try</span>\r\n      <span class=\"token punctuation\">{</span>\r\n        <span class=\"token class-name\"><span class=\"token keyword\">var</span></span> chunks <span class=\"token operator\">=</span> modelOutPut<span class=\"token punctuation\">.</span><span class=\"token function\">Split</span><span class=\"token punctuation\">(</span>separator<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n        <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\"><span class=\"token keyword\">int</span></span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> chunks<span class=\"token punctuation\">.</span>Length<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span>\r\n        <span class=\"token punctuation\">{</span>\r\n          <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>chunks<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token function\">IndexOf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"FILE: \"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\r\n          <span class=\"token punctuation\">{</span>\r\n            <span class=\"token class-name\"><span class=\"token keyword\">var</span></span> fileName <span class=\"token operator\">=</span> chunks<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token function\">Split</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"FILE: \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token function\">TrimEnd</span><span class=\"token punctuation\">(</span><span class=\"token char\">'\\r'</span><span class=\"token punctuation\">,</span> <span class=\"token char\">'\\n'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n            SaveFile<span class=\"token punctuation\">.</span><span class=\"token function\">SaveContentToFile</span><span class=\"token punctuation\">(</span>chunks<span class=\"token punctuation\">[</span>i <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> Path<span class=\"token punctuation\">.</span><span class=\"token function\">Combine</span><span class=\"token punctuation\">(</span>path<span class=\"token punctuation\">,</span> fileName<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n            i<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\r\n          <span class=\"token punctuation\">}</span>\r\n        <span class=\"token punctuation\">}</span>\r\n\r\n        <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\r\n      <span class=\"token punctuation\">}</span>\r\n      <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">Exception</span> e<span class=\"token punctuation\">)</span>\r\n      <span class=\"token punctuation\">{</span>\r\n        Console<span class=\"token punctuation\">.</span><span class=\"token function\">WriteLine</span><span class=\"token punctuation\">(</span><span class=\"token interpolation-string\"><span class=\"token string\">$\"Error saving the pipeline: </span><span class=\"token interpolation\"><span class=\"token punctuation\">{</span><span class=\"token expression language-csharp\">e<span class=\"token punctuation\">.</span>Message</span><span class=\"token punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n        <span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\r\n      <span class=\"token punctuation\">}</span>\r\n\r\n    <span class=\"token punctuation\">}</span>\r\n  <span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>It’s that easy to create a kernel function which then can be included in a plan by the kernel. Don’t worry about the <code class=\"language-text\">SaveFile</code> class for now, that just writes the content into a file in given path. You can look up the source for that in the GitHub repository.</p>\n<h2 id=\"planner\" style=\"position:relative;\"><a href=\"#planner\" aria-label=\"planner permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Planner</h2>\n<p>Now that we have our function ready, let’s go ahead and create our planner. You might be asking what is a planner anyway, which I will answer nothing special. It’s a function which takes user’s ask and returns a plan created using AI and any plugins or kernel functions which are registered to accomplish the ask.</p>\n<p>There are two types of planners you can use at the time of writing this post (this is in preview so anything can happen):</p>\n<ul>\n<li><strong>HandlebarsPlanner</strong>: It’s a sequential planner which is using the <a href=\"https://handlebarsjs.com/guide/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Handlebars’ syntax</a> to generate a plan using a single call to LLMs. This has multiple benefits such as the ability to inspect a plan before execution or the ability to save it and load it later to save costs. In addition to those, since it’s using Handlebars it can have <strong>loops</strong> and <strong>conditions</strong> in the plan as well.</li>\n<li><strong>FunctionCallingStepwisePlanner</strong>: This one has the ability to use the ReAct model which allows the AI to make a function call, reason over it and make another call if necessary.</li>\n</ul>\n<div class=\"custom-block info\"><div class=\"custom-block-body\"> <strong>Note:</strong> In addition to this, the feature is also baked into the model and is called automatic function calling which does not require a planner at all, more on this at the end.</div></div>\n<h3 id=\"creating-the-planner\" style=\"position:relative;\"><a href=\"#creating-the-planner\" aria-label=\"creating the planner permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Creating the planner</h3>\n<p>Let’s start by creating our planner and see how it will create a plan. We need a few things before we start:</p>\n<ul>\n<li>The directory which we need to save the pipelines into.</li>\n<li>The directory which we intend to save our plan into.</li>\n<li>The function which is going to be called (Azure DevOps or GitHub Actions).</li>\n<li>Adding the native function to our kernel as plugin.</li>\n<li>And finally the separator since our native function requires that to extract the pipelines from the output.</li>\n</ul>\n<p>First we can ready our directories from the <code class=\"language-text\">appsettings.json</code> file:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"51142243582955430000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`var planTemplatePath = Configuration!.GetValue<string>(&quot;PlanPath&quot;)!;\r\nvar pipelineDir = Configuration!.GetValue<string>(&quot;PipelineDir&quot;)!;`, `51142243582955430000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token class-name\"><span class=\"token keyword\">var</span></span> planTemplatePath <span class=\"token operator\">=</span> Configuration<span class=\"token operator\">!</span><span class=\"token punctuation\">.</span><span class=\"token generic-method\"><span class=\"token function\">GetValue</span><span class=\"token generic class-name\"><span class=\"token punctuation\">&lt;</span><span class=\"token keyword\">string</span><span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token string\">\"PlanPath\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">!</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> pipelineDir <span class=\"token operator\">=</span> Configuration<span class=\"token operator\">!</span><span class=\"token punctuation\">.</span><span class=\"token generic-method\"><span class=\"token function\">GetValue</span><span class=\"token generic class-name\"><span class=\"token punctuation\">&lt;</span><span class=\"token keyword\">string</span><span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token string\">\"PipelineDir\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">!</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span></span></pre></div>\n<p>Next let’s add our function to our kernel:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"65203901281930764000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`kernel.ImportPluginFromType<ExtrcatPipelineFromOutput>();`, `65203901281930764000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\">kernel<span class=\"token punctuation\">.</span><span class=\"token generic-method\"><span class=\"token function\">ImportPluginFromType</span><span class=\"token generic class-name\"><span class=\"token punctuation\">&lt;</span>ExtrcatPipelineFromOutput<span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<p>Since our planner will have to pass parameters to prompts and plugins, we need to create a <code class=\"language-text\">KernelArguments</code> object:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"69474108044605690000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`var initialArguments = new KernelArguments()\r\n{\r\n  { &quot;input&quot;, description },\r\n  { &quot;path&quot;, pipelineDir },\r\n  { &quot;function&quot;, function },\r\n  { &quot;separator&quot;, kernelSettings.Separator }\r\n};`, `69474108044605690000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token class-name\"><span class=\"token keyword\">var</span></span> initialArguments <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token constructor-invocation class-name\">KernelArguments</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\r\n<span class=\"token punctuation\">{</span>\r\n  <span class=\"token punctuation\">{</span> <span class=\"token string\">\"input\"</span><span class=\"token punctuation\">,</span> description <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\r\n  <span class=\"token punctuation\">{</span> <span class=\"token string\">\"path\"</span><span class=\"token punctuation\">,</span> pipelineDir <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\r\n  <span class=\"token punctuation\">{</span> <span class=\"token string\">\"function\"</span><span class=\"token punctuation\">,</span> function <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\r\n  <span class=\"token punctuation\">{</span> <span class=\"token string\">\"separator\"</span><span class=\"token punctuation\">,</span> kernelSettings<span class=\"token punctuation\">.</span>Separator <span class=\"token punctuation\">}</span>\r\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Next we will create our planner and ask:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"77107010144817700000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`var planner = new HandlebarsPlanner(new HandlebarsPlannerOptions() { AllowLoops = true });\r\nstring ask = @\\$&quot;Given the provided function use the proper prompt to generate the output\r\n          with provided input, then save them in the provided directory \\${pipelineDir}&quot;;`, `77107010144817700000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token class-name\"><span class=\"token keyword\">var</span></span> planner <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token constructor-invocation class-name\">HandlebarsPlanner</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token constructor-invocation class-name\">HandlebarsPlannerOptions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> AllowLoops <span class=\"token operator\">=</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">string</span></span> ask <span class=\"token operator\">=</span> <span class=\"token interpolation-string\"><span class=\"token string\">@$\"Given the provided function use the proper prompt to generate the output\r\n          with provided input, then save them in the provided directory $</span><span class=\"token interpolation\"><span class=\"token punctuation\">{</span><span class=\"token expression language-csharp\">pipelineDir</span><span class=\"token punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span></span></pre></div>\n<p>As for our plan, and to save some cost, we can check if our plan is previously created or not, if it is, we will load it from a file, if not we will create it and then save it to the file:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"97863919204695520000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`string planTemplate = &quot;&quot;;\r\nHandlebarsPlan plan;\r\nif (File.Exists(planTemplatePath))\r\n{\r\n  planTemplate = await File.ReadAllTextAsync(planTemplatePath);\r\n  plan = new HandlebarsPlan(planTemplate);\r\n}\r\nelse\r\n{\r\n  plan = await planner.CreatePlanAsync(kernel, ask, initialArguments);\r\n  Console.WriteLine(plan.ToString());\r\n  SaveFile.SaveContentToFile(plan.ToString(), planTemplatePath);\r\n}`, `97863919204695520000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token class-name\"><span class=\"token keyword\">string</span></span> planTemplate <span class=\"token operator\">=</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token class-name\">HandlebarsPlan</span> plan<span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>File<span class=\"token punctuation\">.</span><span class=\"token function\">Exists</span><span class=\"token punctuation\">(</span>planTemplatePath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\r\n<span class=\"token punctuation\">{</span>\r\n  planTemplate <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> File<span class=\"token punctuation\">.</span><span class=\"token function\">ReadAllTextAsync</span><span class=\"token punctuation\">(</span>planTemplatePath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  plan <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token constructor-invocation class-name\">HandlebarsPlan</span><span class=\"token punctuation\">(</span>planTemplate<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span>\r\n<span class=\"token keyword\">else</span>\r\n<span class=\"token punctuation\">{</span>\r\n  plan <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> planner<span class=\"token punctuation\">.</span><span class=\"token function\">CreatePlanAsync</span><span class=\"token punctuation\">(</span>kernel<span class=\"token punctuation\">,</span> ask<span class=\"token punctuation\">,</span> initialArguments<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  Console<span class=\"token punctuation\">.</span><span class=\"token function\">WriteLine</span><span class=\"token punctuation\">(</span>plan<span class=\"token punctuation\">.</span><span class=\"token function\">ToString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  SaveFile<span class=\"token punctuation\">.</span><span class=\"token function\">SaveContentToFile</span><span class=\"token punctuation\">(</span>plan<span class=\"token punctuation\">.</span><span class=\"token function\">ToString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> planTemplatePath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>If we print our plan, it might look like this:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"85128306132071940000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`{{!-- Step 1: Call the chosen function with input and assign the result to a new variable &quot;result&quot; --}}\r\n{{set 'result' (DevOps-GitHubActions input=@root.input)}}\r\n\r\n{{!-- Step 2: Call the ExtractPipelineFromOutput-Extract helper with the necessary parameters to save the pipeline to a file --}}\r\n{{#if (ExtrcatPipelineFromOutput-Extract modelOutPut=result separator=@root.separator path=@root.path)}}\r\n    {{json &quot;The pipeline has been successfully saved!&quot;}}\r\n{{else}}\r\n    {{json &quot;The pipeline could not be saved.&quot;}}\r\n{{/if}}`, `85128306132071940000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"handlebars\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-handlebars line-numbers\"><code class=\"language-handlebars\"><span class=\"token handlebars language-handlebars\"><span class=\"token comment\">{{!-- Step 1: Call the chosen function with input and assign the result to a new variable \"result\" --}}</span></span>\r\n<span class=\"token handlebars language-handlebars\"><span class=\"token delimiter punctuation\">{{</span><span class=\"token variable\">set</span> <span class=\"token string\">'result'</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">DevOps-GitHubActions</span> <span class=\"token variable\">input</span><span class=\"token punctuation\">=</span><span class=\"token punctuation\">@</span><span class=\"token variable\">root</span><span class=\"token punctuation\">.</span><span class=\"token variable\">input</span><span class=\"token punctuation\">)</span><span class=\"token delimiter punctuation\">}}</span></span>\r\n\r\n<span class=\"token handlebars language-handlebars\"><span class=\"token comment\">{{!-- Step 2: Call the ExtractPipelineFromOutput-Extract helper with the necessary parameters to save the pipeline to a file --}}</span></span>\r\n<span class=\"token handlebars language-handlebars\"><span class=\"token delimiter punctuation\">{{</span><span class=\"token block keyword\">#if</span> <span class=\"token punctuation\">(</span><span class=\"token variable\">ExtrcatPipelineFromOutput-Extract</span> <span class=\"token variable\">modelOutPut</span><span class=\"token punctuation\">=</span><span class=\"token variable\">result</span> <span class=\"token variable\">separator</span><span class=\"token punctuation\">=</span><span class=\"token punctuation\">@</span><span class=\"token variable\">root</span><span class=\"token punctuation\">.</span><span class=\"token variable\">separator</span> <span class=\"token variable\">path</span><span class=\"token punctuation\">=</span><span class=\"token punctuation\">@</span><span class=\"token variable\">root</span><span class=\"token punctuation\">.</span><span class=\"token variable\">path</span><span class=\"token punctuation\">)</span><span class=\"token delimiter punctuation\">}}</span></span>\r\n    <span class=\"token handlebars language-handlebars\"><span class=\"token delimiter punctuation\">{{</span><span class=\"token variable\">json</span> <span class=\"token string\">\"The pipeline has been successfully saved!\"</span><span class=\"token delimiter punctuation\">}}</span></span>\r\n<span class=\"token handlebars language-handlebars\"><span class=\"token delimiter punctuation\">{{</span><span class=\"token variable\">else</span><span class=\"token delimiter punctuation\">}}</span></span>\r\n    <span class=\"token handlebars language-handlebars\"><span class=\"token delimiter punctuation\">{{</span><span class=\"token variable\">json</span> <span class=\"token string\">\"The pipeline could not be saved.\"</span><span class=\"token delimiter punctuation\">}}</span></span>\r\n<span class=\"token handlebars language-handlebars\"><span class=\"token delimiter punctuation\">{{</span><span class=\"token block keyword\">/if</span><span class=\"token delimiter punctuation\">}}</span></span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>And last we invoke our plan and see the results:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"30306249062442370000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`var result = await plan.InvokeAsync(kernel, initialArguments);\r\nConsole.WriteLine(result);`, `30306249062442370000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token class-name\"><span class=\"token keyword\">var</span></span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> plan<span class=\"token punctuation\">.</span><span class=\"token function\">InvokeAsync</span><span class=\"token punctuation\">(</span>kernel<span class=\"token punctuation\">,</span> initialArguments<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\nConsole<span class=\"token punctuation\">.</span><span class=\"token function\">WriteLine</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span></span></pre></div>\n<p>We should see our pipelines getting created in the desired directory.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 706px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/60e159594bb7667db95c95b6984c22a6/9f21b/pipelines.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 24.074074074074073%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAy0lEQVR42o3Qy26DMBCFYZ6i4HAzMYZCwOBALi6govb9n+mv20WlLhJ18enMbI40E+im577uLNsHUtWIWHJIi7+Sf0iPPiVBoTVqbKmmDm1aRJIRhjGRSH6JOH0oOiTEuSRTyqcmsNPGedu4fu7M+zuDc35fscsbw90x3BxNPz3VmhlzcaiqJTg1hm4yjMvZF1j664BdZ0ZnMbeR07lHleVTZaV9cUue5wQyUxR14c+tKfuKstPUtvnxPRevR/+C8LGXECEEqfTnRxFf1wiPOJcYzwkAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"GitHub Actions workflows being created by the planner\"\n        title=\"\"\n        src=\"/static/60e159594bb7667db95c95b6984c22a6/9f21b/pipelines.png\"\n        srcset=\"/static/60e159594bb7667db95c95b6984c22a6/01bf6/pipelines.png 270w,\n/static/60e159594bb7667db95c95b6984c22a6/07484/pipelines.png 540w,\n/static/60e159594bb7667db95c95b6984c22a6/9f21b/pipelines.png 706w\"\n        sizes=\"(max-width: 706px) 100vw, 706px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<h2 id=\"automatic-function-calling\" style=\"position:relative;\"><a href=\"#automatic-function-calling\" aria-label=\"automatic function calling permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Automatic function calling</h2>\n<p>As mentioned before you can enable automatic function calling similar to **** and not use a planner, all you need is to pass in an execution settings object to the <em>OpenAI</em>:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"29208455921326860000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`// Enable auto function calling\r\nOpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()\r\n{\r\n    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions\r\n};\r\nvar result = chatCompletionService.GetStreamingChatMessageContentsAsync(\r\n                        history,\r\n                        executionSettings: openAIPromptExecutionSettings,\r\n                        kernel: kernel);`, `29208455921326860000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token comment\">// Enable auto function calling</span>\r\n<span class=\"token class-name\">OpenAIPromptExecutionSettings</span> openAIPromptExecutionSettings <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\r\n<span class=\"token punctuation\">{</span>\r\n    ToolCallBehavior <span class=\"token operator\">=</span> ToolCallBehavior<span class=\"token punctuation\">.</span>AutoInvokeKernelFunctions\r\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> result <span class=\"token operator\">=</span> chatCompletionService<span class=\"token punctuation\">.</span><span class=\"token function\">GetStreamingChatMessageContentsAsync</span><span class=\"token punctuation\">(</span>\r\n                        history<span class=\"token punctuation\">,</span>\r\n                        <span class=\"token named-parameter punctuation\">executionSettings</span><span class=\"token punctuation\">:</span> openAIPromptExecutionSettings<span class=\"token punctuation\">,</span>\r\n                        <span class=\"token named-parameter punctuation\">kernel</span><span class=\"token punctuation\">:</span> kernel<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>For more information on how to use this approach use the <a href=\"https://learn.microsoft.com/en-us/semantic-kernel/agents/plugins/using-the-kernelfunction-decorator?tabs=Csharp\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">documentation on Microsoft Learn</a>.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>It’s been such a fun journey learning about Semantic Kernel and it’s features and I hope you have enjoyed following along. Stay tuned for more AI content soon with a very exciting post on how to have your very own private and free setup and call it from your application.</p>","timeToRead":5,"frontmatter":{"title":"Semantic kernel series - Last part - Planners","unformattedDate":"2024-05-27T00:00:00.000Z","date":"May 27, 2024","path":"/semantic-kernel-planners/","author":"Yaser Adel Mehraban","tags":["semantickernel","AI","OpenAi","plugins"],"thumbnail":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAABJ0lEQVR42iWQzUpCURSFfYagN+kBGjWtkYNmRbMaBeEsUghBCBpYWUk0CEuqQYFFNLjWoMzQFBKDUhRCr/eec+5RtD+Mr3NpstkL9vpYawdUR9Ev9tG5LsPyD1/3ebSVYXBzzW52jZAVYiW7zMZenOR6gmQ8SSyT5+mxSeNin5x1ynlBUXq16XqSgGp5DM+G6IM+V7E67k6K30SE7+1VwuklxtPzjG6NMLkwQ3A6ytREkLHIESfHFSrRWdKbi1jVAQ/VNtoHCiHxpKRtK+Yih+TKb1wWBC9Nh6ateW58IIVDo9WjUPuk3ZEIpYxHIVwbRyjq74KOK1GGE5BmSOUfCTzdxXFdwqk7bks1Bj1ttINW2tQxr9HCpPDw1L9Hml0ZuJ9M+VpK/gD4TA8f0CnYjwAAAABJRU5ErkJggg=="},"backgroundColor":"transparent","images":{"fallback":{"src":"/static/2f70a5229d7587e540a083b90b8c558b/04277/planner.png","srcSet":"/static/2f70a5229d7587e540a083b90b8c558b/35840/planner.png 750w,\n/static/2f70a5229d7587e540a083b90b8c558b/2f636/planner.png 1080w,\n/static/2f70a5229d7587e540a083b90b8c558b/24e91/planner.png 1366w,\n/static/2f70a5229d7587e540a083b90b8c558b/149b3/planner.png 1920w,\n/static/2f70a5229d7587e540a083b90b8c558b/04277/planner.png 1954w","sizes":"(min-width: 1954px) 1954px, 100vw"},"sources":[{"srcSet":"/static/2f70a5229d7587e540a083b90b8c558b/35743/planner.webp 750w,\n/static/2f70a5229d7587e540a083b90b8c558b/0af22/planner.webp 1080w,\n/static/2f70a5229d7587e540a083b90b8c558b/471e5/planner.webp 1366w,\n/static/2f70a5229d7587e540a083b90b8c558b/f057b/planner.webp 1920w,\n/static/2f70a5229d7587e540a083b90b8c558b/1b93c/planner.webp 1954w","type":"image/webp","sizes":"(min-width: 1954px) 1954px, 100vw"}]},"width":1954,"height":439}}}}}},{"node":{"id":"e7551125-3b7a-5371-aecb-3b3c784f7b6f","html":"<p>In my previous post, I introduced you to foundational concepts of <a href=\"https://learn.microsoft.com/en-us/semantic-kernel/overview/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Semantic Kernel</a>, offering a glimpse into its potential. Now, when I was learning about the what and the why, that wasn’t enough for me to fully understand the concepts and that’s why I started writing these series.</p>\n<!--more-->\n<p>Semantic Kernel Series:</p>\n<p>✔️ Part one: <a href=\"/blog/2024/04/30/semantic-kernel\">Intro</a>\r\n<br/>\r\n✔️ Part two: <a href=\"/blog/2024/05/13/semantic-kernel-plugins\">Plugins</a>\r\n<br/>\r\n✔️ Part three: <a href=\"/blog/2024/05/27/semantic-kernel-planners/\">Planners and Native Function plugins</a></p>\n<p><a href=\"https://github.com/yashints/semantic-kernel-devops\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">You can find the code on my GitHub repository here</a>.</p>\n<p>In order for us to learn about the concepts, the best way is with a story, and I chose DevOps because I was interested in finding better ways to automate daily tasks in that space for my course. Let’s go through the context and see what we’re trying to achieve.</p>\n<h2 id=\"context\" style=\"position:relative;\"><a href=\"#context\" aria-label=\"context permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Context</h2>\n<p>I want to use Semantic Kernel to generate Azure DevOps pipelines/GitHub Actions workflow for my application with simple and details instructions (aka prompts). Now the application might have multiple tiers and each might have dependency with one another and I wanted to see how this will work out.</p>\n<p>The first thing we need after we have our starter project (<a href=\"../04/semantic-kernel.md\">use my previous post to create yours</a>), is to define our prompts. I want to use plugins at this point since it is very easy with them to get my prompts introduced to the kernel and execute them based on different inputs.</p>\n<h2 id=\"setup\" style=\"position:relative;\"><a href=\"#setup\" aria-label=\"setup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup</h2>\n<p>Here is what we need to get the whole setup working:</p>\n<ul>\n<li>An instance of the kernel.</li>\n<li>An instance of the Azure OpenAI or OpenAI to setup the kernel with.</li>\n<li>A plugin with different functions for Azure DevOps and GitHub Actions.</li>\n<li>Input from the user describing the application and its structure.</li>\n</ul>\n<h2 id=\"prompts\" style=\"position:relative;\"><a href=\"#prompts\" aria-label=\"prompts permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prompts</h2>\n<p>As I mentioned we would use plugins and their functions to be able to get our input passed to our Azure OpenAI service via the kernel. Technically we could add these as inline code and it works perfectly, however, that would mean we have to define these one by one and it just blows our code base. A much better way is to use the built in feature of the kernel which allows us to load multiple plugins with their functions from a directory.</p>\n<p>All you need is a folder which contains all your plugins, and for each plugin, a subdirectory per function. Every function which is mapped to our prompts will need two files:</p>\n<ul>\n<li><code class=\"language-text\">config.json</code> which contains a description, type, and the parameters for completion or chat depending on what you intend to use.</li>\n<li><code class=\"language-text\">skprompt.txt</code> which has the prompt in natural language.</li>\n</ul>\n<h2 id=\"plugin-setup\" style=\"position:relative;\"><a href=\"#plugin-setup\" aria-label=\"plugin setup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Plugin setup</h2>\n<p>Let’s set our plugin and its function up. As mentioned we intend to generate either an Azure DevOps Pipeline, or GitHub Actions workflow, so one plugin and two function will do the job. Our directory structure will look like this:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 307px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/40f98b10d1028af20e1bdfed583f50b2/4651d/dir.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 112.59259259259258%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAYAAAALHW+jAAAACXBIWXMAABYlAAAWJQFJUiTwAAADvUlEQVR42oVV2XIaSRDUD0ggBmaY4RhOcd83SAQgDEjcQhgk79OGI/T/X5Cb1SDCrLD90HTR011dWVWZfaXrOjweDwzDULPb7Ybb44ZHZg5Zkz2apsHlcqk1sWWILd+8Xu9pXMXicaSSSQRtG9lcDrVaBclUCqVyBdlMFqlUEpFoFPf3D2g2m8hkMmh3OmjRzuXyCIfDKpgzh+lkArlSBYvZDIvFDP/+/In92zsG/SHGwwESd3cYDr9hvV5jNp9hMBhg87LB+/s/KObzCoVpmgeH4l3CNy0LpuGF0+lEIBhQG5y3tyfYkgaBrB3/+3w+5UDXjXPI4tC2Q4gzUr8/gDxvTCYSqBBykqmIRCIoFIvIpNO0o7CDwTMHn5GdHEpSQ+EIqpUKQqEQ1oSyIbTp8zN2uz2WiyWenib4vt9js9mgmMuqKP/v6ORQfiTKW5dUTcI3EWQUPr8fFg/JN4vpEAQ2C2easl+/6Ew5lA0ej4Fs1o9220YgYPKQRfh+VflSqaRsn+VTlwQCAcK2/+xQ0wy2hI3VKoq7hI2Hbg+jpymmE0LdfcfmdYvhoI/J5ImwX1n9Pp0GoBvGZcheVtfn47A8alH6LhqLqQIIzGazhVqlqmDHuC4RW5Z51n/nDr2GgplKZeBnOxxawTwxQdrKw7bR3Nohp7/k9oJDEzr7KhJL4OPjA9FoCOPRGG+7HWas8GO/h9V6hdFkhuWUYzlH//ERL4ReLuXVpb9W/OrUT7xNaCR2NptFo15Ho9HEHWEWiwVE4gk8kHI5tk2a9MtzLRoJf4F9cijQJMnCAO0oDBqZcUu2CEPku8PhUPCFTTc3DvXtC2TZGIvFGU1DsWK+XLOZ59jvtxiNR2zuN8wXK6xXC/J5iNftFr3HISajEavd+9KTKkJJbjBoq8LkC0XSroxCIU87j263SwWqo0i7Wq2iVq+hUq2hXCyhQnaZXuMyUyyLnA6a1EGN0JxwEp7MMm5oC2yBfH19rWbXURP/2tixOAWiUGIkDaV5a1a4wbnEItRZKNFCidR/VJvfUi+d8fOAn0IRIAXvVZ66PNxjnvbvPxRrRAefKRpN5jtEphiG93eNfdA1wzg0qlTRoSA7VDXVM8Dky7pAlllS4NH1yw4PEhYlvCUlLEhINUr+PZ+BMpuXySdEKYQIRbvdol1hGlpIpxIHtf5aFJ1VDmHEVgiRu31C25IJq/ULOq0mZrMpWp0etqsVxuNv6PB9mc7nyGVTZ/J/Btl7fPXE/twknP189T5lX+zDC+m+KA7/AWutkDO1c7y9AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Prompt directory structure\"\n        title=\"\"\n        src=\"/static/40f98b10d1028af20e1bdfed583f50b2/4651d/dir.png\"\n        srcset=\"/static/40f98b10d1028af20e1bdfed583f50b2/01bf6/dir.png 270w,\n/static/40f98b10d1028af20e1bdfed583f50b2/4651d/dir.png 307w\"\n        sizes=\"(max-width: 307px) 100vw, 307px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p><em>DevOps</em> is the name of our plugin, and <em>AzDevOps</em> and <em>GitHubActions</em> are our function names.</p>\n<h2 id=\"prompt-text\" style=\"position:relative;\"><a href=\"#prompt-text\" aria-label=\"prompt text permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prompt text</h2>\n<p>You can write your prompts however you like, just make sure you follow the principles of <a href=\"https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/prompt-engineering\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">prompt engineering</a> which in short is all about the details and be as specific as you can.</p>\n<p>Here is how mine looks like for GitHub Actions:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"87938588507227000000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`INSTRUCTIONS:\r\n\r\nGenerate workflow YAML files to deploy an application to Azure from GitHub Actions.\r\n\r\nRULES:\r\n\r\n- All YAML files must be complete\r\n- YAML files must be listed one by one\r\n- Every file is indicated with &quot;FILE:&quot; followed by it's path\r\n- Every file content must begin and end with #-----#\r\n- All pipelines should use either GitHub hosted runners with latest ubuntu version.\r\n- All YAML files should contain two stages for build and deploy where deploy depends on build\r\n\r\nDESCRIPTION:{{\\$input}}`, `87938588507227000000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"txt\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-txt line-numbers\"><code class=\"language-txt\">INSTRUCTIONS:\r\n\r\nGenerate workflow YAML files to deploy an application to Azure from GitHub Actions.\r\n\r\nRULES:\r\n\r\n- All YAML files must be complete\r\n- YAML files must be listed one by one\r\n- Every file is indicated with \"FILE:\" followed by it's path\r\n- Every file content must begin and end with #-----#\r\n- All pipelines should use either GitHub hosted runners with latest ubuntu version.\r\n- All YAML files should contain two stages for build and deploy where deploy depends on build\r\n\r\nDESCRIPTION:{{$input}}</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>The details of how the workflow is going to be generated is outlined in details and at the end I have left a placeholder for a variable called <code class=\"language-text\">$input</code> which will be passed by the user to the kernel later.</p>\n<p>And here is what the <code class=\"language-text\">config.json</code> looks like for this prompt:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"88941871565608420000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`{\r\n  &quot;schema&quot;: 1,\r\n  &quot;description&quot;: &quot;Create pipeline YAML files for GitHub Actions&quot;,\r\n  &quot;type&quot;: &quot;completion&quot;,\r\n  &quot;completion&quot;: {\r\n    &quot;max_tokens&quot;: 1000,\r\n    &quot;temperature&quot;: 0.5,\r\n    &quot;top_p&quot;: 0,\r\n    &quot;presence_penalty&quot;: 0,\r\n    &quot;frequency_penalty&quot;: 0\r\n  },\r\n  &quot;input&quot;: {\r\n    &quot;parameters&quot;: [\r\n      {\r\n        &quot;name&quot;: &quot;input&quot;,\r\n        &quot;description&quot;: &quot;The description of the deployment to be be created&quot;,\r\n        &quot;defaultValue&quot;: &quot;&quot;\r\n      }\r\n    ]\r\n  }\r\n}`, `88941871565608420000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-json line-numbers\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\r\n  <span class=\"token property\">\"schema\"</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span>\r\n  <span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Create pipeline YAML files for GitHub Actions\"</span><span class=\"token punctuation\">,</span>\r\n  <span class=\"token property\">\"type\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"completion\"</span><span class=\"token punctuation\">,</span>\r\n  <span class=\"token property\">\"completion\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">\"max_tokens\"</span><span class=\"token operator\">:</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">,</span>\r\n    <span class=\"token property\">\"temperature\"</span><span class=\"token operator\">:</span> <span class=\"token number\">0.5</span><span class=\"token punctuation\">,</span>\r\n    <span class=\"token property\">\"top_p\"</span><span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>\r\n    <span class=\"token property\">\"presence_penalty\"</span><span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>\r\n    <span class=\"token property\">\"frequency_penalty\"</span><span class=\"token operator\">:</span> <span class=\"token number\">0</span>\r\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\r\n  <span class=\"token property\">\"input\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">\"parameters\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\r\n      <span class=\"token punctuation\">{</span>\r\n        <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"input\"</span><span class=\"token punctuation\">,</span>\r\n        <span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"The description of the deployment to be be created\"</span><span class=\"token punctuation\">,</span>\r\n        <span class=\"token property\">\"defaultValue\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span>\r\n      <span class=\"token punctuation\">}</span>\r\n    <span class=\"token punctuation\">]</span>\r\n  <span class=\"token punctuation\">}</span>\r\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>You don’t need to know the details of the parameters for now, all that is important is the definition of the input parameter and the fact that we intend to use the completion feature of Azure OpenAI.</p>\n<h2 id=\"input\" style=\"position:relative;\"><a href=\"#input\" aria-label=\"input permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Input</h2>\n<p>For our inputs, I also would like to use files, but you don’t have to follow this convention, this just keeps the code clean and short so it’s more understandable for me and other beginners learning the concepts.</p>\n<p>I have created a folder called desc which includes two files one for an application written with <code class=\"language-text\">.Net 8</code> and one for a <code class=\"language-text\">node</code> based application.</p>\n<p>Here is the content of the <code class=\"language-text\">node</code> based input file:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"58426482567665050000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`This is an application written in NodeJs and has below components:\r\n\r\n- A front end app which is written in React and uses create-react-app starter. This will be hosted in an Azure Static Web App and is stored in the \\`frontend\\` directory.\r\n- A backend API which is going to be hosted in an Azure Function as the backend for the static web app in the \\`api\\` directory.\r\n- The API uses a Cosmos DB database as its datastore.`, `58426482567665050000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"txt\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-txt line-numbers\"><code class=\"language-txt\">This is an application written in NodeJs and has below components:\r\n\r\n- A front end app which is written in React and uses create-react-app starter. This will be hosted in an Azure Static Web App and is stored in the `frontend` directory.\r\n- A backend API which is going to be hosted in an Azure Function as the backend for the static web app in the `api` directory.\r\n- The API uses a Cosmos DB database as its datastore.</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<h2 id=\"setting-up-the-kernel\" style=\"position:relative;\"><a href=\"#setting-up-the-kernel\" aria-label=\"setting up the kernel permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting up the kernel</h2>\n<p>In order to setup the kernel we need a few things:</p>\n<ul>\n<li>The information about the Azure OpenAI service like endpoint, key and model number.</li>\n<li>A way for the user to specify which input and prompt to use.</li>\n<li>Setting up the kernel so it knows about our Azure OpenAI service and our plugin directory.</li>\n<li>Calling the kernel and getting the result.</li>\n</ul>\n<p>We already covered how to setup the Azure OpenAI part with the kernel in our first post, here I just show you how to load the plugins from the directory:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"2496903402599359500\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`//reading the name of the plugin directory from our configuration\r\nvar pluginDirectories = Configuration!.GetSection(&quot;PluginSettings:Root&quot;).Get<string>();\r\n\r\n// loading the plugins from the plugin directory\r\nvar skillImport = kernel.ImportPluginFromPromptDirectory(pluginDirectories!);\r\n\r\n// read user's task description from given file\r\nstring description = await File.ReadAllTextAsync(file.FullName!);\r\n\r\n// this is a data structure that holds temporary data while the kernel task runs\r\nvar context = new KernelArguments();\r\n\r\n// associate user's description with &quot;input&quot; variable\r\nstring key = &quot;input&quot;;\r\ncontext.Add(key, description);\r\n\r\n// call the kernel and tell it which plugin function to call and pass to the LLM\r\nvar result = await kernel.InvokeAsync(skillImport[function], context);\r\nConsole.WriteLine(result.GetValue<string>());`, `2496903402599359500`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token comment\">//reading the name of the plugin directory from our configuration</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> pluginDirectories <span class=\"token operator\">=</span> Configuration<span class=\"token operator\">!</span><span class=\"token punctuation\">.</span><span class=\"token function\">GetSection</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"PluginSettings:Root\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token generic-method\"><span class=\"token function\">Get</span><span class=\"token generic class-name\"><span class=\"token punctuation\">&lt;</span><span class=\"token keyword\">string</span><span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token comment\">// loading the plugins from the plugin directory</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> skillImport <span class=\"token operator\">=</span> kernel<span class=\"token punctuation\">.</span><span class=\"token function\">ImportPluginFromPromptDirectory</span><span class=\"token punctuation\">(</span>pluginDirectories<span class=\"token operator\">!</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token comment\">// read user's task description from given file</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">string</span></span> description <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> File<span class=\"token punctuation\">.</span><span class=\"token function\">ReadAllTextAsync</span><span class=\"token punctuation\">(</span>file<span class=\"token punctuation\">.</span>FullName<span class=\"token operator\">!</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token comment\">// this is a data structure that holds temporary data while the kernel task runs</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> context <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token constructor-invocation class-name\">KernelArguments</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token comment\">// associate user's description with \"input\" variable</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">string</span></span> key <span class=\"token operator\">=</span> <span class=\"token string\">\"input\"</span><span class=\"token punctuation\">;</span>\r\ncontext<span class=\"token punctuation\">.</span><span class=\"token function\">Add</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">,</span> description<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token comment\">// call the kernel and tell it which plugin function to call and pass to the LLM</span>\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> kernel<span class=\"token punctuation\">.</span><span class=\"token function\">InvokeAsync</span><span class=\"token punctuation\">(</span>skillImport<span class=\"token punctuation\">[</span>function<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\nConsole<span class=\"token punctuation\">.</span><span class=\"token function\">WriteLine</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span><span class=\"token generic-method\"><span class=\"token function\">GetValue</span><span class=\"token generic class-name\"><span class=\"token punctuation\">&lt;</span><span class=\"token keyword\">string</span><span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<h2 id=\"output\" style=\"position:relative;\"><a href=\"#output\" aria-label=\"output permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Output</h2>\n<p>You can find the <a href=\"https://github.com/yashints/semantic-kernel-devops\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">full code for this post here</a>. Simply clone the code, build and run it passing the required information like so:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"78469817111826860000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`git clone https://github.com/yashints/semantic-kernel-devops.git\r\n\r\ncd semantic-kernel-devops\r\n\r\ndotnet restore\r\n\r\ndotnet build\r\n\r\ndotnet run -- -i .\\desc\\dotnet.txt -f GitHubActions`, `78469817111826860000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-bash line-numbers\"><code class=\"language-bash\"><span class=\"token function\">git</span> clone https://github.com/yashints/semantic-kernel-devops.git\r\n\r\n<span class=\"token builtin class-name\">cd</span> semantic-kernel-devops\r\n\r\ndotnet restore\r\n\r\ndotnet build\r\n\r\ndotnet run -- <span class=\"token parameter variable\">-i</span> .<span class=\"token punctuation\">\\</span>desc<span class=\"token punctuation\">\\</span>dotnet.txt <span class=\"token parameter variable\">-f</span> GitHubActions</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>I am passing the <code class=\"language-text\">.Net</code> application prompt and tell the kernel to create a GitHub Actions workflow.</p>\n<p>The result will look like this:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"94530943011715860000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`FILE: .github/workflows/dotnet.yml\r\n#-----#\r\nname: Build and Deploy\r\n\r\non:\r\n  push:\r\n    branches:\r\n      - master\r\n\r\njobs:\r\n  build:\r\n    name: Build\r\n    runs-on: ubuntu-latest\r\n    strategy:\r\n      matrix:\r\n        dotnet-version: ['8.x']\r\n        \r\n    steps:\r\n    - name: Checkout code\r\n      uses: actions/checkout@v2\r\n      \r\n    - name: Setup .NET Core\r\n      uses: actions/setup-dotnet@v1\r\n      with:\r\n        dotnet-version: \\${{ matrix.dotnet-version }}\r\n\r\n    - name: Restore dependencies\r\n      run: dotnet restore\r\n      \r\n    - name: Build\r\n      run: dotnet build --configuration Release --no-restore\r\n      \r\n    - name: Test\r\n      run: dotnet test --no-restore --verbosity normal\r\n\r\n  deploy:\r\n    needs: build\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - name: Login via Az module\r\n      uses: azure/login@v1\r\n      with:\r\n        creds: \\${{ secrets.AZURE_CREDENTIALS }}\r\n\r\n    - name: 'Run Azure Functions Action'\r\n      uses: Azure/functions-action@v1\r\n      id: fa\r\n      with:\r\n        app-name: 'myFunctionApp'\r\n        package: 'api'\r\n        publish-profile: \\${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}\r\n\r\n    - name: 'Deploy to Azure Web App'\r\n      uses: azure/webapps-deploy@v2\r\n      with:\r\n        app-name: 'myWebApp'\r\n        package: 'frontend'\r\n        publish-profile: \\${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}\r\n#-----#`, `94530943011715860000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"yaml\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-yaml line-numbers\"><code class=\"language-yaml\"><span class=\"token key atrule\">FILE</span><span class=\"token punctuation\">:</span> .github/workflows/dotnet.yml\r\n<span class=\"token comment\">#-----#</span>\r\n<span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Build and Deploy\r\n\r\n<span class=\"token key atrule\">on</span><span class=\"token punctuation\">:</span>\r\n  <span class=\"token key atrule\">push</span><span class=\"token punctuation\">:</span>\r\n    <span class=\"token key atrule\">branches</span><span class=\"token punctuation\">:</span>\r\n      <span class=\"token punctuation\">-</span> master\r\n\r\n<span class=\"token key atrule\">jobs</span><span class=\"token punctuation\">:</span>\r\n  <span class=\"token key atrule\">build</span><span class=\"token punctuation\">:</span>\r\n    <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Build\r\n    <span class=\"token key atrule\">runs-on</span><span class=\"token punctuation\">:</span> ubuntu<span class=\"token punctuation\">-</span>latest\r\n    <span class=\"token key atrule\">strategy</span><span class=\"token punctuation\">:</span>\r\n      <span class=\"token key atrule\">matrix</span><span class=\"token punctuation\">:</span>\r\n        <span class=\"token key atrule\">dotnet-version</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string\">'8.x'</span><span class=\"token punctuation\">]</span>\r\n        \r\n    <span class=\"token key atrule\">steps</span><span class=\"token punctuation\">:</span>\r\n    <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Checkout code\r\n      <span class=\"token key atrule\">uses</span><span class=\"token punctuation\">:</span> actions/checkout@v2\r\n      \r\n    <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Setup .NET Core\r\n      <span class=\"token key atrule\">uses</span><span class=\"token punctuation\">:</span> actions/setup<span class=\"token punctuation\">-</span>dotnet@v1\r\n      <span class=\"token key atrule\">with</span><span class=\"token punctuation\">:</span>\r\n        <span class=\"token key atrule\">dotnet-version</span><span class=\"token punctuation\">:</span> $<span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> matrix.dotnet<span class=\"token punctuation\">-</span>version <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span>\r\n\r\n    <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Restore dependencies\r\n      <span class=\"token key atrule\">run</span><span class=\"token punctuation\">:</span> dotnet restore\r\n      \r\n    <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Build\r\n      <span class=\"token key atrule\">run</span><span class=\"token punctuation\">:</span> dotnet build <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>configuration Release <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>no<span class=\"token punctuation\">-</span>restore\r\n      \r\n    <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Test\r\n      <span class=\"token key atrule\">run</span><span class=\"token punctuation\">:</span> dotnet test <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>no<span class=\"token punctuation\">-</span>restore <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>verbosity normal\r\n\r\n  <span class=\"token key atrule\">deploy</span><span class=\"token punctuation\">:</span>\r\n    <span class=\"token key atrule\">needs</span><span class=\"token punctuation\">:</span> build\r\n    <span class=\"token key atrule\">runs-on</span><span class=\"token punctuation\">:</span> ubuntu<span class=\"token punctuation\">-</span>latest\r\n    <span class=\"token key atrule\">steps</span><span class=\"token punctuation\">:</span>\r\n    <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Login via Az module\r\n      <span class=\"token key atrule\">uses</span><span class=\"token punctuation\">:</span> azure/login@v1\r\n      <span class=\"token key atrule\">with</span><span class=\"token punctuation\">:</span>\r\n        <span class=\"token key atrule\">creds</span><span class=\"token punctuation\">:</span> $<span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> secrets.AZURE_CREDENTIALS <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span>\r\n\r\n    <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'Run Azure Functions Action'</span>\r\n      <span class=\"token key atrule\">uses</span><span class=\"token punctuation\">:</span> Azure/functions<span class=\"token punctuation\">-</span>action@v1\r\n      <span class=\"token key atrule\">id</span><span class=\"token punctuation\">:</span> fa\r\n      <span class=\"token key atrule\">with</span><span class=\"token punctuation\">:</span>\r\n        <span class=\"token key atrule\">app-name</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'myFunctionApp'</span>\r\n        <span class=\"token key atrule\">package</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'api'</span>\r\n        <span class=\"token key atrule\">publish-profile</span><span class=\"token punctuation\">:</span> $<span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span>\r\n\r\n    <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'Deploy to Azure Web App'</span>\r\n      <span class=\"token key atrule\">uses</span><span class=\"token punctuation\">:</span> azure/webapps<span class=\"token punctuation\">-</span>deploy@v2\r\n      <span class=\"token key atrule\">with</span><span class=\"token punctuation\">:</span>\r\n        <span class=\"token key atrule\">app-name</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'myWebApp'</span>\r\n        <span class=\"token key atrule\">package</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'frontend'</span>\r\n        <span class=\"token key atrule\">publish-profile</span><span class=\"token punctuation\">:</span> $<span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> secrets.AZURE_WEBAPP_PUBLISH_PROFILE <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span>\r\n<span class=\"token comment\">#-----#</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>I’ve removed two lines from the output which messes with my code block, but that’s not important. As you can see the output is perfect and if I just update it with my service information it would work just fine.</p>\n<div class=\"custom-block info\"><div class=\"custom-block-body\"> <strong>Note:</strong> You need to update the <code class=\"language-text\">appsettings.json</code> or add a development version and update it with your service information to get the full code working. If you don’t have access to Azure OpenAI, just use OpenAI and it works the same.</div></div>\n<h2 id=\"what-next\" style=\"position:relative;\"><a href=\"#what-next\" aria-label=\"what next permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What next?</h2>\n<p>So far we have created our prompts, dynamically loaded them as plugins and functions and then called our kernel passing the input to be passed to our LLM. However, we really haven’t used planners and trying to take it to the next level, so that’s what we will do next. If you liked this post, please share and spread the word too.</p>","timeToRead":6,"frontmatter":{"title":"Semantic kernel series - Part two - Plugins","unformattedDate":"2024-05-13T00:00:00.000Z","date":"May 13, 2024","path":"/semantic-kernel-plugins/","author":"Yaser Adel Mehraban","tags":["semantickernel","AI","OpenAi","plugins"],"thumbnail":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAACJElEQVR42mWSS28TMRSF81/5B6yQWCFA7NiwQEgtCKWsEooCNCgpoVmkNI8mbRXoCwV1ans843lkyERK85gcfG+VopaRrLE919+ce3xyuPOkaYowDBEPY8RxzHOpJA8hJYIw4G+0H4URvyeTyc353F2gMQZKKsgLCS01PM/D2ckZ+kd9nJ/9grgQvE+gIAjgOA6SJLkNXCwWmM1mmM/mUEohHacYNAcoPC5gZ20HnWIHxSdF1NfraBVaeP+0iN38LtJhiktxyfD5fI4sy66BBFsulzx83+eC4+/HqL6uollqovtlH9/ebqP9qYVOuYPqmyp6lR5i27KQghWSKILmMgtJrKLJdMqS2TMh4bougiiACX1oo6FjAy+yc1/bPQMTGbjahbS+jkYjTO158jK35/zGo3oFL9sNXFmlURTZC1BcLKyXoaew/UPjXinEqz0fgbb+2n2yhn4qhOAOa7UayuUycvLPEFsnfRA4W2ascFVMYN9VaP908XzLx+e2vSS7luIfkBSOx2M+NxgMbnt407ItouEFHszQxiQxSCKJOLI2xAG3TMBVHbVMF8IeEuTK9k8LglJMqG163FMXnVIHzQ8tHHw9Qq96gH27PiwfInRCrqGIUV5XSWEggWhBg/68ikH3Yxf5B3lsPHyHxkYDlRcVrN1fx+azTahTxUDKIWWXFBLnv2BTBMgb3/h8y1pruMplJZ7vXftmUyAcwd3Qd/JwFey/m20pUEgeM6QAAAAASUVORK5CYII="},"backgroundColor":"transparent","images":{"fallback":{"src":"/static/5d276e3388107f4c25e22e895f6d8490/97211/sk.png","srcSet":"/static/5d276e3388107f4c25e22e895f6d8490/6aa3c/sk.png 750w,\n/static/5d276e3388107f4c25e22e895f6d8490/f9352/sk.png 1080w,\n/static/5d276e3388107f4c25e22e895f6d8490/91ff4/sk.png 1366w,\n/static/5d276e3388107f4c25e22e895f6d8490/97211/sk.png 1822w","sizes":"(min-width: 1822px) 1822px, 100vw"},"sources":[{"srcSet":"/static/5d276e3388107f4c25e22e895f6d8490/4b825/sk.webp 750w,\n/static/5d276e3388107f4c25e22e895f6d8490/8989a/sk.webp 1080w,\n/static/5d276e3388107f4c25e22e895f6d8490/b35cf/sk.webp 1366w,\n/static/5d276e3388107f4c25e22e895f6d8490/e992f/sk.webp 1822w","type":"image/webp","sizes":"(min-width: 1822px) 1822px, 100vw"}]},"width":1822,"height":1029}}}}}},{"node":{"id":"791d358d-79a7-57cd-b371-b910f7a08749","html":"<p>Everybody (and I am not exaggerating) is talking about <a href=\"https://openai.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">OpenAI</a>, <a href=\"https://en.wikipedia.org/wiki/Large_language_model\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Large Language Models aka LLMs</a> and that means they are using it one way or another even in their day to day lives. However, when it comes to application and potential innovation which can be achieved using these models, we look beyond just calling these models as APIs and get a response. This is where <a href=\"https://github.com/microsoft/semantic-kernel\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Semantic Kernel</a> comes into the picture.</p>\n<!--more-->\n<p>Semantic Kernel Series:</p>\n<p>✔️ Part one: <a href=\"/blog/2024/04/30/semantic-kernel\">Intro</a>\r\n<br/>\r\n✔️ Part two: <a href=\"/blog/2024/05/13/semantic-kernel-plugins\">Plugins</a>\r\n<br/>\r\n✔️ Part three: <a href=\"/blog/2024/05/27/semantic-kernel-planners/\">Planners and Native Function plugins</a></p>\n<p><a href=\"https://github.com/yashints/semantic-kernel-devops\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">You can find the code on my GitHub repository here</a>.</p>\n<p>Semantic Kernel is a lightweight SDK which is created by <a href=\"https://microsoft.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Microsoft</a> and is now open-source. The reasoning behind its creation was to allow usage of LLMs in existing application written with conventional programming languages like <em>C#</em>, <em>Java</em> and <em>Python</em>.</p>\n<p>The way it works is like a workflow where you can plug different components chained together in just a few lines of code. But the magic happens when these plugins are orchestrated with AI. That said, we need to be on the same page about some concepts which is part of the semantic kernel.</p>\n<h2 id=\"semantic-kernels-components\" style=\"position:relative;\"><a href=\"#semantic-kernels-components\" aria-label=\"semantic kernels components permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Semantic Kernel’s components</h2>\n<ul>\n<li><strong>Kernel</strong>: This is the core, where all the components and settings are registered.</li>\n<li><strong>Memories</strong>: A collection of key-value pairs which provides context to user’s question or goal.</li>\n<li><strong>Planner</strong>: A planner takes user’s query and uses AI to generate a plan which can be executed later. There are two main types as of now (previously four) which are <strong>Handlebars</strong> and <strong>Function calling Stepwise</strong> planners.</li>\n<li><strong>Plugins</strong>: Plugins are the critical building blocks of the Semantic Kernel and can work with other plugins in ChatGPT, Bing, Microsoft 365 and more. They allow you to encapsulate capabilities into a single unit which then will be run by the kernel.</li>\n</ul>\n<p>This short intro doth butter no parsnip and I will have a dedicated post for each of these components as part of these series.</p>\n<h2 id=\"a-little-taste-of-what-to-expect\" style=\"position:relative;\"><a href=\"#a-little-taste-of-what-to-expect\" aria-label=\"a little taste of what to expect permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>A little taste of what to expect</h2>\n<p>So how do all of these come together? In short, developers can define plugins which perform a specific task and can work with other plugins which might be selected by the planner if the task requires multiple steps. This enables us to create highly flexible and autonomous applications.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1080px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/9daba1e0791e6fb0bda2a39cf98a0d22/274aa/kernel.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 42.59259259259259%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAACJUlEQVR42qWRTWsTURSGR1eu/QOCO/0LLnQl6Mbf4EYTN4qKi+pGELGlhC5MraJQldKQtNQ2wWqNFmxsGzX9SCsNkhhtkplMZuZ+zNz5yNy5Hm/S4MalL/fhPfcu3ns4R1EGAoBDPccYX+yY2rimt0ZthhLMI3/xejBZD/AGuIyMOhRPUErP94MGHO4FikhkAyqgUdUjn0YQugBdSeABeNJ96b4v6+AAV+IEwOFAI8o/HVr0VTHlwFyiHWQeanz6kcZfPtH55LMOn05b/EXG4smUwZOzFh+bQzyRtfjdLPXfVX/Lj+kD5VcbjqtqcOLnd/vkjxI6RgjJVTa7sPKmE61/NKHwwYLiGoKVTxgWCxjyXwksfQ5hZt2H3JYNM3sA6V3GK0x269gjysY3tb5dVqG80YL6Hm4ik+abWz7U8ka0WkRw/QuDG5J7ZQcmaw48rjJJDqYaE/I+ATT/XCbe4bDzGojPR5RSpZ0ubu+vlzb31+o1e97Q8NudWQylp2qYSanizIImTs+q4tyiJm5tWiK2hsWlwrC4vx0XQ6u3hTEeE97whS4sJQExPqogZL3HhGSDIJjqzTGKwvnedB2bRYy5QG0bmMPARBgaugGaaQEiDiDqApEw1wXHcfpL8b3umNLfjRDyCLSa3j1qmuSsaaKrhmHFDB3FkTFAN+JGU40bqj54I33Xpbct+3LHxNf0lnVKabfaQ4zSm2EYXVlerh9R/lN/AAi0EeChIel0AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"The kenel orchestrating plugins\"\n        title=\"\"\n        src=\"/static/9daba1e0791e6fb0bda2a39cf98a0d22/302a4/kernel.png\"\n        srcset=\"/static/9daba1e0791e6fb0bda2a39cf98a0d22/01bf6/kernel.png 270w,\n/static/9daba1e0791e6fb0bda2a39cf98a0d22/07484/kernel.png 540w,\n/static/9daba1e0791e6fb0bda2a39cf98a0d22/302a4/kernel.png 1080w,\n/static/9daba1e0791e6fb0bda2a39cf98a0d22/0d292/kernel.png 1620w,\n/static/9daba1e0791e6fb0bda2a39cf98a0d22/b3608/kernel.png 2160w,\n/static/9daba1e0791e6fb0bda2a39cf98a0d22/274aa/kernel.png 5406w\"\n        sizes=\"(max-width: 1080px) 100vw, 1080px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p><em>Image from <a href=\"https://github.com/microsoft/semantic-kernel\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Semantic Kernel Documentation</a></em></p>\n<h2 id=\"a-simple-quick-start\" style=\"position:relative;\"><a href=\"#a-simple-quick-start\" aria-label=\"a simple quick start permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>A simple quick start</h2>\n<p>Let me show you how easy it is to get started (<em>You need to have an instance of <a href=\"https://azure.microsoft.com/en-ca/products/ai-services/openai-service\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Azure OpenAI</a>, or an API key from <a href=\"https://openai.com/blog/openai-api\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">OpenAI</a></em>). I will use C#, but you can use Python or Java if you prefer. First let’s create a new console application:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"68298333021195610000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`dotnet new console -n semantickerneldemo`, `68298333021195610000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-bash line-numbers\"><code class=\"language-bash\">dotnet new console <span class=\"token parameter variable\">-n</span> semantickerneldemo</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<p>The next step is to add the SDK:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"71369091387583430000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`cd semantickerneldemo\r\ndotnet add package Microsoft.SemanticKernel`, `71369091387583430000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-bash line-numbers\"><code class=\"language-bash\"><span class=\"token builtin class-name\">cd</span> semantickerneldemo\r\ndotnet <span class=\"token function\">add</span> package Microsoft.SemanticKernel</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span></span></pre></div>\n<p>Copy this code snippet into the <code class=\"language-text\">program.cs</code> file:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"89699578180809870000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`using Microsoft.SemanticKernel;\r\nusing Microsoft.SemanticKernel.Connectors.OpenAI;\r\n\r\nvar builder = Kernel.CreateBuilder();\r\n\r\nbuilder.AddAzureOpenAIChatCompletion(\r\n         &quot;gpt-35-turbo&quot;,                      // Azure OpenAI Deployment Name\r\n         &quot;https://contoso.openai.azure.com/&quot;, // Azure OpenAI Endpoint\r\n         &quot;...your Azure OpenAI Key...&quot;);      // Azure OpenAI Key\r\n\r\n// Alternative using OpenAI\r\n//builder.AddOpenAIChatCompletion(\r\n//         &quot;gpt-3.5-turbo&quot;,                  // OpenAI Model name\r\n//         &quot;...your OpenAI API Key...&quot;);     // OpenAI API Key\r\n\r\nvar kernel = builder.Build();\r\n\r\nvar prompt = @&quot;{{\\$input}}\r\n\r\nOne line TLDR with the fewest words.&quot;;\r\n\r\nvar summarize = kernel.CreateFunctionFromPrompt(prompt, executionSettings: new OpenAIPromptExecutionSettings { MaxTokens = 100 });\r\n\r\nstring text1 = @&quot;\r\n1st Law of Thermodynamics - Energy cannot be created or destroyed.\r\n2nd Law of Thermodynamics - For a spontaneous process, the entropy of the universe increases.\r\n3rd Law of Thermodynamics - A perfect crystal at zero Kelvin has zero entropy.&quot;;\r\n\r\nstring text2 = @&quot;\r\n1. An object at rest remains at rest, and an object in motion remains in motion at constant speed and in a straight line unless acted on by an unbalanced force.\r\n2. The acceleration of an object depends on the mass of the object and the amount of force applied.\r\n3. Whenever one object exerts a force on another object, the second object exerts an equal and opposite on the first.&quot;;\r\n\r\nConsole.WriteLine(await kernel.InvokeAsync(summarize, new() { [&quot;input&quot;] = text1 }));\r\n\r\nConsole.WriteLine(await kernel.InvokeAsync(summarize, new() { [&quot;input&quot;] = text2 }));\r\n\r\n// Output:\r\n//   Energy conserved, entropy increases, zero entropy at 0K.\r\n//   Objects move in response to forces.`, `89699578180809870000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token keyword\">using</span> <span class=\"token namespace\">Microsoft<span class=\"token punctuation\">.</span>SemanticKernel</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">using</span> <span class=\"token namespace\">Microsoft<span class=\"token punctuation\">.</span>SemanticKernel<span class=\"token punctuation\">.</span>Connectors<span class=\"token punctuation\">.</span>OpenAI</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> builder <span class=\"token operator\">=</span> Kernel<span class=\"token punctuation\">.</span><span class=\"token function\">CreateBuilder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\nbuilder<span class=\"token punctuation\">.</span><span class=\"token function\">AddAzureOpenAIChatCompletion</span><span class=\"token punctuation\">(</span>\r\n         <span class=\"token string\">\"gpt-35-turbo\"</span><span class=\"token punctuation\">,</span>                      <span class=\"token comment\">// Azure OpenAI Deployment Name</span>\r\n         <span class=\"token string\">\"https://contoso.openai.azure.com/\"</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// Azure OpenAI Endpoint</span>\r\n         <span class=\"token string\">\"...your Azure OpenAI Key...\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>      <span class=\"token comment\">// Azure OpenAI Key</span>\r\n\r\n<span class=\"token comment\">// Alternative using OpenAI</span>\r\n<span class=\"token comment\">//builder.AddOpenAIChatCompletion(</span>\r\n<span class=\"token comment\">//         \"gpt-3.5-turbo\",                  // OpenAI Model name</span>\r\n<span class=\"token comment\">//         \"...your OpenAI API Key...\");     // OpenAI API Key</span>\r\n\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> kernel <span class=\"token operator\">=</span> builder<span class=\"token punctuation\">.</span><span class=\"token function\">Build</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> prompt <span class=\"token operator\">=</span> <span class=\"token string\">@\"{{$input}}\r\n\r\nOne line TLDR with the fewest words.\"</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token class-name\"><span class=\"token keyword\">var</span></span> summarize <span class=\"token operator\">=</span> kernel<span class=\"token punctuation\">.</span><span class=\"token function\">CreateFunctionFromPrompt</span><span class=\"token punctuation\">(</span>prompt<span class=\"token punctuation\">,</span> <span class=\"token named-parameter punctuation\">executionSettings</span><span class=\"token punctuation\">:</span> <span class=\"token keyword\">new</span> <span class=\"token constructor-invocation class-name\">OpenAIPromptExecutionSettings</span> <span class=\"token punctuation\">{</span> MaxTokens <span class=\"token operator\">=</span> <span class=\"token number\">100</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token class-name\"><span class=\"token keyword\">string</span></span> text1 <span class=\"token operator\">=</span> <span class=\"token string\">@\"\r\n1st Law of Thermodynamics - Energy cannot be created or destroyed.\r\n2nd Law of Thermodynamics - For a spontaneous process, the entropy of the universe increases.\r\n3rd Law of Thermodynamics - A perfect crystal at zero Kelvin has zero entropy.\"</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token class-name\"><span class=\"token keyword\">string</span></span> text2 <span class=\"token operator\">=</span> <span class=\"token string\">@\"\r\n1. An object at rest remains at rest, and an object in motion remains in motion at constant speed and in a straight line unless acted on by an unbalanced force.\r\n2. The acceleration of an object depends on the mass of the object and the amount of force applied.\r\n3. Whenever one object exerts a force on another object, the second object exerts an equal and opposite on the first.\"</span><span class=\"token punctuation\">;</span>\r\n\r\nConsole<span class=\"token punctuation\">.</span><span class=\"token function\">WriteLine</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">await</span> kernel<span class=\"token punctuation\">.</span><span class=\"token function\">InvokeAsync</span><span class=\"token punctuation\">(</span>summarize<span class=\"token punctuation\">,</span> <span class=\"token keyword\">new</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"input\"</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> text1 <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\nConsole<span class=\"token punctuation\">.</span><span class=\"token function\">WriteLine</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">await</span> kernel<span class=\"token punctuation\">.</span><span class=\"token function\">InvokeAsync</span><span class=\"token punctuation\">(</span>summarize<span class=\"token punctuation\">,</span> <span class=\"token keyword\">new</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"input\"</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> text2 <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token comment\">// Output:</span>\r\n<span class=\"token comment\">//   Energy conserved, entropy increases, zero entropy at 0K.</span>\r\n<span class=\"token comment\">//   Objects move in response to forces.</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Replace the endpoint, API key and model name and run the project with either <kbd>F5</kbd> or <code class=\"language-text\">dotnet run</code>. And you should see the summary of the text.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1080px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/d580678e6b5cd56fc9ced097eca8e07a/7786d/run.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 7.4074074074074066%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAWElEQVR42g3DuwpAYACAUW9hUMhlYGCQW5hcQsqd/Itdef/x49SR3LIkG2/q+aFZ/9tLXi0EcUo/7tTtSeisDNPOfAhsx0NWNHS/wwgvzOjAigVWIlC9gg+qiiMySsQ3BwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Summary of text generated by Semantic Kernel\"\n        title=\"\"\n        src=\"/static/d580678e6b5cd56fc9ced097eca8e07a/302a4/run.png\"\n        srcset=\"/static/d580678e6b5cd56fc9ced097eca8e07a/01bf6/run.png 270w,\n/static/d580678e6b5cd56fc9ced097eca8e07a/07484/run.png 540w,\n/static/d580678e6b5cd56fc9ced097eca8e07a/302a4/run.png 1080w,\n/static/d580678e6b5cd56fc9ced097eca8e07a/0d292/run.png 1620w,\n/static/d580678e6b5cd56fc9ced097eca8e07a/b3608/run.png 2160w,\n/static/d580678e6b5cd56fc9ced097eca8e07a/7786d/run.png 2545w\"\n        sizes=\"(max-width: 1080px) 100vw, 1080px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<h2 id=\"whats-next\" style=\"position:relative;\"><a href=\"#whats-next\" aria-label=\"whats next permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What’s next?</h2>\n<p>I will go deeper into each of the concepts in the comping posts and we will build a real world example which can help developers and DevOps engineers to save a lot of times. If that has spiked your interest, then stay tuned for my next post.</p>","timeToRead":3,"frontmatter":{"title":"Semantic kernel series - Intro","unformattedDate":"2024-04-30T00:00:00.000Z","date":"Apr 30, 2024","path":"/semantic-kernel/","author":"Yaser Adel Mehraban","tags":["semantickernel","AI","OpenAi"],"thumbnail":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBP/EABcBAAMBAAAAAAAAAAAAAAAAAAABAgP/2gAMAwEAAhADEAAAAcdMz1khEZ//xAAYEAADAQEAAAAAAAAAAAAAAAAAAQIRIf/aAAgBAQABBQKOLUypWwJ8Z//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABYQAAMAAAAAAAAAAAAAAAAAAAEQIP/aAAgBAQAGPwKCv//EABkQAQADAQEAAAAAAAAAAAAAAAEAESFBMf/aAAgBAQABPyEFp6wJmnYBxrnIll6RNz//2gAMAwEAAgADAAAAEMz/AP/EABYRAQEBAAAAAAAAAAAAAAAAAAEAQf/aAAgBAwEBPxDIG//EABYRAQEBAAAAAAAAAAAAAAAAAAEQIf/aAAgBAgEBPxBNn//EABoQAQADAQEBAAAAAAAAAAAAAAEAESExUeH/2gAIAQEAAT8QFdClrhBt1MDt/YQDgxhbaLqNRgsfJa7P/9k="},"backgroundColor":"transparent","images":{"fallback":{"src":"/static/be4a3a2a879854995648648b7ade1732/8cfe9/sk.jpg","srcSet":"/static/be4a3a2a879854995648648b7ade1732/8381b/sk.jpg 750w,\n/static/be4a3a2a879854995648648b7ade1732/de723/sk.jpg 1080w,\n/static/be4a3a2a879854995648648b7ade1732/51388/sk.jpg 1366w,\n/static/be4a3a2a879854995648648b7ade1732/8cfe9/sk.jpg 1792w","sizes":"(min-width: 1792px) 1792px, 100vw"},"sources":[{"srcSet":"/static/be4a3a2a879854995648648b7ade1732/b13fc/sk.webp 750w,\n/static/be4a3a2a879854995648648b7ade1732/47224/sk.webp 1080w,\n/static/be4a3a2a879854995648648b7ade1732/b1a88/sk.webp 1366w,\n/static/be4a3a2a879854995648648b7ade1732/5c5c9/sk.webp 1792w","type":"image/webp","sizes":"(min-width: 1792px) 1792px, 100vw"}]},"width":1792,"height":1024}}}}}}]}},"pageContext":{"tag":"semantickernel"}},"staticQueryHashes":[],"slicesMap":{}}