Bài 4 · Vận dụng · 20 phút· Cập nhật 11/06/2026
Đọc, sửa code & chạy lệnh an toàn
Biên soạn bởi Nguyễn Anh Tuấn
Các công cụ Read/Edit/Write/Bash/Grep/Glob; duyệt diff; cho phép theo từng lệnh; checkpoint & hoàn tác (rewind).
Ở bài “Cách hoạt động” bạn đã gặp các công cụ. Giờ ta đi sâu vào nhóm làm việc với code - chia làm hai loại theo mức rủi ro:
- ▸ĐỌC (an toàn): Read xem file, Grep tìm theo nội dung, Glob tìm file theo tên.
- ▸LÀM (cần thận trọng): Edit sửa một đoạn, Write ghi cả file, Bash chạy lệnh.
- ▸Edit = THAY MỘT ĐOẠN CHÍNH XÁC → nên Claude luôn Read file trước khi Edit.
Một lần sửa nhỏ trông như sau - chú ý nó đọc trước, rồi trình diff để bạn duyệt:
› Đổi tiêu đề trang chủ trong @src/Home.tsx thành “Xin chào”.
⏺ Read(src/Home.tsx)
Tôi sẽ sửa đúng dòng tiêu đề:
⏺ Edit(src/Home.tsx)
- <h1>Home</h1>
+ <h1>Xin chào</h1>
Áp dụng thay đổi này? [Đồng ý / Bỏ qua]
Edit vs Write
Mặc định, mọi thay đổi file đều đi qua bạn. Claude trình một bản diff (dòng − bị bỏ, + thêm vào); bạn Đồng ý hoặc Bỏ qua. Trong VS Code/JetBrains, diff hiện ngay trong editor.
- ▸Đọc diff: thay đổi có đúng ý? có đụng nhầm phần khác không?
- ▸Bỏ qua nếu sai và nói lý do - Claude sẽ sửa lại theo góp ý.
- ▸Đừng bấm “Đồng ý” theo phản xạ; duyệt diff là bước kiểm soát ít tốn công nhất của bạn.
Duyệt nhanh không phải duyệt ẩu
Bấm duyệt từng lần sẽ mệt với những lệnh an toàn lặp đi lặp lại (vd chạy test). Giải pháp: luật quyền trong settings.json - tự cho phép thứ an toàn, chặn cứng thứ nguy hiểm. Cú pháp là Tool(mẫu):
.claude/settings.json - mục permissions
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Edit(src/**)"
],
"deny": [
"Bash(curl *)",
"Bash(rm *)",
"Read(./.env)",
"Read(./secrets/**)"
]
}
} Thử xem bộ luật trên quyết định thế nào với từng hành động:
allow
- Bash(npm run lint)
- Bash(npm run test *)
- Edit(src/**)
- Read(~/.zshrc)
deny
- Bash(curl *)
- Bash(rm *)
- Read(./.env)
- Read(./secrets/**)
Bấm một hành động để xem Claude xử lý ra sao:
Khớp một luật trong allow → chạy không cần hỏi.
Luật khớp: Bash(npm run test *)
- ▸Cú pháp: Bash(npm run test *) - dấu * khớp mọi đối số (chú ý khoảng trắng trước *).
- ▸Đường dẫn: * trong một bậc thư mục, ** xuyên nhiều bậc (vd Read(./secrets/**)).
- ▸DENY luôn thắng ALLOW; không luật nào khớp → Claude HỎI. Gõ /permissions để xem & sửa.
Đặt luật ở đâu
Lỡ Claude sửa một loạt file mà bạn không ưng? Claude Code tự chụp ảnh trạng thái trước mỗi lần sửa, nên bạn có thể quay lui (rewind) nhanh - thường bằng cách bấm Esc hai lần để mở bảng hoàn tác.
- ▸Rewind = quay file về một thời điểm trước trong phiên - tiện khi thử sai.
- ▸Khác git: ảnh chụp này thuộc phiên, đóng phiên là mất.
- ▸KHÔNG hoàn tác được tác dụng phụ ngoài file: lệnh đã đổi DB, đã deploy, đã gửi mạng.
Rewind tiện, git mới là chỗ dựa
Vài thói quen giữ cho bạn an toàn khi để AI đụng vào máy:
- ▸Chặn bí mật bằng deny: Read(./.env), Read(./secrets/**) - đừng để khoá/mật khẩu lọt vào ngữ cảnh.
- ▸Phạm vi: Claude chỉ làm trong thư mục dự án; mở rộng phải chủ động (vd --add-dir).
- ▸Cảnh giác lệnh từ nguồn lạ (file/web nó đọc có thể “gài” chỉ dẫn) - đọc trước khi cho chạy.
- ▸Trên máy thật: ở default/acceptEdits; dành bypassPermissions cho môi trường cô lập.
Tổng kết
Câu hỏi thường gặp
Vì công cụ Edit hoạt động bằng cách THAY MỘT ĐOẠN VĂN BẢN CHÍNH XÁC trong file - nó cần biết đoạn cũ trông đúng từng ký tự thế nào (kể cả khoảng trắng) để thay đúng chỗ, không đụng phần khác. Đọc trước cũng giúp nó sửa hợp ngữ cảnh. Đây là lý do kỹ thuật, không phải nó “tò mò”.
Edit thay một ĐOẠN nhỏ trong file đang có (an toàn, ít rủi ro ghi đè nhầm). Write ghi CẢ FILE - tạo mới hoặc ghi đè toàn bộ. Sửa vài dòng thì dùng Edit; tạo file mới hoặc thay sạch nội dung thì Write. Với file đã tồn tại, Claude vẫn đọc trước khi Write đè.
Tuỳ mức tin tưởng. acceptEdits tiện khi task rõ ràng và bạn đang theo dõi sát. Nhưng “tự nhận” nghĩa là một thay đổi sai có thể lọt qua mà bạn không kịp nhìn. Mẹo: dùng allow/deny để tự động hoá những thứ AN TOÀN (vd Bash(npm run test *)) và vẫn để Claude hỏi ở phần rủi ro.
Trong settings.json (mục permissions) - cấp dự án (.claude/settings.json, chia sẻ qua git), cấp cá nhân (~/.claude/settings.json), hay cục bộ (.claude/settings.local.json, không commit). Gõ /permissions để xem & sửa. Quy tắc vàng: DENY luôn thắng ALLOW; không luật nào khớp thì Claude HỎI.
Không hẳn. Rewind dùng ảnh chụp riêng của Claude Code để quay lui nhanh trong phiên - tiện khi thử sai. Nhưng nó KHÔNG thay git: đóng phiên là mất, và nó KHÔNG hoàn tác được “tác dụng phụ” đã xảy ra ngoài file (vd lệnh đã đổi cơ sở dữ liệu, đã deploy, đã gửi mạng). Việc quan trọng vẫn phải commit vào git.
Tick những điều em tự tin làm được. Càng lên cao, em càng hiểu sâu.
Trả lời vài câu để chắc rằng em đã nắm bài.
Vì sao Claude phải ĐỌC file trước khi dùng công cụ Edit?
- 1
Đọc trước khi sửa
Nhờ Claude sửa một dòng trong một file. Quan sát: nó làm gì TRƯỚC khi gọi
Edit?Hoàn thành khi: Bạn thấy nó
Readfile đó trước, rồi mớiEdit- và giải thích được vì sao (Editcần khớp đoạn cũ chính xác). - 2
Duyệt một diff
Để Claude đề xuất một thay đổi ở chế độ
default. Đọc bản diff, rồi đồng ý HOẶC bỏ qua kèm lý do.Hoàn thành khi: Bạn ra quyết định dựa trên nội dung diff (không bấm bừa); nếu bỏ qua, nêu được vì sao.
- 3
Viết luật quyền
Dùng công cụ ở Bước 3 làm mẫu. Viết một luật allow cho “chạy test” và một luật deny cho “xoá bằng rm”.
Hoàn thành khi: Ví dụ allow:
Bash(npm run test *); deny:Bash(rm *). Bạn giải thích được vì sao denyrmlà khôn ngoan. - 4
Đoán quyết định
Với bộ luật ở Bước 3, lệnh "
rm -rf build" sẽ được Tự chạy / Hỏi / Bị chặn? Còn "git push"?Hoàn thành khi: “
rm -rf build” → Bị chặn (khớp denyBash(rm *)); “git push” → Hỏi (không luật nào khớp). - 5
Chặn bí mật
Thêm luật deny để Claude không bao giờ đọc
.envvà thư mụcsecrets/trong một dự án của bạn.Hoàn thành khi:
permissions.denycóRead(./.env)vàRead(./secrets/**); thử nhờ Claude đọc.env→ bị chặn.