cover

Prompt Engineering:寫出好 Prompt 的實用技巧

很多人覺得 AI 不好用,問題往往不在 AI,而在 Prompt。

同一個模型,給它「幫我寫一個 function」和「你是一位資深 TypeScript 工程師,請寫一個處理日期格式化的 utility function,需要支援 ISO 8601 和 locale format,包含 JSDoc 和 unit test」——你得到的結果品質天差地遠。

Prompt Engineering 不是什麼神秘的黑魔法,它就是清楚地告訴 AI 你要什麼。這篇文章整理了我在日常開發中實際在用的 Prompt 技巧和模板。

Prompt 到回應的流程

flowchart LR
    User["使用者"] --> SP["System Prompt\n角色設定 + 規則"]
    User --> UP["User Prompt\n任務描述 + 範例"]

    SP --> Model["LLM 模型\n理解指令\n推理生成"]
    UP --> Model

    Model --> Parse["Output Parsing\n格式化輸出"]
    Parse --> Result["最終結果\nCode / JSON / 文字"]

    subgraph 品質因素["影響輸出品質的因素"]
        direction TB
        F1["明確性:指令是否清楚"]
        F2["具體性:有沒有給細節"]
        F3["範例:有沒有 few-shot"]
        F4["格式:有沒有指定輸出"]
        F5["參數:temperature / top-p"]
    end

    Model -.-> 品質因素

    style SP fill:#4a90d9,color:#fff
    style UP fill:#f5a623,color:#fff
    style Model fill:#7ed321,color:#fff
    style Parse fill:#9013fe,color:#fff

基本原則:四個核心要素

不管你用什麼模型,好的 Prompt 都遵循這四個原則:

1. 明確(Be Specific)

❌ 不好的 Prompt:
「幫我寫一個 API」

✅ 好的 Prompt:
「用 Express.js + TypeScript 寫一個 GET /api/users/:id 的 endpoint,
從 PostgreSQL 查詢使用者資料,回傳 JSON 格式,包含 error handling。」

2. 給 Context(Provide Context)

❌ 不好的 Prompt:
「這段 code 有 bug,幫我修」

✅ 好的 Prompt:
「以下的 React component 在 useEffect 中呼叫 API,
但會造成 infinite re-render。我用的是 React 18 + TypeScript。
請找出問題並修正:
[貼上程式碼]」

3. 給範例(Provide Examples)

❌ 不好的 Prompt:
「把這些 log 轉成結構化格式」

✅ 好的 Prompt:
「把以下 log 轉成 JSON 格式。

範例:
輸入:2024-01-15 14:23:01 ERROR [auth] Login failed for user admin
輸出:{"timestamp": "2024-01-15T14:23:01", "level": "ERROR", "module": "auth", "message": "Login failed for user admin"}

請處理以下 log:
[貼上 log]」

4. 指定格式(Specify Output Format)

❌ 不好的 Prompt:
「列出 React 和 Vue 的差異」

✅ 好的 Prompt:
「以 Markdown 表格比較 React 和 Vue,包含以下欄位:
特性、React 的做法、Vue 的做法、個人推薦。
最後加一段 50 字以內的總結。」

常見技巧

1. System Prompt:設定角色和背景

System Prompt 定義 AI 的「人格」和行為規範。它會影響整個對話的基調。

System Prompt 範例:

你是一位有 10 年經驗的 Senior Backend Engineer,專精 Node.js 和 PostgreSQL。
你的回答風格:
- 直接給解法,不要廢話
- 程式碼要包含 error handling 和 TypeScript 型別
- 如果有多種做法,列出 pros/cons 讓我選
- 如果我的做法有安全風險,主動提醒

好的 System Prompt 的特點:

  • 定義角色和專長
  • 設定回答風格
  • 列出具體的行為規範
  • 設定邊界(什麼不該做)

2. Few-shot Learning:給 2-3 個範例

Few-shot 是 Prompt Engineering 中 CP 值最高的技巧。模型看到範例後,會「照著做」。

請幫我把 API 文件轉成 TypeScript interface。

範例 1:
API 文件:GET /users - 回傳 {id: number, name: string, email: string}
TypeScript:
interface User {
  id: number;
  name: string;
  email: string;
}

範例 2:
API 文件:GET /posts - 回傳 {id: number, title: string, tags: string[]}
TypeScript:
interface Post {
  id: number;
  title: string;
  tags: string[];
}

請轉換:
API 文件:GET /orders - 回傳 {id: number, items: [{productId: number, quantity: number}], total: number, status: "pending" | "completed"}

關鍵:範例的格式要跟你期望的輸出一致。 AI 不只學內容,也學格式。

3. Chain-of-Thought (CoT):要求分步思考

當任務需要推理時,要求 AI 分步驟思考可以顯著提升正確率。

❌ 直接問:
「這個演算法的時間複雜度是什麼?」

✅ 加入 CoT:
「請分析這個演算法的時間複雜度。
要求:
1. 先辨識每個迴圈和遞迴的結構
2. 分別標出每一層的複雜度
3. 推導出整體複雜度
4. 給出最終答案(Big-O 表示法)

[貼上程式碼]」

CoT 特別有用的場景:

  • 複雜的 debug(讓 AI 一步步排查)
  • 架構設計(讓 AI 先列出考量因素再給建議)
  • 程式碼重構(讓 AI 先分析現有結構再提方案)

4. Output Formatting:要求 JSON / Markdown / 表格

明確告訴 AI 你要什麼格式,它就會照做。

請分析以下程式碼的問題,用以下 JSON 格式回答:

{
  "issues": [
    {
      "severity": "high | medium | low",
      "line": "行號",
      "description": "問題描述",
      "suggestion": "修改建議",
      "code": "修改後的程式碼"
    }
  ],
  "overallScore": "1-10 的品質評分",
  "summary": "一句話總結"
}

這在自動化場景特別有用——LLM 輸出 JSON,你的程式直接 parse 使用。

5. Temperature & Top-P:什麼時候該調?

大多數時候用預設值就好,但特定場景需要調整:

場景Temperature原因
程式碼生成0 - 0.2要精確,不要創意
Bug 修復0要確定性結果
日常對話0.5 - 0.7平衡自然度和準確性
創意寫作0.7 - 1.0鼓勵多樣性
Brainstorming0.9 - 1.2要意想不到的想法

實務建議:寫程式的時候 temperature 設 0,寫文章的時候設 0.7。 大多數情況下不需要動 Top-P。


工程師專用 Prompt 模板

以下是我在日常開發中常用的三個模板:

Code Review Prompt

請 review 以下程式碼,從這些面向分析:

1. **正確性**:邏輯是否正確?有沒有 edge case 沒處理?
2. **效能**:有沒有效能問題?N+1 query?不必要的計算?
3. **安全性**:有沒有 injection、XSS、資訊洩露風險?
4. **可維護性**:命名是否清楚?結構是否合理?
5. **TypeScript**:型別定義是否完善?有沒有用 any?

回答格式:
- 每個問題標註嚴重程度(🔴 高 / 🟡 中 / 🟢 低)
- 給出具體的修改建議和範例程式碼
- 最後給一個 1-10 的整體評分

技術背景:Node.js + TypeScript + Express + PostgreSQL

程式碼:
[貼上程式碼]

Bug Debugging Prompt

我遇到一個 bug,請幫我排查。

環境資訊:
- Runtime: Node.js 20 + TypeScript 5.3
- Framework: Next.js 14 (App Router)
- Database: PostgreSQL 16
- 部署環境: Docker on AWS ECS

問題描述:
[描述症狀]

錯誤訊息:
[貼上 error log]

相關程式碼:
[貼上程式碼]

我已經嘗試過:
[列出你試過的解法]

請分析:
1. 最可能的根本原因是什麼?
2. 如何驗證這個假設?
3. 具體的修復方案?
4. 怎麼避免未來再發生?

Architecture Discussion Prompt

我在設計一個系統,請幫我分析架構方案。

系統需求:
- [功能需求]
- [非功能需求:QPS、延遲、資料量]
- [團隊規模和技術棧]
- [預算限制]

我目前考慮的方案:
[描述方案 A]
[描述方案 B]

請從以下面向比較:
1. 技術可行性
2. 維護成本(人力和基礎設施)
3. 擴展性
4. 潛在風險和 trade-off
5. 是否有我沒考慮到的方案?

請用表格整理比較結果,最後給出你的推薦和理由。

常見錯誤

1. 太模糊

❌ 「幫我改善這段程式碼」
→ 改善什麼?效能?可讀性?安全性?功能性?

✅ 「請改善這段程式碼的效能,目前處理 10 萬筆資料需要 30 秒,目標是 5 秒內」

2. 太長、塞太多指令

Prompt 越長不代表越好。如果你塞了 20 條規則,AI 很可能忽略其中幾條。

❌ 一個 Prompt 裡放 15 個不同的要求

✅ 拆成多次對話:
   第一輪:寫出基本功能
   第二輪:加上 error handling
   第三輪:加上 test cases

3. 沒給 Context

AI 不知道你的專案架構、使用的框架版本、團隊的 coding style。你覺得「顯而易見」的事情,AI 完全不知道。

❌ 「怎麼做 authentication?」

✅ 「在 Next.js 14 App Router 中,用 NextAuth.js v5 實作 Google OAuth,
   database adapter 用 Prisma + PostgreSQL。
   請給出完整的設定步驟和程式碼。」

4. 不迭代

很少有一次就完美的 Prompt。好的做法是:

第一次 → 得到初步結果
第二次 → 「這個不錯,但 error handling 不夠完整,請補上以下情況...」
第三次 → 「請把這段重構成用 Result pattern 而不是 try-catch」

Prompt Engineering 是對話,不是一次性指令。


進階技巧

Prompt Chaining

把複雜任務拆成多個 Prompt,前一個的輸出當作後一個的輸入:

flowchart LR
    P1["Prompt 1\n分析需求\n列出功能點"] --> O1["功能清單"]
    O1 --> P2["Prompt 2\n設計 API\n定義 interface"]
    P2 --> O2["API 規格"]
    O2 --> P3["Prompt 3\n實作程式碼\n包含 test"]
    P3 --> O3["完成的程式碼"]

    style P1 fill:#4a90d9,color:#fff
    style P2 fill:#f5a623,color:#fff
    style P3 fill:#7ed321,color:#fff

Negative Prompting

告訴 AI 不要做什麼,有時比告訴它要做什麼更有效:

請寫一個 Express middleware。
- 不要使用 any 型別
- 不要使用 console.log,改用 logger
- 不要使用 var,只用 const 和 let
- 不要在 middleware 裡直接回傳 response,要 next() 給下一層

角色扮演 + 對抗

讓 AI 扮演不同角色來挑戰你的設計:

你現在是一位 Staff Engineer,專門在 code review 中找問題。
請用最嚴格的標準審查以下架構設計,
特別注意 scalability、fault tolerance 和 security。
不要客氣,直接指出所有可能的問題。

延伸閱讀

推薦資源: