Bỏ qua điều hướng
Lập trình viên

Mọi điều lập trình viên cần biết về prompt engineering

Hướng dẫn prompt engineering cho lập trình viên: tối ưu in-context learning (học trong ngữ cảnh), gỡ lỗi logic phức tạp và refactor code.

Tuan Tran Van
9 phút đọc
Mục lục (10 phần)
  1. Prompt engineering là gì và vì sao lập trình viên cần nó?
  2. Cấu tạo của một prompt hiệu quả
  3. Các kỹ thuật prompt nền tảng
  4. Prompt để gỡ lỗi (debugging)
  5. Prompt để refactor và tối ưu code
  6. Prompt để xây dựng tính năng mới
  7. Những anti-pattern cần tránh
  8. Bắt đầu: quy trình lặp và tinh chỉnh prompt
  9. Các câu hỏi thường gặp
  10. Tài liệu tham khảo

Prompt engineering (PE) là quá trình thiết kế và tối ưu hóa các chỉ dẫn đầu vào để điều khiển mô hình ngôn ngữ lớn (LLM) thực thi các nhiệm vụ cụ thể.

PE không phải là sự ngẫu nhiên, mà là một dạng lập trình bằng ngôn ngữ tự nhiên. Làm chủ PE giúp lập trình viên biến LLM từ một chatbot thông thường thành một cộng sự (pair programmer) có khả năng thực hiện các tác vụ từ gỡ lỗi logic đến refactor kiến trúc hệ thống với độ chính xác cao.

Đầu tư vào prompt engineering là đầu tư vào khả năng kiểm soát hệ thống. Thay vì hy vọng vào một kết quả may rủi, lập trình viên dùng PE để đảm bảo tính ổn định của đầu ra (output) trong môi trường production. Hiểu rõ cơ chế vận hành của mô hình giúp bạn khai thác tối đa hiệu suất mà không cần tốn chi phí fine-tune lại trọng số.

Hình minh hoạ prompt engineering cho lập trình viên: mô hình ngôn ngữ lớn trở thành cộng sự lập trình đáng tin cậy, với prompt đóng vai trò mã viết bằng ngôn ngữ tự nhiên

Prompt engineering là gì và vì sao lập trình viên cần nó?

Prompt engineering thực chất là một hình thức "lập trình mô hình". Cơ chế cốt lõi khiến PE hoạt động là in-context learning (học trong ngữ cảnh) — khả năng mô hình ngôn ngữ lớn (LLM) học hành vi hoặc định dạng mới ngay từ ví dụ bạn đưa vào cửa sổ ngữ cảnh (context window), mà không cần huấn luyện lại. Trọng số (weights) — các tham số mô hình đã học cố định trong quá trình huấn luyện — vẫn giữ nguyên; mô hình chỉ "học tạm" trong phạm vi đoạn hội thoại hiện tại.

Đối với kỹ sư phần mềm, PE là quá trình "ngoại hóa bộ não" (externalizing the brain). Hãy coi LLM như một "người ngoài ngành có học thức" (educated layperson): họ thông minh nhưng hoàn toàn thiếu ngữ cảnh về dự án của bạn. PE giúp bạn chuyển logic nghiệp vụ từ tư duy sang ngôn ngữ để mô hình thực thi. Trong môi trường production, PE là lớp kiểm soát logic, giúp khống chế định dạng đầu ra (như JSON) và giảm độ trễ (latency) bằng cách tối ưu số lượng token sử dụng.

Cấu tạo của một prompt hiệu quả

Một prompt chuẩn kỹ thuật cần được cấu trúc rõ ràng, ưu tiên dùng XML tags để phân tách dữ liệu, giúp mô hình phân biệt đâu là chỉ dẫn và đâu là dữ liệu đầu vào.

Sơ đồ năm thành phần của một prompt hiệu quả: Role, Context, Task, Reference và Format

  1. Role (Vai trò): gán một định danh chuyên gia (ví dụ: Senior DevOps Engineer).
  2. Context (Ngữ cảnh): cung cấp tài liệu API, phiên bản framework và kiến trúc hệ thống.
  3. Task (Nhiệm vụ): chỉ dẫn cụ thể, đặt ở đầu hoặc cuối prompt (tối ưu hóa cửa sổ ngữ cảnh).
  4. Reference (Tài liệu): các đoạn mã mẫu hoặc schema dữ liệu, đặt trong thẻ <reference>.
  5. Format & Constraints (Định dạng & Ràng buộc): yêu cầu JSON, Markdown và cung cấp "lối thoát" nếu không có kết quả.

Ví dụ một prompt mẫu:

xml
<role>Bạn là một Senior React Developer chuyên về tối ưu hiệu năng.</role>
 
<context>
Dự án dùng React 18, TypeScript. Component hiện tại gặp lỗi re-render vô tận.
</context>
 
<reference>
[Chèn mã nguồn component tại đây]
</reference>
 
<task>
Hãy phân tích dependency array của useEffect trong mã nguồn trên.
Yêu cầu:
1. Xác định nguyên nhân gây infinite loop.
2. Cung cấp mã sửa lỗi dùng functional updates hoặc memoization.
3. Nếu không tìm thấy lỗi logic, hãy trả về "Unsure".
</task>
 
<format>Trả về dưới định dạng JSON: {"issue": string, "solution": string, "code": string}</format>

Các kỹ thuật prompt nền tảng

Sơ đồ so sánh năm kỹ thuật prompt nền tảng: zero-shot, few-shot, chain-of-thought, role prompting và prompt chaining

  • Zero-shot: đưa lệnh trực tiếp, không kèm ví dụ. Phù hợp cho các tác vụ sinh mã khuôn mẫu (boilerplate) đơn giản.
  • Few-shot: cung cấp 2–5 ví dụ. Để tiết kiệm token, hãy dùng cấu trúc tối giản input -> output thay vì User: Input, Assistant: Output.
  • Chain-of-thought (CoT): dùng cụm "think step-by-step" hoặc yêu cầu mô hình giải trình logic trong thẻ <thought> trước khi viết code. Cách này tạo "không gian tính toán" giúp xử lý các bài toán logic phức tạp.
  • Role prompting: gán vai trò (ví dụ "Security Auditor") để mô hình ưu tiên tri thức về lỗ hổng bảo mật (OWASP, SQL injection).
  • Prompt chaining: chia nhỏ quy trình. Ví dụ: Prompt 1 (phân tích lỗi) → Prompt 2 (viết bản vá) → Prompt 3 (viết unit test). Cách này giảm tỷ lệ lỗi so với việc nhồi nhét một "mega-prompt".

Prompt để gỡ lỗi (debugging)

Thay vì hỏi "Tại sao code lỗi?", hãy áp dụng công thức "Expected vs Actual":

"Mã này được kỳ vọng thực hiện [behavior] nhưng thực tế đang trả về [current behavior] khi nhận đầu vào [input]. Lỗi log là [error message]. Hãy mô phỏng thực thi từng dòng để tìm điểm mâu thuẫn."

Bạn cũng có thể dùng kỹ thuật "rubber ducking": giải thích logic của mình cho AI và yêu cầu nó chỉ ra sự khác biệt giữa lời giải thích của bạn và mã nguồn thực tế.

Ví dụ một prompt gỡ lỗi:

text
<code>
for (let i = 0; i <= users.length; i++) {
  process(users[i].id);
}
</code>
Task: Mã trên gặp lỗi TypeError khi chạy.
Expected: Duyệt qua tất cả phần tử trong mảng users.
Actual: Lỗi "Cannot read property 'id' of undefined" ở vòng lặp cuối.
Hãy phân tích loop bounds và sửa lại.

Prompt để refactor và tối ưu code

Khi refactor, hãy xác định mục tiêu cụ thể: độ phức tạp thời gian O(n), tính dễ đọc, hoặc xóa bỏ boilerplate.

  1. Yêu cầu AI refactor logic (ví dụ: chuyển nested loop thành Map để tối ưu về O(n)).
  2. Yêu cầu giải thích chi tiết các thay đổi để tránh side effects.
  3. Quan trọng nhất: yêu cầu AI viết unit test (Jest/Vitest) cho đoạn code mới để đảm bảo tính toàn vẹn của logic nghiệp vụ.

Prompt để xây dựng tính năng mới

Đừng yêu cầu AI viết toàn bộ tính năng ngay lập tức. Hãy thực hiện quy trình dựng khung (scaffolding):

  • Bước 1: cung cấp tài liệu API và yêu cầu AI lập kế hoạch triển khai (system design).
  • Bước 2: yêu cầu AI viết các interface hoặc type definitions.
  • Bước 3: triển khai từng module nhỏ dựa trên kế hoạch đã duyệt.
  • Bước 4: yêu cầu AI liệt kê và xử lý các trường hợp biên (edge cases) như null data hoặc network timeout.

Quy trình xây dựng tính năng mới theo từng bước: lập kế hoạch, viết interface, triển khai từng module và xử lý các trường hợp biên

Những anti-pattern cần tránh

  • Vague prompts: chỉ dẫn mơ hồ kiểu "Sửa code này hộ tôi".
  • Overloading: nhồi nhét quá nhiều yêu cầu (refactor + viết test + viết doc) vào một lần gọi.
  • Vague success criteria: không định nghĩa rõ thế nào là code "sạch" hoặc "tối ưu".
  • Vague references: dùng các từ thay thế như "nó", "đoạn code trên" trong một hội thoại quá dài khiến AI mất dấu ngữ cảnh.
  • Ignoring AI questions: bỏ qua các câu hỏi làm rõ của mô hình khi nó gặp điểm mâu thuẫn trong logic của bạn.

Bắt đầu: quy trình lặp và tinh chỉnh prompt

Triết lý tối thượng là "Always Be Iterating" (ABI). Prompt engineering là một chu kỳ:

  1. Viết: tạo prompt dựa trên khung Role–Task–Context.
  2. Đánh giá: kiểm tra output (có chạy được không? có đúng định dạng không?).
  3. Tinh chỉnh: điều chỉnh vị trí chỉ dẫn (needle in a haystack), thêm ví dụ (few-shot) hoặc thêm ràng buộc.
  4. Thử lại: lặp lại cho đến khi đạt độ ổn định (stability) cần thiết cho môi trường production.

Vòng lặp ABI trong prompt engineering: Viết, Đánh giá, Tinh chỉnh và Thử lại

Các câu hỏi thường gặp

Sự khác biệt giữa PE cho chat và PE cho production là gì? PE cho chat linh hoạt và ngẫu hứng. PE cho production yêu cầu tính nhất quán tuyệt đối: dùng các tham số như temperature = 0temperature điều khiển mức độ ngẫu nhiên của câu trả lời, đặt về 0 buộc mô hình luôn chọn đáp án chắc chắn nhất nên cùng một prompt sẽ cho kết quả lặp lại ổn định — cùng định dạng có cấu trúc (JSON/XML) để tích hợp vào pipeline hệ thống.

AI có thực sự "suy nghĩ" khi dùng Chain-of-thought không? Không. CoT thực chất là tạo ra các token trung gian đóng vai trò "không gian tính toán". Việc mô tả logic từng bước giúp mô hình kích hoạt các liên kết dữ liệu chính xác hơn trước khi đưa ra kết luận.

Làm thế nào để tránh ảo giác (hallucination) của AI trong code? Cung cấp ngữ cảnh thực tế (tài liệu API, thư viện), yêu cầu trích dẫn nguồn và luôn cung cấp một lối thoát: "Nếu không chắc chắn về thư viện này, hãy báo là không biết".

Tài liệu tham khảo

Đọc tiếp

Chia sẻ bài viết

X / TwitterFacebookLinkedIn