jvinhit//lab

Search posts

Type to search across journal entries.

↑ ↓ navigate ↵ open esc close

Claude Code từ zero đến thành thạo · Phần 10 — Best practices và prompt library

Toàn bộ best practice của Claude Code quy về một ràng buộc duy nhất là context window. Sáu nhóm thực hành, năm kiểu thất bại kinh điển kèm cách sửa, và sáu pattern làm nên một prompt tốt.

Claude Code là môi trường lập trình agentic. Khác một chatbot trả lời rồi chờ, nó đọc file, chạy lệnh, sửa code và tự đi qua vấn đề trong lúc bạn xem, lái, hoặc bỏ đi hẳn.

Điều đó đổi cách bạn làm việc: thay vì tự viết code rồi nhờ Claude review, bạn mô tả thứ mình muốn và Claude tìm cách xây. Nhưng quyền tự chủ đó đi kèm một đường cong học tập, và Claude làm việc trong những ràng buộc bạn cần hiểu.

Gần như mọi best practice đều quy về một ràng buộc duy nhất: context window đầy rất nhanh, và chất lượng giảm khi nó đầy dần.

Context window giữ toàn bộ hội thoại — mọi tin nhắn, mọi file Claude đọc, mọi output lệnh. Chỉ một phiên debug hay một lượt khám phá codebase có thể ngốn hàng chục nghìn token. Khi context sắp đầy, Claude bắt đầu “quên” chỉ dẫn cũ và mắc lỗi nhiều hơn.

Nhớ câu đó rồi thì phần còn lại của bài chỉ là hệ quả.

1. Cho Claude một cách tự kiểm chứng

Đây là thực hành có tỉ lệ đầu tư trên hiệu quả cao nhất.

Claude dừng khi công việc trông có vẻ xong. Không có thứ gì để nó chạy kiểm tra thì “trông có vẻ xong” là tín hiệu duy nhất nó có — và bạn trở thành vòng kiểm chứng: mọi lỗi nằm chờ tới khi bạn phát hiện ra. Cho nó thứ trả về pass hoặc fail, vòng lặp tự khép: Claude làm, chạy kiểm tra, đọc kết quả, và lặp tới khi qua.

“Thứ kiểm tra” là bất cứ gì trả về tín hiệu Claude đọc được: test suite, exit code của build, linter, một script so output với fixture, hoặc screenshot trình duyệt so với bản thiết kế.

Chiến lượcTrướcSau
Cấp tiêu chí kiểm chứng”implement a function that validates email addresses""write a validateEmail function. example test cases: user@example.com is true, invalid is false. run the tests after implementing”
Kiểm chứng thay đổi UI bằng mắt”make the dashboard look better""[dán screenshot] implement this design. take a screenshot of the result and compare it to the original. list differences and fix them”
Xử lý nguyên nhân gốc, không phải triệu chứng”the build is failing""the build fails with this error: [dán lỗi]. fix it and verify the build succeeds. address the root cause, don’t suppress the error”

Có thứ kiểm tra rồi thì quyết định nó chặn việc dừng chặt tới đâu:

  • Trong một prompt — bảo Claude chạy kiểm tra và lặp ngay trong cùng tin nhắn.
  • Xuyên suốt phiên — đặt nó thành điều kiện /goal. Một bộ đánh giá riêng kiểm lại sau mỗi lượt và Claude làm tiếp tới khi goal được giải quyết.
  • Như một cổng cứng — một Stop hook chạy kiểm tra của bạn dưới dạng script và chặn lượt kết thúc cho tới khi nó pass. (Claude Code ghi đè hook và kết thúc lượt sau 8 lần chặn liên tiếp.)
  • Bằng ý kiến thứ hai — một subagent kiểm chứng hoặc một dynamic workflow tự kiểm kết quả của mình, để model đang làm việc không phải là model chấm điểm.

Mỗi bậc đánh đổi công sức thiết lập lấy sự chú ý của bạn. Bản trong-một-prompt dùng được ngay hôm nay. Bản /goal và Stop hook là thứ khiến một lượt chạy không người trông kết thúc đúng.

Và luôn yêu cầu Claude đưa bằng chứng thay vì khẳng định thành công: output test, lệnh nó chạy kèm kết quả trả về, hoặc screenshot. Đọc bằng chứng nhanh hơn tự chạy lại kiểm chứng — và nó dùng được cho cả những phiên bạn không ngồi xem.

2. Khám phá trước, lập plan, rồi mới code

Để Claude nhảy thẳng vào code có thể cho ra thứ giải sai vấn đề. Bốn pha:

  1. Explore — vào plan mode, bảo Claude đọc và trả lời câu hỏi mà không đổi gì.
  2. Plan — yêu cầu một kế hoạch cài đặt chi tiết. Bấm Ctrl+G để mở plan trong editor và sửa trực tiếp.
  3. Implement — duyệt plan hoặc bấm Shift+Tab để thoát plan mode, rồi để Claude code, đối chiếu với chính plan của nó.
  4. Commit — commit kèm message mô tả và mở PR.

Nhưng plan mode cũng tốn chi phí. Với task có phạm vi rõ và sửa chữa nhỏ — sửa typo, thêm một dòng log, đổi tên biến — bảo Claude làm thẳng.

Lập plan hữu ích nhất khi bạn chưa chắc về cách tiếp cận, khi thay đổi động vào nhiều file, hoặc khi bạn không quen code đang sửa. Nguyên tắc gọn: nếu bạn mô tả được cái diff trong một câu, bỏ qua plan.

3. Cấp ngữ cảnh cụ thể trong prompt

Claude suy ra được ý định, nhưng không đọc được suy nghĩ của bạn.

Chiến lượcTrướcSau
Khoanh vùng task”add tests for foo.py""write a test for foo.py covering the edge case where the user is logged out. avoid mocks.”
Trỏ tới nguồn”why does ExecutionFactory have such a weird api?""look through ExecutionFactory’s git history and summarize how its api came to be”
Tham chiếu pattern sẵn có”add a calendar widget""look at how existing widgets are implemented on the home page… HotDogWidget.php is a good example. follow the pattern…”
Mô tả triệu chứng”fix the login bug""users report that login fails after session timeout. check the auth flow in src/auth/, especially token refresh. write a failing test that reproduces the issue, then fix it”

Prompt mơ hồ vẫn có chỗ dùng khi bạn đang khám phá và chấp nhận lái lại. Một câu như “what would you improve in this file?” làm lộ ra những thứ bạn không nghĩ tới để mà hỏi.

Cấp nội dung giàu thông tin bằng năm cách: tham chiếu file bằng @; dán thẳng ảnh; đưa URL tài liệu (dùng /permissions để allowlist các domain hay dùng); đổ dữ liệu vào bằng cat error.log | claude; hoặc để Claude tự đi lấy bằng lệnh Bash, MCP tool, hay đọc file.

4. Cấu hình môi trường

CLAUDE.md hiệu quả

Chạy /init để sinh bản khởi đầu, rồi tinh chỉnh dần. Không có định dạng bắt buộc — giữ nó ngắn và dễ đọc với người:

# Code style

- Use ES modules (import/export) syntax, not CommonJS (require)
- Destructure imports when possible (eg. import { foo } from 'bar')

# Workflow

- Be sure to typecheck when you're done making a series of code changes
- Prefer running single tests, and not the whole test suite, for performance

Với từng dòng, hãy hỏi: “Bỏ dòng này đi thì Claude có mắc lỗi không?” Không thì cắt. File CLAUDE.md phình to khiến Claude bỏ qua chính những chỉ dẫn bạn cần!

✅ Nên có❌ Không nên
Lệnh Bash mà Claude không đoán đượcThứ Claude tự đọc code là biết
Luật code style khác mặc địnhConvention chuẩn của ngôn ngữ mà Claude đã biết
Cách chạy test và test runner ưa dùngTài liệu API chi tiết (link tới docs thay vì chép)
Quy ước repo (đặt tên branch, quy tắc PR)Thông tin thay đổi thường xuyên
Quyết định kiến trúc riêng của projectGiải thích dài hoặc hướng dẫn kiểu tutorial
Điểm kỳ quặc của môi trường dev (env var bắt buộc)Mô tả từng file của codebase
Cạm bẫy hoặc hành vi không hiển nhiênLời khuyên hiển nhiên kiểu “write clean code”

Hai tín hiệu chẩn đoán rất hữu ích:

  • Claude cứ làm một việc bạn không muốn dù đã có luật cấm → file có lẽ quá dài và luật đó bị lạc mất.
  • Claude hỏi bạn những thứ CLAUDE.md đã trả lời → cách diễn đạt có lẽ mơ hồ.

Coi CLAUDE.md như code: review khi có chuyện, tỉa định kỳ, và kiểm chứng thay đổi bằng cách quan sát hành vi Claude có thật sự đổi không. Thêm nhấn mạnh kiểu “IMPORTANT” hay “YOU MUST” để tăng mức tuân thủ. Commit nó vào git để cả team đóng góp — giá trị của file này cộng dồn theo thời gian.

Bốn thứ còn lại

  • Permission — tiền phê duyệt tool bạn tin bằng /permissions, bật sandbox bằng /sandbox. Xem phần 7.
  • CLI tool — đây là cách tốn ít context nhất để làm việc với dịch vụ ngoài. Dùng GitHub thì cài gh; không có nó Claude vẫn gọi được GitHub API nhưng request không xác thực hay dính rate limit. Claude cũng học được CLI tool nó chưa biết: “Use foo-cli-tool --help to learn about foo tool, then use it to solve A, B, C.”
  • Hook — dùng cho hành động phải xảy ra mọi lần, không ngoại lệ. Khác chỉ dẫn trong CLAUDE.md vốn chỉ mang tính khuyến nghị, hook là tất định. Claude tự viết hook được: “Write a hook that runs eslint after every file edit.” Xem phần 13.
  • Skill và subagent — skill cấp kiến thức miền và quy trình tái dùng; subagent chạy trong context riêng với bộ tool riêng. Xem phần 12 và 16.

5. Giao tiếp cho hiệu quả

Hỏi Claude những câu bạn sẽ hỏi một senior engineer. Khi làm quen codebase mới, dùng Claude Code để học: How does logging work? How do I make a new API endpoint? What edge cases does CustomerOnboardingFlowImpl handle? Why does this code call foo() instead of bar() on line 333? Không cần prompt đặc biệt gì — hỏi thẳng.

Với feature lớn, để Claude phỏng vấn bạn trước. Bắt đầu bằng một prompt tối thiểu và yêu cầu nó phỏng vấn bằng tool AskUserQuestion:

I want to build [mô tả ngắn]. Interview me in detail using the AskUserQuestion tool.

Ask about technical implementation, UI/UX, edge cases, concerns, and tradeoffs.
Don't ask obvious questions, dig into the hard parts I might not have considered.

Keep interviewing until we've covered everything, then write a complete spec to SPEC.md.

Xong spec rồi thì mở phiên mới để thực thi — phiên mới có context sạch tập trung hoàn toàn vào cài đặt, và bạn có một spec viết ra để đối chiếu.

Spec hữu ích nhất là spec tự chứa: nó nêu tên file và interface liên quan, nói rõ cái gì nằm ngoài phạm vi, và kết bằng một bước kiểm chứng end-to-end chứng minh feature chạy. Thời gian bỏ ra làm spec chính xác có giá trị hơn thời gian ngồi xem quá trình cài đặt.

6. Quản lý phiên làm việc

Lái lại sớm và thường xuyên. Kết quả tốt nhất đến từ vòng phản hồi chặt.

  • Esc — dừng Claude giữa chừng. Context được giữ nên bạn chuyển hướng được.
  • Esc Esc hoặc /rewind — mở menu rewind, khôi phục hội thoại và code, hoặc tóm tắt từ một tin nhắn.
  • "Undo that" — bảo Claude hoàn tác thay đổi của nó.
  • /clear — reset context giữa các task không liên quan.

Nếu bạn đã sửa lưng Claude hơn hai lần về cùng một chuyện trong một phiên, context đã đầy những cách tiếp cận thất bại. Chạy /clear và bắt đầu lại bằng một prompt cụ thể hơn, có gộp thứ bạn vừa học được. Một phiên sạch với prompt tốt hơn gần như luôn thắng một phiên dài với đống chỉnh sửa tích tụ.

Quản context quyết liệt. /clear giữa các task; /compact <instructions> khi cần giữ mạch; Esc Esc rồi Summarize from here / Summarize up to here để nén một phần; /btw cho câu hỏi không cần nằm lại trong context. Và tuỳ biến hành vi compact ngay trong CLAUDE.md, ví dụ: “When compacting, always preserve the full list of modified files and any test commands.”

Dùng subagent để điều tra. Vì context là ràng buộc căn bản, subagent là một trong những công cụ mạnh nhất bạn có:

Use subagents to investigate how our authentication system handles token
refresh, and whether we have any existing OAuth utilities I should reuse.

Tận dụng checkpoint để liều. Thay vì hoạch định kỹ từng nước, bảo Claude thử một thứ mạo hiểm. Không được thì rewind và thử hướng khác.

Đặt tên phiên và coi chúng như branch. Mỗi luồng công việc một context riêng, đặt tên kiểu oauth-migration để tìm lại được.


Tự động hoá và mở rộng quy mô

Chạy non-interactive:

# Truy vấn một lần
claude -p "Explain what this project does"

# Output có cấu trúc cho script
claude -p "List all API endpoints" --output-format json

# Streaming để xử lý theo thời gian thực
claude -p "Analyze this log file" --output-format stream-json --verbose

Chạy nhiều phiên song song — bốn cách, khác nhau ở mức bạn phải tự điều phối: worktree (phiên CLI riêng trong checkout git cô lập), desktop app (quản lý nhiều phiên local trực quan), Claude Code on the web (chạy trên cloud), và agent team (điều phối tự động, có task chung, nhắn tin và một team lead).

Ngoài việc song song hoá, nhiều phiên còn mở ra các workflow tập trung vào chất lượng — vì context sạch giúp review tốt hơn: Claude không bị thiên vị về phía code mà chính nó vừa viết. Mẫu Writer/Reviewer:

Phiên A (Writer)Phiên B (Reviewer)
Implement a rate limiter for our API endpoints
Review the rate limiter implementation in @src/middleware/rateLimiter.ts. Look for edge cases, race conditions, and consistency with our existing middleware patterns.
Here's the review feedback: [output phiên B]. Address these issues.

Làm tương tự được với test: một Claude viết test, một Claude khác viết code để pass.

Toả việc ra nhiều file cho migration lớn:

for file in $(cat files.txt); do
  claude -p "Migrate $file from React to Vue. Return OK or FAIL." \
    --allowedTools "Edit,Bash(git commit *)"
done

Tinh chỉnh prompt dựa trên 2–3 file đầu, rồi mới chạy toàn bộ. Flag --allowedTools giới hạn thứ Claude làm được — điều này quan trọng khi chạy không người trông.

Thêm bước review đối kháng. Chạy càng lâu không người trông thì một lượt kiểm tra độc lập càng quan trọng. Reviewer chạy trong context subagent mới toanh chỉ thấy diff và tiêu chí bạn đưa, không thấy dòng suy luận đã tạo ra thay đổi — nên nó đánh giá kết quả trên chính giá trị của kết quả.

Use a subagent to review the rate limiter diff against PLAN.md. Check that
every requirement is implemented, the listed edge cases have tests, and
nothing outside the task's scope changed. Report gaps, not style preferences.

Nhưng cẩn thận: một reviewer được yêu cầu tìm lỗ hổng thì thường sẽ báo ra vài cái, kể cả khi công việc đã ổn — vì đó là thứ nó được giao. Chạy theo mọi phát hiện dẫn tới over-engineering: thêm tầng trừu tượng, code phòng thủ, và test cho những trường hợp không thể xảy ra. Hãy bảo reviewer chỉ nêu lỗ hổng ảnh hưởng tới tính đúng đắn hoặc tới yêu cầu đã nêu, phần còn lại coi là tuỳ chọn.


Năm kiểu thất bại kinh điển

Nhận ra sớm là tiết kiệm được rất nhiều thời gian.

Kiểu thất bạiTriệu chứngCách sửa
Phiên bồn rửa bátBắt đầu một task, hỏi chuyện không liên quan, rồi quay lại task đầu. Context đầy thông tin vô dụng/clear giữa các task không liên quan
Sửa lưng mãi không xongClaude làm sai, bạn sửa, vẫn sai, bạn sửa tiếp. Context ô nhiễm bởi các hướng thất bạiSau hai lần sửa hỏng, /clear và viết prompt khởi đầu tốt hơn
CLAUDE.md quá chi tiếtFile quá dài nên Claude bỏ qua nửa số luật vì chúng lạc trong đống nhiễuTỉa không thương tiếc. Claude đã làm đúng mà không cần chỉ dẫn thì xoá, hoặc chuyển thành hook
Khoảng trống tin-rồi-mới-kiểmClaude cho ra bản cài đặt trông hợp lý nhưng không xử lý edge caseLuôn cấp phương tiện kiểm chứng. Không kiểm chứng được thì đừng ship
Khám phá vô tậnBạn bảo Claude “investigate” mà không khoanh vùng. Nó đọc hàng trăm file, làm đầy contextKhoanh hẹp phạm vi điều tra, hoặc dùng subagent để việc khám phá không ăn vào context chính

Sáu pattern làm nên một prompt tốt

Prompt library của Claude Code là bộ prompt copy-paste, gắn thẻ theo task và theo vai trò. Nó xếp theo năm pha vòng đời phần mềm — discover, design, build, ship, operate — và theo nhóm việc: Onboard, Understand, Plan, Prototype, Implement, Refactor, Test, Debug, Review, Git, Release, Incident, Automate, Data. Nhiều prompt còn gắn thẻ vai trò cho người không phải engineer: pm, design, docs, marketing, ops, data, security.

Nhưng giá trị lâu dài không nằm ở việc chép prompt — nó nằm ở sáu pattern chung khiến các prompt đó chạy được:

Mô tả kết quả, không mô tả các bước. Nói thứ bạn muốn và để Claude tìm file.

add rate limiting to the public API and make sure existing tests still pass

Cho nó cách tự kiểm việc mình làm. Yêu cầu run, test, compare, verify ngay trong cùng prompt để nó lặp thay vì dừng sau một lần thử.

write the migration, run it against the dev database, and confirm the schema matches

Trỏ tới một mẫu tham chiếu. Nêu tên một file, test, hay pattern sẵn có để code mới nhất quán với thứ bạn đang có.

add a settings page that follows the same layout as the profile page

Nêu mục tiêu đo được. Khi đích là hiệu năng hay độ phủ, đưa chỉ số và ngưỡng để “xong” là không mơ hồ.

get the bundle size under 200KB and show me what you removed

Đưa hiện vật, đừng mô tả nó. Dán thẳng lỗi, log, screenshot, output plan, hoặc gõ @ để tham chiếu file. Claude đọc nguồn thay vì đọc bản mô tả của bạn về nguồn.

why is the build failing? @build.log

Nói rõ bạn muốn câu trả lời ở dạng nào. Nêu định dạng, độ dài, hoặc đối tượng đọc để lời giải thích khớp với cách bạn sẽ dùng nó.

explain how the payment retry logic works as an HTML page with a diagram, then open it in my browser

Xây trực giác của riêng bạn

Các pattern trong bài này không phải luật cứng. Chúng là điểm khởi đầu tốt nói chung, nhưng có thể không tối ưu cho mọi tình huống.

Đôi khi bạn nên để context tích tụ, vì bạn đang ở sâu trong một vấn đề phức tạp và lịch sử đó có giá trị. Đôi khi nên bỏ qua bước lập plan và để Claude tự xoay, vì task mang tính thăm dò. Đôi khi một prompt mơ hồ lại đúng, vì bạn muốn xem Claude diễn giải vấn đề thế nào trước khi ràng buộc nó.

Hãy để ý thứ gì hiệu quả. Khi Claude cho ra kết quả tốt, để ý bạn đã làm gì: cấu trúc prompt, ngữ cảnh bạn cấp, mode bạn đang ở. Khi Claude vật lộn, hỏi vì sao — context quá nhiễu? prompt quá mơ hồ? task quá lớn cho một lượt?


Hết chặng vận hành hằng ngày

Sáu phần vừa rồi (5–10) đã phủ toàn bộ việc dùng Claude Code ở mức thành thạo: bàn phím và CLI, slash command, permission, session và checkpoint, các workflow thường gặp, và best practice.

Từ phần 11, series chuyển sang biến Claude Code thành công cụ riêng của bạn: bốn cơ chế mở rộng — skill, hook, MCP và plugin.

Nguồn

Docs gốc cập nhật thường xuyên; khi có mâu thuẫn, tin bản tiếng Anh.