過去一年有關(guān)大模型應(yīng)用構(gòu)建的干貨經(jīng)驗(yàn)之戰(zhàn)術(shù)篇
過去一年,大模型應(yīng)用以前所未有之勢從出現(xiàn)到繁榮。LLM應(yīng)用從原型展示向生產(chǎn)落地演進(jìn)。近日,Oreilly刊發(fā)了由 Eugene Yan, Bryan Bischof等人撰寫的大模型總結(jié)性文章《What We Learned from a Year of Building with LLMs?》,由于作者們背景各不相同,有獨(dú)立咨詢顧問(Hamel Husain,Jason Liu),有研究人員(Shreya Shankar),還有科技公司AI團(tuán)隊(duì)領(lǐng)袖(Eugene Yan,Bryan Bischof),以及AI領(lǐng)域布道師(Charles Frye),這使得文章內(nèi)容更為全面深入。他們從戰(zhàn)術(shù)、運(yùn)營和戰(zhàn)略三個(gè)部分展開解讀了自己過去一年有關(guān)LLM應(yīng)用開發(fā)與運(yùn)營的全方位經(jīng)驗(yàn)。
一、戰(zhàn)術(shù)篇
本部分探討有關(guān)提升質(zhì)量和可靠性的提示技巧、構(gòu)建檢索增強(qiáng)生成(RAG)、應(yīng)用流程工程( flow engineering)以及評估和監(jiān)控的最佳實(shí)踐和常見陷阱,進(jìn)而構(gòu)建穩(wěn)健的LLM應(yīng)用。
提示技巧
在開發(fā)新應(yīng)用時(shí),建議首先考慮提示技術(shù)。提示的重要性往往容易被人低估或高估。它被低估是因?yàn)?,正確的提示技巧若使用得當(dāng),可以帶來意想不到的成效。而其被高估,則是因?yàn)?,即便是基于提示的?yīng)用,也需要圍繞提示進(jìn)行大量的工程設(shè)計(jì)才能確保良好的運(yùn)行。
盡可能利用基礎(chǔ)的提示技術(shù)獲取最大收益
一些提示技巧在各種模型和任務(wù)上一直有助于提升性能:n-shot 提示 + 上下文學(xué)習(xí), chain-of-thought, 以及提供相關(guān)資源。
通過n-shot提示進(jìn)行的上下文學(xué)習(xí)的思路是向LLM提供一些示例,利用這些示例展示了任務(wù)過程并將輸出與用戶期望對齊。
一些建議:
- 如果n太低,模型可能會過度依賴這些特定示例,損害其泛化能力。作為一個(gè)經(jīng)驗(yàn)法則,目標(biāo)是n ≥ 5。不要害怕高達(dá)幾十個(gè)的n。
- 示例應(yīng)代表預(yù)期輸入分布。如果你正在構(gòu)建一個(gè)電影摘要器,包括不同類型的樣本,大致按照期望在實(shí)踐中看到的比例。
- 不一定需要提供完整的輸入-輸出對。在許多情況下,僅僅提供所需輸出的示例就足夠了。
- 如果正在使用一個(gè)支持工具調(diào)用( tool use)的LLM,n-shot示例也應(yīng)使用希望Agent使用的工具。
在chain-of-thought (CoT)提示中,鼓勵(lì)大語言模型在返回最終回答之前解釋它的思考過程。把它想象成為大語言模型提供一個(gè)草稿本,這樣它就不必全部在內(nèi)存中完成。原始方法是簡單地添加短語“讓我們一步一步來思考”作為指令的一部分。然而,我們發(fā)現(xiàn)讓CoT更具體,通過額外的一兩個(gè)句子增加具體性,通常能顯著減少幻覺率。例如,當(dāng)讓一個(gè)LLM總結(jié)會議紀(jì)要時(shí),可以明確相關(guān)步驟,例如:
- 首先,在草稿本上列出關(guān)鍵決策、后續(xù)事項(xiàng)及相關(guān)負(fù)責(zé)人。
- 然后,檢查草稿本中的細(xì)節(jié)與記錄是否事實(shí)一致。
- 最后,將關(guān)鍵點(diǎn)整合成簡明的摘要。
最近,出現(xiàn)一些有關(guān)COT技術(shù)是否有效的質(zhì)疑(Chain of Thoughtlessness? An Analysis of CoT in Planning(https://arxiv.org/abs/2405.04776)),以及使用COT 進(jìn)行推理時(shí)究竟發(fā)生了什么,存在著明顯的爭論。但無論如何,這是一個(gè)值得嘗試的技術(shù)。
提供相關(guān)資源是擴(kuò)展模型知識庫、減少幻覺和增加用戶信任的強(qiáng)大機(jī)制。這通常通過檢索增強(qiáng)生成 (RAG) 來完成,為模型提供它可以直接利用的文本片段是一種必不可少的技巧。提供相關(guān)資源時(shí),僅僅包含它們是不夠的;別忘了告訴模型優(yōu)先使用它們,直接引用它們,有時(shí)還要提及哪些資源不足。這些都有助于將Agent基于知識庫作出響應(yīng)。
結(jié)構(gòu)化輸入和輸出
構(gòu)建結(jié)構(gòu)化的輸入和輸出有助于模型更好地理解輸入,以及可靠地輸出以便于與下游系統(tǒng)集成。向輸入添加序列化格式可以給模型提供更多線索以理解上下文中Token和附加元數(shù)據(jù)(如類型)的特定Token之間的關(guān)系,或?qū)⒄埱笈c模型訓(xùn)練數(shù)據(jù)中的類似示例關(guān)聯(lián)。
例如,互聯(lián)網(wǎng)上關(guān)于編寫SQL的許多問題都是通過指定SQL schema開始的。因此,可能期望有效的Text-to-SQL提示應(yīng)包括結(jié)構(gòu)化的schema定義。
結(jié)構(gòu)化輸出具有類似的目的,但它也簡化了整合到系統(tǒng)的下游組件中。Instructor 和Outlines 對于結(jié)構(gòu)化輸出很有幫助。(如果正在導(dǎo)入LLM API SDK,使用Instructor; 如果正在導(dǎo)入Huggingface以用于自托管模型,使用 Outlines。)結(jié)構(gòu)化輸入清晰地表達(dá)任務(wù),并類似于訓(xùn)練數(shù)據(jù)的格式化,增加了提升輸出更好的可能性。
當(dāng)使用結(jié)構(gòu)化輸入時(shí),要意識到每種LLM都有它們自己的偏好。Claude偏好xml,而GPT偏愛Markdown和JSON。使用XML,甚至可以通過提供一個(gè)響應(yīng)標(biāo)簽來預(yù)填Claude的響應(yīng),就像這樣。
messages=[
{
"role": "user",
"content": """Extract the <name>, <size>, <price>, and <color>
from this product description into your <response>.
<description>The SmartHome Mini
is a compact smart home assistant
available in black or white for only $49.99.
At just 5 inches wide, it lets you control
lights, thermostats, and other connected
devices via voice or app—no matter where you
place it in your home. This affordable little hub
brings convenient hands-free control to your
smart devices.
</description>"""
},
{
"role": "assistant",
"content": "<response><name>"
}
]
編寫“單一職責(zé)”的小提示
在軟件開發(fā)中,有一個(gè)常見的反模式“全能型對象”(God Object),也就是指那種幾乎包攬所有功能的類或函數(shù)。在編寫提示(Prompt)時(shí),這一概念同樣適用。最開始,編寫提示往往是簡明扼要的:寫下幾句指示語,舉幾個(gè)例子,接著事情就可以開展了。不過,隨著我們試圖提高程序性能,處理越來越多的特殊情況,提示中的復(fù)雜性也在不知不覺中增長。這意味著需要更多的指示語和更復(fù)雜的邏輯推理,還要加入許多例子。就這樣,一段原本簡短的提示竟變成了一個(gè)長達(dá) 2,000 Token 的龐然大物。更令人頭痛的是,它對那些更常見、更簡單的情況的處理效果還不如以前那樣好了!
在努力讓系統(tǒng)和代碼保持簡潔的同時(shí),在創(chuàng)建提示方面也應(yīng)該堅(jiān)持這一原則。就以會議紀(jì)要為例,可以將它拆解成幾個(gè)步驟:
1. 將關(guān)鍵決策、待辦事項(xiàng)以及責(zé)任承擔(dān)者提取出來,并整理成結(jié)構(gòu)化的格式。
2. 核對提取出的信息,確保其與原始會議記錄的內(nèi)容保持一致。
3. 基于已結(jié)構(gòu)化的信息,生成一個(gè)簡練的摘要。
如此一來,就可將一個(gè)復(fù)雜的提示拆分成了多個(gè)簡單、專注并且容易理解的小提示。分開處理這些提示之后,也就能夠逐一迭代和評估它們。
優(yōu)化上下文
重新審視必須向 Agent 提供多少上下文信息。學(xué)習(xí)米開朗基羅,不是堆砌,而是精簡。RAG 被廣泛用于整合所有可能相關(guān)的信息片段,但關(guān)鍵在于如何從中提煉出必要內(nèi)容?
把發(fā)送給模型的最終提示——全部上下文、元提示(meta-prompting)以及 RAG 結(jié)果——單獨(dú)放在一張白紙上閱讀,能有效幫助重新審視上下文配置。這種方法會幫助發(fā)現(xiàn)了文中的冗余、自我矛盾及格式問題。
另一個(gè)重要的優(yōu)化點(diǎn)在于上下文的結(jié)構(gòu)安排。將文檔以“袋子模型(bag-of-docs)”的形式呈現(xiàn)對人幫助不大,不應(yīng)默認(rèn)它對 Agent同樣有效。應(yīng)深思熟慮地組織上下文結(jié)構(gòu),明確突出不同部分之間的關(guān)系,盡可能地簡化信息抽取過程。
信息檢索/RAG
除了提示之外,另一個(gè)引導(dǎo)LLM的有效方法是在提示中提供知識。這會將LLM建立在提供的上下文中,然后用于上下文學(xué)習(xí)。這就是所謂的檢索增強(qiáng)生成 (RAG)。實(shí)踐者發(fā)現(xiàn) RAG 在提供知識和提高輸出方面非常有效,同時(shí)與微調(diào)相比,它需要更少的努力和成本。RAG 的效果取決于檢索到的文檔的相關(guān)性、密度和細(xì)節(jié)。
檢索增強(qiáng)生成(RAG)的輸出質(zhì)量取決于檢索到的文檔的質(zhì)量,而文檔質(zhì)量可以從以下幾個(gè)方面考慮。
第一個(gè)也是最明顯的指標(biāo)是相關(guān)性。這通常通過排名指標(biāo)量化,例如平均倒數(shù)排名 (MRR) 或歸一化折現(xiàn)累積增益 (NDCG)。MRR 評估系統(tǒng)在排序列表中將第一個(gè)相關(guān)結(jié)果排名的效果,而 NDCG 則考慮所有結(jié)果的相關(guān)性及其位置。它們衡量系統(tǒng)在將相關(guān)文檔排得更高,而將不相關(guān)文檔排得更低方面的效果。例如,如果我們要檢索用戶摘要來生成電影評論摘要,我們會希望將特定電影的評論排得更高,同時(shí)排除其他電影的評論。
與傳統(tǒng)的推薦系統(tǒng)類似,檢索到的項(xiàng)目的排名將對 LLM 在下游任務(wù)中的表現(xiàn)產(chǎn)生重大影響。為了衡量這種影響,運(yùn)行一個(gè)基于 RAG 的任務(wù),但將檢索到的項(xiàng)目打亂 - RAG 輸出的表現(xiàn)如何?
其次,還需要考慮信息密度。如果兩篇文檔同樣相關(guān),應(yīng)該優(yōu)先考慮更簡潔、包含更少無關(guān)細(xì)節(jié)的文檔?;氐诫娪袄?,可以認(rèn)為電影劇本和所有用戶評論在廣義上都是相關(guān)的。但是,最高評分的評論和編輯評論可能在信息密度方面更高。
最后,考慮文檔中提供的細(xì)節(jié)程度。假設(shè)要構(gòu)建一個(gè) RAG 系統(tǒng),從自然語言生成 SQL 查詢??梢院唵蔚靥峁┌忻谋砀窦軜?gòu)作為上下文。但是,如果包含列描述和一些代表性值呢?額外的細(xì)節(jié)可以幫助 LLM 更好地理解表格的語義,從而生成更準(zhǔn)確的 SQL。
不要忘記關(guān)鍵字搜索;將其作為基準(zhǔn)并用于混合搜索。
鑒于基于向量檢索的 RAG 演示如此流行,人們很容易忘記或忽視信息檢索領(lǐng)域數(shù)十年的研究和解決方案。
盡管如此,embedding無疑是一種強(qiáng)大的工具,但它并不是萬能的。首先,雖然embedding擅長捕捉高層次的語義相似性,但在處理更具體的、基于關(guān)鍵字的查詢時(shí),比如用戶搜索姓名(如 Ilya)、縮略語(如 RAG)或 ID(如 claude-3-sonnet)時(shí),嵌入式可能會顯得力不從心。基于關(guān)鍵字的搜索,如 BM25,就是為此而明確設(shè)計(jì)的。經(jīng)過多年的基于關(guān)鍵字的搜索,用戶可能已經(jīng)認(rèn)為這是理所當(dāng)然的,如果他們期望檢索的文檔沒有被返回,他們可能會感到沮喪。
其次,使用關(guān)鍵字檢索可以更直觀地了解檢索到文檔的原因--可以查看與查詢相匹配的關(guān)鍵字。相比之下,基于嵌入的檢索就不那么容易理解了。最后,由于 Lucene 和 OpenSearch 等系統(tǒng)經(jīng)過數(shù)十年的優(yōu)化和實(shí)戰(zhàn)檢驗(yàn),關(guān)鍵詞搜索的計(jì)算效率通常更高。
在大多數(shù)情況下,混合搜索的效果最好:關(guān)鍵詞匹配用于明顯的匹配,嵌入式搜索用于同義詞、超義詞和拼寫錯(cuò)誤,以及多模態(tài)搜索(如圖像和文本)。Shortwave 分享了他們?nèi)绾螛?gòu)建 RAG 管道(https://www.shortwave.com/blog/deep-dive-into-worlds-smartest-email-ai/),包括查詢重寫、關(guān)鍵詞 + 嵌入檢索和排序。
對于新知識,優(yōu)先考慮 RAG 而不是微調(diào)
RAG 和微調(diào)都可以用來將新信息整合到LLM中,并提升特定任務(wù)的性能。那么,應(yīng)該先嘗試哪個(gè)呢?
最近的研究表明,RAG 可能更勝一籌。一項(xiàng)研究將 RAG 與無監(jiān)督微調(diào)(也稱為持續(xù)預(yù)訓(xùn)練)進(jìn)行了比較,并在 MMLU 的一個(gè)子集和當(dāng)前事件上評估了兩種方法。他們發(fā)現(xiàn),對于訓(xùn)練過程中遇到的知識以及全新的知識,RAG 的性能始終優(yōu)于微調(diào)。在另一篇論文中,他們將 RAG 與農(nóng)業(yè)數(shù)據(jù)集上的監(jiān)督微調(diào)進(jìn)行了比較。同樣地,RAG 帶來的性能提升比微調(diào)更大,尤其是對于 GPT-4(參見論文的表格 20)。
除了性能提升之外,RAG 還具有幾個(gè)實(shí)際優(yōu)勢。首先,與持續(xù)預(yù)訓(xùn)練或微調(diào)相比,更新檢索索引更容易,也更便宜!其次,如果檢索索引中存在包含有毒或有偏見內(nèi)容的問題文檔,可以輕松地刪除或修改這些文檔。
此外,RAG 中的 R (檢索)提供了對文檔檢索方式的更細(xì)粒度的控制。例如,如果我們?yōu)槎鄠€(gè)組織托管 RAG 系統(tǒng),通過對檢索索引進(jìn)行分區(qū),可以確保每個(gè)組織只能檢索到自己索引中的文檔。這可以確保不會無意中將一個(gè)組織的信息暴露給另一個(gè)組織。
長文本模型并不會讓 RAG 過時(shí)
Gemini 1.5 提供了高達(dá) 1000 萬個(gè)標(biāo)記的上下文窗口,有些人開始質(zhì)疑 RAG 的未來。
雖然長上下文對于分析多個(gè)文檔或與 PDF 聊天等用例來說是一個(gè)改變游戲規(guī)則的功能,但關(guān)于 RAG 即將消亡的傳言都被大大夸大了。
首先,即使上下文窗口有 1000 萬個(gè) token,仍然需要一種方法來選擇信息輸入模型。其次,除了狹窄的“大海撈針”評估之外,還沒有看到令人信服的數(shù)據(jù)表明模型可以有效地推理如此大的上下文。因此,如果沒有好的檢索(和排序),可能會讓模型被干擾因素所淹沒,甚至可能會用完全不相關(guān)的信息填充上下文窗口。
最后是成本。Transformer 的推理成本隨著上下文長度呈二次方增長(或在空間和時(shí)間上都呈線性增長)。僅僅因?yàn)榇嬖谝粋€(gè)模型可以在回答每個(gè)問題之前讀取你組織的整個(gè) Google Drive 內(nèi)容,并不意味著這是一個(gè)好主意。可以類比一下如何使用 RAM:仍然從磁盤讀取和寫入,即使存在 RAM 達(dá)到數(shù)十 TB 的計(jì)算實(shí)例。
所以,不要急著把你的 RAG 扔進(jìn)垃圾桶。即使上下文窗口的大小不斷增大,這種模式仍然會很有用。
微調(diào)和優(yōu)化工作流(Workflow)
提示引導(dǎo)LLM只是第一步。為了充分利用它們,需要跳出單一提示的局限,擁抱工作流。例如,如何將一個(gè)復(fù)雜的任務(wù)分解成多個(gè)更簡單的任務(wù)?微調(diào)或緩存何時(shí)有助于提高性能并降低延遲/成本?下面分享一些經(jīng)過驗(yàn)證的策略和真實(shí)世界的例子,幫助優(yōu)化和構(gòu)建可靠的 LLM 工作流。
逐步的多輪“流程”可以帶來巨大的提升。我們已經(jīng)知道,將一個(gè)大型提示分解成多個(gè)較小的提示,可以獲得更好的結(jié)果。AlphaCodium 就是一個(gè)例子:通過從單一提示切換到多步驟工作流程,他們將 GPT-4 在 CodeContests 上的準(zhǔn)確率(pass@5)從 19% 提高到 44%。詳細(xì)閱讀:??微軟、OpenAI大佬暗示LLM應(yīng)用開發(fā)范式遷移:從Prompt Engineering到Flow Engineering??。該工作流程包括:
- 反思問題
- 在公開測試集上進(jìn)行推理
- 生成可能的方案
- 對可能的方案進(jìn)行排序
- 生成合成測試集
- 在公開測試集和合成測試集中反復(fù)迭代方案。
目標(biāo)明確的小任務(wù)最適合作為Agent或流程提示。雖然不強(qiáng)制要求每個(gè)Agent提示都請求結(jié)構(gòu)化輸出,但是,結(jié)構(gòu)化輸出對于與編排Agent與環(huán)境互動的任何系統(tǒng)的接口都有很大幫助。
一些嘗試:
- 一個(gè)明確的規(guī)劃步驟,盡可能嚴(yán)格規(guī)定。考慮提供預(yù)定義的計(jì)劃供選擇。
- 將原始的用戶提示改寫成Agent提示。注意,這個(gè)過程是有損失的!
- 以Chain、DAG 和狀態(tài)機(jī)的Agent行為;不同的依賴關(guān)系和邏輯關(guān)系可能更適合不同的規(guī)模,也可能不那么適合。能否從不同的任務(wù)架構(gòu)中優(yōu)化性能?
- 規(guī)劃驗(yàn)證;規(guī)劃可以包括如何評估其他Agent響應(yīng)的說明,以確保最終組裝能很好地協(xié)同工作。
- 具有固定上游狀態(tài)的提示工程--確保Agent提示是根據(jù)之前可能發(fā)生的情況的變體集合進(jìn)行評估的。
優(yōu)先采用確定性的工作流
雖然 Agent可以動態(tài)地響應(yīng)用戶請求和環(huán)境,但它們的非確定性本質(zhì)使得它們難以部署。Agent執(zhí)行的每個(gè)步驟都有失敗的可能性,而從錯(cuò)誤中恢復(fù)的可能性很小。因此,代理成功完成多步任務(wù)的可能性隨著步驟數(shù)量的增加而呈指數(shù)級下降。結(jié)果,構(gòu)建Agent的團(tuán)隊(duì)發(fā)現(xiàn)很難部署可靠的Agent。
一種很有前景的方法是讓Agent系統(tǒng)生成確定性的計(jì)劃,然后以結(jié)構(gòu)化、可重復(fù)的方式執(zhí)行這些計(jì)劃。在第一步中,給定一個(gè)高級目標(biāo)或提示,Agent會生成一個(gè)計(jì)劃。然后,該計(jì)劃以確定性的方式執(zhí)行。這使得每個(gè)步驟都更加可預(yù)測和可靠。好處包括:
- 生成的計(jì)劃可以作為少量樣本,用于提示或微調(diào)。
- 確定性執(zhí)行使系統(tǒng)更加可靠,因此更易于測試和調(diào)試。此外,故障可以追溯到計(jì)劃中的特定步驟。
- 生成的計(jì)劃可以表示為有向無環(huán)圖(DAG),與靜態(tài)提示相比,它更容易理解和適應(yīng)新情況。
最成功的Agent構(gòu)建者可能是那些在管理初級工程師方面經(jīng)驗(yàn)豐富的人,因?yàn)樯捎?jì)劃的過程類似于我們?nèi)绾沃笇?dǎo)和管理初級工程師。我們給初級工程師明確的目標(biāo)和具體的計(jì)劃,而不是含糊不清的開放式指示,我們也應(yīng)該對我們的Agent做同樣的事情。
最終,構(gòu)建可靠、可工作的Agent的關(guān)鍵可能在于采用更結(jié)構(gòu)化、確定性的方法,以及收集數(shù)據(jù)來改進(jìn)提示和微調(diào)模型。沒有這些,我們將構(gòu)建出可能在某些時(shí)候工作得異常好的Agent,但平均而言,會讓用戶失望,從而導(dǎo)致用戶保留率低。
除了溫度(temperature)之外,如何獲得更多樣化的輸出
假設(shè)你的任務(wù)需要 LLM 輸出的多樣性。也許你正在編寫一個(gè) LLM 管道,根據(jù)用戶之前購買的商品列表來推薦商品。當(dāng)你多次運(yùn)行提示時(shí),你可能會注意到生成的推薦結(jié)果過于相似——所以你可能會在 LLM 請求中增加溫度參數(shù)。
簡單來說,增加溫度參數(shù)會使 LLM 響應(yīng)更加多樣化。在采樣時(shí),下一個(gè)標(biāo)記的概率分布變得更加平坦,這意味著通常不太可能出現(xiàn)的標(biāo)記會被更多地選中。盡管如此,在增加溫度時(shí),你可能會注意到與輸出多樣性相關(guān)的某些故障模式。例如,目錄中一些可能很合適的商品可能永遠(yuǎn)不會被 LLM 輸出。如果這些商品在訓(xùn)練時(shí)非常有可能遵循提示,那么同一批商品可能會在輸出中過度表示。如果溫度過高,你可能會得到引用不存在的商品(或胡言亂語?。┑妮敵觥?/p>
換句話說,增加溫度并不能保證 LLM 會從你期望的概率分布(例如,均勻隨機(jī))中采樣輸出。盡管如此,我們還有其他技巧來增加輸出多樣性。最簡單的方法是調(diào)整提示中的元素。例如,如果提示模板包含一個(gè)項(xiàng)目列表,例如歷史購買記錄,每次將這些項(xiàng)目插入提示時(shí)對其進(jìn)行隨機(jī)排序會產(chǎn)生顯著影響。
此外,保留一個(gè)最近輸出的簡短列表有助于防止冗余。在推薦商品的例子中,通過指示 LLM 避免推薦來自這個(gè)最近列表的商品,或者通過拒絕并重新采樣與最近建議相似的輸出,可以進(jìn)一步使響應(yīng)多樣化。另一個(gè)有效的策略是改變提示中使用的措辭。例如,加入類似“選擇用戶會經(jīng)常使用并喜歡的商品”或“選擇用戶可能會推薦給朋友的商品”這樣的短語可以轉(zhuǎn)移焦點(diǎn),從而影響推薦商品的多樣性。
緩存作用被低估
緩存無需對相同輸入重新計(jì)算響應(yīng),從而節(jié)省了成本,消除了生成延遲。此外,如果某個(gè)回復(fù)之前已被屏蔽,我們就可以提供經(jīng)過審核的回復(fù),從而降低提供有害或不適當(dāng)內(nèi)容的風(fēng)險(xiǎn)。
一種直接的緩存方法是為正在處理的項(xiàng)目使用唯一的 ID,例如我們正在總結(jié)新文章或產(chǎn)品評論。當(dāng)收到請求時(shí),我們可以檢查緩存中是否已經(jīng)存在摘要。如果存在,我們可以立即返回;如果不存在,我們就生成、保護(hù)并提供摘要,然后將其存儲在緩存中,以備將來的請求。
對于更開放的查詢,我們可以借鑒搜索領(lǐng)域的技術(shù),后者也利用緩存來處理開放式輸入。自動完成和拼寫糾正等功能也有助于規(guī)范用戶輸入,從而提高緩存命中率。
何時(shí)微調(diào)
在某些任務(wù)中,即使是設(shè)計(jì)最巧妙的提示也會有不足之處。例如,即使經(jīng)過大量的提示工程設(shè)計(jì),系統(tǒng)可能仍然無法返回可靠、高質(zhì)量的輸出。如果是這樣,就有必要針對特定任務(wù)對模型進(jìn)行微調(diào)。
最佳實(shí)踐:
- Honeycomb 的自然語言查詢助手:最初,"programming manual "是在提示中提供的,同時(shí)還提供了 n 個(gè)示例供用戶在上下文中學(xué)習(xí)。雖然效果不錯(cuò),但對模型進(jìn)行微調(diào)后,特定領(lǐng)域語言的語法和規(guī)則輸出效果更好。地址:https://www.honeycomb.io/blog/introducing-query-assistant
然而,微調(diào)雖然有效,但代價(jià)也很大。需要對微調(diào)數(shù)據(jù)進(jìn)行標(biāo)注,對模型進(jìn)行微調(diào)和評估,并最終對模型進(jìn)行部署管理。因此,要考慮較高的前期成本是否值得。如果通過提示可以實(shí)現(xiàn) 90% 的目標(biāo),那么微調(diào)可能就不值得投入。不過,如果決定進(jìn)行微調(diào),為了降低收集人工標(biāo)注樣本的成本,可以在合成數(shù)據(jù)上生成并進(jìn)行微調(diào),或者在開源數(shù)據(jù)上進(jìn)行微調(diào)。
評估與監(jiān)督
評估 LLM 可能是一個(gè)雷區(qū)。LLM 的輸入和輸出是任意文本,我們?yōu)槠湓O(shè)定的任務(wù)也多種多樣。然而,嚴(yán)謹(jǐn)周到的評估至關(guān)重要--OpenAI 的技術(shù)領(lǐng)袖就從事評估工作并對個(gè)別評估提出反饋意見絕非偶然。
評估 LLM 應(yīng)用程序需要多種定義和還原:它可以是簡單的單元測試,也可以更像是可觀測性,還可能只是數(shù)據(jù)科學(xué)。我們發(fā)現(xiàn)所有這些觀點(diǎn)都很有用。在下面的章節(jié)中,我們將就構(gòu)建評估 和監(jiān)控pipeline的重要性提供一些經(jīng)驗(yàn)。
從真實(shí)的輸入/輸出樣本中創(chuàng)建一些基于斷言的單元測試
創(chuàng)建單元測試(即斷言),其中包含來自生產(chǎn)的輸入和輸出樣本,并基于至少三個(gè)標(biāo)準(zhǔn)對輸出進(jìn)行預(yù)期。雖然三個(gè)標(biāo)準(zhǔn)可能看起來是任意的,但這是一個(gè)實(shí)用的開始數(shù)字;更少的標(biāo)準(zhǔn)可能表明你的任務(wù)沒有得到充分定義或過于開放,就像一個(gè)通用聊天機(jī)器人。這些單元測試或斷言應(yīng)該由pipeline中的任何更改觸發(fā),無論它是編輯提示、通過 RAG 添加新上下文還是其他修改。這篇寫作用例中給出了一個(gè)基于斷言的測試示例(https://hamel.dev/blog/posts/evals/#step-1-write-scoped-tests)。
考慮從指定要包含或排除在所有響應(yīng)中的短語或想法的斷言開始。還要考慮檢查以確保單詞、項(xiàng)目或句子計(jì)數(shù)在一定范圍內(nèi)。對于其他類型的生成,斷言看起來可能不同。執(zhí)行評估(Execution-evaluation)是評估代碼生成的一種強(qiáng)大方法,其中你運(yùn)行生成的代碼并確定運(yùn)行時(shí)的狀態(tài)是否足以滿足用戶請求。
舉例來說,如果用戶需要一個(gè)名為 foo 的新函數(shù),那么在執(zhí)行Agent生成的代碼后,foo 應(yīng)該是可調(diào)用的!執(zhí)行評估所面臨的一個(gè)挑戰(zhàn)是,Agent代碼離開運(yùn)行時(shí)的形式經(jīng)常與目標(biāo)代碼略有不同。將斷言 "放寬 "到任何可行答案都能滿足的絕對最弱假設(shè)是有效的。
最后,按照客戶的預(yù)期使用產(chǎn)品(即 "dogfooding")可以深入了解真實(shí)世界數(shù)據(jù)中的失敗類型。這種方法不僅有助于識別潛在的弱點(diǎn),還能提供有用的生產(chǎn)樣本,并將其轉(zhuǎn)換為 evals。
LLM-as-Judge(LLM充當(dāng)法官)可以(在一定程度上)發(fā)揮作用,但并不是銀彈
LLM-as-Judge,即我們使用一個(gè)強(qiáng)大的 LLM 來評估其他 LLM 的輸出,有些人對此持懷疑態(tài)度。(不過,如果實(shí)施得當(dāng),LLM-as-Judge 與人類判斷之間的相關(guān)性還是不錯(cuò)的,至少可以幫助建立新提示或新技術(shù)的性能預(yù)設(shè)。具體來說,在進(jìn)行配對比較(如對照組與治療組)時(shí),LLM-as-Judge 通常能正確地判斷方向,盡管輸贏的偏差可能比較大。
以下是一些建議,可以讓LLM-as-Judge 發(fā)揮最大作用:
- ?使用成對比較:與其要求 LLM 在Likert scale上對單項(xiàng)輸出打分,不如向它提供兩個(gè)選項(xiàng),讓它選擇更好的那個(gè)。這往往會帶來更穩(wěn)定的結(jié)果。
- 控制位置偏差:提交選項(xiàng)的順序會使 LLM 的決策出現(xiàn)偏差。為了減少這種偏差,可以將每個(gè)配對比較進(jìn)行兩次,每次交換配對的順序。交換順序后,確保正確的選項(xiàng)獲勝!
- 允許并列:在某些情況下,兩個(gè)選項(xiàng)可能同樣好。因此,允許LLM宣布平局,這樣就不必武斷地選出勝者。
- 使用COT:在給出最終偏好之前,要求 LLM 解釋其決定,可以提高評估的可靠性。另外,這還能讓您使用較弱但較快的 LLM,并仍能獲得類似的結(jié)果。由于pipeline的這一部分經(jīng)常處于批處理模式,CoT 帶來的額外延遲不成問題。
- 控制回答長度:LLM 往往偏向于較長的回答。為減少這種偏差,應(yīng)確保成對的回答長度相似。
LLM-as-Judge 的一個(gè)特別強(qiáng)大的應(yīng)用是根據(jù)回歸結(jié)果檢查新的提示策略。如果已經(jīng)跟蹤了一系列生產(chǎn)結(jié)果,有時(shí)可以使用新的提示策略重新運(yùn)行這些生產(chǎn)示例,并使用 LLM-as-Judge 快速評估新策略可能存在的問題。
下面是一個(gè)簡單而有效的 "LLM-as-Judge "迭代方法示例,我們只需記錄 LLM 響應(yīng)、法官評價(jià)(即 CoT)和最終結(jié)果。然后與利益相關(guān)者一起對其進(jìn)行審查,以確定需要改進(jìn)的地方。經(jīng)過三次迭代,人類與 LLM 的一致性從 68% 提高到 94%!
不過,LLM-as-Judge 并非銀彈。在語言的某些微妙方面,即使是最強(qiáng)大的模型也無法進(jìn)行可靠的評估。此外,我們還發(fā)現(xiàn)傳統(tǒng)的分類器和獎(jiǎng)勵(lì)模型可以達(dá)到比 LLM-as-Judge 更高的準(zhǔn)確度,而且成本和延遲更低。在代碼生成方面,LLM-as-Judge 可能比執(zhí)行評估等更直接的評估策略更弱。
"實(shí)習(xí)生測試”評估產(chǎn)品
在評估一代產(chǎn)品時(shí),我們喜歡使用以下 "實(shí)習(xí)生測試":如果您將語言模型的準(zhǔn)確輸入(包括上下文)作為一項(xiàng)任務(wù)交給相關(guān)專業(yè)的普通大學(xué)生,他們能成功嗎?需要多長時(shí)間?
如果答案是否定的,因?yàn)長LM缺乏所需的知識,那么請考慮如何豐富背景知識。
如果答案是否定的,而且我們根本無法改進(jìn)語境來解決這個(gè)問題,那么我們可能遇到了對這代LLM來說太難的任務(wù)。
如果答案是肯定的,但需要一段時(shí)間,我們可以嘗試降低任務(wù)的復(fù)雜性。它可以分解嗎?任務(wù)的某些方面是否可以更加模板化?
如果答案是肯定的,他們會很快得到答案,那么就該深入研究數(shù)據(jù)了。模型做錯(cuò)了什么?我們能找到失敗的模式嗎?試著讓模型在做出反應(yīng)之前或之后解釋自己,以幫助你建立思維理論。
過分強(qiáng)調(diào)某些測試成績會影響整體成績
這方面的一個(gè)例子是 "大海撈針"(NIAH)評估。最初的評估有助于量化模型召回率隨著上下文大小的增加而增加,以及召回率如何受針的位置影響。然而,它已經(jīng)被過分強(qiáng)調(diào),以至于在雙子座 1.5 的報(bào)告中被列為圖 1。評估涉及在重復(fù)保羅-格雷厄姆(Paul Graham)文章的長文檔中插入一個(gè)特定短語("The special magic {city} number is: {number}"),然后提示模型回憶魔術(shù)數(shù)字(magic number)。
雖然有些模型可以達(dá)到近乎完美的記憶效果,但 NIAH 是否真正反映了實(shí)際應(yīng)用中所需的推理和記憶能力,還是個(gè)問題。考慮一個(gè)更實(shí)際的場景:給定一個(gè)小時(shí)的會議紀(jì)要,LLM能否總結(jié)出關(guān)鍵決策和下一步步驟,并將每個(gè)項(xiàng)目正確歸屬于相關(guān)人員?這項(xiàng)任務(wù)更切合實(shí)際,它超越了死記硬背的范疇,還考慮了解析復(fù)雜討論、識別相關(guān)信息和綜合總結(jié)的能力。
下面是一個(gè)實(shí)用的 NIAH 評估實(shí)例。利用醫(yī)患視頻通話的記錄,LLM 被問及病人的用藥情況。其中還包括一個(gè)更具挑戰(zhàn)性的 NIAH,即插入一個(gè)關(guān)于披薩配料的隨機(jī)配料的短語,例如 "制作完美披薩所需的秘密配料是:浸泡過濃咖啡的紅棗、檸檬、杏仁和杏仁油:浸泡過濃咖啡的紅棗、檸檬和山羊奶酪"。藥物任務(wù)的回憶率約為 80%,披薩任務(wù)的回憶率為 30%。
另外,過分強(qiáng)調(diào) NIAH 評估可能會降低提取和總結(jié)任務(wù)的性能。因?yàn)檫@些 LLM 非常精細(xì)地關(guān)注每個(gè)句子,它們可能會開始將無關(guān)細(xì)節(jié)和干擾項(xiàng)視為重要內(nèi)容,從而將其納入最終輸出(而它們本不應(yīng)該這樣做?。?/p>
這也適用于其他評估和用例。例如,總結(jié)。強(qiáng)調(diào)事實(shí)的一致性可能會導(dǎo)致摘要不那么具體(因此不太可能與事實(shí)不一致),也可能不那么相關(guān)。反之,如果強(qiáng)調(diào)寫作風(fēng)格和口才,則可能導(dǎo)致更多花哨的營銷型語言,從而造成事實(shí)不一致。
將標(biāo)注簡化為二元任務(wù)或成對比較
用Likert scale對模型輸出提供開放式反饋或評分對認(rèn)知能力要求很高。因此,收集到的數(shù)據(jù)會因人類評分者之間的差異而變得更加嘈雜,從而降低其實(shí)用性。更有效的方法是簡化任務(wù),減輕標(biāo)注者的認(rèn)知負(fù)擔(dān)。二元分類和成對比較是兩種行之有效的任務(wù)。
在二元分類中,標(biāo)注者需要對模型的輸出做出簡單的 "是 "或 "否 "判斷。他們可能會被問到生成的摘要是否與源文件的事實(shí)一致,或者建議的回復(fù)是否相關(guān),或者是否含有毒性。與Likert scale相比,二元判定更為精確,評分者之間的一致性更高,吞吐量也更大。Doordash 就是這樣設(shè)置標(biāo)簽隊(duì)列的,通過一棵 "是 "與 "否 "的問題樹來標(biāo)記菜單項(xiàng)。
在成對比較中,標(biāo)注者會看到一對模型響應(yīng),并詢問哪個(gè)更好。對于人類來說,說出 "A 比 B 好 "比單獨(dú)給 A 或 B 打分更容易,因此標(biāo)注速度更快、更可靠(比Likert scale更可靠)。在一次 Llama2 會議上,Llama2 論文的作者托馬斯-斯基亞洛姆(Thomas Scialom)證實(shí),成對比較比收集監(jiān)督下的微調(diào)數(shù)據(jù)(如書面回復(fù))更快、更便宜。前者的成本為每單位 3.5 美元,而后者的成本為每單位 25 美元。
(無參考文獻(xiàn))評估(EVAL)和圍欄(guardrails)可以互換使用
Guardrails 有助于捕捉不恰當(dāng)或有害的內(nèi)容,而 evals 則有助于衡量模型輸出的質(zhì)量和準(zhǔn)確性。就無參考的 evals 而言,它們可以說是一枚硬幣的兩面。無參照評估是指不依賴于 "黃金 "參照(如人工撰寫的答案)的評估,可以僅根據(jù)輸入提示和模型的響應(yīng)來評估輸出的質(zhì)量。
其中的一些例子是摘要評估,我們只需考慮輸入文檔,就能對摘要的事實(shí)一致性和相關(guān)性進(jìn)行評估。如果摘要在這些指標(biāo)上得分較低,我們就可以選擇不向用戶顯示它,從而有效地將評估用作圍欄。同樣,無參考翻譯 evals 可以在不需要人工翻譯參考的情況下評估翻譯質(zhì)量,這同樣允許我們將其用作圍欄。
LLM 在不應(yīng)該返回輸出時(shí)也會返回輸出
使用 LLM 時(shí)的一個(gè)主要挑戰(zhàn)是,它們經(jīng)常會在不應(yīng)該產(chǎn)生輸出的情況下產(chǎn)生輸出。這可能導(dǎo)致無害但無意義的響應(yīng),或更嚴(yán)重的缺陷,如毒性或危險(xiǎn)內(nèi)容。例如,當(dāng)被要求從文檔中提取特定屬性或元數(shù)據(jù)時(shí),LLM 可能會自信地返回值,即使這些值實(shí)際上并不存在。另外,由于我們在上下文中提供了非英語文檔,因此模型可能會以英語以外的語言做出響應(yīng)。
雖然我們可以嘗試提示 LLM 返回 "不適用 "或 "未知 "的響應(yīng),但這并非萬無一失。即使有對數(shù)概率,它們也不是衡量輸出質(zhì)量的好指標(biāo)。雖然日志概率表明了輸出中出現(xiàn)標(biāo)記的可能性,但并不一定反映了生成文本的正確性。相反,對于經(jīng)過訓(xùn)練以響應(yīng)查詢并生成連貫響應(yīng)的指令調(diào)整模型來說,對數(shù)概率可能沒有得到很好的校準(zhǔn)。因此,雖然高對數(shù)概率可能表明輸出是流暢和連貫的,但并不意味著它是準(zhǔn)確或相關(guān)的。
雖然謹(jǐn)慎的提示工程能在一定程度上起到幫助作用,但我們還應(yīng)輔之以強(qiáng)大的防護(hù)機(jī)制,以檢測和過濾/再生不受歡迎的輸出。例如,OpenAI 提供了一個(gè)內(nèi)容節(jié)制 API,可以識別不安全的回應(yīng),如仇恨言論、自殘或性輸出。同樣,還有許多用于檢測個(gè)人身份信息(PII)的軟件包。這樣做的好處之一是,guardrails 在很大程度上與用例無關(guān),因此可以廣泛應(yīng)用于特定語言的所有輸出。此外,通過精確檢索,如果沒有相關(guān)文檔,我們的系統(tǒng)可以確定性地回答 "我不知道"。
由此得出的一個(gè)推論是,LLM 可能無法在預(yù)期時(shí)間內(nèi)產(chǎn)生輸出結(jié)果。發(fā)生這種情況的原因有很多,從直接的問題(如來自 API 提供商的長尾延遲)到更復(fù)雜的問題(如輸出被內(nèi)容審核過濾器阻止)。因此,必須持續(xù)記錄輸入和(可能缺乏的)輸出,以便進(jìn)行調(diào)試和監(jiān)控。
幻覺是一個(gè)頑固的問題。
內(nèi)容安全或 PII 缺陷備受關(guān)注,因此很少發(fā)生,而事實(shí)不一致則不同,它頑固存在,檢測起來更具挑戰(zhàn)性。它們更常見,發(fā)生率基線為 5%-10%,而根據(jù)我們從LLM的提供者那里了解到的情況,要將其控制在 2% 以下是很有挑戰(zhàn)性的,即使是在摘要等簡單任務(wù)中也是如此。
為了解決這個(gè)問題,我們可以將提示工程(生成的上游)和事實(shí)不一致防護(hù)(生成的下游)結(jié)合起來。在提示工程方面,CoT 等技術(shù)可以讓 LLM 在最終返回輸出之前解釋其推理,從而幫助減少幻覺。然后,我們可以應(yīng)用事實(shí)不一致圍欄(https://eugeneyan.com/writing/finetuning/)來評估摘要的事實(shí)性,并過濾或重新生成幻覺。在某些情況下,幻覺可以被確定地檢測出來。在使用來自 RAG 檢索的資源時(shí),如果輸出是結(jié)構(gòu)化的,并能識別出資源是什么,那么就應(yīng)該能夠手動驗(yàn)證它們來自輸入上下文。
原文:https://www.oreilly.com/radar/what-we-learned-from-a-year-of-building-with-llms-part-i/
本文轉(zhuǎn)載自?? AI工程化??,作者: ully
