如何在保證模型性能條件下優化Prompt降低使用成本及響應延遲?
隨著大模型應用的不斷發展,提示工程技術也在快速迭代更新,越來越多的任務通過精妙的Prompt或者agentic workflow等方式解鎖。但隨之而來,大量詳細的、巨大的prompt卻會帶來高的成本以及緩慢的響應。這也使得高成本和高延遲成為了大模型應用落地生產的主要障礙。隨著當下LLM應用已經不再是單次的對話,而是復雜的組合AI系統(伯克利:即使模型再強大,復合AI系統( Compound AI Systems)都將會是一種領先的應用模式)都將會是一種領先的應用模式),提示規模爆炸性增長,這樣的問題變得更加尖銳。
就以最近很火的GraphRAG為例,處理64頁的文稿,就花了7美元,使用成本相當的高,這在研究和演示場景這樣的情況并不突出,但是真到需要處理大規模數據,服務大量用戶的實際生產場景中,這樣的情況是無法接受的。
Prompt會很大的主要原因是它包含了很多內容,比如任務描述,場景約束,工具描述,多輪的交互記憶等等,在每一次和大模型交互時,都需要將其提供給大模型,再加上系統框架的必要的再封裝,會導致實際提交給LLM比用戶提交的更大。
成本和延遲與prompt大小及調用次數密切相關,那如何才能在不降低精度的情況下,減少Prompt大小以及降低LLM調用次數呢?下面是Jan Majewski在開發它的應用(房產搜索助理)時總結prompt大小與成本延遲的量化關系以及五個優化的思路。
1)量化關系
- 成本
- 延遲
對于成本,輸出token是輸入token的 3 倍,但同時對于復雜的任務來講,提示(輸入token)會比輸出要長得多,減少輸入token帶來的收益依然可觀。 對于延遲,主要是由輸出token決定的,其處理時間是輸入token的 200 倍。
2)優化手段:
1. 將大的prompt拆分成多層次調用
在撰寫prompt時不必將所有內容都寫到一個大的prompt中,比如把規劃和執行分開,Jan Majewski指出他的應用性能提升的關鍵之一在于將Prompt拆分成兩個部分:決策Agent,它對下一步可以采取的措施有總體指導,以及如何處理來自模型的輸出;執行Agent/Chats,它對具體步驟(如報價搜索、數據比較或房地產知識)有詳細說明。
這種架構允許首先選擇需要使用的特定任務提示,而無需在每次調用時發送大量token執行指令,從而將token的平均使用量減少了 60% 以上。
2. 關注發送給LLM的最終Prompt
如前面提到,LLM 收到的最終Prompt可能與最初用戶撰寫的Prompt相差很大。 框架在使用工具、內存、上下文和 Agent 的內部推理時,都會自動擴展Prompt,這也會使prompt增加數千個token。另外,在LLM應用執行過程中,涉及到了很多的環節,可能進行了幾十次調用,如何監控和排錯也就十分重要。對于開發者來講,使用 LangSmith 進行深入分析是一個比較好的選擇,近日dify也集成了這樣的可觀測工具。
3.可以通過編碼,減少LLM調用量。
有時候一些任務使用常規的代碼實現更為高效經濟,而無需都撰寫Prompt操縱LLM來實現。比如,使用 Python 函數處理 LLM 調用的上游/下游一些瑣碎的任務。當前,大部分的LLM應用開發的框架都支持將傳統函數與LLM調用混合在一起使用,比如Promptflow,langchain等。比如下面的一段代碼,可以直接使用python lib完成語言檢測,這樣就可以明確語言類型明確傳遞給LLM,無需在Prompt中去限定有關語言的描述,從而減少在 LLM 的處理復雜度以及Prompt大小。
from langdetect import detect
prompt = """
Summarize the following message in {language}:
Message: {input}
"""
prompt = ChatPromptTemplate.from_template(prompt)
def detect_language(input_message):
input_message["language"] = detect(input_message["input"])
return input_message
detect_language_step= RunnablePassthrough.assign(input_message=detect_language)
chain_summarize_in_message_language = (
detect_language_step
| RunnablePassthrough.assign(
language=lambda x: x["input_message"]["language"]
)
| prompt
| llm )
4. 慎用Agent,它們會導致token消耗大大增加
能夠使用工具的Agent能夠極大的擴展LLM的能力范圍,但它們同時也非常消耗token。下面的圖表顯示了 Agent的一般處理流程,可以看到Agent 通常需要調用 LLM 至少兩次:首先計劃如何使用工具,然后解析其輸出以提供最終答案。對于一些較為簡單的任務,Agent 的方法可能有些重,而使用 Completion 的簡單指令提示則能以兩倍的速度提供類似的結果。
5. 使用 LLM 進行推理,但使用 SQL 或 Python 進行統計計算
雖然,現在的LLM能力相較于之前已經有了很大提高,比如通過精心構造Prompt完成數據分析(新加坡提示工程大賽冠軍最強Prompt工程技巧分享,僅用大模型也能做數據分析),但對于數據計算來講,仍然不如Python和SQL來的高效準確經濟。
建議做法是使用 LLM 理解問題和數據,然后將其轉換為更合適的分析語言(如SQL或Python)進行數據處理匯總,最后再將結果提供給 LLM 進行分析洞察。
總結
Jan Majewski給出了一些常見的思路來減少Prompt的大小以及減少LLM的調用,除此之外,還有很多prompt壓縮、LLM Cache等技術降低應用成本及減少應用延遲。未來筆者還將介紹這一領域的進展,歡迎關注。
參考:
??https://www.youtube.com/watch?v=EuzDssiyLmo??
??https://blog.baeke.info/2024/07/07/trying-out-graph-rag/??
本文轉載自??AI工程化??,作者: ully
