← Lập trình với Claude Code

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:

claude - ~/web-app

Đổ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

Edit thay một đoạn nhỏ trong file đang có - ít rủi ro. Write ghi cả file (tạo mới hoặc đè sạch). Sửa vài dòng → Edit; tạo file mới → Write. Với file đã tồn tại, Claude vẫn đọc trước khi đè.

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

Khi quen tay, bạn sẽ duyệt rất nhanh - nhưng vẫn phải nhìn. Lỗi nguy hiểm nhất thường nằm ở thay đổi “trông có vẻ đúng”. Việc lớn thì để Claude chia nhỏ, mỗi diff gọn để dễ soi.

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:

Tự chạy Bash(npm run test unit)

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

.claude/settings.json (dự án - chia sẻ qua git), ~/.claude/settings.json (cá nhân - mọi dự án), hoặc .claude/settings.local.json (cục bộ - không commit). Bí mật của riêng bạn nên để ở bản cục bộ hoặc cấp cá nhân.

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

Hãy xem rewind là “nút Undo nhanh trong lúc làm”, còn git mới là bản lưu thật: commit thường xuyên để có điểm quay về chắc chắn. (Phím/lệnh rewind có thể khác trên máy bạn - đối chiếu /help.) Quy trình git có hẳn một bài riêng ở cuối khoá.

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

Bạn vừa nắm phần “tay chân” của Claude Code: đọc/sửa/chạy, duyệt diff, tinh chỉnh allow/deny, rewind, và giữ bí mật + phạm vi an toàn. Bài tiếp theo dạy cách cho Claude nhớ quy ước dự án để nó bám đúng mà bạn khỏi nhắc lại: CLAUDE.md & bộ nhớ.

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.

Bạn kiểm soát điều đó. Thêm luật deny như Read(./.env)Read(./secrets/**) để CHẶN cứng. Ngoài ra Claude chỉ làm trong thư mục dự án; muốn cho nó thấy thư mục khác phải chủ động mở rộng phạm vi (--add-dir). Nguyên tắc: chặn bí mật, và đọc diff trước khi đồng ý chạy lệnh lạ.

Tick những điều em tự tin làm được. Càng lên cao, em càng hiểu sâu.

Tick những điều em tự tin làm được sau khi học bài này. 0/6

Trả lời vài câu để chắc rằng em đã nắm bài.

Câu 1/3 Điểm: 0

Vì sao Claude phải ĐỌC file trước khi dùng công cụ Edit?

  1. 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ó Read file đó trước, rồi mới Edit - và giải thích được vì sao (Edit cần khớp đoạn cũ chính xác).

  2. 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. 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 deny rm là khôn ngoan.

  4. 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 deny Bash(rm *)); “git push” → Hỏi (không luật nào khớp).

  5. 5

    Chặn bí mật

    Thêm luật deny để Claude không bao giờ đọc .env và thư mục secrets/ trong một dự án của bạn.

    Hoàn thành khi: permissions.denyRead(./.env)Read(./secrets/**); thử nhờ Claude đọc .env → bị chặn.