Semantic Kernel 入門系列:Kernel 內核和Skills 技能

opendotnet 發佈 2024-01-17T18:21:39.650862+00:00

理解了LLM的作用之後,如何才能構造出與LLM相結合的應用程式呢?

理解了LLM的作用之後,如何才能構造出與LLM相結合的應用程式呢?

首先我們需要把LLM AI的能力和原生代碼的能力區分開來,在Semantic kernel(以下簡稱SK),LLM的能力稱為 semantic Function ,代碼的能力稱為 native function,兩者平等的稱之為function(功能),一組功能構成一個技能(skill)。SK的基本能力均是由skill構成。

有了一堆skill之後並不能直接執行,需要有一個配置和管理的單元,就像是MVC 需要ASP.NET框架一樣,Skill也需要有一個Kernel進行組織管理。

Kernel 除了組織管理Skill,還兼顧了基礎服務的配置,例如OpenAI/Azure OpenAI的授權信息,默認的LLM模型選擇等等。另外當涉及到上下文的管理,技能參數的傳遞時,Kernel也能發揮重要的作用。

接下來我們就以開始著手上手SK應用開發的學習。

準備階段

  1. 首先準備一個應用環境,Console 可以,ASP.NET 也可以,Notebooks 也可以。使用Notebooks的話推薦參考官方的Notebooks合集和Uncle John's Semantic Kernel Recipes。

  2. 應用環境準備好之後,和所有的.Net 庫一樣,接下來就是安裝SK的nuget 包。由於是一個較新的包,所以更新變化會比較快。

dotnet add package Microsoft.SemanticKernel --prerelease
  1. 接下來進行應用內的準備工作,首先創建一個 kernel;

var kernel = Kernel.Builder.Build;
using Microsoft.SemanticKernel;
  1. 然後配置基礎模型,基礎模型目前有四個:

    由於Azure OpenAI提供了和Open AI相同的能力,所以以上的模型配置可以選擇OpenAI的接口,也可以選擇Azure OpenAI的接口,根據自己有哪個選哪個的原則使用。

    當然以上模型也提供了基本的接口定義,如果有自己的LLM AI接口的話,也可以自行實現相關接口,然後使用。

    這裡以OpenAI的接口為例,繼續進行學習。

  • TextCompletion,最常用的GPT-3的模型,常用於文本生成

  • ChatCompetion,GPT3.5模型,也就是所謂的ChatGPT的模型,基本就用於聊天功能

  • EmbeddingGeneration,嵌入模型,這個將用於Memory的生成和搜索,在後期能力擴展時將會有極大的用途

  • ImageGeneration,圖形模型,也就是DALL-E模型,用於圖片的生成

kernel.Config.AddOpenAITextCompletionService("ServiceId","text-davinci-003",Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
// 簡單的技能任務使用TextCompletion即可
// 1. ServiceId 用於指定當前模型的配置,相同的模型不能有重複的ServiceId配置
// 2. modelId 指定TextCompetion所使用的LLM 模型,目前基本為 text-davinci-003
// 3. apikey OpenAI 接口調用需要使用的APIkey

Semantic Function

  1. 註冊一個Semantic Function

using Microsoft.SemanticKernel.SemanticFunctions;
var summaryFunction = kernel.CreateSemanticFunction(prompt,new PromptTemplateConfig);
// ⚠️ Semantic Function的核心就是prompt⚠️
// 這裡偷懶,使用Semantic Kernel官方樣例庫裡面的的Summary Skill
var prompt =
"""
[SUMMARIZATION RULES]
DONT WASTE WORDS
USE SHORT, CLEAR, COMPLETE SENTENCES.
DO NOT USE BULLET POINTS OR DASHES.
USE ACTIVE VOICE.
MAXIMIZE DETAIL, MEANING
FOCUS ON THE CONTENT
[BANNED PHRASES]
This article
This document
This page
This material
[END LIST]
Summarize:
Hello how are you?
+++++
Hello
Summarize this
{{$input}}
+++++
""";
// 使用擴展方法在Kernel上註冊一個SemanticFunction
// prompt 是Semantic Function的核心,如何設計一個好的prompt是成功構建Semantic Function的關鍵所在,也是未來LLM AI 應用中的重要內容
// PromptTemplateConfig 用於配置prompt 模板的相關參數
// functionName 是自定義的功能名稱[可選]
// skillName 是自定義的技能名稱[可選]

可以注意到的是在prompt中,有一個變量參數 {{$input}},這是SK的默認輸入參數,用於注入需要處理的用戶輸入,這樣的格式用於預防Prompt Injection,這就是另外一個話題了。

  1. 執行Function

var input = "Multi-modal interfaces are becoming increasingly popular for app developers. These interfaces allow users to interact with apps in a variety of ways by combining different modes of input and output, such as voice, touch, and visuals, to create a more interactive and engaging user experience. In this blog we will overview how you can use Semantic Kernel with a multi-modal example. ";
var resultContext = await kernel.RunAsync(input,summaryFunction);
// 定義需要處理的輸入
// 通過 Kernel 運行 function
// 輸出結果
resultContext.Result.Dump;
// output
// Multi-modal interfaces are becoming increasingly popular for app developers, combining different modes of input and output such as voice, touch, and visuals to create a more interactive and engaging user experience. Semantic Kernel can be used to create a multi-modal example.

以上就完成了一個簡單的Semantic Function的使用。

好的,我們繼續。

Native Function

  1. 聲明一個Native Skill

using Microsoft.SemanticKernel.SkillDefinition;
[SKFunction("Convert a string to uppercase.")]
public string Uppercase(string text)
return text.ToUpper(System.Globalization.CultureInfo.CurrentCulture);
// 這裡偷懶,使用Semantic Kernel CoreSkills中的 TextSkill
public class TextSkill {
{
}
}

這裡只需要對方法添加一個SKFunction的注釋,就可以轉變為一個SK的Native Function。

  1. 註冊Native Skill

var textSkill = kernel.ImportSkill(new TextSkill,nameof(TextSkill));
// skillInstance 就是Native Skill的實例
// skillName 自定義的技能名稱 [可選]

這裡使用到的是一個Import,意味著導入了SkillInstance中所有的定義SKFunction。而Semantic Skill 也有一個對應的Import方法ImportSemanticSkillFromDirectory,可以從一個文件夾中導入所有技能。

  1. 執行Function

var uppercaseFunction = textSkill[nameof(TextSkill.Uppercase)];
var nativeResultContext = await kernel.RunAsync(input,uppercaseFunction);
// 註冊Native Function 如何沒有指定 SKFunctionName的話,都會是用方法聲明的名稱,使用nameof這種偷懶方法可以方便得從Skill集合中獲取對應的Function
// 通過 Kernel 運行 function
// 輸出結果
nativeResultContext.Result.Dump;
// output:
// MULTI-MODAL INTERFACES ARE BECOMING INCREASINGLY POPULAR FOR APP DEVELOPERS. THESE INTERFACES ALLOW USERS TO INTERACT WITH APPS IN A VARIETY OF WAYS BY COMBINING DIFFERENT MODES OF INPUT AND OUTPUT, SUCH AS VOICE, TOUCH, AND VISUALS, TO CREATE A MORE INTERACTIVE AND ENGAGING USER EXPERIENCE. IN THIS BLOG WE WILL OVERVIEW HOW YOU CAN USE SEMANTIC KERNEL WITH A MULTI-MODAL EXAMPLE.

以上就完成了一個簡單的Native Function的使用。

鏈式調用

當完成了以上Skill和Function的準備之後,就可以想辦法將多個Skill串聯起來使用了,就像是命令行中的管道,函數式編程中的管道一樣。

var upperSummeryContext = await kernel.RunAsync(input, summaryFunction,uppercaseFunction);
// kernel.RunAsync 本身就支持多個Function參數,並按照順序依次執行
// 輸出結果
upperSummeryContext.Result.Dump;
// output:
// MULTI-MODAL INTERFACES ARE BECOMING INCREASINGLY POPULAR FOR APP DEVELOPERS, COMBINING DIFFERENT MODES OF INPUT AND OUTPUT SUCH AS VOICE, TOUCH, AND VISUALS TO CREATE A MORE INTERACTIVE AND ENGAGING USER EXPERIENCE. SEMANTIC KERNEL CAN BE USED TO CREATE A MULTI-MODAL EXAMPLE.

至此,一個簡單的結合了LLM AI能力和原生代碼能力的應用就構建成功了。

參考資料:

  1. Concepts Overview for Semantic Kernel | Microsoft Learn: https://learn.microsoft.com/en-us/semantic-kernel/concepts-sk/

  2. Kernel in Semantic Kernel | Microsoft Learn:https://learn.microsoft.com/en-us/semantic-kernel/concepts-sk/kernel

  3. Skills in Semantic Kernel | Microsoft Learn:https://learn.microsoft.com/en-us/semantic-kernel/concepts-sk/skills

  4. How to write semantic skills in Semantic Kernel | Microsoft Learn: https://learn.microsoft.com/en-us/semantic-kernel/howto/semanticfunctions

  5. How to write native skills in Semantic Kernel | Microsoft Learn: https://learn.microsoft.com/en-us/semantic-kernel/howto/nativefunctions

  6. SK-Recipes:https://github.com/johnmaeda/SK-Recipes

關鍵字: