前一篇我們認識了Plugins以及它在Semantic Kernel裡的作用,本篇就開始動手來打造Plugins,首先來看的semantic functions,在上一篇內容有提到Plugins分成2類,分別是Semantic functions與Native functions,其中semantic functions的組成以Prompt為主,透過Prompt engineering叫LLM模型做它本身就能做的事情,像是文本生成、改寫、翻譯等文本生成的任務。
範例採用C#程式語言,並以主控台應用程式做為示範,使用的是.net 7.0。
此外GPT模型使用的是Azure OpenAI GPT-4,事實也可以依需求改用OpenAI服務,而模型也可以改用GPT-3.5。
Semantic Functions 依寫作方式有不同的做法,其中一種做法是"內嵌",做法是直接將Semantic Functions寫在單一程式內容裡,這種做法因無法在不同程式做reuse,所以通常是特定專用的情況才會採取這個寫法。(有寫過網頁的開發者,可以想像類似一段CSS或JS直接寫在某個HTML裡)。
var kernel = new KernelBuilder()
.WithAzureChatCompletionService(
deploy_model, // Azure OpenAI Deployment Name
aoai_Endpoint, // Azure OpenAI Endpoint
api_Key // Azure OpenAI Key
).Build();
這裡有個需要注意的地方,當你只需要一個參數時,這個參數名稱請直接使用input這個變數名稱,待會後面可以直接做資料的輸入。
const string funcDefinition = @"
你是一位facebook小編,請使用輕鬆灰諧的語氣,撰寫下列主題的貼文,內容500個字以內,#zh-tw
###
{{$input}}
###
";
var excuseFunction = kernel.CreateSemanticFunction(funcDefinition,
skillName: "FacebookAgent", functionName: "Post",
maxTokens: 2000, temperature: 0.2,
description: "產生facebook貼文");
var result = await kernel.RunAsync(@"ChatGPT對校園教育的衝擊", excuseFunction);
上一個範例在Prompt Template裡僅使用1個參數,而參數名稱直接使用預設名稱{{$input}},但如果想客制化的話要怎麼做?,也很簡單,這時候只需要建立ContextVariables物件就可以做的到。
直接延用上一個範例做改寫。
const string funcDefinition = @"
你是一位facebook小編,請使用輕鬆灰諧的語氣,撰寫下列主題的貼文,內容500個字以內,#zh-tw
###
{{$post_subject}}
###
";
var contextVars = new ContextVariables()
{
["post_subject"] = "ChatGPT對校園教育的衝擊"
};
var result = await kernel.RunAsync(excuseFunction, contextVars);
接下來這個範例,同時示範如何在Semantic Functions使用多個參數,以及結合Few Shot 運用。同樣延續前面的範例,納入Few Shot技巧,讓模型學習寫作風格後,再依主題要求產生文案內容
const string funcDefinition = @"
你是一位facebook小編,請先思考一下下列提供的範例寫作風格
###
{{$fewshot_sample}}
###
接著撰寫下列主題的貼文,內容500個字以內,#zh-tw
###
{{$post_subject}}
###
";
//few-shot,帶入方文山詞創作範例
string fewshot_sample = @"
竹籬上 停留著 蜻蜓
玻璃瓶裡插滿 小小 森林
青春 嫩綠的很 鮮明
百葉窗 折射的 光影
像有著心事的 一張 表情
而你 低頭拆信 想知道關於我的事情
月色搖晃樹影 穿梭在熱帶雨林
你離去的原因從來不說明
你的謊像陷阱我最後才清醒
幸福只是水中的倒影
月色搖晃樹影穿梭在熱帶雨林
悲傷的雨不停全身血淋淋
那深陷在沼澤我不堪的愛情
是我無能為力的傷心
蘆葦花開歲已寒 若霜又降路遙漫長
牆外是誰在吟唱 鳳求凰
梨園台上 西皮二黃
卻少了妳 無人問暖
誰在彼岸 天涯一方
在夢裡我醞釀著情緒
等回憶等那一種熟悉
人世間最溫柔的消息
是曾經被你擁入懷裡
";
var contextVars = new ContextVariables()
{
["fewshot_sample"] = fewshot_sample,
["post_subject"] = "ChatGPT對校園教育的衝擊"
};
var result = await kernel.RunAsync(excuseFunction, contextVars);
範例原始碼 : https://github.com/iangithub/sklearn/tree/main/InlineSemanticFunction
本篇內容說明如何使用inline的方式建立Semantic functions,更運用prompt engineering 提升Semantic functions能力,然而inline的撰寫方式不利於reuse,所以接下來我們會說明如何建立便於reuse的Semantic functions。
嗨,我是Ian,我喜歡分享與討論,今年跟2位朋友合著了一本ChatGPT主題書,如果你是一位開發者,這本書或許會有些幫助,https://www.tenlong.com.tw/products/9786263335189
這次的鐵人賽文章也會同時發佈於個人blog,歡迎關注我的blog : https://medium.com/@ianchen_27500