跳至主要內容

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)

常見反模式

  1. 過長的 System Prompt:超過 2000 字的系統提示往往效果下降,模型會「忘記」前面的指令
  2. 模糊的指令:「寫一篇好文章」vs「寫一篇 500 字的技術部落格文章,目標讀者是初學者」
  3. 假設模型記得上下文:每次呼叫都是獨立的,需要在 prompt 中帶入必要的上下文
  4. 忽略 temperature 設定:創意任務用高 temperature(0.7-1.0),事實性任務用低 temperature(0-0.3)

小結

Prompt Engineering 本質上是「跟模型溝通的藝術」。思維鏈讓模型展示推理過程、少樣本提示定義輸出格式、自我反思降低錯誤率、任務分解處理複雜問題——這些技巧組合使用,能讓 LLM 的輸出品質大幅提升。最重要的是:持續測試和迭代你的提示,小小的措辭改變往往有巨大的影響。

分享這篇文章