Hướng dẫn Prompt Engineering cho Tester (Phần 1): Làm chủ framework RCIICO chuẩn ISTQB CT-GenAI

Bài viết sẽ đi từ kiến thức cơ bản nhất (LLM là gì, prompt là gì), qua phân tích chi tiết từng thành phần của RCIICO, đến câu hỏi quan trọng mà nhiều tester bỏ qua: khi nào cần dùng đầy đủ framework, và khi nào có thể đơn giản hoá?

Phần 1: Hiểu cơ bản về LLM và Prompt

1.1. LLM là gì?

Large Language Model (LLM) là loại mô hình AI được huấn luyện trên lượng dữ liệu văn bản khổng lồ, có khả năng hiểu và sinh ngôn ngữ tự nhiên. Các LLM phổ biến hiện nay bao gồm GPT (OpenAI), Claude (Anthropic), Gemini (Google), Llama (Meta). Khi bạn gõ một câu vào ChatGPT hay Claude và nhận được phản hồi, đó chính là LLM đang làm việc.

Cần lưu ý ba đặc điểm quan trọng của LLM mà ISTQB CT-GenAI nhấn mạnh [1]:

Non-deterministic: cùng một câu hỏi có thể cho ra hai câu trả lời khác nhau ở hai lần hỏi.

Dễ "hallucinate": có thể tự bịa thông tin nghe có vẻ đúng nhưng sai.

Phụ thuộc nặng vào input: chất lượng câu trả lời tỉ lệ thuận với chất lượng câu hỏi.

Đặc điểm thứ ba chính là lý do prompt engineering trở thành kỹ năng cốt lõi.

1.2. Prompt là gì?

Prompt là phần văn bản (hoặc đôi khi cả hình ảnh, file) bạn cung cấp cho LLM để mô hình thực hiện một tác vụ. Prompt không chỉ là "câu hỏi" — nó là bộ chỉ dẫn đầy đủ giúp LLM hiểu bạn cần gì.

1.3. Prompt Engineering là gì?

Prompt engineering là quá trình thiết kế và tinh chỉnh prompt một cách có hệ thống để LLM cho ra kết quả chính xác, đầy đủ và phù hợp với mục tiêu. Theo ISTQB CT-GenAI Section 2.1, đây là kỹ năng đảm bảo "GenAI tools thực hiện tác vụ kiểm thử một cách chính xác và hiệu quả, đồng thời tester thu được kết quả hữu ích từ LLM" [1].

Phần 2: Framework RCIICO — Cấu trúc 6 thành phần của prompt chuyên nghiệp

Đây là framework nền tảng nhất trong ISTQB CT-GenAI Section 2.1.1. Tên RCIICO là viết tắt từ chữ cái đầu của 6 thành phần: Role — Context — Instruction — Input data — Constraints — Output format [1].

Hãy đi sâu vào từng thành phần.

2.1. R — Role (Vai trò)

Role định danh "vai" mà LLM nên đóng khi xử lý prompt. Đây là thành phần thường bị bỏ qua nhất nhưng tác động rất lớn đến chất lượng output.

Vì sao? Vì LLM được huấn luyện trên đa dạng văn bản — từ blog tạp nham đến tài liệu kỹ thuật chuyên sâu. Khi bạn không chỉ định role, LLM sẽ "lấy trung bình" — cho ra câu trả lời chung chung. Khi bạn nói "Bạn là một senior tester có 8 năm kinh nghiệm trong ngành ngân hàng", LLM sẽ ưu tiên phong cách diễn đạt và mức độ chuyên môn phù hợp với vai trò đó.

Ví dụ tốt:

"Bạn là một test architect có kinh nghiệm 10 năm với hệ thống ERP tài chính, am hiểu các chuẩn SOX và PCI-DSS."

Ví dụ chưa đủ:

"Bạn là tester."

Role càng cụ thể về chuyên môn, ngành nghề và thâm niên thì output càng chất lượng.

2.2. C — Context (Bối cảnh)

Context cung cấp thông tin nền về hệ thống, sản phẩm, dự án. Đây là thành phần giúp LLM hiểu "câu chuyện lớn" xung quanh tác vụ.

Context tốt nên trả lời được:

Hệ thống đang làm gì? Phục vụ ai?

Đang ở giai đoạn nào (MVP, ổn định, mở rộng)?

Có ràng buộc kỹ thuật/tuân thủ đặc biệt không?

Team và tech stack hiện tại ra sao?

Ví dụ tốt:

"Tôi đang làm việc trên một internet banking web app dành cho khách hàng cá nhân tại Việt Nam. Hệ thống tích hợp với core banking T24, có yêu cầu bảo mật theo chuẩn PCI-DSS, hiện đang trong giai đoạn UAT trước go-live."

Không có context, LLM phải "đoán" — và thường đoán theo hướng generic (ví dụ: ứng dụng web Mỹ, không có ràng buộc tuân thủ đặc biệt).

2.3. I — Instruction (Chỉ dẫn)

Instruction là yêu cầu cụ thể về tác vụ cần thực hiện. Đây là phần "cốt lõi" — không có instruction thì không có prompt.

Nguyên tắc viết instruction tốt:

Dùng động từ rõ ràng: "tạo", "phân tích", "so sánh", "ưu tiên hoá", "tổng hợp"...

Cụ thể về phạm vi: "5 test case quan trọng nhất" thay vì "đầy đủ test case".

Chia nhỏ nếu có nhiều ý: dùng bullet list thay vì câu dài lê thê.

Ví dụ tốt:

Hãy tạo bộ test case cho chức năng đăng nhập, bao gồm:
- Happy path (3 test case)
- Negative cases — sai mật khẩu, tài khoản bị khoá, OTP sai (5 test case)
- Boundary cases — độ dài input, ký tự đặc biệt (3 test case)
- Security cases — SQL injection, brute force (4 test case)

Ví dụ mơ hồ:

"Viết test case cho login, càng nhiều càng tốt."

LLM sẽ trả ra danh sách dài nhưng nông, hoặc tự "tưởng tượng" những thứ bạn không cần.

2.4. I — Input data (Dữ liệu đầu vào)

Input data là dữ liệu cụ thể mà LLM cần xử lý — user story, code, screenshot, log error, requirement document, file CSV…

Phần này thường được bỏ qua hoặc cung cấp thiếu, dẫn đến LLM bịa ra giả định về dữ liệu — đây là nguồn gốc lớn nhất của hallucination.

Ví dụ tốt:

[Input data] User story:
"Là khách hàng đã đăng ký, tôi muốn đăng nhập bằng số điện thoại +
mật khẩu + OTP để truy cập tài khoản. OTP có hiệu lực 60 giây,
sai 3 lần liên tiếp khoá tài khoản 15 phút."

Acceptance criteria:
- Số điện thoại đầu vào: 10 chữ số, bắt đầu bằng 0.
- Mật khẩu: tối thiểu 8 ký tự, có chữ hoa, chữ thường, số.
- OTP: 6 chữ số.

Cung cấp đủ input data là cách duy nhất để LLM cho ra test case đúng với hệ thống của bạn, không phải hệ thống chung chung.

2.5. C — Constraints (Ràng buộc)

Constraints là các giới hạn, yêu cầu đặc biệt mà output phải tuân thủ. Đây là thành phần quyết định chất lượng "chiều sâu" của output.

Constraints có thể bao gồm:

Số lượng: tối đa bao nhiêu test case?

Phong cách: viết bằng tiếng Việt hay tiếng Anh? Trang trọng hay gọn?

Tránh điều gì: không tạo test case trùng, không dùng từ ngữ marketing…

Ưu tiên điều gì: ưu tiên security, ưu tiên trải nghiệm người dùng…

Ví dụ tốt:

[Constraints]
- Tối đa 15 test case có giá trị cao nhất, không liệt kê dài dòng.
- Mỗi test case phải có ID, mức ưu tiên (High/Medium/Low), tag (Functional/Security/Performance).
- Không tạo test case trùng lặp về bản chất.
- Viết bằng tiếng Việt, ngôn ngữ chuyên ngành kiểm thử.

Không có constraints, LLM thường có hai xu hướng tệ: (1) trả lời quá dài và lan man, (2) tạo nội dung chung chung không phù hợp với team.

2.6. O — Output format (Định dạng đầu ra)

Output format chỉ định cấu trúc kết quả mong muốn — bảng Markdown, JSON, danh sách bullet, đoạn văn, code block…

Tại sao quan trọng? Vì format quyết định bạn có dùng được output ngay hay phải mất thời gian định dạng lại.

Ví dụ tốt:

[Output format]
Bảng Markdown với các cột:
| ID | Tiêu đề | Mức ưu tiên | Pre-condition | Steps | Expected Result | Tag |

Sau bảng, thêm phần "Tóm tắt" liệt kê:
- Tổng số test case theo loại (functional/security/boundary/negative)
- 3 rủi ro lớn nhất chưa được cover

Khi bạn cần import vào TestRail, JIRA hay Excel, format chuẩn từ đầu giúp tiết kiệm hàng giờ thao tác thủ công.

Phần 3: Ví dụ tổng hợp — Áp dụng đầy đủ RCIICO

Ráp 6 thành phần lại thành một prompt hoàn chỉnh:

[R - Role] Bạn là một senior tester có 8 năm kinh nghiệm kiểm thử
ứng dụng web ngành ngân hàng, am hiểu chuẩn PCI-DSS.

[C - Context] Tôi đang làm việc trên một internet banking web app
dành cho khách hàng cá nhân. Hệ thống có yêu cầu bảo mật cao và
đang tích hợp xác thực 2 lớp qua OTP SMS, hiện đang trong giai đoạn UAT.

[I - Instruction] Hãy tạo bộ test case cho chức năng đăng nhập, bao gồm:
- Happy path (3 cases)
- Negative cases (5 cases)
- Boundary cases (3 cases)
- Security cases (4 cases)

[I - Input data] User story:
"Là khách hàng đã đăng ký, tôi muốn đăng nhập bằng số điện thoại +
mật khẩu + OTP để truy cập tài khoản. OTP có hiệu lực 60 giây,
sai 3 lần liên tiếp khoá tài khoản 15 phút."

[C - Constraints]
- Tối đa 15 test case có giá trị cao nhất.
- Mỗi test case có ID, mức ưu tiên, tag.
- Không trùng lặp về bản chất.
- Viết bằng tiếng Việt.

[O - Output format] Bảng Markdown với cột:
ID | Tiêu đề | Mức ưu tiên | Pre-condition | Steps | Expected Result | Tag.
Cuối bảng tổng hợp 3 rủi ro lớn chưa cover.

So sánh với prompt yếu phổ biến: "Viết test case cho chức năng đăng nhập." — sự khác biệt về chất lượng output là rõ rệt.

Phần 4: Khi nào cần dùng đầy đủ RCIICO, khi nào không?

Đây là câu hỏi quan trọng mà nhiều tester bỏ qua. RCIICO là framework "vàng" cho tác vụ chuyên nghiệp, nhưng không phải prompt nào cũng cần đủ 6 thành phần. Việc áp dụng máy móc có thể làm chậm công việc thay vì tăng năng suất.

4.1. Khi nào NÊN dùng đầy đủ RCIICO?

Tác vụ có giá trị cao, output sẽ được sử dụng chính thức:

Sinh test case cho release quan trọng.

Viết test report gửi stakeholder.

Sinh test data cho UAT.

Phân tích yêu cầu cho dự án phức tạp.

Tác vụ lặp lại nhiều lần:

Khi bạn biết sẽ dùng prompt này 10-50 lần (ví dụ: review từng user story trong sprint), đầu tư vào prompt RCIICO chuẩn ngay từ đầu sẽ tiết kiệm rất nhiều thời gian sau này.

Tác vụ trong domain đặc thù:

Ngân hàng, bảo hiểm, y tế, ERP — những ngành mà LLM dễ "đoán sai" nếu không có context và role rõ ràng.

Tác vụ output cần format chuẩn để import:

Khi bạn cần copy-paste vào TestRail, JIRA, hoặc Excel mà không muốn chỉnh sửa thủ công.

4.2. Khi nào KHÔNG cần dùng đầy đủ?

Câu hỏi nhanh, mang tính khám phá:

"Có những kỹ thuật test design nào cho boundary value?" — đây là câu hỏi tra cứu kiến thức, không cần Role/Context/Constraints.

Brainstorm sơ khởi:

Khi bạn đang muốn LLM gợi ý "ý tưởng test scenario nào nên thử cho tính năng này?" — output là đầu vào cho suy nghĩ tiếp, không phải sản phẩm cuối.

Tác vụ rất ngắn, kết quả nhanh dùng nhanh quên:

"Sửa lỗi ngữ pháp giúp tôi đoạn này", "Dịch test case này sang tiếng Anh" — không cần framework đầy đủ.

Khi đang chat tương tác qua nhiều lượt:

Nếu bạn đã thiết lập context ở lượt đầu, các lượt sau chỉ cần instruction ngắn — LLM nhớ lại context từ session.

4.3. Quy tắc thực dụng — "đủ là đủ"

Một quy tắc thực dụng từ kinh nghiệm cộng đồng: càng quan trọng càng dùng đủ, càng nhanh càng cắt bớt. Bạn có thể chia tác vụ làm 3 nhóm:

Mức độ | Số thành phần RCIICO cần | Ví dụ
Quick query | 1-2 (chỉ Instruction, có thể có Input data) | Tra kiến thức, dịch nhanh, fix grammar
Standard task | 3-4 (thường: Role + Instruction + Input data + Output format) | Sinh test case nhanh cho task nhỏ
Mission-critical | Đầy đủ 6 | Release quan trọng, output gửi stakeholder, tác vụ lặp lại nhiều

Tester chuyên nghiệp là người biết chọn đúng mức độ — không lười cắt giảm khi cần kỹ lưỡng, cũng không "over-engineer" prompt cho những việc đơn giản.

Lời kết

Framework RCIICO là nền tảng quan trọng nhất của prompt engineering theo chuẩn ISTQB CT-GenAI. Khi bạn làm chủ được việc viết đầy đủ lẫn biết khi nào cắt bớt, prompt sẽ trở thành công cụ làm việc thực sự hiệu quả — không phải gánh nặng.

Lời khuyên cuối: hãy bắt đầu bằng việc viết 5 prompt RCIICO đầy đủ cho các tác vụ thường gặp nhất của bạn, lưu chúng vào một file Markdown trong IDE (như đã hướng dẫn ở bài "Tester thời AI: Vì sao đã đến lúc chuyển dịch từ Excel sang IDE?"), và tinh chỉnh dần qua thực tế. Đây là khoản đầu tư có lãi suất cao nhất bạn có thể làm cho công việc kiểm thử của mình trong năm 2026.

Trong phần 2 của loạt bài này, IT Learn sẽ hướng dẫn bạn các kỹ thuật prompting nâng cao theo ISTQB CT-GenAI: few-shot prompting, prompt chaining, meta prompting và iterative refinement — những công cụ mạnh giúp giải quyết các tác vụ phức tạp mà RCIICO đơn lẻ chưa đủ.

Theo dõi blog của IT Learn để không bỏ lỡ phần 2, hoặc liên hệ với chúng tôi qua hộp tin nhắn để được tư vấn lộ trình học tập phù hợp.

Tài liệu tham khảo

[1] ISTQB®. Certified Tester Specialist Level Syllabus – Testing with Generative AI (CT-GenAI) v1.0, July 2025. Tham chiếu cụ thể: Section 2.1 (Effective Prompt Development), Section 2.1.1 (Structure of Prompts for Generative AI in Software Testing — 6 components: Role, Context, Instruction, Input data, Constraints, Output format), Section 2.2 (Applying Prompt Engineering Techniques to Software Test Tasks). https://istqb.org/

[2] Anthropic. "Prompt Engineering Overview", Claude Documentation — phần "Be clear and direct" và "Use examples" trùng khớp với nguyên tắc Role/Instruction/Input data của RCIICO. https://docs.claude.com/en/docs/build-with-claude/prompt-engineering/overview

[3] OpenAI. "Best Practices for Prompt Engineering with the OpenAI API" — hướng dẫn về việc chỉ định format đầu ra (tương đương Output format trong RCIICO). https://platform.openai.com/docs/guides/prompt-engineering