搭建 Prompt 管理後台(二):打造 LLM Prompt 版本控制功能
背景
在上篇文章中,我提到因為工作上需求,建立了一個簡易的 Prompt 管理後台。還沒看過前一篇的讀者,建議先閱讀開發背景 🙂

總之呢,雖然開發了初步的 Prompt 管理後台,但面對不同 Prompt 版本的切換管理、甚至是團隊內多人協作,就需要版本控制來解決。
功能需求
- 支持查看 Prompt 過去版本,能比較不同 Prompt 結果差異
- 可以下載/複製 輸出結果為 json 格式
- (進階)支持測試及發佈新版本的 Prompt,區分測試及正式版
其他需求 (Non-Functional Requirement)
- 容錯 (Fault-tolerance) :當批量進行 LLM 查詢時, 如果某些 id 失敗不能全部重來

設計迭代過程
系統設計/軟體開發有趣的地方在於,一個問題往往有許多種方法可以解決,只在於如何取捨。以這次版本控制功能來說,我就思考了好幾個方案,最後才確定用目前的設計。
v0: 無版本控制
- 每入 videoId 產生一筆 Prompt + LLM Output 的紀錄
- 可以調整這筆紀錄的 Prompt、重新觸發 LLM 測試
Schema
- createdAt: 創建時間
- updatedAt: 創建時間
- video_id(string): video的唯一鍵,用來查詢在GCS的檔案
- prompt(string): 實際輸入提示詞
- feature(string): LLM輸出結果
接著思考:要如何加入版本控制?
Potential Solution 1: 調整現有 schema、容納多個版本
為了容納多版本,可以將 prompt 及 feature 改成 array。當每次用戶有新嘗試 (ex.調整 Prompt 重新觸發 LLM),就在後面插入一個新版本,如下方調整:
Schema
- createdAt: 創建時間
- updatedAt: 創建時間
- video_id(string): video的唯一鍵,用來查詢在GCS的檔案
- prompts([]string): 輸入提示詞的歷史紀錄
- features([]string): LLM輸出結果的歷史紀錄這個方案的特點是由於每次變更都插入 (append),用戶所有的操作都會被記錄下來。但仔細想會發現,這個方案無法進行有效的版本控制,因為只要對同個 video有操作,版本就會立即覆蓋。
Potential Solution 2: 透過新紀錄及 status 管理線上版本
有鑒於上面的版本覆蓋問題,聯想到第二個方案:如果變更 prompt,並不會創建新紀錄,只有當創建新任務才會新增一筆 record。因此使用時,用戶可以盡情測試一個 prompt,等確定後再新增一筆紀錄覆蓋原有版本即可。
但即使如此,變更 prompt 時還是會改到最新版本。因此為了區分 test 跟 production,需要再加入 status 的概念。每筆新增紀錄預設都是 "Test",只要當用戶選擇升級才會變成 "Production"。
Schema
- createdAt: 創建時間
- updatedAt: 創建時間
- video_id(string): video的唯一鍵,用來查詢在GCS的檔案
- prompt(string): 實際輸入提示詞
- feature(string): LLM輸出結果
- status (string): 紀錄此版本的狀態:Production為線上版本、Test是測試版本其實這個方案是可行的,能解決版本控制/切換的問題。但如果參考像是 github 這種成熟的版本控制系統,會發現它還需要保存過去版本部署紀錄。這種「版本部署」及「LLM 任務」的不同特性,讓我決定採用接下來分拆方案。
Final Solution: 分拆 LLM任務及版本部署
我決定不再將歷史紀錄放在 tasks table,而是將它視為「測試紀錄」,並且另外創建一個專門做版本管理的 version table。
tasks table
- createdAt: 創建時間
- updatedAt: 創建時間
- video_id(string): video的唯一鍵,用來查詢在GCS的檔案
- prompt(string): 實際輸入提示詞
- feature(string): LLM輸出結果
- status (string): 紀錄此版本的狀態:Production為線上版本、Test是測試版本
version table
- createdAt
- updatedAt
- promptVersions: []PromptVersion
- featureVersions: []FeatureVersion
- currentPrompt
- currentPromptVersion
- currentFeature
- currentFeatureVersion
不只是分拆 table,在前端頁面也進行分隔。這樣好處在於,用戶可以隨意在 tasks 進行測試,不用擔心影響到正式版本。唯有當對測試結果滿意後,就可以點選 "Publish",將紀錄同步到 version table。
這個設計不僅讓後端管理 tasks 及 version 的分工邏輯變得明確,也更容易支持像「版本部署紀錄」這種進階功能。
小結
其實上面設計也是迭代了好幾版才算比較滿意。如果嚴格一點檢視,系統設計對於非功能要求如 scalability、fault-tolerance 等考慮還是顯得比較欠缺。但我覺得學習系統設計就是這樣,要實際處理過問題,才會知道系統哪裡可能有瓶頸,再去看別人的系統設計影片時也才比較有感覺。
至於功能方面,之後可能也要規劃如何將這些實際 LLM 的計算結果,與正式服務進行整合、甚至可以指定使用版本。我也發現有不少開源方案都有成熟的 Prompt 版本管理服務,連結附在下方,也可以找時間參考看看別人怎麼做。
參考
- Pezzo: https://docs.pezzo.ai/introduction/what-is-pezzo
- For more LLM Ops tools
