Nếu bạn đã dùng ChatGPT nhiều, chắc bạn đã thấy các bài viết blog kiểu:
- Đị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
Mở đầu: "Prompt là code" — từ mindset đến workflow
10 prompt magic khiến ChatGPT siêu thông minh!" "Từ khóa bí mật giúp AI trả lời hay hơn!
Đó không phải prompt engineering. Đó là tips, tricks, hacks — thú vị nhưng không dùng được cho production.
Prompt engineering thật sự là kỹ thuật. Nó có:
- Mục tiêu đo lường được (score, accuracy)
- Quy trình lặp lại (baseline → iterate → verify)
- Version control (v1, v2, v3 của prompt)
- Regression testing (prompt mới không làm tệ case cũ)
Nói cách khác: prompt là code. Và bạn viết code cho production thế nào, thì viết prompt production thế ấy.
Bài này đặt nền tảng cho cả Module 3 và Module 4 (Prompt Evaluation). Đọc kỹ.
Prompt engineering là gì?
Định nghĩa chính thức:
Prompt engineering là quy trình iteratively improve một prompt để đạt reliability và chất lượng cao hơn cho output từ LLM.
Keywords:
- 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
Phân biệt với các khái niệm khác
| Prompting tip | Prompt engineering | |
|---|---|---|
| Mục đích | Get better response lẻ | Build production system |
| Approach | "Try this magic phrase" | Systematic iteration |
| Metric | Gut feel | Numeric score |
| Output | Prompt string | Prompt + test dataset + graders |
| Scale | Individual user | Team, thousands of users |
Vòng lặp 5 bước (core loop)
┌─────────────────────────────────────────────────────┐
│ │
│ ┌──────────────┐ │
│ │ 1. Set goal │ │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ 2. Write v1 │ ◀─────────────────────┐ │
│ └──────┬───────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌──────────────┐ │ │
│ │ 3. Evaluate │ │ │
│ └──────┬───────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌──────────────┐ │ │
│ │ 4. Apply │ │ │
│ │ technique │ │ │
│ └──────┬───────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌──────────────┐ │ │
│ │ 5. Re-eval │ ─── score tăng? ──────┘ │
│ └──────────────┘ Không → iterate │
│ Có → continue or ship │
│ │
└─────────────────────────────────────────────────────┘
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ệ:
Prompt để trả lời câu hỏi user tốt hơn
Tốt:
Prompt tạo meal plan 1 ngày cho athlete. Input: height, weight, goal, dietary restrictions. Output: meal plan có đủ calories, macro breakdown, timing bữa, portion gram cụ thể.
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.
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}])
Đâ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:
| Version | Score |
|---|---|
| v1 (baseline) | 2.3/10 |
| v2 (+clear wording) | 3.9/10 |
| v3 (+specific guidelines) | 7.8/10 |
| v4 (+examples) | 8.9/10 |
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.
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ụ:
[
{
"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"
]
},
...
]
2. Grader
Function chấm điểm cho 1 output. Có 2 loại:
- Code-based: check bằng code Python (regex, parse JSON, so sánh)
- Model-based: dùng Claude khác chấm theo rubric
Chi tiết ở Module 4.
3. Runner
Function chạy prompt qua toàn dataset, aggregate score:
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)
Trong khóa này, bạn sẽ dùng PromptEvaluator helper — class wrap 3 phần trên.
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
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 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_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}])
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_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}])
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.
Techniques bạn sẽ học trong Module 3
┌──────────────────────────────────────────────┐
│ │
│ 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 │
│ │
└──────────────────────────────────────────────┘
Mỗi technique:
- 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)
Thứ tự áp dụng khi iterate:
- 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)
Tại sao eval là "must-have"?
Không eval = không biết đang đi đâu.
Without 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: ":|"
3 tháng sau, user complain. Dev không biết bug ở đâu.
With eval
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."
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.
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:
Prompt engineering cho app của tôi
- App tôi có bao nhiêu distinct prompt? (chatbot, classifier, summarizer...)
- Với mỗi prompt, goal cụ thể là gì?
- Làm sao tôi đo được "tốt" (3-5 criteria/prompt)?
- Test dataset đến từ đâu (user logs? synthetic? manual curate?)?
- Ai sẽ grade (code? model? human?)?
### 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.
---
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.