Nhập môn prompt engineering — Prompt là code

3 — Prompt EngineeringTrung cấp25 phút

Nếu bạn đã dùng ChatGPT nhiều, chắc bạn đã thấy các bài viết blog kiểu:

Bạn sẽ học được
  • Định nghĩa prompt engineering và phân biệt với "tip trick ChatGPT"
  • Mô tả vòng lặp 5 bước của quy trình iterate prompt
  • Hiểu vì sao eval là không thể thiếu cho prompt engineering thật sự
  • Xác định baseline score cho prompt đầu tiên
  • Setup framework để track improvement qua các version prompt

Prompt engineering là gì?

Định nghĩa chính thức:

Keywords:

Phân biệt với các khái niệm khác

  • Iteratively — không 1 lần viết xong, mà vòng lặp
  • Improve — phải có cách đo trước/sau, không phải "tôi cảm thấy tốt hơn"
  • Reliability — consistent qua nhiều input khác nhau
  • Quality — output meet yêu cầu
Prompting tipPrompt engineering
Mục đíchGet better response lẻBuild production system
Approach"Try this magic phrase"Systematic iteration
MetricGut feelNumeric score
OutputPrompt stringPrompt + test dataset + graders
ScaleIndividual userTeam, thousands of users

Vòng lặp 5 bước (core loop)

Bước 1: Set goal

Viết xuống rõ ràng prompt này phải làm gì. Không trừu tượng.

Tệ:

Tốt:

Goal phải testable — có thể viết checklist pass/fail.

Bước 2: Write v1 (baseline)

Viết prompt đơn giản nhất có thể. Không cần đẹp.

Đây là baseline. Hầu như chắc chắn tệ. Score 2-3/10 là bình thường.

Bước 3: Evaluate

Chạy prompt qua test dataset (10-30 case), chấm điểm.

Chi tiết của evaluation sẽ cover ở Module 4. Bây giờ chỉ cần hiểu: mỗi version prompt sẽ có 1 score.

Bước 4: Apply technique

Chọn 1 technique (clear/direct, specific, examples, XML structure) và áp dụng vào prompt.

Rule: Mỗi iteration chỉ đổi 1 thứ. Thay đổi 3 thứ cùng lúc → không biết cái nào đóng góp cải thiện.

Bước 5: Re-evaluate

Chạy lại eval. So sánh:

Score tăng → technique đó hoạt động. Tiếp tục iterate hoặc ship.

Score không tăng (hoặc giảm) → rollback, thử technique khác.

VersionScore
v1 (baseline)2.3/10
v2 (+clear wording)3.9/10
v3 (+specific guidelines)7.8/10
v4 (+examples)8.9/10
┌─────────────────────────────────────────────────────┐
│                                                     │
│   ┌──────────────┐                                  │
│   │  1. Set goal │                                  │
│   └──────┬───────┘                                  │
│          │                                          │
│          ▼                                          │
│   ┌──────────────┐                                  │
│   │  2. Write v1 │ ◀─────────────────────┐          │
│   └──────┬───────┘                       │          │
│          │                               │          │
│          ▼                               │          │
│   ┌──────────────┐                       │          │
│   │  3. Evaluate │                       │          │
│   └──────┬───────┘                       │          │
│          │                               │          │
│          ▼                               │          │
│   ┌──────────────┐                       │          │
│   │  4. Apply    │                       │          │
│   │   technique  │                       │          │
│   └──────┬───────┘                       │          │
│          │                               │          │
│          ▼                               │          │
│   ┌──────────────┐                       │          │
│   │  5. Re-eval  │ ─── score tăng? ──────┘          │
│   └──────────────┘     Không → iterate            │
│                        Có → continue or ship        │
│                                                     │
└─────────────────────────────────────────────────────┘
def run_prompt(inputs):
    prompt = f"""What should this person eat?
    - Height: {inputs['height']}
    - Weight: {inputs['weight']}
    - Goal: {inputs['goal']}
    - Restrictions: {inputs['restrictions']}
    """
    return chat([{"role": "user", "content": prompt}])

Framework setup

Để vòng lặp này hoạt động, cần 3 thứ:

1. Test dataset

List input + expected output / criteria. Ví dụ:

2. Grader

Function chấm điểm cho 1 output. Có 2 loại:

Chi tiết ở Module 4.

3. Runner

Function chạy prompt qua toàn dataset, aggregate score:

  • Code-based: check bằng code Python (regex, parse JSON, so sánh)
  • Model-based: dùng Claude khác chấm theo rubric
[
  {
    "input": {
      "height": 175,
      "weight": 70,
      "goal": "build muscle",
      "restrictions": "no pork"
    },
    "criteria": [
      "Total calories between 2800-3200",
      "Protein > 150g",
      "No pork in meals",
      "Specify timing for each meal"
    ]
  },
  ...
]

3. Runner

Trong khóa này, bạn sẽ dùng PromptEvaluator helper — class wrap 3 phần trên.

def run_evaluation(prompt_fn, dataset):
    scores = []
    for case in dataset:
        output = prompt_fn(case["input"])
        score = grade(output, case["criteria"])
        scores.append(score)
    return sum(scores) / len(scores)

Ví dụ thực chiến: Meal planner

Bước 1: Goal

Viết prompt tạo 1-day meal plan cho athlete.

Bước 2: v1 baseline

Bước 3: Test 3 athlete

Result v1: Score 2.3/10. Claude output mông lung, thiếu calories, thiếu timing.

Bước 4: Apply technique — Clear & direct (bài 6.16)

def run_v1(inputs):
    prompt = f"What should this person eat?\n- Height: {inputs['height']}\n- Weight: {inputs['weight']}\n- Goal: {inputs['goal']}\n- Restrictions: {inputs['restrictions']}"
    return chat([{"role": "user", "content": prompt}])

Bước 4: Apply technique — Clear & direct (bài 6.16)

Bước 5: Re-eval v2

Result v2: Score 3.9/10. Output đã structured hơn, có tên bữa.

Iterate: v3 — Add specific guidelines (bài 6.17)

def run_v2(inputs):
    prompt = f"""Generate a one-day meal plan for an athlete with:
- Height: {inputs['height']} cm
- Weight: {inputs['weight']} kg
- Goal: {inputs['goal']}
- Dietary restrictions: {inputs['restrictions']}"""
    return chat([{"role": "user", "content": prompt}])

Iterate: v3 — Add specific guidelines (bài 6.17)

Result v3: Score 7.8/10. Đáp ứng hầu hết criteria.

Iterate: v4 — Add examples (bài 6.18)

Thêm 1 example input/output chất lượng cao.

Result v4: Score 8.9/10. Format chuẩn, consistent qua các input.

Ship v4

8.9/10 acceptable. Deploy v4 production.

Key observation: Từ 2.3 → 8.9 — cải thiện 3.8x qua 4 iteration. Không có quy trình này, bạn có thể stuck ở 3.9 mà không biết cách cải thiện.

def run_v3(inputs):
    prompt = f"""Generate a one-day meal plan for an athlete...

Guidelines:
1. Include daily caloric total
2. Show protein/fat/carb breakdown
3. Specify meal timing
4. Only foods meeting restrictions
5. Portion sizes in grams"""
    return chat([{"role": "user", "content": prompt}])

Techniques bạn sẽ học trong Module 3

Mỗi technique:

Thứ tự áp dụng khi iterate:

  • Cover 1 failure pattern phổ biến
  • Có ví dụ trước/sau cụ thể
  • Có số liệu improvement (như meal plan 2.3 → 8.9)
  • Clear & direct — luôn áp dụng đầu
  • Specific guidelines — luôn áp dụng thứ 2
  • Examples — áp dụng khi corner case nhiều
  • XML tags — áp dụng khi prompt complex (nhiều variable)
┌──────────────────────────────────────────────┐
│                                              │
│   6.14 Structured data — JSON output         │
│   6.16 Clear & direct — first line matters   │
│   6.17 Specific & detailed — guidelines      │
│   6.18 Providing examples — few-shot         │
│   6.19 XML tags — structure complex prompts  │
│                                              │
└──────────────────────────────────────────────┘

Tại sao eval là "must-have"?

Không eval = không biết đang đi đâu.

Without eval

3 tháng sau, user complain. Dev không biết bug ở đâu.

With eval

Dev: "Prompt mới của tôi tốt hơn rồi!"
PM: "Tốt như nào? Có metric không?"
Dev: "... tôi test 1 case thấy hay."
PM: ":|"

With eval

Ship với confidence. Debug có cơ sở.

Quy tắc: Nếu prompt sẽ chạy production (hoặc với user ngoài bạn), bắt buộc có eval. Không lười.

Dev: "v5 score 8.9 trên test set 50 cases. 
      vs v4 score 8.2.  
      Cải thiện đến từ: xử lý edge case restrictions kép."
PM: "Deploy."

Anti-patterns

❌ Iterate nhiều thứ cùng lúc

"Tôi thử v2: thêm example + đổi tone + xài XML" → score tăng từ 3 → 7. Không biết thứ nào contribute.

Fix: 1 change / iteration.

❌ Overfit test dataset

Viết prompt tối ưu cho 5 case test, production fail vì case mới khác.

Fix: Test dataset phải đa dạng, đủ lớn (30-100 cases), include edge.

❌ Không version control prompt

Prompt ở đâu? Ai edit lần cuối? Version nào đang chạy prod?

Fix: Prompt trong file .py hoặc .md, commit vào git. Có CHANGELOG.

❌ Không regression test

v3 ship prod → bug user → rollback v2 → v2 giờ fail case khác. Không biết vì sao.

Fix: Mỗi version eval trên cùng dataset, lưu score history.

❌ Skip baseline

Bắt đầu với prompt đã engineered kỹ → không biết gain từ engineering bao nhiêu.

Fix: Luôn write baseline simple trước. Score baseline là benchmark.

Áp dụng ngay

Bài tập 1: Framework mental model (15 phút)

Trong my-goals.md, trả lời:

Bài tập 2: Viết baseline (15 phút)

Chọn 1 trong 3 prompt của bạn. Viết v1 đơn giản nhất có thể. Chạy qua 3 input mẫu. Ghi output.

Đừng cố làm hay. Goal là có baseline để compare v2, v3 sau.

## Prompt engineering cho app của tôi

1. App tôi có bao nhiêu distinct prompt? (chatbot, classifier, summarizer...)
2. Với mỗi prompt, goal cụ thể là gì?
3. Làm sao tôi đo được "tốt" (3-5 criteria/prompt)?
4. Test dataset đến từ đâu (user logs? synthetic? manual curate?)?
5. Ai sẽ grade (code? model? human?)?

Tóm tắt bài học

🎯 Prompt engineering = quy trình kỹ thuật, không phải "magic words".

🎯 Core loop 5 bước: Goal → v1 → Eval → Technique → Re-eval. Iterate.

🎯 Framework cần 3 thành phần: Test dataset, Grader, Runner.

🎯 Mỗi iteration chỉ đổi 1 thứ để biết cái gì contribute improvement.

🎯 No eval = no engineering. Production prompt BẮT BUỘC có eval.

Tài liệu tham khảo
  • Anthropic prompt engineering guide
  • Anthropic prompt library
Nội dung này có hữu ích không?