Prompt Engineering : 設計並優化給 LLM 的輸入文字,讓模型更穩定、準確地輸出你想要的答案,重點不是改模型,而是改輸入與互動流程
核心原則 :
- 明確(Be explicit):清楚說明任務、輸出格式、語言、字數上限
- 示例驅動(Show examples):用 few-shot(2–5 範例)示範正確行為
- 限制輸出(Constrain output):要求 JSON / 表格 / 只回傳一個詞/不要多話
- 指定風格(Style & role):告訴模型扮演什麼角色(專家、客服、法律顧問…)
- 避免歧義(Disambiguate):別用「它」或模糊語句,指代要清楚
- 測試與度量(Measure & iterate):用自動化指標或人類評估比較不同 prompt
- 考慮成本(Token cost):長 prompt(few-shot、context)會增加 token 費用與延遲
常用參數
- temperature:隨機性(0 → deterministic,0.7 普通創意,>1 創意多但容易亂)
- do_sample:是否取樣(True 用 sampling,False 用 greedy/beam)
- top_k、top_p(nucleus):截斷策略,控制生成多樣性
- max_new_tokens / max_length:產生長度上限
- stop_sequences:遇到指定字串就停止,常用於 API
- 建議 :
- 分類 / 結構化輸出 → temperature=0、do_sample=False
- 創意生成 → temperature=0.7 & top_p=0.9
Prompt 設計流程
- 定義任務與成功標準:想要分類、抽取、摘要、還是生成對話?成功的衡量指標是什麼?(accuracy / F1 / ROUGE / 人評)
- 選模型:小型 local 模型或雲端大模型?(決定 token cost 與可能性)
- 一稿 prompt(baseline):寫一個最簡單、最直接的 prompt
- 加入約束:語言、格式、長度、回傳格式(JSON)、是否允許模型猜測
- few-shot 加強:加入 2–5 個示例(最好是與目標資料分布一致的例子)
- 超參數 sweep:測試 temperature、top_p、do_sample、max_new_tokens。
- 自動化測試:在 validation 集上用 metric 評估(例如 classification 用 accuracy/F1)。
- 迭代:根據錯誤模式微調 prompt(加入更多示例、更明確的約束、或改變例子順序)
提示優化技巧
- 控制冗言:在 prompt 最後再一次要求「只回傳 JSON」或「不要多說」以避免雜訊
- 把範例放在最接近輸入的地方:有些模型對 prompt 的局部上下文權重較高
- 示例多樣化但一致:few-shot 的例句要代表真實分布;不要只放非常簡單例子然後測驗難例
- Chain-of-Thought(CoT):若任務需要推理,可在 prompt 要求「逐步思考」,或提供「示範步驟」。注意 CoT會產生長輸出與較高成本
- 分解任務(Prompt Chaining):把複雜任務拆成多個 prompt(先抽取事實 → 再生成答案)
測試與自動化比較 Prompt
- 準備 validation dataset(N 範例,含 gold label / gold answer)
- 建立多個 prompt 版本(A/B/C…),每個保存為模板
- 自動化呼叫模型:把每個 prompt 套到所有 validation(驗證),收集模型輸出
- 計算指標:
- classification(分類) → accuracy(準確率) / F1
- 抽取 → EM(Exact Match) / F1
- 摘要 → ROUGE
- QA → EM/F1
- 錯誤分析:把錯誤輸出抽樣,分類錯誤類型(格式錯、內容錯)
- 迭代:針對主要錯誤改 prompt 或加入 more examples
範例
from transformers import pipeline
generator = pipeline("text-generation", model="gpt2") # 若有中文 GPT2 可換
prompt_base = """範例1:
句子:"這家餐廳很讚,服務態度很好。"
標籤:POSITIVE
範例2:
句子:"產品品質太差,我不會再買。"
標籤:NEGATIVE
請依照上例判斷下面句子的情感,並只回傳 POSITIVE 或 NEGATIVE(不要其他文字)。
句子:"{}"
標籤:"""
texts = [
"這次購買很滿意,出貨速度快。",
"商品與描述不符,品質差。"
]
for temp in [0.0, 0.7]:
print("=== temperature =", temp, "===")
for t in texts:
out = generator(prompt_base.format(t), max_new_tokens=10, temperature=temp, do_sample=(temp>0))
print(t, "->", out[0]["generated_text"].split("標籤:")[-1].strip())
print()
