可以說,目前的大型語言模型 (LLM) 工程領域令人振奮。自去年 11 月推出 ChatGPT 以來,該行業一直在發生着巨大的變化。我們都看到了整個行業中 AI 工具的興起,它以驚人的速度開辟了産品和開發的可能性。
Instacart 一直在以驚人的速度采用 LLM 和 GenAI:隻需看看我們的内部助手Ava、我們超強的 AI 搜尋Ask Instacart或我們ML 平台中的創新。我們一直在探索用例、功能,最重要的是如何為我們的員工、客戶、商家和購物者創造價值。
任何使用過這些模型的人都知道,這種新興技術具有無限的可能性;但這些可能性目前受到許多挑戰的限制:從上下文大小問題到幻覺,再到似乎無法完成你為其設定的任務的模型。
幸運的是,有許多技術可以幫助您使用 LLM 建構産品。本文探讨了其中一些技術,希望能夠真正為您打開更多的可能性!
這裡簡單說一下:所有這些提示技術都已在 GPT-4 中實作和使用。有些技術也已在 GPT-3.5 中使用。GPT-4 是目前同類最佳的對話模型,遠遠優于 GPT-3.5 和所有其他對話模型。如果 GPT-4 對您的用例而言經濟實惠,我強烈建議您使用它。
本文将探讨我們在 Instacart 内部生産力工具中使用的提示技術。這些技術結合了行業和學術研究以及我們自己的小規模内部開發工作。建議您在自己的評估環境中并使用特定用例測試這些技術。
提示的力量
使用大型語言模型的一個有趣的方面是提示的概念。這是我們與模型的握手,是我們與這個人工智能實體交談和互動的工具。而且,就像你最喜歡的食譜中的香料一樣,正确的提示技術可以顯著改變結果。我們将在這裡介紹一些衆所周知的技術,請跳過前面的内容,檢視下面我們開發的一些更有趣的技術。
首先,讓我們來談談一種聽起來像是從認知科學教科書中掉下來的技術:思維鍊(CoT)。思維鍊是一種簡單的提示技術,具有非常有趣的含義,我們将在下一節中讨論。CoT 有幾種不同的形式,但最流行的一種就是在提示中添加短語“讓我們一步一步來”。與許多這些技術一樣,它非常簡單,讓人覺得很傻。最近又出現了“深吸一口氣,想出一個回答計劃”。模型呼吸的時間不會比它深入思考的時間多,但這些短語提示模型在确定方向之前進行更多思考,并在答案空間中完善其位置。
下面是一個使用 CoT 為您之前在對話中充實的文章生成标題的示例(這就是我為這篇文章所做的!):
現在我們将為文章生成标題。首先一步一步地
确定
文章中最重要的元素是什麼,以及一般來說什麼才是好的标題。
完成這些之後,生成标題。
另一種衆所周知的提示技術是ReAct。這是您授予模型在其自身文本生成流程之外采取行動的能力的地方。這可能是查找網頁、執行數學計算,甚至在内部文檔源中查找資訊。通常,您會用模型的能力來提示它。例如:
在回答以下問題時,您還可以采取以下行動來擷取更多資訊:
在回答以下問題時,您還可以采取以下操作
來擷取更多資訊:
INTERNAL_LOOKUP:<搜尋詞> - 在内部來源中進行搜尋
GOOGLE_SEARCH:<搜尋詞> - 針對您的搜尋詞進行網絡搜尋
CALCULATION:<數學詞> - 執行算術計算,即
CALCULATION:2 * (8^10)
操作必須位于輸出的末尾,您将獲得
響應結果。請為使用者重述所有資訊。
操作必須位于輸出的末尾,您将得到響應結果。請為使用者重述所有資訊。
現在,當模型響應時,它可能會使用 INTERNAL_LOOKUP、GOOGLE_SEARCH 或計算,我們的軟體将執行操作并重新要求模型使用新資訊完成任務。
通過這種方式,我們可以為模型建立一個功能庫。更進階的形式可以在ChatGPT 的插件系統中看到。
法學碩士與人類之間的相似之處
将人類認知與大型語言模型 (LLM) 進行比較是一個有趣的探索。與 LLM 的互動與與聰明但睡眠不足的實習生的互動有多麼相似,這通常令人難以置信。後者需要清晰、明确的訓示才能産生所需的輸出,LLM 也是如此。他們都需要指導才能專注于任務,而不會偏離混亂的反應或 LLM 的幻覺。
就像人類實習生一樣,LLM 也受益于犯錯和自我糾正的空間。雖然拟人化的 LLM 可能會引起懷疑,但它實際上有助于更好地建構我們的互動,進而最大限度地提高成功完成任務的機會。這是另一個引人注目的“人性化”元素:LLM 就像實習生一樣,如果得到正确的推動和糾正,可能會給你帶來意想不到的幽默或令人震驚的深刻回應。這種體驗令人興奮、不可預測,有時甚至令人沮喪。
其中一個例子是在小樣本學習示例中使用短語“謝謝”。如果你在小樣本示例中對模型很有禮貌,那麼它可以幫助傳達下一個示例背後的正确含義。在小樣本學習中,我們提供了 2-5 個涵蓋不同情況的輸出示例。我們發現,如果你隻使用問答示例,有時模型會感到困惑,認為下一個問題是對上一個答案的更正,而不是新示例。通過說“謝謝,太棒了,下一個問題是:”,它實際上比沒有說“謝謝”表現更好。在我們的測試中,字面上的“謝謝”比其他形式效果更好!
當我們重新審視對 LLM 實習生的認識時,我們就能更務實地看待我們的提示。想象一下,一個受過非專業、通識教育的人,在缺乏你所在領域的具體知識的情況下,可能會如何處理你的任務。在反思和改進我自己表現不佳的提示後,我發現了一個趨勢。将 LLM 視為一個聰明但經常困惑的參與者,促使我重寫了提示,更公開地解決任務要求。
這種觀點的改變不僅僅是理論上的;它已經在學術 研究和日常工程實踐中證明了其價值。通過在與法學碩士的互動中注入一絲人性——将他們視為善意但可能略顯困惑的人——我們可以提高他們的表現和我們的整體體驗。
進階提示技巧
現在,我們将介紹我們在 Instacart 開發的一些提示技術。我們并不聲稱自己是唯一想出這些技術的人,甚至沒有聲稱自己是唯一使用行業術語的人,但我們在開發用于内部工作流程的Ava 系列産品時使用了所有這些技術。我已經按越來越複雜的程度訂購了這些産品,是以一定不要錯過分類和木偶!
思考空間——先制定計劃
思考空間是明确鼓勵 LLM 在開始回答問題之前制定計劃。這可能是選擇正确詞語的一個非常微妙的平衡。特别是,ChatGPT 已經使用RLHF進行了訓練,可以直接回答使用者的問題,而不是等待。通常你需要明确提示模型不要回答問題。例如,這是我們用來生成内部代碼審查的拉取請求 (PR) 标題和描述的提示的一部分。
首先,讓我們為拉取請求描述建立一個大綱。不要
生成标題和描述,隻寫大綱。一定要根據你在 diff 中看到的内容
思考更改的類别(例如 1. 添加
--foo 參數的更改,2. 添加網絡調用重試等)。
例如,這個特定的提示還省略了輸出的所有格式說明或如何選擇标題(我們在生成 PR 的後續讨論中包括了這些說明)。
這讓模型有空間去思考如何最好地編寫拉取請求。将模型視為人類,我們隻是告訴它在實際編寫輸出之前先制作初稿或大綱。
有時,提示模型思考在好的答案版本中什麼是重要的也是一個好主意(“首先列出構成好的拉取請求的 5 件事”),盡管很多時候這種預先思考可以直接融入提示中,進而節省生成時間。例如:
好的拉取請求描述清晰、簡潔,并充分列出
變更的複雜部分。在撰寫拉取請求
描述時,最好的方法是在描述中引用變更,但
也不要過度描述小變更(尤其是一行變更)。
鑒于此,為拉取請求描述建立一個大綱,隻
寫大綱
……等等……
這樣,我們就将一些關于“什麼是好的拉取請求”的思考融入到了提示中,而且我們不必花時間或生成令牌來制作這個靜态清單。我們仍然希望給模型留出空間來思考依賴于特定查詢的問題部分(此示例中的特定拉取請求會發生變化)。
蒙特卡洛——集思廣益
在蒙特卡羅技術中,我們要求模型生成幾個不同的選項,然後使用這些選項建立一個最終答案,該答案将帶來所有生成答案的最佳方面。您可以在這裡看到思考空間的呼應,因為模型再次有犯錯的空間,嘗試不同的方法,然後才建立輸出。
當您需要使用模型執行創造性過程時,蒙特卡羅非常适合。思考如何與同僚一起解決創造性問題——首先通過列出想法進行頭腦風暴。蒙特卡羅是使用 LLM 進行此操作的技術。
這是我最近為女兒的生日聚會提出想法并根據這些想法建立最終标題的提示:
我正在為我 9 歲女兒的生日派對尋找創意。她喜歡
Pokemon、柯基犬、Roblox,也喜歡和朋友們一起玩。
首先列出适合孩子的生日派對的元素,這些元素可以
在預算内完成,然後列出
根據她的興趣而制定的有趣主題/派對元素。
然後為派對提出 5 個截然不同的創意。
最後建立一個最終的單一标題推薦,将
選項中的最佳元素結合起來。
蒙特卡洛最棒的地方在于,當你以互動方式進行時,你會在生成過程中獲得 5 個額外的選項。我經常會發現清單中的某個選項對我有吸引力,然後我就選擇了它。請注意,指定想法應盡可能不同是一個好主意,否則在某些情況下,模型會重複五次,措辭略有不同。
我發現這種技巧在産生幽默想法時特别有用。GPT-4 并不擅長幽默或笑話,是以讓它産生許多選項對于找到真正有趣的東西非常有用。
自我糾正——自我批評
自我修正是指讓模型思考其答案,并轉換角色,批判性地思考它可以改進的地方,然後利用這些想法來得出最終答案。這與上面的蒙特卡羅技術配合使用效果最好,因為它可以分析每個選項并提供批評。如果您還提供了有關什麼是“良好”答案的指導,您可以要求它在提供技術時牢記這些指導。
讓我們再次嘗試上面的 PR 标題和描述生成,這次進行自我修正:
現在我們将為 PR 生成标題。标題應簡潔地表
明拉取請求的目的是什麼。理想情況下,它應該是
對拉取請求目的的簡短而清晰的描述。
生成 5 個可能截然不同的标題,然後對其進行批評。
最後在批評之後生成一個完善的最終标題。
這裡最重要的部分是“然後批評它們”。通過讓模型形成批評,您可以讓模型改進其觀察結果。同樣,當以互動方式使用模型時,您還可以了解模型在形成這些批評和最終答案時“思考”的内容。
分類——隻回答特定選項
分類是一種非常有趣的提示技術,它利用了 LLM 中一些較少使用的功能。使用 LLM 時可能遇到的一個問題是希望讓模型回答本質上是一個多項選擇題。使用标準提示時,您可能會遇到很多問題,例如模型想要先思考其答案,或者在答案前加上标題資訊(“您的問題的答案是 A”,而不是隻說“A”)。當以程式設計方式使用 LLM 的輸出時,從 LLM 中提取正确的輸出可能非常困難。
我們在内部 OpenAI / LLM 代理上建構了一個 API 端點,以保證輸出有效。啟用此 API 的一個關鍵見解是 LLM 能夠可靠地重複答案中上下文中的标簽。有了這種能力,我們可以制作如下提示:
仔細考慮以下陳述,并
在回答之前仔細思考您的推理:
天空是藍色的。
可能的答案:
000 正确
001 錯誤
002 不确定
直接引用答案編号來回答問題。
雖然這使得處理模型的輸出變得更容易,但僅僅使用上面的提示會引入我們之前讨論過的問題。LLM 通過從提供的輸入中生成下一個最可能的标記(此處指字元或單詞片段)來發揮作用。計算每個潛在下一個标記的機率,它們選擇可能性最大的标記。我們可以通過在對 OpenAI 的請求中使用 logit_bias 參數來推動該機率,如果我們将偏差設定為 100,我們可以強制模型從一組特定的标記中進行選擇。一旦我們将模型的響應限制為“000”、“001”、“002”等,我們就會要求它生成一個标記(通過将 max_tokens 設定為 1),確定我們的答案始終是一個有效的選項。值得注意的是,所有三位數的數字組合都被視為單個标記。
但是等等——思考空間、CoT 以及為模型提供做出正确決策空間的所有其他技術怎麼樣?我們的 API 實際上允許“深度思考”模式,在該模式下,它可以進行 CoT 和其他“大聲”思考,方法是先要求它仔細思考推理但不提供答案,然後在後續回合中使用 logit_bias 強制得出最終答案。通常,以對話方式使用多輪提示可以應用多種技術。
讓我們通過一個例子來思考一下這是如何工作的。假設你想從我們上面為拉取請求生成的選項清單中選擇正确的标題。我們不想生成最終标題,而是想讓模型選擇它生成的最佳标題,并且我們想強迫它選擇一個且隻有一個對象,但我們希望給它思考的空間和自我批評的能力,我們可以這樣做:
消息 1:
請仔細考慮以下問題,并在回答前仔細思考您的理由:
考慮到這些更改,以下哪個标題可以作為最佳的拉取請求标題:
更改
請務必深呼吸并仔細考慮您的答案
可能的答案:
000 最好的 PR EVAR!!!
001 添加 CRUD 端點
002 為 /api/books 添加 POST 和 DELETE 處理程式
您将首先仔細考慮這個問題,并寫下一個可以引導我找到答案的想法的項目符号清單。
模型用它的推理做出回應,然後我們說:
消息 2:
謝謝。現在請找出最符合上述推理的答案
。
隻需參考上面答案清單中的項目編号即可。
第一個補全要求正常響應,并具有對所有标記的完全通路權限。隻有對第二條消息的響應僅限于答案标記。還請注意,需要進行一些調整才能獲得正确的提示,因為我們已經看到小的單詞變化(例如:删除“謝謝”)會導緻響應保真度的巨大差異。
關于此技術的注意事項:我們建議在分類時使用較低的溫度(甚至 0)。溫度表示模型在下一代循環中選擇不是“最有可能”的标記的可能性。在我們的例子中,我們可能總是想要最有可能的标記。另一件事是,根據您的問題,允許模型在您的選擇中有所作為可能很重要。上面的“不确定”就是一個例子。但在其他情況下,“無”或“無事可做”也可能是合适的。
木偶戲——為模特代言
這是我最喜歡的提示技巧。我要指出的是,我們并不是唯一想出這種技巧的人。
在幾乎所有的 LLM API 中,您都會将對話狀态傳遞給每個生成調用。您必須傳入文本/json,以顯示使用者所說的内容、助手所說的内容以及系統所說的内容。有趣的是,即使助手沒有開始響應,您也可以告訴它它已經開始響應。您可以告訴它它說了任何您想要說的話。這在少樣本提示中已經很常用了,但當您需要特定格式的輸出,甚至是思考時,您也可以使用它來阻止模型漫無目的或奇怪地回答的傾向。
例如,當我們希望模型為拉取請求腳本輸出 JSON 對象時,我們會這樣做:
使用者:最後根據
下面的 JSON 格式輸出标題和描述,嚴格遵循下面的格式非常重要。
{
"title": "<title>",
"description": "<description">,
}
助手: {
"title": "
請注意此提示中添加了最後兩行。通過這種方式,我們欺騙模型,讓它認為它已經開始輸出“{”字元,是以應該“以 json 思考”。我們也不會讓它猜測“title”鍵,而是提示它已經開始輸入标題。這減輕了模型以您想要的輸出格式開始響應的負擔。它使模型稍微放松一點,隻輸出您想要的答案。(在上面的例子中,User:請Assistant: 參閱 OpenAI API 中的角色)
我們稱其為傀儡,因為你在強迫模型說出你想要它說的确切内容。模型看到這一點并将其解釋為已經說過。然後,為了不自相沖突,它會從那裡繼續思考。
這也可以用于讓 LLM 遵循你的提示規則,例如如果你用以下方式結束提示:
助理:首先,我會仔細考慮各種選擇,找出
每種方法的優點。
在這種情況下,我們提醒模型,它在回答之前正在仔細考慮事情。
結論
我們與您分享了我們想出的一些技巧,也希望聽到您自己發現的任何技巧!Ada Cohen 和 Kevin Lei 在撰寫本文和提出這些技巧方面發揮了重要作用。
祝您提示愉快!
其他閱讀材料
這是基于大量論文、熱門文章和資源而建立的。如果您正在尋找更多資訊,以下是我們認為特别值得一讀的内容
- 快速工程指南 — https://www.promptingguide.ai/
- Anthropic 的提示設計指南和有用的提示技巧
- Dair.ai 的 Prompt 指南:https://github.com/dair-ai/Prompt-Engineering-Guide
- 密度鍊論文——一種快速總結的技巧
- OpenAI 的食譜——尤其是提高可靠性的技術
- 使用“根據”減少虛假事實
- Python 的 React 模式
作者:Ben Bernard
出處:https://tech.instacart.com/monte-carlo-puppetry-and-laughter-the-unexpected-joys-of-prompt-engineering-4b9272e0c4eb