.NET 中的提示工程
在本文中,您將探索基本的提示工程概念。 許多 AI 模型都是以提示為基礎,這表示它們會透過預測演算法所產生的回應 (完成的答案) 來回應使用者輸入文字 (提示)。 較新的模型通常還支援聊天形式的完成答案,並使用根據角色 (系統、使用者、助理) 和聊天歷史記錄的訊息來保留對話。
使用提示
請考慮下列文字產生範例,其中「提示」為使用者輸入,而「完成」為模型輸出:
提示:「任期最短的總統是」
完成:「Pedro Lascurain」。
完成看起來是正確的,但如果您的應用程式應該幫助學習美國歷史的學生呢? Pedro Lascurain 的 45 分鐘任期是所有總統中任期最短的,但他曾擔任過墨西哥總統。 學習美國歷史的學生可能正在尋找有關 "William Henry Harrison" 的資料。 很顯然的,如果您能為應用程式提供某些內容,其對目標使用者來說可能就更實用。
提示工程會藉由提供指示、範例和提示來為提示添加上下文,以幫助模型生成更好的完成答案。
支援文字生成的模型通常不需要任何的特定格式,但您應該組織您的提示,以便模型能清楚什麼是指示、什麼是範例。 支援基於聊天的應用程式的模型會使用三個角色來組織完成的答案:控制聊天的系統角色、代表使用者輸入的使用者角色,以及用於回應使用者的助理角色。 將您的提示分成適於每個角色的訊息:
- 系統訊息可為模型提供助理相關指示。 提示只能有一個系統訊息,而且必須是第一個訊息。
- 使用者訊息包含來自使用者的提示並且會顯示範例、歷史提示或包含給助理的指示。 聊天完成範例至少必須有一個使用者訊息。
- 助理訊息會顯示範例或歷程的完成答案,而且必須包含對前一個使用者訊息的回應。 助理訊息並非必要,但如果您包含一個助理訊息,就必須將其與使用者訊息配對,才能形成範例。
使用指示來改善完成的答案
指示是告訴模型如何回應的文字。 指示可以是指示詞或命令式:
- 「指示詞」告訴模型如何表現,但不是簡單的命令;想像對於即興演員的角色設定:「您正在協助學生了解美國歷史,除非學生特別詢問其他國家,否則就是談論美國」。
- 「命令式」是模型要遵循的明確命令。 「翻譯成塔加拉族文:」
指令比命令更開放且更具彈性:
- 您可以在一個指示中合併數個指示詞。
- 當您將指示與範例搭配使用時,效果通常更好。 不過,由於命令式是明確的命令,因此,模型不需要範例即可了解它們 (雖然您可能會使用範例來對模型表示如何將回應格式化)。 由於指示詞不會確切地告訴模型該怎麼做,因此,每個範例都有助於讓模型運作得更好。
- 通常最好將一個困難的指示分解成一系列步驟,而您可以使用一連串指示詞來完成這些步驟。 您也應該告訴模型輸出每個步驟的結果,如此就能輕鬆地進行細微的調整。 雖然您可自行將指示分解成數個步驟,但直接告訴模型執行該指示並輸出每個步驟的結果會比較容易。 此方法稱為「思維鏈提示」。
主要和支援的內容增加了上下文
您可以提供內容來將更多的上下文新增至指示中。
「主要內容」是您想要模型使用指示來處理的文字。 無論指示採取何種動作,模型都將在主要內容上執行該動作來產生完成。
「支援內容」是您在指示中參考的文字,但其不是指示的目標。 模型會使用支援內容來完成指示,這表示支援內容也會出現在完成中,通常會以某種結構 (例如標題或資料行標籤) 顯示。
將標籤與您的指示內容搭配使用,以協助模型了解如何將之與指示搭配使用。 不要太過擔心精確度:標籤不必與指示完全相符,因為模型將會處理字組形式和大小寫之類的內容。
假設您使用「摘要說明美國總統的成就」指示來產生清單。 模型可能會以任意數目的方式進行組織及排序。 但是,如果您希望清單依一組特定類別來將成就分組,該怎麼做? 使用支援內容,將該資訊新增至指示。
調整指示,讓模型依類別分組,並附加指定那些類別的支援內容:
prompt = """
Instructions: Summarize US Presidential accomplishments, grouped by category.
Categories: Domestic Policy, US Economy, Foreign Affairs, Space Exploration.
Accomplishments: 'George Washington
- First president of the United States.
- First president to have been a military veteran.
- First president to be elected to a second term in office.
- Received votes from every presidential elector in an election.
- Filled the entire body of the United States federal judges; including the Supreme Court.
- First president to be declared an honorary citizen of a foreign country, and an honorary citizen of France.
John Adams ...' ///Text truncated
""";
使用範例來引導模型
範例是對模型表示如何透過提供樣本使用者輸入和模型輸出來回應的文字。 模型使用範例來推斷要在完成中包含的內容。 範例可以出現在工程提示中的指示之前或之後,但這兩者不應混用。
範例會以提示開頭且可以選擇性地包含完成的答案。 範例中的完成不需包含逐字回應,其可能僅包含一個格式化的字組、未排序清單中的第一個項目符號,或者指出每個完成應如何開始之類的內容。
範例會根據其是否包含逐字完成來分類為「零樣本學習」或「少樣本學習」。
- 零樣本學習範例包含不含逐字完成的提示。 此方法會測試模型的回應,而不需為它提供範例資料輸出。 零樣本提示可具有包含指引的完成答案,例如,指出模型應該透過包括 "1." 作為完成答案來輸出已排序的清單。
- 少樣本學習範例包含數個提示與逐字完成的配對。 少樣本學習可以藉由新增到模型的現有知識來變更該模型的行為。
了解提示
指引是傳達所需輸出結構或格式的文字。 如同指示,模型不會處理指引,就好像其是使用者輸入一樣。 如同範例,指引會對模型表示您所需的內容,而不是告訴模型該怎麼做。 您可以視需要新增多個指引,如此就能逐一查看以取得您所需的結果。 指引可與指示或範例搭配使用,而且應位於提示結尾。
假設您使用指示來告訴模型依類別產生總統成就清單,以及告訴模型要使用哪些類別的支援內容。 您決定想要讓模型產生具有全大寫類別的巢狀清單,在每個類別中每位總統的成就都會以其姓名開頭列成一行,並依時間順序排列總統。 在您的指示和支援內容之後,您可以新增三個指引,以對模型表示如何建構及格式化清單:
prompt = """
Instructions: Summarize US Presidential accomplishments, grouped by category.
Categories: Domestic Policy, US Economy, Foreign Affairs, Space Exploration.
Accomplishments: George Washington
First president of the United States.
First president to have been a military veteran.
First president to be elected to a second term in office.
First president to receive votes from every presidential elector in an election.
First president to fill the entire body of the United States federal judges; including the Supreme Court.
First president to be declared an honorary citizen of a foreign country, and an honorary citizen of France.
John Adams ... /// Text truncated
DOMESTIC POLICY
- George Washington:
- John Adams:
""";
- DOMESTIC POLICY 會對模型表示您希望其以此全大寫類別開始每個群組。
- - George Washington:對模型表示,以已列成一行的 George Washington 成就開始每個區段。
- - John Adams:對模型表示,其應該依時間順序列出其餘的總統。
使用 .NET 的範例提示
.NET 提供各種工具來提示和與不同的 AI 模型聊天。 使用語意核心來連線到各種不同的 AI 模型和服務以及其他 SDK,例如官方 OpenAI .NET 程式庫。 語義核心包括用於建立具有不同角色的提示和維護聊天歷史記錄的工具,以及許多其他功能。
請思考下列程式碼範例:
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
// Create a kernel with OpenAI chat completion
#pragma warning disable SKEXP0010
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: "phi3:mini",
endpoint: new Uri("http://localhost:11434"),
apiKey: "")
.Build();
var aiChatService = kernel.GetRequiredService<IChatCompletionService>();
var chatHistory = new ChatHistory();
chatHistory.Add(
new ChatMessageContent(AuthorRole.System, "You are a helpful AI Assistant."));
while (true)
{
// Get user prompt and add to chat history
Console.WriteLine("Your prompt:");
chatHistory.Add(new ChatMessageContent(AuthorRole.User, Console.ReadLine()));
// Stream the AI response and add to chat history
Console.WriteLine("AI Response:");
var response = "";
await foreach (var item in
aiChatService.GetStreamingChatMessageContentsAsync(chatHistory))
{
Console.Write(item.Content);
response += item.Content;
}
chatHistory.Add(new ChatMessageContent(AuthorRole.Assistant, response));
Console.WriteLine();
}
前面的程式碼提供了以下概念的範例:
- 建立聊天歷史記錄服務,以提示 AI 模型根據作者的角色來進行完成的答案。
- 使用
AuthorRole.System
訊息設定 AI。 - 接受使用者輸入以允許在
AuthorRole.User
的上下文中使用不同類型的提示。 - 以非同步的方式串流傳輸 AI 的完成答案,以提供動態的聊天體驗。
擴充您的提示工程技術
您也可以使用更進階的提示工程技術來增強您的提示的能力,這些技術在其自己的文章中進行了深入介紹。
- LLM 有權杖輸入限制,會限制您可在提示中容納的文字數量。 使用內嵌和向量資料庫解決方案來減少代表指定文字片段所需的標記數目。
- LLM 不會在您的資料中定型,除非您自行將其定型,但這很昂貴又耗時。 使用檢索增強生成 (RAG) 來讓您的資料可供 LLM 使用,而無需對其進行訓練。