iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
AI & Data

OpenAI 從提示工程(Prompt Engineering)到語義核心(Semantic Kernel)的實踐系列 第 10

Semantic Kernel的實踐:開發篇-沒有Semantic Kernel的LLM應用體驗

  • 分享至 

  • xImage
  •  

前言

本篇開始進入LLM應用的開發,首先假設我們只知道LLM以及前面所學到的Prompt技巧,不知道任何的SDK。我想目前多數有在開發LLM應用,應該都是這一類的情況,畢竟像是LangChain/Semantic Kernel都還是非常新的,才正要起飛而已呢。因此本篇會以一個範例示範在不依賴任何SDK之下,如何用Prompt技巧實作LLM應用。

從指令(Command)到語義(Semantic)

開發LLM應用與過去的應用有很大的一個差別是,傳統應用是以安排好的操作介面為主軸,指引使用者進行操作,使用者僅能在已預先設計好的介面操作,並且無法隨意的提出需求,例如下圖的查詢畫面,有輸入框,有查詢按鈕。

https://ithelp.ithome.com.tw/upload/images/20230925/20126569LyJr5FdTgZ.png

這種方式是一種指令模式,程式邏輯依據按鈕Click事件與輸入框內容取得資料,再組裝成查詢的程式碼,進行查詣處理並返回結果。

而LLM應用則是大不同,最明顯的就是聊天對話模型(人類最自然的行為模型),例如:找出iPhone 15 pro max 商品資料。而這也就是Prompt,因此開發LLM應用時,開發者必須將思維從指令(Command)改變成語義(Semantic)

LLM應用程式流程(簡易型應用)大致會是這樣的:

  • 使用Prompt提出需求
  • LLM模型理解需求
  • LLM模型生成回應

前面我們提到一個好的生成回應,很大的關鍵是取決於Prompt,然而現實上我們並無法期待所有的人都能下一手好的Prompt,於是LLM應用程式流程會再進一步變成:

  • 使用Prompt提出需求
  • 程式引入Prompt技巧,改造原輸入的Prompt內容
  • LLM模型理解需求
  • LLM模型生成回應

案例操作 - 風格模擬貼文小幫手

  • 假定大家都已申請好OpenAI的API或是Microsoft Azure OpenAI服務,所以已經具備了2個重要資訊,API端點以及API授權金鑰。
  • 這個範例的模型選用的是GPT-4
  • 範例情境是:提供輸入貼文主題,然後生成"春上村樹"文筆風格的貼文內容
  • 考量GPT模型不一定知道會"春上村樹",以及為了防止幻覺現象,因此採用Few-shot技巧,在Prompt中注入"春上村樹"文筆範例,讓GPT模型先進行理解,然後再依提供的內容進行相似文筆風的內容改寫
  • 程式邏輯主軸
    • 預先定義好Prompt樣版
    • 使用者的Prompt透過Prompt樣版進行結合改造
    • 採用Few-shot技巧加入"春上村樹"文筆風格參考資料
    • 呼叫GPT-4模型API,包含重要參數的配置
    • 取得GPT-4模型生成回應

程式碼片段如下:

  • Prompt樣版
請你閱讀###內的文章的寫作風格

###
你要做一個不動聲色的大人了。不准情緒化,不准偷偷想念,不准回頭看。去過自己另外的生活。
就經驗性來說,人強烈追求什麼的時候,那東西基本上是不來的,而當你極力迴避它的時候,它卻自然找到頭上。
不管全世界所有人怎麼說,我都認為自己的感受才是正確的。 無論別人怎麼看,我絕不打亂自己的節奏。 喜歡的事自然可以堅持,不喜歡怎麼也長久不了。
哪裡有人喜歡孤獨,只不過不亂交朋友罷了,那樣只能落得失望。
剛剛好,看見你幸福的樣子,於是幸福著你的幸福。
我們的人生,在那之間有所謂陰影的中間地帶。能夠認識那陰影的層次,並去理解它,才是健全的知性。
我認為我的工作是觀察人和世界,而不是去評判他們。我一直希望自己遠離所謂的結論,我想讓世界一切都敞開懷抱
歸根結底,一個人是否有可能對另一個人有完美的理解?我們可以花費大量時間和精力去結識另一個人,但最後,我們可以接近那個人的本質嗎?我們說服自己,我們很了解對方,但是我們真的了解任何人的重要本質嗎?
###

請你使用相同的寫作風格,對下面的文章進行改寫,並且產生500個字以內的內容,使用繁體中文

###
{{user_prompt}}
###

  • API重要參數配置
public RequestModel(string sysContent)
{
	/*
	 * sysContent Sample : 
	 * "現在開始你是一位專欄作家"
	 */

	Messages = new List<Message>
	{
		new Message() { Role = "system", Content = sysContent }
	};
	Temperature = 0.8f;
	Top_p = 0.95f;
	Frequency_Penalty = 0;
	Presence_Penalty = 0;
	Max_Tokens = 2000;
}
  • 主程式碼片段
// 以template方式,進行prompt改造
string prompt_template = File.ReadAllText(filePath);
prompt_template = prompt_template.Replace("{{user_prompt}}", prompt);

using (HttpClient client = new HttpClient())
{
	//設定模型扮演的角色
	var requestModel = new RequestModel("現在開始你是一位專欄作家。");
	//加入改造後的prompt
	requestModel.AddUserMessages(prompt_template);

	//API請求
	var json = JsonConvert.SerializeObject(requestModel);
	var data = new StringContent(json, Encoding.UTF8, "application/json");
	client.DefaultRequestHeaders.Add("api-key", api_Key);
	var response = await client.PostAsync(api_Endpoint, data);
	var responseContent = await response.Content.ReadAsStringAsync();

	//API回應
	var completion = JsonConvert.DeserializeObject<Completion>(responseContent);

	//輸出模型生成結果
	Console.WriteLine(completion.Choices[0].Message.Content);

}
  • 生成結果
    https://ithelp.ithome.com.tw/upload/images/20230925/20126569fO1KBpVNde.png

本範例雖然採用部署於 Microsoft Azure OpenAI 服務的模型,但可自行置換為OpenAI,參數是相同的。
範例原始碼github連結 : https://github.com/iangithub/sklearn/tree/main/WithoutSkSample

結語

本篇帶出一個開發LLM應用時本質上的變化,從指令轉化為語義,人類最自然的行為模型,然後這僅僅只是一個開端,對於簡易型的應用可能足夠,但對於較複雜全面性的LLM應用,就不只是prompt而已,包含需要不同模型的支援、外部資料源、長短期記憶等,後續的文章會一一說明這部份如何輔以semantic kernel sdk 來滿足開發上的需求。

嗨,我是Ian,我喜歡分享與討論,今年跟2位朋友合著了一本ChatGPT主題書,如果你是一位開發者,這本書或許會有些幫助,https://www.tenlong.com.tw/products/9786263335189
這次的鐵人賽文章也會同時發佈於個人blog,歡迎關注我的blog : https://medium.com/@ianchen_27500


上一篇
Semantic Kernel的實踐:開發前準備-認識API及工具介面
下一篇
Semantic Kernel的實踐:開發篇-為何需要semantic kernel
系列文
OpenAI 從提示工程(Prompt Engineering)到語義核心(Semantic Kernel)的實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言