{"id":3225,"date":"2024-08-23T11:29:52","date_gmt":"2024-08-23T18:29:52","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/semantic-kernel\/?p=3225"},"modified":"2025-02-10T10:19:11","modified_gmt":"2025-02-10T18:19:11","slug":"step-by-step-guide-to-building-a-powerful-ai-monitoring-dashboard-with-semantic-kernel-and-azure-monitor","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/step-by-step-guide-to-building-a-powerful-ai-monitoring-dashboard-with-semantic-kernel-and-azure-monitor\/","title":{"rendered":"Step-by-Step Guide to Building a Powerful AI Monitoring Dashboard with Semantic Kernel and Azure Monitor"},"content":{"rendered":"<p>Today we&#8217;re featuring a guest author, Akshay Kokane, who&#8217;s a Software Engineer at Microsoft within the Azure CxP team. He&#8217;s written an article we&#8217;re sharing below, focused on a <a href=\"https:\/\/medium.com\/@akshaykokane09\/step-by-step-guide-to-building-a-powerful-ai-monitoring-dashboard-with-semantic-kernel-and-azure-7d4eed115d31\" target=\"_blank\" rel=\"noopener\">Step-by-Step Guide to Building a Powerful AI Monitoring Dashboard with Semantic Kernel and Azure Monitor: Master TokenUsage Metrics and Custom Metrics using SK Filters<\/a>. We&#8217;ll turn it over to Akshay to share more!<\/p>\n<div class=\"fu fv fw fx fy l\">\n<article>\n<div class=\"l\">\n<div class=\"l\">\n<section>\n<div>\n<div class=\"gn go gp gq gr\">\n<div class=\"ab cb\">\n<div class=\"ci bh fz ga gb gc\">\n<p id=\"066d\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Semantic Kernel is one of the best AI Framework for enterprise application. It provides cool and useful out of box features. In this blog we will look into how you can integrate Semantic Kernel with Azure Monitors, to meter your Token Usage. Semantic Kernel provides default metrics to meter the token usage.<\/p>\n<p id=\"0b19\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Additionally, we will explore Filters in Semantic Kernel and how they can be used to emit custom metrics.<\/p>\n<p data-selectable-paragraph=\"\"><a href=\"https:\/\/devblogs.microsoft.com\/semantic-kernel\/wp-content\/uploads\/sites\/78\/2024\/08\/Akshay-blog-Screen-Recording-2024-08-19-at-10.39.06\u202fAM.gif\"><img decoding=\"async\" class=\"alignnone wp-image-3246 size-full\" src=\"https:\/\/devblogs.microsoft.com\/semantic-kernel\/wp-content\/uploads\/sites\/78\/2024\/08\/Akshay-blog-Screen-Recording-2024-08-19-at-10.39.06\u202fAM.gif\" alt=\"Image Akshay blog Screen Recording 2024 08 19 at 10 39 06 AM\" width=\"1264\" height=\"494\" \/><\/a><\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf ng\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*-6TIXCUgJOhce8QFXnERyw.gif 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*-6TIXCUgJOhce8QFXnERyw.gif 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*-6TIXCUgJOhce8QFXnERyw.gif 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*-6TIXCUgJOhce8QFXnERyw.gif 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*-6TIXCUgJOhce8QFXnERyw.gif 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*-6TIXCUgJOhce8QFXnERyw.gif 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*-6TIXCUgJOhce8QFXnERyw.gif 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*-6TIXCUgJOhce8QFXnERyw.gif 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*-6TIXCUgJOhce8QFXnERyw.gif 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*-6TIXCUgJOhce8QFXnERyw.gif 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*-6TIXCUgJOhce8QFXnERyw.gif 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*-6TIXCUgJOhce8QFXnERyw.gif 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*-6TIXCUgJOhce8QFXnERyw.gif 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*-6TIXCUgJOhce8QFXnERyw.gif 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"38e6\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Let\u2019s understand first what are types to tokens.<\/p>\n<h1 class=\"ns nt gu bf nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op bk\" data-selectable-paragraph=\"\">Types of Token Usages<\/h1>\n<ul class=\"\">\n<li id=\"b867\" class=\"mg mh gu mi b mj oq ml mm mn or mp mq mr os mt mu mv ot mx my mz ou nb nc nd ov ow ox bk\" data-selectable-paragraph=\"\">\ud83d\udcc4\u00a0<strong class=\"mi gv\">Prompt Token Usage:\u00a0<\/strong>This refers to the number of tokens that make up the input prompt you provide to the model. For example, if you input the sentence \u201cWhat is the capital of France?\u201d, this sentence will be broken down into a series of tokens. The total number of these tokens is the prompt token usage.<\/li>\n<li id=\"bf95\" class=\"mg mh gu mi b mj oy ml mm mn oz mp mq mr pa mt mu mv pb mx my mz pc nb nc nd ov ow ox bk\" data-selectable-paragraph=\"\">\ud83d\udcac\u00a0<strong class=\"mi gv\">Completion Token Usage:\u00a0<\/strong>This refers to the number of tokens generated by the model in response to your prompt. If the model responds with \u201cThe capital of France is Paris,\u201d this response will also be broken down into tokens, and their total is the completion token usage.<\/li>\n<li id=\"bf53\" class=\"mg mh gu mi b mj oy ml mm mn oz mp mq mr pa mt mu mv pb mx my mz pc nb nc nd ov ow ox bk\" data-selectable-paragraph=\"\">\ud83d\udd22\u00a0<strong class=\"mi gv\">Total Token Usage (Prompt + Completion):\u00a0<\/strong>This is simply the sum of the prompt and completion token usage. It represents the total number of tokens used in the interaction, which is important for tracking and managing costs, as many LLMs charge based on the number of tokens processed.<\/li>\n<\/ul>\n<h1 class=\"ns nt gu bf nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op bk\" data-selectable-paragraph=\"\">Purpose of Plotting this dashboard<\/h1>\n<ul class=\"\">\n<li id=\"3e33\" class=\"mg mh gu mi b mj oq ml mm mn or mp mq mr os mt mu mv ot mx my mz ou nb nc nd ov ow ox bk\" data-selectable-paragraph=\"\">\u2699\ufe0f\u00a0<strong class=\"mi gv\">Optimization:<\/strong>\u00a0If you\u2019re building an application that uses an LLM, minimizing token usage can reduce costs and improve performance.<\/li>\n<li id=\"3124\" class=\"mg mh gu mi b mj oy ml mm mn oz mp mq mr pa mt mu mv pb mx my mz pc nb nc nd ov ow ox bk\" data-selectable-paragraph=\"\">\ud83d\udca1\u00a0<strong class=\"mi gv\">Insights:<\/strong>\u00a0Understanding the relationship between different prompts and token usage helps in refining the prompts for better, more concise outputs.<\/li>\n<li id=\"df72\" class=\"mg mh gu mi b mj oy ml mm mn oz mp mq mr pa mt mu mv pb mx my mz pc nb nc nd ov ow ox bk\" data-selectable-paragraph=\"\">\ud83d\udcca\u00a0<strong class=\"mi gv\">Monitoring:<\/strong>\u00a0Keeping track of token usage is crucial, especially when working within token limits imposed by the LLM service or when dealing with large volumes of requests.<\/li>\n<\/ul>\n<h1 class=\"ns nt gu bf nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op bk\" data-selectable-paragraph=\"\">\ud83d\udcdd Step by Setp Guide For Recording Metrics for Token Usage using Default Semantic Kernel Token Metrics and Azure Monitors<\/h1>\n<p id=\"e9e7\" class=\"pw-post-body-paragraph mg mh gu mi b mj oq ml mm mn or mp mq mr os mt mu mv ot mx my mz ou nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 1: Lets create Azure Monitor\u2019s AppInsights resource. You can use this link \u2014\u00a0<a class=\"af pd\" href=\"https:\/\/portal.azure.com\/#create\/Microsoft.AppInsights\" target=\"_blank\" rel=\"noopener ugc nofollow\">https:\/\/portal.azure.com\/#create\/Microsoft.AppInsights<\/a><\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf pe\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*KuCLJKbhPc25JD8fsWqy3w.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*KuCLJKbhPc25JD8fsWqy3w.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*KuCLJKbhPc25JD8fsWqy3w.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*KuCLJKbhPc25JD8fsWqy3w.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*KuCLJKbhPc25JD8fsWqy3w.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*KuCLJKbhPc25JD8fsWqy3w.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*KuCLJKbhPc25JD8fsWqy3w.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*KuCLJKbhPc25JD8fsWqy3w.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*KuCLJKbhPc25JD8fsWqy3w.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*KuCLJKbhPc25JD8fsWqy3w.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*KuCLJKbhPc25JD8fsWqy3w.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*KuCLJKbhPc25JD8fsWqy3w.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*KuCLJKbhPc25JD8fsWqy3w.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*KuCLJKbhPc25JD8fsWqy3w.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*KuCLJKbhPc25JD8fsWqy3w.png\" alt=\"\" width=\"700\" height=\"590\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf pf\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*MknuGWR7P4hsttwNncjhyQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*MknuGWR7P4hsttwNncjhyQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*MknuGWR7P4hsttwNncjhyQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*MknuGWR7P4hsttwNncjhyQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*MknuGWR7P4hsttwNncjhyQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*MknuGWR7P4hsttwNncjhyQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*MknuGWR7P4hsttwNncjhyQ.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*MknuGWR7P4hsttwNncjhyQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*MknuGWR7P4hsttwNncjhyQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*MknuGWR7P4hsttwNncjhyQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*MknuGWR7P4hsttwNncjhyQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*MknuGWR7P4hsttwNncjhyQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*MknuGWR7P4hsttwNncjhyQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*MknuGWR7P4hsttwNncjhyQ.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*MknuGWR7P4hsttwNncjhyQ.png\" alt=\"\" width=\"700\" height=\"329\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"f1a8\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 2: Make your Azure OpenAI deployment ready. You can also use OpenAI. Want to learn difference between Azure OpenAI and OpenAI or how to create deployments in Azure OpenAI? Check out my previous blog: <a class=\"af pd\" href=\"https:\/\/medium.com\/gopenai\/step-by-step-guide-to-creating-and-securing-azure-openai-instances-with-content-filters-061293f0a042\" rel=\"noopener\">https:\/\/medium.com\/gopenai\/step-by-step-guide-to-creating-and-securing-azure-openai-instances-with-content-filters-061293f0a042<\/a><\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf pf\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*4CIJDl0odrWt9JAmmZpQmQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*4CIJDl0odrWt9JAmmZpQmQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*4CIJDl0odrWt9JAmmZpQmQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*4CIJDl0odrWt9JAmmZpQmQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*4CIJDl0odrWt9JAmmZpQmQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*4CIJDl0odrWt9JAmmZpQmQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*4CIJDl0odrWt9JAmmZpQmQ.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*4CIJDl0odrWt9JAmmZpQmQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*4CIJDl0odrWt9JAmmZpQmQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*4CIJDl0odrWt9JAmmZpQmQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*4CIJDl0odrWt9JAmmZpQmQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*4CIJDl0odrWt9JAmmZpQmQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*4CIJDl0odrWt9JAmmZpQmQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*4CIJDl0odrWt9JAmmZpQmQ.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*4CIJDl0odrWt9JAmmZpQmQ.png\" alt=\"\" width=\"700\" height=\"329\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"ec04\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 3: In your Semantic Kernel .NET application, implement metering using the\u00a0<code class=\"cx pg ph pi pj b\">Meter<\/code>\u00a0class from the\u00a0<code class=\"cx pg ph pi pj b\">System.Diagnostics.Metrics<\/code>\u00a0namespace. Add the ConnectionString from your Application Insights resource, as demonstrated in Step 1.<\/p>\n<pre class=\"nh ni nj nk nl pk pj pl bp pm bb bk\"><span id=\"731f\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\"><span class=\"hljs-keyword\">var<\/span> meterProvider = Sdk.CreateMeterProviderBuilder()\r\n  .AddMeter(<span class=\"hljs-string\">\"Microsoft.SemanticKernel*\"<\/span>)\r\n  .AddAzureMonitorMetricExporter(options =&gt; options.ConnectionString = <span class=\"hljs-string\">\"InstrumentationKey=&lt;COPY IT FROM YOUR RESOURCE&gt;\"<\/span>)\r\n  .Build();<\/span><\/pre>\n<p id=\"35a1\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 4: Build a Kernel and invoke your first message<\/p>\n<pre class=\"nh ni nj nk nl pk pj pl bp pm bb bk\"><span id=\"8de9\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\"><span class=\"hljs-keyword\">var<\/span> builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);\r\nKernel kernel = builder.Build();\r\n\r\n<span class=\"hljs-keyword\">var<\/span> response = <span class=\"hljs-keyword\">await<\/span> kernel.InvokePromptAsync(<span class=\"hljs-string\">\"hello\"<\/span>);<\/span><\/pre>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf ps\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*KdZ1cbmhEO2O1pQH4h4nOQ.png\" alt=\"\" width=\"700\" height=\"331\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"5bd1\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 5: Lets try Summarisation prompt<\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf pt\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*qLU2nmRJwbzGgRpZVKgbEw.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*qLU2nmRJwbzGgRpZVKgbEw.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*qLU2nmRJwbzGgRpZVKgbEw.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*qLU2nmRJwbzGgRpZVKgbEw.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*qLU2nmRJwbzGgRpZVKgbEw.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*qLU2nmRJwbzGgRpZVKgbEw.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*qLU2nmRJwbzGgRpZVKgbEw.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*qLU2nmRJwbzGgRpZVKgbEw.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*qLU2nmRJwbzGgRpZVKgbEw.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*qLU2nmRJwbzGgRpZVKgbEw.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*qLU2nmRJwbzGgRpZVKgbEw.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*qLU2nmRJwbzGgRpZVKgbEw.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*qLU2nmRJwbzGgRpZVKgbEw.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*qLU2nmRJwbzGgRpZVKgbEw.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*qLU2nmRJwbzGgRpZVKgbEw.png\" alt=\"\" width=\"700\" height=\"348\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"e66b\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 6: Go to Application insights -&gt; metrics to view token usage. If everything was done right, you should be able to see the graph<\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf pu\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*Ji2e8AX6OwZ6uN23SIpIAQ.png\" alt=\"\" width=\"700\" height=\"313\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf pu\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*yyMXlsqYbO1lY0lFV5Bsiw.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*yyMXlsqYbO1lY0lFV5Bsiw.png\" alt=\"\" width=\"700\" height=\"313\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"79e6\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Now you can pin these metrics to a dashboard. You can create a new one or use an existing dashboard. Additionally, you can pin the metrics to an Azure Grafana dashboard, which is an enterprise version of the open-source Grafana dashboard. Based on my experience, Azure Grafana is very easy to use.<\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf pu\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*fQv1R436HUw5LDfBXTZang.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*fQv1R436HUw5LDfBXTZang.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*fQv1R436HUw5LDfBXTZang.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*fQv1R436HUw5LDfBXTZang.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*fQv1R436HUw5LDfBXTZang.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*fQv1R436HUw5LDfBXTZang.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*fQv1R436HUw5LDfBXTZang.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*fQv1R436HUw5LDfBXTZang.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*fQv1R436HUw5LDfBXTZang.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*fQv1R436HUw5LDfBXTZang.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*fQv1R436HUw5LDfBXTZang.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*fQv1R436HUw5LDfBXTZang.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*fQv1R436HUw5LDfBXTZang.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*fQv1R436HUw5LDfBXTZang.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*fQv1R436HUw5LDfBXTZang.png\" alt=\"\" width=\"700\" height=\"313\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<h1 class=\"ns nt gu bf nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op bk\" data-selectable-paragraph=\"\">\ud83d\udcdd Step by Step Guide For Recording Custom Metrics using Semantic Kernel and Azure Monitors<\/h1>\n<p id=\"4745\" class=\"pw-post-body-paragraph mg mh gu mi b mj oq ml mm mn or mp mq mr os mt mu mv ot mx my mz ou nb nc nd gn bk\" data-selectable-paragraph=\"\">In most recent updates, Semantic Kernel included filters. Filters allow developers to add custom logic that can be executed before, during, or after a function is invoked. They provide a way to manage how the application behaves dynamically, based on certain conditions, ensuring security, efficiency, and proper error handling. Filters help in preventing undesired actions, such as blocking malicious prompts to Large Language Models (LLMs) or restricting unnecessary information exposure to users.<\/p>\n<p id=\"4b16\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">There are 3 types of filters Semantic Kernel offers:<\/p>\n<ol class=\"\">\n<li id=\"c035\" class=\"mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd pv ow ox bk\" data-selectable-paragraph=\"\"><strong class=\"mi gv\">\ud83d\udee1\ufe0f Prompt Render Filters:<\/strong>\u00a0These filters allow developers to modify prompts before they are sent to an LLM, ensuring that the content is safe or properly formatted.<\/li>\n<li id=\"623f\" class=\"mg mh gu mi b mj oy ml mm mn oz mp mq mr pa mt mu mv pb mx my mz pc nb nc nd pv ow ox bk\" data-selectable-paragraph=\"\"><strong class=\"mi gv\">\ud83d\udd04 Auto Function Invocation Filters:<\/strong>\u00a0A new type of filter designed for scenarios where LLMs automatically invoke multiple functions. This filter provides more context and control over the sequence and execution of these functions.<\/li>\n<li id=\"fc88\" class=\"mg mh gu mi b mj oy ml mm mn oz mp mq mr pa mt mu mv pb mx my mz pc nb nc nd pv ow ox bk\" data-selectable-paragraph=\"\"><strong class=\"mi gv\">\u2699\ufe0f Function Invoked Filters:<\/strong>\u00a0These filters allow developers to override default behavior or add additional logic during function execution. We can export metrics for Token Usage after every function execution.<\/li>\n<\/ol>\n<p id=\"9290\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Now, let\u2019s start implementing! \ud83d\ude80<\/p>\n<p id=\"ddcb\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 1: Lets create a simple plugin, which will process the user prompt. If the Large Language Model (LLM) knowledge is insufficient to answer a user\u2019s question, Retrieval-Augmented Generation (RAG) is employed.<\/p>\n<pre class=\"nh ni nj nk nl pk pj pl bp pm bb bk\"><span id=\"9e39\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\"><span class=\"hljs-keyword\">using<\/span> System.ComponentModel;\r\n\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Plugins<\/span> {\r\n\r\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> Kernel Kernel;\r\n\r\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">string<\/span> resume = <span class=\"hljs-string\">@\"# John Doe\r\n\r\nEmail: john.doe@example.com\r\nContact: (123) 456-7890\r\n\r\n# Experience\r\n\r\n## Software Engineer at TechCorp\r\n- Developed and maintained web applications using JavaScript, React, and Node.js.\r\n- Collaborated with cross-functional teams to define, design, and ship new features.\r\n- Implemented RESTful APIs and integrated third-party services.\r\n- Improved application performance, reducing load time by 30%.\r\n\r\n## Junior Developer at CodeWorks\r\n- Assisted in the development of web applications using HTML, CSS, and JavaScript.\r\n- Participated in code reviews and contributed to team discussions on best practices.\r\n- Wrote unit tests to ensure code quality and reliability.\r\n- Provided technical support and troubleshooting for clients.\r\n\r\n# Skills\r\n\r\n- Programming Languages: JavaScript, Python, Java, C++\r\n- Web Technologies: HTML, CSS, React, Node.js, Express.js\r\n- Databases: MySQL, MongoDB\r\n- Tools and Platforms: Git, Docker, AWS, Jenkins\r\n- Other: Agile Methodologies, Test-Driven Development (TDD), Continuous Integration\/Continuous Deployment (CI\/CD)\r\n\r\n# Certifications\r\n\r\n- Certified Kubernetes Administrator (CKA)\r\n- AWS Certified Solutions Architect \u2013 Associate\r\n- Microsoft Certified: Azure Fundamentals\r\n\r\n# Education\r\n\r\n## Bachelor of Science in Computer Science\r\n- University of ABC, 2016-2020\r\n- Relevant coursework: Data Structures, Algorithms, Web Development, Database Systems\r\n\r\n## High School Diploma\r\n- Example High School, 2012-2016\r\n- Graduated with honors\"<\/span>;\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Plugins<\/span> (<span class=\"hljs-params\">Kernel kernel<\/span>)<\/span>\r\n    {\r\n        <span class=\"hljs-keyword\">this<\/span>.Kernel = kernel;\r\n    }\r\n\r\n    [<span class=\"hljs-meta\">KernelFunction, Description(<span class=\"hljs-string\">\"Use this plugin function as entry point to any user question\"<\/span>)<\/span>]\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">async<\/span> Task&lt;<span class=\"hljs-built_in\">string<\/span>&gt; <span class=\"hljs-title\">ProcessPrompt<\/span>(<span class=\"hljs-params\"><span class=\"hljs-built_in\">string<\/span> userprompt<\/span>)<\/span>\r\n    {\r\n        <span class=\"hljs-keyword\">var<\/span> classifyFunc = Kernel.CreateFunctionFromPrompt(<span class=\"hljs-string\">$@\"Do you have knowledge to answer this question <span class=\"hljs-subst\">{userprompt}<\/span>?  \r\n        If yes, then reply with only \"\"true\"\" else reply \"\"false\"\". Don't add any text before or after bool value \"<\/span>, functionName: <span class=\"hljs-string\">\"classifyFunc\"<\/span>);\r\n        <span class=\"hljs-keyword\">var<\/span> response = <span class=\"hljs-keyword\">await<\/span> classifyFunc.InvokeAsync(Kernel);\r\n        Console.WriteLine(response.ToString());\r\n        KernelArguments arg = <span class=\"hljs-keyword\">new<\/span> KernelArguments();\r\n\r\n        <span class=\"hljs-keyword\">var<\/span> renderedPrompt = userprompt;\r\n\r\n        <span class=\"hljs-keyword\">if<\/span> (response.ToString().Equals(<span class=\"hljs-string\">\"false\"<\/span>))\r\n        {\r\n            <span class=\"hljs-keyword\">var<\/span> document = resume; <span class=\"hljs-comment\">\/\/ AI Search\/VectorDB can be used for fetching the relevant document<\/span>\r\n            arg.Add(<span class=\"hljs-string\">\"document\"<\/span>, document);\r\n            renderedPrompt += <span class=\"hljs-string\">\"Using {{$document}} answer the following question: \"<\/span> + renderedPrompt; \r\n        }\r\n        <span class=\"hljs-keyword\">var<\/span> answerTheQuestionFunc = Kernel.CreateFunctionFromPrompt(renderedPrompt, functionName: <span class=\"hljs-string\">\"answerTheQuestionFunc\"<\/span>);\r\n        response = <span class=\"hljs-keyword\">await<\/span> answerTheQuestionFunc.InvokeAsync(Kernel, arg);\r\n\r\n        <span class=\"hljs-keyword\">return<\/span> response.ToString();\r\n\r\n    }\r\n}<\/span><\/pre>\n<p id=\"a286\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Don\u2019t forget to register your Plugin with Kernel,<\/p>\n<pre class=\"nh ni nj nk nl pk pj pl bp pm bb bk\"><span id=\"a98e\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\">kernel.Plugins.AddFromObject(<span class=\"hljs-keyword\">new<\/span> Plugins(kernel));<\/span><\/pre>\n<p id=\"bb31\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">So the flow will be something like this:<\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf pw\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*OwogZHfpqlY-21wmhX0ERg.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*OwogZHfpqlY-21wmhX0ERg.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*OwogZHfpqlY-21wmhX0ERg.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*OwogZHfpqlY-21wmhX0ERg.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*OwogZHfpqlY-21wmhX0ERg.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*OwogZHfpqlY-21wmhX0ERg.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*OwogZHfpqlY-21wmhX0ERg.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*OwogZHfpqlY-21wmhX0ERg.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*OwogZHfpqlY-21wmhX0ERg.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*OwogZHfpqlY-21wmhX0ERg.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*OwogZHfpqlY-21wmhX0ERg.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*OwogZHfpqlY-21wmhX0ERg.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*OwogZHfpqlY-21wmhX0ERg.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*OwogZHfpqlY-21wmhX0ERg.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*OwogZHfpqlY-21wmhX0ERg.png\" alt=\"\" width=\"700\" height=\"1217\" \/><\/picture><\/div>\n<\/div><figcaption class=\"px ff py ne nf pz qa bf b bg z du\" data-selectable-paragraph=\"\">Example : Adding filter to log metrics, if function used RAG or not<\/figcaption><\/figure>\n<p id=\"008b\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 2: Add Filter using\u00a0<code class=\"cx pg ph pi pj b\"><strong class=\"mi gv\">IFunctionInvocationFilter<\/strong><\/code><strong class=\"mi gv\">\u00a0. This filter will\u00a0<\/strong>emit metrics called \u201cRagUsage\u201d. If the context has argument named \u201cdocument\u201d, that means RAG technique will be used (usedRag=true), if it is not there it means RAG was not used (usedRag = false).<\/p>\n<pre class=\"nh ni nj nk nl pk pj pl bp pm bb bk\"><span id=\"a5a6\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\">\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RAGUsageFilter<\/span> : <span class=\"hljs-title\">IFunctionInvocationFilter<\/span>\r\n{\r\n    \r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">async<\/span> Task <span class=\"hljs-title\">OnFunctionInvocationAsync<\/span>(<span class=\"hljs-params\">FunctionInvocationContext context, Func&lt;FunctionInvocationContext, Task&gt; next<\/span>)<\/span>\r\n    {\r\n        <span class=\"hljs-keyword\">var<\/span> functionName = context.Function.Name;\r\n\r\n        <span class=\"hljs-keyword\">var<\/span> meter = <span class=\"hljs-keyword\">new<\/span> Meter(<span class=\"hljs-string\">\"Microsoft.SemanticKernel\"<\/span>, <span class=\"hljs-string\">\"1.0.0\"<\/span>);\r\n\r\n        <span class=\"hljs-keyword\">var<\/span> ragCounter = meter.CreateCounter&lt;<span class=\"hljs-built_in\">int<\/span>&gt;(<span class=\"hljs-string\">\"semantic_kernel.ragUsage\"<\/span>);\r\n        \r\n        <span class=\"hljs-keyword\">if<\/span> (context.Arguments.ContainsName(<span class=\"hljs-string\">\"document\"<\/span>))\r\n        {\r\n            <span class=\"hljs-keyword\">var<\/span> renderedPrompt = <span class=\"hljs-string\">\"\"<\/span>;\r\n            ragCounter.Add(<span class=\"hljs-number\">1<\/span>, KeyValuePair.Create&lt;<span class=\"hljs-built_in\">string<\/span>, <span class=\"hljs-built_in\">object<\/span>&gt;(<span class=\"hljs-string\">\"UsedRag\"<\/span>, <span class=\"hljs-literal\">false<\/span>));\r\n        }\r\n        <span class=\"hljs-keyword\">else<\/span> \r\n        {\r\n            ragCounter.Add(<span class=\"hljs-number\">1<\/span>, KeyValuePair.Create&lt;<span class=\"hljs-built_in\">string<\/span>, <span class=\"hljs-built_in\">object<\/span>&gt;(<span class=\"hljs-string\">\"UsedRag\"<\/span>, <span class=\"hljs-literal\">true<\/span>));\r\n        }\r\n  \r\n        <span class=\"hljs-keyword\">await<\/span> next(context);\r\n    }\r\n}<\/span><\/pre>\n<p id=\"6b2d\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Then update the kernel builder to add this as singleton\u00a0<code class=\"cx pg ph pi pj b\">IFunctionInvocationFilter<\/code><\/p>\n<pre class=\"nh ni nj nk nl pk pj pl bp pm bb bk\"><span id=\"5b7b\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\"><span class=\"hljs-keyword\">var<\/span> builder = Kernel.CreateBuilder()\r\n        .AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);\r\n\r\nbuilder.Services.AddSingleton&lt;IFunctionInvocationFilter, RAGUsageFilter&gt;();\r\n\r\nKernel kernel = builder.Build();<\/span><\/pre>\n<p id=\"db40\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Step 3: Enable AutoFunctionCalling. I am going to use OpenAI FunctionCalling, to automatically invoke the plugin function.<\/p>\n<pre class=\"nh ni nj nk nl pk pj pl bp pm bb bk\"><span id=\"39a6\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\">\r\n<span class=\"hljs-type\">OpenAIPromptExecutionSettings<\/span> <span class=\"hljs-variable\">openAIPromptExecutionSettings<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span>() \r\n{\r\n    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions\r\n};\r\n<span class=\"hljs-type\">KernelArguments<\/span> <span class=\"hljs-variable\">args<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title.class\">KernelArguments<\/span>();\r\n\r\nargs.ExecutionSettings = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title.class\">Dictionary<\/span>&lt;string, PromptExecutionSettings&gt;() {\r\n    {PromptExecutionSettings.DefaultServiceId, openAIPromptExecutionSettings}\r\n};<\/span><\/pre>\n<p id=\"e4c1\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Now lets invoke the prompt, and record if user questions requires RAG or not<\/p>\n<pre class=\"nh ni nj nk nl pk pj pl bp pm bb bk\"><span id=\"6e61\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\"><span class=\"hljs-comment\">\/\/ RAG needed, as the question is about my resume<\/span>\r\n<span class=\"hljs-keyword\">var<\/span> response = <span class=\"hljs-keyword\">await<\/span> kernel.<span class=\"hljs-title.class\">InvokePromptAsync<\/span>(<span class=\"hljs-string\">\"Tell me more about my resume\"<\/span>, args); \r\nresponse.<span class=\"hljs-title.class\">ToString<\/span>()<\/span><\/pre>\n<pre class=\"qb pk pj pl bp pm bb bk\"><span id=\"f903\" class=\"pn nt gu pj b bg po pp l pq pr\" data-selectable-paragraph=\"\"><span class=\"hljs-comment\">\/\/ RAG not needed, as the question is general question<\/span>\r\n<span class=\"hljs-keyword\">var<\/span> response = <span class=\"hljs-keyword\">await<\/span> kernel.InvokePromptAsync(<span class=\"hljs-string\">\"Tell me story about lion\"<\/span>, args); \r\nresponse.ToString()<\/span><\/pre>\n<p id=\"9757\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Note: I am using .NET Interactive notebook, but the above code blocks can be inside the loop and can take input from users to give real chat like experience.<\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf qc\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*mYSXiu2oulv4yHs_KDvLgA.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*mYSXiu2oulv4yHs_KDvLgA.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*mYSXiu2oulv4yHs_KDvLgA.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*mYSXiu2oulv4yHs_KDvLgA.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*mYSXiu2oulv4yHs_KDvLgA.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*mYSXiu2oulv4yHs_KDvLgA.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*mYSXiu2oulv4yHs_KDvLgA.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*mYSXiu2oulv4yHs_KDvLgA.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*mYSXiu2oulv4yHs_KDvLgA.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*mYSXiu2oulv4yHs_KDvLgA.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*mYSXiu2oulv4yHs_KDvLgA.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*mYSXiu2oulv4yHs_KDvLgA.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*mYSXiu2oulv4yHs_KDvLgA.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*mYSXiu2oulv4yHs_KDvLgA.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*mYSXiu2oulv4yHs_KDvLgA.png\" alt=\"\" width=\"700\" height=\"223\" \/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"f11f\" class=\"pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk\" data-selectable-paragraph=\"\">Finally we can get this dashboard<\/p>\n<figure class=\"nh ni nj nk nl nm ne nf paragraph-image\">\n<div class=\"nn no fj np bh nq\" tabindex=\"0\" role=\"button\">\n<div class=\"ne nf qd\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*JAebkaBuVWpO34v_jVjJ_w.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*JAebkaBuVWpO34v_jVjJ_w.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*JAebkaBuVWpO34v_jVjJ_w.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*JAebkaBuVWpO34v_jVjJ_w.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*JAebkaBuVWpO34v_jVjJ_w.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*JAebkaBuVWpO34v_jVjJ_w.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*JAebkaBuVWpO34v_jVjJ_w.png 1400w\" type=\"image\/webp\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" \/><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*JAebkaBuVWpO34v_jVjJ_w.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*JAebkaBuVWpO34v_jVjJ_w.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*JAebkaBuVWpO34v_jVjJ_w.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*JAebkaBuVWpO34v_jVjJ_w.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*JAebkaBuVWpO34v_jVjJ_w.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*JAebkaBuVWpO34v_jVjJ_w.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*JAebkaBuVWpO34v_jVjJ_w.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" data-testid=\"og\" \/><img decoding=\"async\" class=\"bh ln nr c\" role=\"presentation\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1050\/1*JAebkaBuVWpO34v_jVjJ_w.png\" alt=\"\" width=\"700\" height=\"437\" \/><\/picture><\/div>\n<div>\n<h1 id=\"4a64\" class=\"ns nt gu bf nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op bk\" data-selectable-paragraph=\"\">Conclusion<\/h1>\n<\/div>\n<\/div>\n<\/figure>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n<\/div>\n<\/div>\n<\/article>\n<\/div>\n<div class=\"ab cb\">\n<div class=\"ci bh fz ga gb gc\">\n<div class=\"qe qf ab iv\">\n<div class=\"qg ab\">We&#8217;d like to thank Akshay for his time and all of his great work. \u00a0Please reach out if you have any questions or feedback through our\u00a0<a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/discussions\/categories\/general\" target=\"_blank\" rel=\"noopener\">Semantic Kernel GitHub Discussion Channel<\/a>. We look forward to hearing from you!\u00a0We would also love your support, if you\u2019ve enjoyed using Semantic Kernel, give us a star on\u00a0<a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>.<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re featuring a guest author, Akshay Kokane, who&#8217;s a Software Engineer at Microsoft within the Azure CxP team. He&#8217;s written an article we&#8217;re sharing below, focused on a Step-by-Step Guide to Building a Powerful AI Monitoring Dashboard with Semantic Kernel and Azure Monitor: Master TokenUsage Metrics and Custom Metrics using SK Filters. We&#8217;ll turn [&hellip;]<\/p>\n","protected":false},"author":149071,"featured_media":2302,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[117],"tags":[48,91,63,9],"class_list":["post-3225","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guest-blog","tag-ai","tag-azure-monitor","tag-microsoft-semantic-kernel","tag-semantic-kernel"],"acf":[],"blog_post_summary":"<p>Today we&#8217;re featuring a guest author, Akshay Kokane, who&#8217;s a Software Engineer at Microsoft within the Azure CxP team. He&#8217;s written an article we&#8217;re sharing below, focused on a Step-by-Step Guide to Building a Powerful AI Monitoring Dashboard with Semantic Kernel and Azure Monitor: Master TokenUsage Metrics and Custom Metrics using SK Filters. We&#8217;ll turn [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/3225","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/149071"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=3225"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/3225\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/2302"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=3225"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=3225"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=3225"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}