Prompt Engineering 進階策略:讓 LLM 輸出更精準
6 分鐘閱讀 1,050 字
Prompt Engineering 進階策略:讓 LLM 輸出更精準
在實際使用大型語言模型開發應用的過程中,我發現「會用」和「用好」之間有非常大的差距。基礎的提示技巧(加上角色設定、給例子)大多數人都會,但面對複雜任務時,輸出品質往往差強人意。本文整理了幾個我認為最有效的進階策略。
策略一:思維鏈(Chain-of-Thought, CoT)
對於需要推理的任務,要求模型「一步一步思考」能顯著提升準確性:
# 基本 CoT
prompt = """
解題時請先展示你的推理過程,再給出最終答案。
問題:一個水箱以每分鐘 3 公升的速度進水,以每分鐘 1.5 公升的速度出水。
如果水箱目前有 20 公升水,容量為 50 公升,幾分鐘後會裝滿?
讓我們一步一步計算:
"""零樣本 CoT(Zero-shot CoT):只需加上「讓我們一步一步思考」就有效:
# 在任何推理問題後面加上這句話
prompt = f"{question}\n\n讓我們一步一步仔細分析這個問題。"策略二:少樣本提示(Few-shot Prompting)
提供幾個「輸入→輸出」的例子,讓模型學習你想要的格式和風格:
prompt = """
將以下客戶評論分類為「正面」、「負面」或「中性」,並提取主要情緒關鍵字。
範例 1:
評論:「商品品質超好,包裝也很精美,下次還會再買!」
分類:正面
關鍵字:品質好、包裝精美、會回購
範例 2:
評論:「運送速度還可以,但商品跟圖片有點差距。」
分類:中性
關鍵字:運送普通、與圖片有落差
範例 3:
評論:「完全是浪費錢,根本不能用,強烈要求退款!」
分類:負面
關鍵字:品質差、要求退款
現在請分析:
評論:「{customer_review}"
"""策略三:結構化輸出(Structured Output)
要求模型輸出特定格式,方便程式解析:
prompt = """
分析以下程式碼並找出問題。請嚴格以下列 JSON 格式回應,不要包含任何其他文字:
```json
{
"issues": [
{
"severity": "high|medium|low",
"line": <行號或 null>,
"description": "<問題描述>",
"suggestion": "<修正建議>"
}
],
"overall_quality": "good|acceptable|needs_improvement",
"summary": "<整體評估,50字以內>"
}程式碼: {code} """
import json response = llm.invoke(prompt) try: result = json.loads(response.content) except json.JSONDecodeError: # 如果解析失敗,可以再次要求修正格式 ...
## 策略四:角色扮演與脈絡設定
給模型一個明確的角色和背景,輸出會更符合預期:
```python
system_prompt = """
你是一位資深的 TypeScript 後端工程師,有 10 年的 Node.js 開發經驗。
你的工作風格:
- 重視型別安全,總是為函式加上完整的型別標注
- 善用 async/await,避免回調地獄
- 喜歡撰寫有意義的錯誤訊息
- 在解釋技術概念時,會搭配具體的程式碼範例
- 回應使用繁體中文
你不會做的事:
- 不會建議使用已被棄用的 API
- 不會忽視錯誤處理
- 不會給出沒有型別的 any
"""策略五:自我反思(Self-Reflection)
讓模型自我審查輸出,能有效降低錯誤率:
# 第一步:生成初始答案
initial_prompt = f"請回答以下問題:{question}"
answer = llm.invoke(initial_prompt)
# 第二步:讓模型自我審查
review_prompt = f"""
以下是對問題「{question}」的回答:
{answer.content}
請仔細檢查這個回答:
1. 回答是否正確且完整?
2. 是否有任何邏輯錯誤或遺漏?
3. 如果有問題,請提供修正後的版本。
如果回答完全正確,請回答「回答正確,無需修正。」
"""
final_answer = llm.invoke(review_prompt)策略六:分解複雜任務(Task Decomposition)
複雜任務不要一次問,拆分成子任務效果更好:
def analyze_business_document(document: str) -> dict:
"""
分析商業文件的多步驟流程
"""
# 步驟 1:提取關鍵資訊
extraction_prompt = f"""
從以下文件中提取:
1. 公司名稱和產業
2. 主要產品或服務(列點)
3. 提到的數字和指標
文件:{document}
"""
extracted = llm.invoke(extraction_prompt)
# 步驟 2:基於提取的資訊進行分析
analysis_prompt = f"""
基於以下資訊進行 SWOT 分析:
{extracted.content}
請分析優勢、劣勢、機會和威脅。
"""
analysis = llm.invoke(analysis_prompt)
# 步驟 3:生成建議
recommendation_prompt = f"""
基於以下 SWOT 分析,提出 3 個具體的策略建議:
{analysis.content}
每個建議需包含:行動項目、預期效益、實施難度。
"""
recommendations = llm.invoke(recommendation_prompt)
return {
"extraction": extracted.content,
"analysis": analysis.content,
"recommendations": recommendations.content
}策略七:提示範本管理
在實際應用中,提示範本應該被版本控制和系統化管理:
from string import Template
from pathlib import Path
import yaml
class PromptManager:
def __init__(self, prompts_dir: str = "prompts"):
self.prompts = {}
self._load_prompts(prompts_dir)
def _load_prompts(self, directory: str):
for file in Path(directory).glob("*.yaml"):
with open(file) as f:
data = yaml.safe_load(f)
self.prompts[data["name"]] = data
def render(self, prompt_name: str, **kwargs) -> str:
prompt_data = self.prompts[prompt_name]
template = Template(prompt_data["template"])
return template.substitute(**kwargs)
# prompts/code_review.yaml
# name: code_review
# version: "1.2"
# template: |
# 你是一位資深工程師,請 code review 以下 $language 程式碼...
pm = PromptManager()
rendered = pm.render("code_review", language="TypeScript", code=my_code)常見反模式
- 過長的 System Prompt:超過 2000 字的系統提示往往效果下降,模型會「忘記」前面的指令
- 模糊的指令:「寫一篇好文章」vs「寫一篇 500 字的技術部落格文章,目標讀者是初學者」
- 假設模型記得上下文:每次呼叫都是獨立的,需要在 prompt 中帶入必要的上下文
- 忽略 temperature 設定:創意任務用高 temperature(0.7-1.0),事實性任務用低 temperature(0-0.3)
小結
Prompt Engineering 本質上是「跟模型溝通的藝術」。思維鏈讓模型展示推理過程、少樣本提示定義輸出格式、自我反思降低錯誤率、任務分解處理複雜問題——這些技巧組合使用,能讓 LLM 的輸出品質大幅提升。最重要的是:持續測試和迭代你的提示,小小的措辭改變往往有巨大的影響。
分享這篇文章