Chuyển đến nội dung chính

AI Skill — Đóng Gói Quy Trình Làm Việc Cho AI

Khi bắt đầu sử dụng AI trong development, chúng ta thường làm việc bằng prompt:

Review this C# code.

Cách này rất tiện. Nhưng khi đưa AI vào làm việc trong một team, một vấn đề bắt đầu xuất hiện: cùng một loại công việc nhưng mỗi lần AI có thể xử lý theo một cách khác nhau.

Bài viết này giải thích AI Skill là gì, tại sao Skill hữu ích trong môi trường team, cách tạo một Skill đơn giản và thực hành trực tiếp với một ví dụ C#.


1. Vấn đề: AI có thể xử lý cùng một công việc theo nhiều cách

Hãy tưởng tượng team có một yêu cầu rất đơn giản:

Review hàm tính Fibonacci bằng C#.

Một developer gửi:

Review this code.

Một lần AI có thể tập trung vào performance. Một lần khác nó tập trung vào naming. Một lần khác nó có thể tự viết lại toàn bộ code.

Ví dụ, cùng một hàm:

public class Utils
{
    public static int Fib(int n)
    {
        if (n == 0) return 0;
        if (n == 1) return 1;

        return Fib(n - 1) + Fib(n - 2);
    }
}

AI có thể đưa ra nhiều hướng review khác nhau:

  • Phân tích độ phức tạp.
  • Đề nghị đổi tên Fib.
  • Đề nghị xử lý số âm.
  • Đề nghị đổi sang iterative algorithm.
  • Đề nghị thêm caching.
  • Thậm chí viết lại toàn bộ implementation.

Không nhất thiết những câu trả lời đó đều sai. Vấn đề là: team không có một workflow review thống nhất.

Prompt "hãy làm theo best practice" chưa giải quyết được vấn đề

Review this code using clean code
and best practices.

Các từ như clean code, best practice hay high quality vẫn để AI tự diễn giải. Mỗi developer cũng có thể hiểu "best practice" theo một cách khác nhau.

Điều chúng ta thực sự muốn là:

Khi review C# code,
hãy luôn kiểm tra 5 tiêu chí này,
theo đúng thứ tự này,
và trả kết quả theo format này.

Đó chính là nơi Skill trở nên hữu ích.


2. Skill là gì?

Một cách hiểu đơn giản:

Skill là một workflow chuyên biệt được đóng gói để AI có thể áp dụng lại cho một loại công việc.

Skill có thể chứa:

  • Quy trình thực hiện công việc.
  • Các quy tắc cần tuân thủ.
  • Checklist.
  • Output format.
  • Template.
  • Điều kiện để sử dụng Skill.
  • Các tài liệu tham chiếu bổ sung.

Vì vậy Skill không đơn giản là:

"Bạn là một C# expert."

Nó gần với một SOP (Standard Operating Procedure) hơn:

Input
  ↓
Workflow
  ↓
Rules / Checklist
  ↓
Output Contract
  ↓
Result

Skill giúp AI giảm việc phải tự suy đoán workflow

Không có Skill, AI phải dựa nhiều hơn vào prompt, context và cách tự suy luận trong từng lần xử lý.

Có Skill, chúng ta cung cấp cho AI một workflow rõ ràng để ưu tiên áp dụng.

flowchart LR A[User Request] --> B{Skill available?} B -->|No| C[General reasoning] B -->|Yes| D[Load Skill] D --> E[Follow workflow] E --> F[Apply rules] F --> G[Produce defined output]

Điểm quan trọng: Skill không làm AI thông minh hơn. Nó giúp AI làm một loại công việc theo cách có cấu trúc và nhất quán hơn.


3. Skill khác gì với một prompt thông thường?

Prompt Skill
Instruction cho một lần xử lý Workflow có thể tái sử dụng
Thường ngắn và theo ngữ cảnh Có cấu trúc rõ ràng
Output có thể thay đổi Có thể quy định output contract
Developer phải nhớ cách prompt Workflow được lưu thành artifact
Khó chuẩn hóa giữa team Có thể version bằng Git

Có thể hình dung:

flowchart TB P[Prompt] --> O1[One-time instruction] ``` S[Skill] --> W[Workflow] S --> R[Rules] S --> C[Checklist] S --> T[Output Template] W --> O2[Reusable process] R --> O2 C --> O2 T --> O2 ```

4. Cấu trúc cơ bản của một Skill

Một Skill có thể rất đơn giản. Ví dụ:

csharp-code-review/
└── SKILL.md

File quan trọng nhất là SKILL.md.

Một Skill thực tế có thể lớn hơn:

csharp-code-review/
├── SKILL.md
├── checklist.md
├── output-template.md
└── references/
    └── coding-conventions.md

Không phải Skill nào cũng cần tất cả các file này. Nguyên tắc đơn giản là: chỉ thêm tài liệu khi workflow thực sự cần.

5. Một Skill có thể gồm nhiều lớp tri thức

Ở ví dụ trước, chúng ta chỉ có một file:

csharp-code-review/
└── SKILL.md

Điều này đủ cho một Skill đơn giản. Nhưng khi workflow trở nên phức tạp, chúng ta thường cần thêm các tài liệu hỗ trợ.

Ví dụ:

csharp-code-review/
├── SKILL.md
├── checklist.md
├── output-template.md
└── references/
    └── coding-conventions.md

Bốn thành phần này có những vai trò khác nhau:

File Vai trò Câu hỏi nó trả lời
SKILL.md Workflow chính AI phải thực hiện công việc này như thế nào?
checklist.md Danh sách kiểm tra Cần kiểm tra những gì?
output-template.md Khuôn mẫu kết quả Kết quả phải được trình bày như thế nào?
references/... Kiến thức tham chiếu Project/team có quy định hoặc convention gì?

Có thể hình dung:

flowchart TD A[User Request] --> B[SKILL.md] B --> C[Workflow] C --> D[checklist.md] C --> E[output-template.md] C --> F[references/coding-conventions.md] D --> G[What to check] E --> H[How to format] F --> I[Project-specific rules] G --> J[Final Review] H --> J I --> J

SKILL.md — Workflow

Đây là file trung tâm của Skill. Nó định nghĩa mục đích, khi nào sử dụng và workflow chính.

---
name: csharp-code-review
description: Reviews C# code against 5 fixed criteria (Correctness, Naming, Error Handling, Performance & Readability, Testability). Use when reviewing C# methods, classes, or pull requests.
---

# C# Code Review Skill

## Purpose

Provide a consistent and structured review of C# code using five fixed review criteria:

1. Correctness
2. Naming
3. Error Handling
4. Performance & Readability
5. Testability

## When to Use

Use this skill when the user asks to:

- Review C# methods or classes.
- Review a C# code change.
- Review a pull request.
- Identify potential bugs, maintainability issues, or design problems in C# code.

Do not use this skill for requirements analysis, architecture design, or general project planning unless the request explicitly includes a C# code review.

## Review Workflow

When reviewing C# code:

1. Read and understand the code and its intended behavior.
2. Evaluate the code against all five review criteria.
3. Use `checklist.md` to ensure the review covers the required checks.
4. Use project conventions from `references/` when they are available.
5. Identify only findings supported by the code, checklist, or applicable project conventions.
6. Determine the review status based on the status rules below.
7. Use `output-template.md` to produce the final review.

Do not skip a review criterion unless the criterion is genuinely not applicable to the code.

## Review Criteria

### 1. Correctness

Evaluate:

- Intended logic and behavior.
- Null and empty input handling.
- Boundary conditions.
- Async/await usage.
- Potential bugs or incorrect behavior.

### 2. Naming

Evaluate:

- Naming clarity.
- PascalCase and camelCase conventions.
- Descriptive names.
- Interface naming conventions.

### 3. Error Handling

Evaluate:

- Input validation.
- Guard clauses where appropriate.
- Exception handling.
- Silent exception swallowing.
- Appropriate exception types.

### 4. Performance & Readability

Evaluate:

- Unnecessary database or I/O calls.
- N+1 query risks.
- Unnecessary allocations or repeated enumeration.
- Complexity.
- Magic numbers or hardcoded values.
- Overall readability.

### 5. Testability

Evaluate:

- Isolation of business logic.
- Hidden side effects.
- External dependencies.
- Direct database/file/time dependencies.
- Single responsibility.

## Review Status

Assign one of the following statuses:

### APPROVED

Use when no significant issues are found and the code satisfies the applicable review criteria.

### NEEDS REVISION

Use when issues should be addressed before the code is considered ready, but there is no critical correctness or safety issue.

### BLOCKER

Use when a critical issue prevents the code from being safely accepted, such as a serious correctness problem or a critical violation of an applicable project rule.

When uncertain between two statuses, prefer the less severe status unless the evidence clearly supports the more severe classification.

## Supporting Files

Use the following files when they are available:

- `checklist.md` — detailed checks for each review criterion.
- `output-template.md` — required structure for the final review.
- `references/` — project-specific coding conventions and rules.

The supporting files refine this skill; they do not replace the five fixed review criteria defined above.

## Output Requirements

The final review must:

- Follow `output-template.md`.
- Cover all five review criteria.
- Keep each detailed feedback section concise.
- Provide actionable recommendations based on the findings.
- Avoid reporting issues that are unsupported by the code or applicable project conventions.

Điểm quan trọng là: SKILL.md có thể hướng dẫn AI đọc các tài liệu hỗ trợ khi cần.

Không nên hiểu rằng chỉ cần đặt file vào cùng một folder thì AI chắc chắn sẽ tự động đọc tất cả. Workflow của Skill phải chỉ ra những tài liệu nào cần sử dụng.

checklist.md — Những gì cần kiểm tra

# C# Review Checklist

## 1. Correctness
- [ ] Happy path logic matches intended behavior
- [ ] Null inputs and empty collections are handled
- [ ] Boundary conditions (off-by-one, min/max values) are considered
- [ ] Avoid `async void` (unless required by event handlers)
- [ ] Async methods return `Task` or `Task<T>` and are properly awaited

## 2. Naming
- [ ] Classes, Methods, and Properties use PascalCase
- [ ] Variables and Parameters use camelCase
- [ ] Interfaces start with an `I` prefix
- [ ] Names are descriptive and avoid vague words (e.g., `Data`, `Process`, `Info`)

## 3. Error Handling
- [ ] Invalid inputs are validated early (Guard clauses)
- [ ] Exceptions are not silently swallowed (`catch (Exception) { }`)
- [ ] Specific exceptions are caught/thrown rather than generic `Exception`

## 4. Performance & Readability
- [ ] No database or I/O calls inside loops (N+1 query risk)
- [ ] Unnecessary allocations or redundant LINQ enumerations are avoided
- [ ] Magic numbers and hardcoded strings are replaced with constants/enums
- [ ] Code is clear and avoids over-engineering

## 5. Testability
- [ ] Logic is isolated and has no hidden side effects
- [ ] Hard dependencies (e.g., `DateTime.Now`, direct DB/File access) are abstracted
- [ ] Method has a single, clear responsibility (SRP)

Checklist giúp biến một yêu cầu chung như "review carefully" thành những điểm có thể kiểm tra cụ thể.

output-template.md — Kết quả phải có cấu trúc

# Code Review Findings

## Overview
- **Status:** [APPROVED | NEEDS REVISION | BLOCKER]
- **Summary:** [Write 1 concise sentence summarizing the overall result]

## Detailed Feedback

### 1. Correctness
- [Maximum 2 sentences. Evaluate logic, edge cases, null handling, and async handling.]

### 2. Naming
- [Maximum 2 sentences. Evaluate naming clarity and PascalCase/camelCase conventions.]

### 3. Error Handling
- [Maximum 2 sentences. Evaluate input validation and exception handling.]

### 4. Performance & Readability
- [Maximum 2 sentences. Evaluate performance risks, complexity, I/O patterns, and magic values.]

### 5. Testability
- [Maximum 2 sentences. Evaluate isolation, side effects, and external dependencies.]

## Actionable Recommendations
- [Most critical fix, derived from the findings above]
- [Second most critical fix, optional]

Template không quyết định AI phải tìm lỗi gì. Nó quyết định: sau khi review xong, kết quả được trình bày như thế nào.

references/coding-conventions.md — Chuẩn riêng của project

# Project C# Coding Conventions

- Public async methods use the Async suffix.
- Public APIs accept CancellationToken when the operation can be cancelled.
- Use String Interpolation for formatted strings.
- Database access must not be performed inside item-by-item loops.
- Service interfaces are required for externally consumed services.

Đây là điểm rất quan trọng: reference không nhất thiết là "best practice của C#".

Nó có thể là:

  • Architecture convention của project.
  • Business rule.
  • Security policy.
  • Coding convention.
  • Framework convention.
  • Quyết định kiến trúc của team.

Ví dụ:

General C# knowledge
        +
Project conventions
        +
Review workflow
        +
Checklist
        +
Output format
        ↓
   Code Review
Lưu ý: Không nên biến references/ thành một "knowledge dump". Không nên:

references/
├── csharp-basics.md
├── all-dotnet-features.md
├── ef-core-documentation.md
├── complete-oop-guide.md
├── design-patterns.md
└── ...
Vì Skill sẽ trở nên nặng và AI phải xử lý quá nhiều context. Nên:

references/
├── coding-conventions.md
├── architecture-rules.md
├── security-guidelines.md
└── testing-conventions.md
Tức là: Reference = thông tin cần thiết để Skill thực hiện đúng công việc trong context của project.

SKILL.md nên nói rõ khi nào cần đọc reference nào, thay vì mặc định đọc tất cả.

Ví dụ:

## Supporting References

Load the following references when applicable:

- `references/coding-conventions.md` — C# naming, async, formatting, and coding conventions.
- `references/architecture-rules.md` — architecture and dependency rules.
- `references/security-guidelines.md` — security-related review requirements.
- `references/testing-conventions.md` — project testing standards.

6. Thực hành: cùng một đoạn code, Skill đầy đủ sẽ làm gì?

Bây giờ hãy thử một ví dụ thực tế hơn.

Đây là code cần review:

public class UserService
{
    public async void ProcessUsers(List<int> ids)
    {
        foreach (var id in ids)
        {
            var u = GetUserFromDb(id);

            if (u.Age > 18)
            {
                Console.WriteLine("Processed user: " + u.Name);
            }
        }
    }

    private User GetUserFromDb(int id) => new User();
}

Giả sử project có đầy đủ:

csharp-code-review/
├── SKILL.md
├── checklist.md
├── output-template.md
└── references/
    └── coding-conventions.md

Workflow lúc này có thể được hiểu như:

flowchart TD A[Input C# Code] --> B[SKILL.md] B --> C[Review Workflow] C --> D[Checklist] C --> E[Project Conventions] C --> F[Output Template] D --> G[Review Findings] E --> G F --> G G --> H[Final Code Review]

Một kết quả có thể có dạng:

# Code Review Findings

## Overview

- **Status:** NEEDS REVISION
- **Summary:** The method has async, null-safety, and
  database-access concerns that should be addressed.

## Detailed Feedback

### 1. Correctness

- `async void` should be avoided for application service
  methods because callers cannot await the operation or
  reliably observe exceptions.
- `ids` is not validated for null.
- `GetUserFromDb(id)` may produce a null user, but the code
  accesses `u.Age` and `u.Name` without validation.

### 2. Naming

- `u` is too short and should be replaced with `user`.
- If required by the project convention, the async method
  should use the `Async` suffix.

### 3. Error Handling

- Invalid input and database failures are not handled
  according to the project's error-handling convention.

### 4. Performance & Readability

- Calling `GetUserFromDb` inside the loop can result in
  one database operation per user.
- The project convention requires batch access when the
  operation can be performed as a single query.
- String interpolation is preferred by the project convention.

### 5. Testability

- Database access is tightly coupled to the service.
- The project convention requires externally consumed
  services to depend on abstractions.

## Actionable Recommendations

- Change `async void` to `Task`.
- Validate input and user results.
- Replace per-item database access with a batch operation.
- Apply the project's naming and formatting conventions.
- Introduce the required abstraction for database access.

Lưu ý: đây là minh họa về workflow, không phải tuyên bố rằng mọi project C# đều phải áp dụng chính xác các quy tắc trên.

Ví dụ như việc bắt buộc dùng interface, CancellationToken, String Interpolation hay batch query chỉ trở thành project convention nếu project đã quy định như vậy.


7. Điều gì thay đổi khi thiếu từng thành phần?

Bây giờ chúng ta có thể thử bỏ từng thành phần để hiểu vai trò của chúng.

Trường hợp 1 — Thiếu output-template.md

Workflow review vẫn có thể hoạt động. Checklist và project conventions vẫn có thể được áp dụng. Nhưng format của kết quả không còn được quy định rõ.

Ví dụ AI có thể trả lời:

There are several issues with this code.

First, async void is problematic...

The variable u should have a better name...

You also have database access inside a loop...

I would recommend refactoring the service...

Nội dung có thể vẫn đúng, nhưng không còn đảm bảo cấu trúc:

Overview
  ↓
Correctness
  ↓
Naming
  ↓
Error Handling
  ↓
Performance
  ↓
Testability
  ↓
Recommendations

Vai trò bị mất ở đây là Format Consistency.

Trường hợp 2 — Thiếu checklist.md

AI vẫn biết workflow chung từ SKILL.md, nhưng các kiểm tra chi tiết có thể không còn được quy định ở một nơi riêng.

Điều này có thể làm tăng nguy cơ bỏ sót những kiểm tra mà team muốn thực hiện thường xuyên.

Vai trò bị mất ở đây là Review Depth / Coverage.

Trường hợp 3 — Thiếu references/coding-conventions.md

AI vẫn có kiến thức C# phổ biến. Nhưng nó không biết những quy định riêng của project nếu những quy định đó chỉ nằm trong reference.

Ví dụ:

General C# knowledge
        ≠
Your project's conventions

AI có thể đưa ra một suggestion hợp lý theo C# nói chung nhưng không phù hợp với kiến trúc hoặc convention của team.

Vai trò bị mất ở đây là Project Alignment.


8. Nhìn Skill như một hệ thống nhiều lớp

Từ ví dụ trên, chúng ta có thể mô hình hóa một Skill phức tạp hơn:

flowchart TB A[SKILL.md
Workflow] B[checklist.md
Coverage] C[output-template.md
Format] D[references/
Project Knowledge] A --> E[AI Review Process] B --> E C --> E D --> E E --> F[Consistent Review]

Mỗi file giải quyết một vấn đề khác nhau:

Thành phần Giải quyết vấn đề
SKILL.md Process — Làm như thế nào?
checklist.md Coverage — Kiểm tra những gì?
output-template.md Format — Trình bày ra sao?
references/ Context — Project có quy định gì?

Có thể nhớ bằng công thức:

\[ \text{Skill} = \text{Process} + \text{Coverage} + \text{Format} + \text{Context} \]

Không phải Skill nào cũng cần đủ bốn thành phần. Một Skill nhỏ có thể chỉ cần SKILL.md. Khi workflow lớn hơn, chúng ta tách các phần chi tiết thành những file riêng để dễ quản lý và tái sử dụng.


9. Một lưu ý quan trọng: nhiều file không đồng nghĩa với Skill tốt hơn

Đây là một lỗi dễ mắc phải khi bắt đầu xây dựng Skill.

Không nên biến:

SKILL.md
checklist.md
template.md
reference-01.md
reference-02.md
reference-03.md
reference-04.md
...

thành mục tiêu tự thân.

Mục tiêu không phải là có thật nhiều file. Mục tiêu là: AI có đúng thông tin cần thiết để thực hiện workflow hay không.

Một Skill tốt có thể chỉ là:

my-skill/
└── SKILL.md

Một Skill phức tạp hơn có thể là:

my-skill/
├── SKILL.md
├── checklist.md
├── output-template.md
└── references/
    └── project-rules.md

Cả hai đều hợp lệ.


10. Từ Skill đến Agent

Bây giờ hãy quay lại câu hỏi ban đầu.

Nếu team có:

skills/
├── csharp-code-review/
├── create-task/
├── create-user-story/
├── development-plan/
└── test-generation/

thì ai quyết định Skill nào cần được sử dụng?

flowchart TD U[User Request] --> A[Agent] A -->|Review code| S1[C# Code Review] A -->|Create task| S2[Create Task] A -->|Create user story| S3[User Story] A -->|Create plan| S4[Development Plan] S1 --> R[Result] S2 --> R S3 --> R S4 --> R

Đây là lúc chúng ta cần Agent.

Nếu Skill trả lời:

HOW — Công việc này được thực hiện như thế nào?

thì Agent sẽ trả lời:

WHO — AI đang đóng vai ai, chịu trách nhiệm gì, và nên dùng Skill nào?

Trong bài tiếp theo, chúng ta sẽ tạo một Developer Agent cho chính project C# Console này và cho Agent sử dụng các Skill vừa tạo.


11. Takeaway

Sau bài này, có thể nhớ Skill bằng bốn từ:

Skill = HOW

HOW to review code
HOW to create a task
HOW to write a user story
HOW to create a development plan

Một Skill tốt không chỉ nói:

"Do this well."

Nó mô tả rõ:

When to use
     ↓
What to do
     ↓
How to do it
     ↓
What rules to follow
     ↓
What to check
     ↓
What output to produce

Và khi workflow lớn hơn, chúng ta có thể tách tri thức thành:

SKILL.md
    ↓
Workflow

checklist.md
    ↓
Coverage

output-template.md
    ↓
Format

references/
    ↓
Project Context

Skill không làm AI thông minh hơn. Skill giúp AI có một workflow rõ ràng, có thể tái sử dụng và phù hợp với cách team muốn làm việc.

Từ đây, câu hỏi tiếp theo rất tự nhiên: Nếu một project có hàng chục Skill, ai sẽ quyết định Skill nào cần được dùng?

Câu trả lời là: Agent.

Nhận xét

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.