譯者 | 朱先忠
審校 | 重樓
引言
大型語言模型(LLM)存在巨大的潛力,但是想開發出高可靠性的生產級LLM應用程序仍然存在相當大的挑戰。在經歷過構建了數十個LLM系統的實踐后,我將成功開發LLM應用的公式提煉為任何團隊都可以遵循的3+1基本原則。
“LLM原生應用程序有10%是訓練復雜模型相關的工作,而另外90%則是實驗數據驅動的工程開發工作。”
構建生產級實用型LLM應用程序需要非常細致的工程實踐。當用戶無法直接與LLM交互時,必須精心編寫有關提示,以涵蓋所有細微差別,因為迭代用戶的反饋信息可能是不可用的。
LLM三角原則介紹
LLM三角原則概括了構建有效LLM原生應用程序的基本指導方針。這一原則提供了一個堅實的概念框架,指導開發人員構建健壯可靠的LLM原生應用程序,并提供指導和支持。
從SOP視角優化三個突出的原則,從而實現最佳的LLM使用
關鍵點
總體來看,LLM三角原則引入了四種編程原則,以幫助你設計和構建LLM原生應用程序。
其中,第一個原則是標準操作程序(SOP:Standard Operating Procedure)。SOP提出我們三角形的三個頂點:模型、工程技術和上下文數據。
通過SOP的視角優化上述三角形的三個頂點的原則是確保高性能LLM原生應用程序的關鍵。
1.標準操作程序(SOP)
標準操作程序(SOP)是工業界眾所周知的術語。這是一套由大型組織編寫的分步驟說明,旨在幫助員工進行日常操作,同時每次都能保持高質量和相似的結果。通過編寫詳細的說明,這將缺乏經驗或低技能的工人變成了專家。
LLM三角原則借鑒了SOP范式,并鼓勵你將該模型視為缺乏經驗/不熟練的工人。我們可以通過向模型“講授”專家應該如何執行這項任務,來確保更高質量的結果。
SOP指導原則
“如果沒有SOP,即使是最強大的LLM也無法提供始終如一的高質量結果。”
在思考SOP指導原則時,我們應該確定哪些技術將幫助我們最有效地實施SOP。
(1)認知建模
為了創建SOP,我們需要選取表現最佳的員工(領域專家),模擬他們如何思考和工作,以實現相同的結果,并記錄下他們所做的一切。
在經過精心編輯和正式確定之后,我們將提供詳細的說明來幫助每一位缺乏經驗或低技能的工人取得成功,并做出優秀的工作業績。
與人類一樣,通過簡化或拆分任務來減少任務的認知難度至關重要。遵循簡單的循序漸進的指導比冗長復雜的程序更直接。
在這個過程中,我們識別出隱藏于其中的隱式認知“跳躍”——專家們采取的小而無意識的步驟,這些步驟會顯著影響結果。這些微妙的、無意識的、往往不言而喻的假設或決定會對最終結果產生重大影響。
“隱式認知跳躍”的一個例子
假設我們想為SQL分析師建模。我們將首先采訪他們,并問他們幾個問題,例如:
- 當要求你分析一個業務問題時,你會怎么做?
- 你如何確保你的解決方案滿足要求?
- <向受訪者反映我們所理解的過程>
- 這能準確地捕捉到你所理解的過程嗎<獲得更正>
- 等等……
一個分析師所經歷的認知過程及對其進行建模的舉例
隱式認知過程呈現出多種形態和形式;一個典型的例子是“特定領域的定義”。例如,“暢銷書”可能是我們領域專家的一個突出術語,而不是其他所有人都了解的術語。
在我們的SQL分析示例中擴展隱式認知過程
最終,我們將獲得一個完整的SOP“配方”,讓我們能夠模仿我們表現最佳的分析師。
在繪制這些復雜的過程時,將其可視化為圖形可能會有所幫助。當整個過程微妙且涉及許多步驟、條件和拆分時,這尤其有用。
圖形形式顯示的“SQL Analyst SOP”包括所有必需的技術步驟
我們的最終解決方案應該模仿SOP中定義的步驟。在此階段,請盡量忽略最終的實現部分。稍后,你可以在整個解決方案中的一個或多個步驟/鏈上實現它。
與其他原則不同,認知建模(SOP寫作)是唯一獨立的過程。強烈建議你在編寫代碼之前先對流程進行建模。話雖如此,在實施它的同時,你可能會根據你獲得的新見解或理解來加以改變。
現在,我們了解了創建一個定義良好的SOP的重要性,該SOP指導我們對問題的業務理解,讓我們探索如何使用各種工程技術有效地實施它。
2.工程技術
工程技術可幫助你實際實施SOP并充分利用模型。在考慮工程技術原則時,我們應該考慮工具箱中的哪些工具(技術)可以幫助我們實施和塑造我們的SOP,并幫助模型實現與我們進行良好的溝通。
工程技術原理示意圖
值得注意的是,一些工程技術僅在提示層中實現,而許多技術需要軟件層才能有效,還有些技術需要將兩層結合在一起。
工程技術層架構
雖然幾乎每天工程技術人員都會發現與發明一些細微差別和技術改進,在此我將介紹兩種主要技術:工作流/鏈和代理。
(1)LLM原生架構(又名“流工程”或“鏈”)
LLM原生架構描述了應用程序為生成任務結果而經歷的代理執行流程。
我們流程中的每一步都是一個獨立的過程,必須發生該過程才能完成我們的任務。其中,一些步驟將會以簡單的確定性代碼方式執行;而對于另外某些步驟,我們會使用LLM(代理)方式來執行。
為此,我們可以進一步反思我們繪制的標準操作程序(SOP)并思考如下問題:
- 我們應該將哪些SOP步驟分配到同一代理上?作為不同的代理,我們應該采取哪些步驟?
- 哪些SOP步驟應該以獨立的方式執行(但它們可能會收到之前步驟的信息)?
- 在確定性代碼執行方式中,我們可以執行哪些SOP步驟?
- 等等……
一個基于給定SOP的“維基百科作者”應用的LLM原生架構示例
在分析我們前面所給出的架構/圖的下一個步驟之前,我們首先定義此步驟的關鍵屬性:
輸入和輸出——這一步驟的特征是什么?在我們采取行動之前需要準備些什么?(這也可以作為代理的輸出格式)
- 質量保證——是什么讓響應“足夠好”?是否有需要人為干預的情況?我們可以配置哪些類型的斷言?
- 自主水平——我們需要對結果的質量進行多少控制?這個階段可以處理哪些用例?換句話說,在這一點上,我們能在多大程度上相信模型能夠獨立工作?
- 觸發器——下一步驟是什么?下一步驟的定義是什么?
- 非功能性——所需的延遲是多少?我們需要特殊的業務監控嗎?
- 故障轉移控制——可能發生哪些類型的故障(系統性和代理性)?我們的退路是什么?
- 狀態管理——我們需要一個特殊的狀態管理機制嗎?我們如何檢索/保存狀態(定義索引鍵)?我們需要持久性存儲嗎?這種狀態的不同用法是什么(例如緩存、日志記錄等)?
- 等等……
(2)什么是代理?
LLM代理是LLM原生架構中的一個獨立組件,其中會涉及到LLM調用。
這里給出的僅是LLM用法的一個實例,其中的提示將包含上下文內容。并非所有代理都是同樣的執行方式——有些會借助現成的“工具”執行,有些則不會,還有些可能在流程中“只使用一次”,而另一些則可能攜帶之前的輸入和輸出信息被遞歸調用或多次調用。
借助現成“工具”執行的代理
一些LLM代理可以使用現成的“工具”,這些工具其實是一些用于計算或網絡搜索等任務的預定義函數。代理輸出指令,這些指令指定應用程序執行的工具和輸入數據,并將最終執行結果返回給代理。
為了理解這個概念,讓我們來看一個簡單的工具調用的提示實現。這種實現方案甚至可以用于未經過原生訓練的調用工具的模型:
You are an assistant with access to these tools:
- calculate(expression: str) -> str - calculate a mathematical
expression
- search(query: str) -> str - search for an item in the inventory
Given an input, Respond with a YAML with keys: `func`(str) and
`arguments`(map) or `message`(str).Given input
區分具有工具的代理(因此是自主代理)和其輸出可以導致執行某一動作的代理是非常重要的。
“自主代理是能夠生成完成任務的方法的代理。”
自主代理有權決定是否采取行動以及采取何種行動。相比之下,一個(非自主)代理只是“處理”我們的請求(例如分類)。基于這個過程,我們的確定性代碼執行一個動作,而模型對此沒有控制權。
自主代理與觸發動作的代理比較
隨著我們增加代理在規劃和執行任務方面的自主權,我們增強了其決策能力,但可能會降低對輸出質量的控制。雖然這看起來像是一個讓它更“智能”或“先進”的神奇解決方案,但這也伴隨著會失去對質量控制的代價。
自主代理的利弊權衡
值得注意的是,要警惕完全自主代理的誘惑。雖然它們的架構可能看起來很吸引人,也更簡單,但將其用于一切(或作為最初的PoC)可能會對“實際生產”情況產生很大的欺騙作用。另外,自主代理難以調試且不可預測(響應質量不穩定),這使得它們無法用于生產。
目前,代理(沒有隱含的指導)還不太擅長規劃復雜的流程,通常會跳過關鍵步驟。例如,在我們的“維基百科作者”應用示例中,它們只會開始寫作,跳過系統化的過程。這使得代理(尤其是自主代理)僅與模型一樣好,或者更準確地說,僅與它們相對于你的任務所訓練的數據一樣好。
與其讓代理(或一群代理)自由地以端到端方式完成所有事情,不如嘗試將它們的任務限制在需要這種敏捷性或創造力的流程/SOP的特定區域。這可以產生更高質量的結果,因為你可以同時享受這兩個世界。
一個很好的例子是AlphaCodium(https://www.codium.ai/blog/alphacodium-state-of-the-art-code-generation-for-code-contests/):通過將結構化流與不同的代理(包括一個負責以迭代方式編寫和測試代碼的新型代理)相結合,它們提高了在CodeContest上GPT-4的準確性(pass@5),其準確率從19%上升到44%。
AlphaSodium的LLM架構
雖然工程技術為實施我們的SOP和優化LLM原生應用程序奠定了基礎,但我們還必須仔細考慮LLM三角原則的另一個關鍵組成部分:模型本身。
3.模型
我們選擇的模型是我們項目成功的關鍵組成部分。在這一方面,選擇使用大型模型(如GPT-4或Claude Opus)可能會產生更好的結果,但相當昂貴,而較小的模型可能不那么“聰明”,但有助于資金預算。在思考模型原則這一方面時,我們應該著眼于確定我們的約束和目標,以及什么樣的模型可以幫助我們實現它們。
模型原理
“并非所有LLM都是一樣的;因此,請將選定的模型與要完成的任務相匹配即可。”
事實上,我們并不總是需要最大的模型;這取決于任務。為了找到正確的匹配,我們必須有一個實驗過程,并嘗試我們解決方案的多種不同版本。
不妨先讓我們來看一個“缺乏經驗的工人”的類比,這將會對作出決定有所幫助。例如,一個擁有許多學歷的非常“聰明”的工人可能很容易在某些任務中取得成功。盡管如此,他們可能對這份工作有些資歷過高;因此,雇傭一個“更便宜”的候選工人將更具成本效益。
在考慮模型時,我們應該根據我們愿意采取的權衡來定義和比較解決方案:
- 任務復雜性——較簡單的任務(如摘要)更容易用較小的模型完成,而推理通常需要較大的模型。
- 推理基礎設施——它應該在云端還是邊緣設備上運行?模型大小可能會影響小型手機,但云服務可以容忍。
- 定價——我們能容忍什么價格?考慮到業務影響和預期使用情況,它是否具有成本效益?
- 延遲——隨著模型變大,延遲也會變大。
- 標記數據——我們是否有可以立即使用的數據,用未經訓練的樣本或相關信息來豐富模型?
在許多情況下,在你擁有“內部專業知識”之前,為經驗豐富的員工支付一點額外費用是有幫助的——LLM也是如此。
如果你沒有標定好的數據,那么建議你從一個更強大(更大)的模型開始,收集數據,然后利用它通過一些小樣本或微調來增強模型的能力。
微調模型
在對模型進行微調之前,你必須考慮幾個方面:
- 隱私——你的數據可能包括必須從模型中保留的私人信息。如果你的數據包含私人信息,你必須首先匿名處理你的數據以避免法律責任。
- 法律、合規性和數據權利——在訓練模型時可能會提出一些法律問題。例如,OpenAI使用條款政策阻止你在沒有OpenAI的情況下使用生成的響應來訓練模型。另一個典型的例子是遵守GDPR(即《通用數據保護條例》,是歐盟的一項重要法律,旨在保護歐盟境內個人的數據隱私和安全)的法律,該法律要求“撤銷權”,用戶可以要求公司從系統中刪除信息。這引發了關于該模型是否應該重新訓練的法律問題。
- 更新延遲——在訓練一個模型時,延遲(或數據截止)時間要比預計高得多。與通過上下文嵌入新信息不同(見下面的“上下文數據”一節)——這種方式能夠提供即時延遲。訓練模型則是一個漫長的過程,需要大量時間。因此,模型的再訓練往往很少被采用。
- 開發和操作——在持續評估結果性能的同時,實施可重復、可擴展和可監控的微調流程至關重要。這個復雜的過程需要持續的維護。
- 成本——再訓練因其復雜性和每次訓練所需的高強度資源(GPU)而被認為是昂貴的。
LLM作為上下文學習者的能力,以及新模型支持更大的上下文窗口的事實,極大地簡化了我們的實現;因此,即使沒有微調,也能提供出色的結果。然而,由于微調的復雜性,建議將其作為最后手段或完全跳過。
相反,對特定任務(例如結構化JSON輸出)或特定領域語言的模型進行微調可能是非常高效的。一個小型的、特定于任務的模型可能非常有效,并且在推理方面比大型LLM便宜得多。但無論如何,確保明智地選擇你的解決方案,并在升級到LLM訓練之前評估所有相關考慮因素。請牢記:
“即使是最強大的模型也需要相關且結構良好的上下文數據才能發光。”
4.上下文數據
LLM是上下文情境學習者。這意味著,通過提供特定任務的信息,LLM代理可以幫助我們在沒有特殊訓練或微調的情況下執行它。這使我們能夠輕松地“講授”新知識或技能。在考慮上下文數據原則時,我們應該致力于組織和建模可用數據,以及如何在提示中組合數據。
上下文數據原則
為了構建我們的上下文,我們需要在發送給LLM的提示中包含相關的(上下文)信息。歸納來看,我們可以使用兩種上下文:
- 嵌入式上下文——作為提示的一部分提供的嵌入式信息。
You are the helpful assistant of , a at
- 附件上下文——提示開始/結束時粘合的信息塊列表
Summarize the provided emails while keeping a friendly tone.
---
<email_0>
<email_1>
上下文通常使用“提示模板”來實現(例如jinja2或mustache,或者只是原生格式化文字字符串)。通過這種方式,我們便可以優雅地組合它們,同時保持提示信息的精髓:
# Embedded context with an attachment context
prompt = f"""
You are the helpful assistant of {name}. {name} is a {role} at {company}.
Help me write a {tone} response to the attached email.
Always sign your email with:
{signature}
---
{email}
"""
(1)小樣本學習
小樣本學習是一種通過示例“教導”LLM而不需要大量微調的強大方法。在提示中提供一些代表性示例可以指導模型理解所需的格式、風格或任務。
例如,如果我們希望LLM生成電子郵件回復,我們可以在提示中包含一些寫得很好的回復示例。這有助于模型學習首選的結構和音調。
我們可以使用不同的例子來幫助模型捕捉不同的極端情況或細微差別,并從中學習。因此,必須包含各種樣本示例,以涵蓋應用程序可能遇到的一系列場景。
隨著應用程序的增長,你可以考慮實現“動態小樣本(https://arxiv.org/abs/1804.09458)”,這涉及以編程方式為每個輸入選擇最相關的示例。雖然它增加了你的實現方案的復雜性,但它確保了模型在每種情況下都能得到最合適的指導,從而有助于顯著提高各種任務的性能,而無需進行昂貴的微調。
(2)檢索增強生成
檢索增強生成(RAG:https://www.promptingguide.ai/techniques/rag)是一種在生成響應之前為其他上下文檢索相關文檔的技術。這就像讓LLM快速瀏覽特定的參考資料,以便幫助提供需要的答案一樣。這種技術可以使響應保持最新和真實,而無需重新訓練模型。
例如,在開發支持聊天機器人應用程序時,RAG可以提取相關的維基頁面幫助,以告知LLM相關的答案。
這種方法通過將反應建立在檢索到的事實基礎上,幫助LLM保持最新狀態并減少虛幻的信息。RAG對于需要更新的或專業化的知識而無需重新訓練整個模型的任務特別方便。
例如,假設我們正在為我們的產品構建一個支持聊天。在這種情況下,我們可以使用RAG從我們的維基幫助中檢索相關文檔,然后將其提供給LLM代理,并要求其根據問題撰寫答案并提供文檔。
在實施RAG時,有三個關鍵部分需要注意:
- 檢索機制——雖然RAG的傳統實現涉及使用向量相似性搜索檢索相關文檔,但有時使用基于關鍵字的搜索(如BM-25)等更簡單的方法會更好或更便宜。
- 索引數據結構——在沒有預處理的情況下,對整個文檔進行索引,可能會限制檢索過程的有效性。有時,我們希望添加數據準備步驟,例如根據文檔準備問題和答案列表。
- 元數據——存儲相關元數據可以更有效地引用和過濾信息(例如,將維基頁面縮小到僅與用戶特定產品查詢相關的頁面)。這個額外的數據層簡化了檢索過程。
(3)提供相關背景
與你的代理相關的上下文信息可能會有所不同。雖然這似乎是有益的,但為模型(就好似一位“非技術工人”)提供過多的信息可能會讓它不知所措。理論上,這會導致模型學習不相關的信息(或令牌連接),這可能會導致混淆和幻覺(https://en.wikipedia.org/wiki/Hallucination_(artificial_intelligence))。
例如,當模型Gemini 1.5作為LLM發布并投入使用時,可以處理多達1000萬個符號,這導致一些從業者質疑上下文是否仍然是一個問題。雖然這是一項了不起的成就,特別是對于某些特定場景應用(如與PDF聊天),但它仍然有限,尤其是在推理各種文檔時。
因此,濃縮一下提示信息并僅向LLM代理提供相關的信息至關重要。這降低了模型在無關符號上的處理能力,提高了質量,優化了延遲,并降低了成本。
當然,已經有許多技巧可以提高所提供上下文的相關性,其中大多數與你如何存儲和編目數據有關。
例如,對于RAG應用程序來說,添加一個數據準備來格式化一下你存儲的信息是很方便的(例如,基于文檔的問題和答案,然后只向LLM代理提供答案;這樣,代理就可以獲得一個總結和更短的上下文),并在檢索到的文檔上使用重新排序算法來優化結果。
“數據為LLM原生應用程序的引擎提供動力。因此,上下文數據的有效性戰略設計會有助于更高效地釋放它們的真正潛力。”
結論
LLM三角原則提供了一種結構化的方法來開發高質量的LLM原生應用程序,它有助于縮短應用LLM的巨大潛力和現實世界實施面臨的挑戰之間的差距。開發人員可以通過專注于3+1關鍵原則(模型、工程技術和上下文數據)來創建更可靠、更有效的LLM驅動的解決方案,所有這些原則都以明確的SOP為指導。
LLM三角原則
關鍵點歸納
從一個明確的SOP開始:模擬你的專家的認知過程,為你的LLM應用程序創建一個循序漸進的指南。在思考其他原則時,將其作為根本指南。
- 選擇正確的模型:在能力和成本之間取得平衡,并考慮從較大的模型開始,然后再考慮轉向較小、微調的模型。
- 利用工程技術:實施LLM原生架構,并戰略性地使用代理來優化性能和保持控制。嘗試不同的提示技巧,為你的應用場景找到最有效的提示。
- 提供相關上下文:在適當的情況下,在上下文學習中使用,包括RAG技術,但要警惕切莫讓不相關的信息淹沒了模型。
- 迭代和實驗:找到正確的解決方案通常需要不斷地測試和改進你的工作。為此,我建議你閱讀和實施文章《構建LLM應用程序:清晰的步驟指南》(https://towardsdatascience.com/building-llm-apps-a-clear-step-by-step-guide-1fe1e6ef60fd)”中強調的有關技巧,以獲得詳細的LLM原生開發過程指南。
通過應用LLM三角原則,開發公司就可以超越簡單的概念驗證,開發出強大的、可用于實戰型的LLM應用程序,從而真正利用這項變革性技術的力量。
譯者介紹
朱先忠,51CTO社區編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。
原文標題:The LLM Triangle Principles to Architect Reliable AI Apps,作者:Almog Baku
鏈接:https://towardsdatascience.com/the-llm-triangle-principles-to-architect-reliable-ai-apps-d3753dd8542e。