12 tính năng Claude Code: giải thích chi tiết kèm ví dụ

Bài này có bản video ngắn:TikTok

1. Tổng quan

Claude Code là một coding agent chạy trong terminal, có thể đọc, sửa, chạy lệnh và tự kiểm tra code trong dự án của bạn. Vấn đề là: agent mạnh nhưng nếu dùng mặc định, nó dễ “đi lạc” – sửa sai file, đọc hết context window, hoặc chạy lệnh nguy hiểm. Bài này giải thích 12 tính năng giúp bạn kiểm soát agent này một cách có chủ đích. Đọc xong, bạn sẽ biết cấu hình CLAUDE.md, permissions, hooks, MCP… để Claude Code làm việc đúng quy ước của team, trên một dự án Spring Boot ví dụ gồm Order, Customer, PaymentService.

2. CLAUDE.md

CLAUDE.md là file memory được Claude Code tự động đọc ở đầu mỗi session. Đây là nơi bạn khai báo quy ước code, cấu trúc thư mục, lệnh build, style guide – để agent không phải hỏi lại mỗi lần.

# CLAUDE.md

## Kiến trúc
- Package `com.nonladev.order`: domain Order, Customer
- Package `com.nonladev.payment`: PaymentService, PaymentGateway (interface)

## Quy ước
- Luôn viết test JUnit 5 + AssertJ cho method public mới
- Không dùng `@Autowired` field injection, chỉ constructor injection
- Chạy `mvn verify` trước khi báo "xong"

## Lệnh thường dùng
- Build: `mvn -q clean verify`
- Chạy local: `mvn spring-boot:run`

Claude đọc file này trước khi thực hiện bất kỳ task nào trong session. Nếu bạn yêu cầu “thêm method hoàn tiền cho PaymentService”, agent sẽ tự biết dùng constructor injection và viết kèm test – không cần nhắc lại.

Lưu ý: Đừng nhồi quá nhiều chi tiết vào CLAUDE.md. File dài làm tốn context window ngay từ đầu session, trong khi phần lớn nội dung không liên quan đến task hiện tại.

3. Permissions

Permissions kiểm soát tool nào Claude được dùng và tool nào bị chặn – quan trọng vì agent có quyền chạy shell command thật.

{
  "permissions": {
    "allow": [
      "Bash(mvn *)",
      "Edit(src/main/java/**)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Edit(src/main/resources/application-prod.properties)"
    ]
  }
}

File settings.json này đặt trong thư mục .claude/. Dòng allow cho phép agent chạy mvn và sửa file trong src/main/java, nhưng dòng deny chặn tuyệt đối lệnh xóa đệ quy và chặn sửa file config production. Khi Claude muốn vượt permission, nó sẽ hỏi bạn xác nhận trước khi thực thi.

Lỗi hay gặp: để permissions quá rộng (allow: ["*"]) khiến agent có thể chạy bất kỳ lệnh nào không cần hỏi – nguy hiểm với file config nhạy cảm hoặc secret.

4. Plan Mode

Plan Mode bắt Claude trình bày kế hoạch trước khi đụng vào code. Bạn review kế hoạch, chỉnh sửa nếu cần, rồi mới cho chạy.

> Thêm tính năng hoàn tiền một phần cho PaymentService

[PLAN MODE]
1. Thêm method refundPartial(Order order, BigDecimal amount) vào PaymentService
2. Validate amount <= order.getTotalPaid()
3. Gọi PaymentGateway.refund(...)
4. Viết PaymentServiceTest cho 2 case: hợp lệ, amount vượt quá

Bạn có muốn tôi thực hiện kế hoạch này? [y/n/edit]

Khi bạn trả lời edit, Claude sẽ sửa plan theo góp ý (ví dụ thêm bước log audit) trước khi chạm vào source code thật. Cách này đặc biệt hữu ích với task sửa nhiều file, vì bạn phát hiện sai hướng ngay từ bước plan, chứ không phải sau khi code đã bị sửa lung tung.

5. Checkpoints

Checkpoints là snapshot tự động của project tại các thời điểm quan trọng trong session, cho phép bạn “rewind” nếu agent làm hỏng việc.

# Xem lịch sử checkpoint trong session
/rewind

# Output
Checkpoint 1 - 10:02 - trước khi sửa PaymentService
Checkpoint 2 - 10:05 - sau khi thêm refundPartial
Checkpoint 3 - 10:09 - sau khi sửa test (đang lỗi)

# Quay lại checkpoint 2
/rewind 2

Khác với git commit, checkpoint không cần bạn tự tạo – Claude Code tự lưu trước mỗi thay đổi lớn. Nếu agent sửa test theo hướng sai (ví dụ comment out assertion để test “pass”), bạn rewind về trạng thái trước đó mà không cần git reset thủ công.

Lưu ý: checkpoint chỉ sống trong phạm vi session hiện tại, không thay thế git. Vẫn nên commit thật khi đạt một milestone.

6. Skills

Skills là file hướng dẫn tái sử dụng, Claude tự áp dụng khi phát hiện task phù hợp – không cần bạn gọi tên mỗi lần.

---
name: spring-boot-test-writer
description: Dùng khi cần viết test cho service layer trong dự án Spring Boot
---

Khi viết test cho một class Service:
1. Dùng JUnit 5 + AssertJ, không dùng Hamcrest
2. Mock dependency bằng Mockito, đặt tên biến `mock<Dependency>`
3. Đặt tên method test theo dạng `should_<expected>_when_<condition>`

File này đặt trong .claude/skills/spring-boot-test-writer.md. Khi bạn yêu cầu “viết test cho PaymentService”, Claude tự nhận ra skill phù hợp và áp dụng convention trong đó, kết quả là:

class PaymentServiceTest {

    private final PaymentGateway mockGateway = mock(PaymentGateway.class);
    private final PaymentService paymentService = new PaymentService(mockGateway);

    @Test
    void should_refundAmount_when_amountIsWithinPaidTotal() {
        Order order = new Order("ORD-1", BigDecimal.valueOf(200));

        paymentService.refundPartial(order, BigDecimal.valueOf(50));

        verify(mockGateway).refund(order.getId(), BigDecimal.valueOf(50));
    }

    @Test
    void should_throwException_when_amountExceedsPaidTotal() {
        Order order = new Order("ORD-2", BigDecimal.valueOf(100));

        assertThatThrownBy(() -> paymentService.refundPartial(order, BigDecimal.valueOf(150)))
            .isInstanceOf(IllegalArgumentException.class);
    }
}

Skills khác CLAUDE.md ở điểm: CLAUDE.md luôn được load, còn skill chỉ load khi ngữ cảnh cần – tiết kiệm context window cho project có nhiều quy ước chuyên biệt.

7. Hooks

Hooks chạy shell script của bạn tại các điểm trong lifecycle của agent, ví dụ PreToolUse (trước khi gọi tool) hoặc PostToolUse (sau khi gọi tool).

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "command": "mvn -q -pl . checkstyle:check"
      }
    ]
  }
}

Mỗi lần Claude sửa file xong (Edit tool), hook tự chạy checkstyle:check. Nếu lệnh fail, output trả về cho Claude, agent tự sửa lại code theo lỗi style trước khi báo hoàn tất task — bạn không cần tự chạy check tay.

[PostToolUse] mvn checkstyle:check
ERROR: PaymentService.java:42: Line is longer than 120 characters
→ Claude tự rút ngắn dòng 42 và chạy lại check

Khi nào không nên dùng: hook chạy mỗi lần tool được gọi, nên nếu script nặng (build full project), session sẽ chậm đáng kể. Chỉ hook vào lifecycle event cần kiểm tra nhanh.

8. MCP

MCP (Model Context Protocol) kết nối Claude với hệ thống bên ngoài – database, API nội bộ, issue tracker – như một tool chuẩn hóa.

{
  "mcpServers": {
    "postgres-orders": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres",
               "postgresql://localhost:5432/orders_db"]
    }
  }
}

Sau khi đăng ký server này trong .claude/settings.json, bạn có thể hỏi trực tiếp:

> Có bao nhiêu Order ở trạng thái PENDING trong bảng orders?

[MCP: postgres-orders] SELECT COUNT(*) FROM orders WHERE status = 'PENDING';
→ 37 orders đang PENDING

Claude tự sinh câu SQL, gọi qua MCP server, và trả kết quả thật từ database — không cần bạn copy query thủ công vào terminal khác.

9. Plugins

Plugin là một bundle đóng gói sẵn skills, MCP server và hooks liên quan nhau, giúp bạn cài một lần thay vì cấu hình từng phần riêng lẻ.

/plugin install spring-boot-toolkit

Lệnh này cài một plugin giả định chứa: skill viết test Spring Boot, hook chạy mvn verify sau mỗi edit, và MCP server kết nối tới Spring Boot Actuator endpoint để agent tự kiểm tra health check. Thay vì bạn phải viết 3 file cấu hình riêng (skill, hook, mcp) như các mục 6–8, plugin gói chung lại thành một package có thể chia sẻ cho cả team qua một dòng lệnh.

10. Context

Context là context window hiện tại của session — toàn bộ file đã đọc, lịch sử hội thoại, output lệnh. Lệnh /context cho bạn thấy nó đang dùng bao nhiêu.

/context
Context usage: 48,200 / 200,000 tokens (24%)
- CLAUDE.md: 1,200 tokens
- Files read: PaymentService.java, Order.java, PaymentServiceTest.java (6,400 tokens)
- Conversation history: 38,000 tokens
- Tool outputs: 2,600 tokens

Khi thấy conversation history chiếm phần lớn, bạn biết nên compact hoặc bắt đầu session mới, tránh để Claude “quên” chi tiết quan trọng đã nói ở đầu session do bị cắt khi context đầy.

11. Slash Commands

Slash command là shortcut cho task bạn chạy lặp lại — gõ / rồi gọi tên, không cần viết lại prompt dài mỗi lần.

---
name: review-pr
description: Review diff hiện tại theo checklist chuẩn
---

Review code diff hiện tại với checklist:
1. Có test cho logic mới không?
2. Có log thông tin nhạy cảm (số thẻ, password) không?
3. Có vi phạm constructor injection convention không?

Trả lời theo format: PASS/FAIL cho từng mục, kèm lý do.

Lưu file này vào .claude/commands/review-pr.md, sau đó gọi:

/review-pr
1. PASS - có PaymentServiceTest cho refundPartial
2. FAIL - log.info chứa order.getCardNumber() ở dòng 58
3. PASS - dùng constructor injection

Slash command khác skill ở điểm: skill tự kích hoạt theo ngữ cảnh, còn slash command cần bạn gọi tên rõ ràng — phù hợp cho checklist cố định như review PR, release note.

12. Compaction

Compaction nén lại lịch sử hội thoại dài thành bản tóm tắt, giải phóng token mà không mất thông tin quan trọng.

/compact
Trước compact: 182,000 / 200,000 tokens
Sau compact:    24,000 / 200,000 tokens

Tóm tắt đã giữ lại:
- Đang làm: thêm refundPartial vào PaymentService
- Đã hoàn thành: PaymentServiceTest (2 test case pass)
- Còn lại: cập nhật OpenAPI spec cho endpoint /refund

Thay vì agent quên sạch lịch sử khi context đầy, compaction giữ lại các mốc quan trọng (task đang làm, đã hoàn thành, còn thiếu) dưới dạng tóm tắt ngắn, rồi tiếp tục session với context trống phần lớn. Bạn nên chủ động gọi /compact sau khi hoàn thành một task con lớn, trước khi chuyển sang task tiếp theo.

13. Subagents

Subagents cho phép Claude Code sinh ra nhiều agent con chạy song song, mỗi agent phụ trách một phần việc độc lập trong một workflow lớn.

---
name: test-writer
description: Chuyên viết unit test cho class được chỉ định
tools: Read, Edit, Bash
---

Bạn chỉ viết test, không sửa logic nghiệp vụ. Dùng JUnit 5 + AssertJ.

Với file subagent này trong .claude/agents/test-writer.md, bạn có thể giao task lớn cho agent chính, rồi agent chính tự phân việc:

> Hoàn thiện module refund: thêm logic, viết test, cập nhật docs

[Main agent] Phân việc thành 3 subagent song song:
  → subagent "code-writer": thêm refundPartial vào PaymentService
  → subagent "test-writer": viết PaymentServiceTest
  → subagent "doc-writer": cập nhật README.md

[3 subagents chạy song song] ... hoàn tất sau 42s

Thay vì agent chính xử lý tuần tự từng bước (code → test → docs, có thể tốn gấp 3 thời gian), subagents xử lý đồng thời các phần việc độc lập — hữu ích với workflow nhiều bước không phụ thuộc chặt vào nhau.

Khi nào không nên dùng: nếu các bước phụ thuộc tuần tự (ví dụ viết test cần code đã xong để biết interface), chạy song song sẽ gây lỗi vì subagent test chạy trước khi code tồn tại. Chỉ dùng subagents cho task có thể tách độc lập thật sự.

14. Kết luận

12 tính năng trên chia thành ba nhóm rõ ràng: nhóm định hướng agent (CLAUDE.md, Skills, Plan Mode), nhóm kiểm soát an toàn (Permissions, Checkpoints, Hooks), và nhóm mở rộng khả năng (MCP, Plugins, Subagents). Context, Slash Commands và Compaction là lớp hạ tầng giúp agent chạy hiệu quả trong một session dài. Bạn không cần dùng hết cả 12 cùng lúc — hãy bắt đầu với CLAUDE.md và Permissions cho dự án hiện tại, sau đó thêm Hooks hoặc MCP khi workflow thực sự cần đến chúng.

Claude CodeAI AgentDevToolsSpring BootProductivity