Agent thay đổi file thật sự, và đôi khi thay đổi nhầm chỗ. Không phải vì nó bị lỗi - chỉ là nó hiểu nhiệm vụ khác với ý bạn. Tin tốt: bạn không phải tự chụp snapshot code, Claude Code tự làm việc đó, và một lượt hỏng có thể tua ngược lại chỉ với vài lần bấm.

Tin không hay lắm: những snapshot này có ranh giới. Mọi thứ agent gõ vào file đều nằm trong một vùng được canh giữ, và từ đó có thể khôi phục lại được. Còn mọi thứ đi vòng qua vùng đó thì nằm ngoài hàng rào - snapshot không nhìn thấy và không thể khôi phục. Biết trước hàng rào nằm ở đâu tốt hơn nhiều so với việc phát hiện ra vào đúng lúc thứ gì đó biến mất.

Dưới đây là cách hoàn tác hoạt động, hàng rào của nó nằm ở đâu, nó tồn tại bao lâu, và dùng gì để bù đắp cho phần còn lại ngoài hàng rào.

Checkpoint là gì

Checkpoint là một snapshot của những file mà agent sắp sửa chỉnh sửa, được chụp trước khi nó động vào chúng. Không phải bản sao lưu của cả project, cũng không phải một mục trong lịch sử phiên bản, mà là một điểm khôi phục đang hoạt động bên trong phiên làm việc hiện tại - tức là bên trong cuộc trò chuyện của bạn với agent.

Điều quan trọng nhất cần nhớ từ mục này: snapshot được tạo tự động trước mỗi tin nhắn bạn gửi. Bạn không tạo nó, không cấu hình nó, và không thể quên bấm nút nào cả. Gửi tin nhắn xong là điểm đó đã có sẵn.

  • Tin nhắn của bạn
  • Snapshot code
  • Agent chỉnh sửa
  • Tin nhắn mới
  • Snapshot mới

Chú ý thứ tự: snapshot trước, chỉnh sửa sau. Chính vì vậy quay lại một điểm nghĩa là "trả code về đúng như trước khi có tin nhắn này". Bạn không chọn một mốc thời gian, mà chọn chính tin nhắn của mình, tin nhắn mà sau đó mọi thứ cần được hủy bỏ.

Và thêm một điều để phần sau dễ hiểu hơn. Checkpoint là chuyện về code. Claude Code cũng biết tua ngược cả cuộc trò chuyện, nhưng đó là một lựa chọn riêng trong menu: code và cuộc trò chuyện quay lại cùng nhau hoặc tách riêng, tùy bạn quyết định.

Cách mở menu hoàn tác

Có hai cách vào, và cả hai làm cùng một việc:

  • lệnh /rewind trong dòng nhập lệnh. Nó còn có các bí danh quen thuộc là /undo và /checkpoint;
  • phím Esc Esc, nếu dòng nhập lệnh đang trống.
Nếu menu không mở lên

Rất có thể dòng nhập lệnh đang có sẵn văn bản. Khi đó lần bấm Esc Esc đầu tiên chỉ xóa nội dung bạn gõ, chứ menu không hiện ra. Văn bản không mất đâu cả: nó chuyển vào lịch sử nhập lệnh, và phím mũi tên lên sẽ lấy lại nó. Nhấn Esc Esc thêm một lần nữa trên dòng đã trống, menu sẽ mở ra.

Sẽ mở ra danh sách các tin nhắn của bạn trong phiên làm việc này. Không phải danh sách file, cũng không phải một thanh thời gian - chính xác là các tin nhắn, mỗi dòng ứng với một tin nhắn bạn đã gửi. Bạn chọn tin nhắn mà sau đó mọi thứ bắt đầu đi sai hướng.

Có một trường hợp riêng: nếu trước đó trong cùng một agent đang chạy bạn đã dùng /clear, ở các phiên bản mới sẽ xuất hiện thêm một dòng ở đầu danh sách. Dòng đó đưa bạn quay lại cuộc trò chuyện trước khi xóa. Như bạn thấy, việc xóa không đốt cháy mất gì cả.

Menu đưa ra những lựa chọn nào

Chọn một điểm xong, agent sẽ hỏi bạn muốn làm gì với nó. Có sáu lựa chọn:

Mục trong menuLàm gì
Restore code and conversationđưa cả code lẫn cuộc trò chuyện về điểm đã chọn
Restore conversationchỉ đưa cuộc trò chuyện quay lại, giữ nguyên file
Restore codechỉ đưa file quay lại, giữ nguyên cuộc trò chuyện
Summarize from heregói gọn cuộc trò chuyện từ điểm này trở đi thành một bản tóm tắt
Summarize up to heregói gọn cuộc trò chuyện đến điểm này, giữ nguyên phần sau
Never mindđóng menu, không làm gì cả

Điều đầu tiên cần biết về bảng này: nội dung menu không cố định. Hai mục liên quan đến code chỉ xuất hiện khi sau điểm đã chọn agent thực sự có thay đổi file. Không thay đổi thì không có gì để khôi phục, và những dòng đó đơn giản là không xuất hiện. Vậy nên nếu menu chỉ có bốn mục thay vì sáu, chương trình của bạn vẫn hoàn toàn bình thường.

Hai dòng Summarize đứng riêng một nhóm. Chúng không làm việc với code mà với độ dài cuộc trò chuyện: gói một đoạn trò chuyện thành bản tóm tắt. Chúng hoàn toàn không đụng đến file trên ổ đĩa. Vì sao cần đến việc này là một chủ đề riêng khá dài, ở đây chỉ cần hiểu rằng đây không phải hoàn tác, và code không quay lại bằng cách này.

Và một chi tiết nhỏ giúp đỡ tiết kiệm công sức. Sau khi khôi phục cuộc trò chuyện, đúng nội dung tin nhắn đó sẽ quay lại dòng nhập lệnh. Không cần nhớ lại mình đã viết gì rồi gõ lại từ đầu - chỉnh lại câu chữ rồi gửi lần nữa.

Hoàn tác khôi phục được gì, và không khôi phục được gì

Trong phạm vi của mình, hoàn tác đáng tin cậy. Nó khôi phục hai thứ: các thay đổi file mà agent thực hiện bằng công cụ chỉnh sửa của nó, và lịch sử trò chuyện trong phiên này.

Còn đây là những gì nằm ngoài hàng rào.

  • Thay đổi do lệnh trong terminal gây ra. Agent không chỉ biết sửa file mà còn chạy được lệnh. Nếu một file bị xóa bằng lệnh rm, bị di chuyển, hoặc bị ghi đè bằng copy, snapshot không nhìn thấy việc đó và không thể khôi phục lại.
  • Thay đổi nằm ngoài agent. Những file mà agent không hề động vào trong phiên này thì hoàn tác không đụng đến chút nào: bạn tự sửa chúng trong trình soạn thảo, một chương trình khác ghi đè lên, một phiên khác chạy song song - tất cả những chuyện đó giữ nguyên như vậy, menu không thể khôi phục hay hủy bỏ được. Nhưng nếu bạn tự tay sửa một file mà agent cũng đang chỉnh sửa, khi khôi phục code file đó sẽ quay về đúng snapshot toàn bộ - kể cả phần bạn đã sửa.
  • Thay đổi của subagent. Nếu agent giao một phần việc cho subagent hỗ trợ, các thay đổi của subagent thường không được đưa vào snapshot, và hoàn tác sẽ không khôi phục được chúng. Những thay đổi này được hoàn tác qua git.
  • Trường hợp hiếm gặp với file liên kết (symlink). Hoàn tác bỏ qua những file này và báo thẳng bằng một dòng riêng. Gặp phải thì bạn sẽ tự hiểu ra, không cần chuẩn bị trước làm gì.
Sửa file và chạy lệnh trong terminal là hai chuyện khác nhau

Nhìn từ bên ngoài, khác biệt gần như không thấy được. Agent báo cáo bình thản như nhau cả khi nó sửa một file lẫn khi nó chạy một lệnh xóa mất file đó. Với bạn đó là hai dòng thông báo trông giống nhau trên màn hình, còn với hoàn tác đó là hai sự kiện khác biệt về bản chất: cái đầu nó sẽ hủy được, cái sau thì không.

Vì vậy một yêu cầu chạy lệnh xóa, di chuyển hay ghi đè thứ gì đó đáng để đọc kỹ hơn một yêu cầu sửa file bình thường. Đây chính là trường hợp phía sau bạn không còn lưới an toàn nào nữa.

Nói ngắn gọn: hoàn tác theo dõi những gì agent gõ vào file, chứ không phải mọi thứ diễn ra trên máy tính của bạn.

Hoàn tác tồn tại được bao lâu

Snapshot không tích lũy mãi mãi. Bản thân các điểm trong menu thì được liệt kê hết, nhưng snapshot của file chỉ được giữ lại cho một trăm điểm gần nhất: với một cuộc trò chuyện thì như vậy là nhiều, nhưng không phải vô hạn, và các điểm cũ dần dần bị đẩy ra.

Bù lại, các điểm không gắn liền với cửa sổ terminal đang mở. Chúng được lưu cùng với phiên làm việc, nên bạn có thể đóng terminal, quay lại vào ngày mai, tiếp tục đúng cuộc trò chuyện đó - và menu hoàn tác vẫn hoạt động như chưa hề có chuyện gì xảy ra.

Nhưng cũng không tồn tại mãi mãi. các phiên làm việc và snapshot của chúng tự động bị dọn đi sau khoảng một tháng, thời hạn này có thể chỉnh lại nếu muốn.

Từ đó rút ra kết luận đơn giản: hoàn tác phát huy tốt trong phạm vi một nhiệm vụ - vài phút, vài giờ, một cuộc trò chuyện với agent. Nó không được thiết kế để làm kho lưu lịch sử của cả project, và đó không phải điểm yếu - chỉ là một công việc khác. Ai cần bao quát những khoảng thời gian dài hơn, chúng ta sẽ nói tiếp ở phần sau.

Bốn lưới an toàn, mỗi cái một vai trò riêng

Undo, snapshot, sao chép thư mục và lịch sử phiên bản không phải bốn cái tên cho cùng một thứ. Chúng bao quát những khoảng thời gian khác nhau và những loại mất mát khác nhau.

Lưới an toànAi tạo raLưu lại gìTồn tại bao lâuBất lực ở đâu
Undo trong trình soạn thảobạn, bằng một cú bấm phímnhững chỉnh sửa gần nhất của bạn trong file đang mởkhông lâu, tùy vào trình soạn thảochỉnh sửa cùng lúc ở nhiều file, và thường là cả những gì được ghi xuống ổ đĩa ngoài trình soạn thảo
CheckpointClaude Code, tự làmcode trước mỗi tin nhắn bạn gửisong song với phiên làm việc, một trăm điểmlệnh trong terminal, thay đổi nằm ngoài agent
Sao chép thư mụcbạn, thủ côngtoàn bộ project tại thời điểm sao chépđến khi bạn xóa nókhông cho biết đã thay đổi những gì, và làm rác ổ đĩa
Lịch sử phiên bản, gitbạn, bằng một hành động có chủ đíchcác trạng thái của project lần lượt theo thời giansong song với projectnhững gì bạn chưa kịp ghi lại vào đó

Chọn lưới an toàn trước hết theo phạm vi bao quát, rồi mới đến thời hạn. Nếu Claude chỉ thay đổi các file bình thường bằng công cụ chỉnh sửa của nó và không đụng đến gì ngoài phiên làm việc, một checkpoint là đủ tốt cho một thử nghiệm năm phút. Nếu công việc có liên quan đến lệnh trong terminal hoặc thay đổi bên ngoài, một mình checkpoint là không đủ, bất kể công việc ngắn hay dài. Và chỉ trong số những lưới an toàn phù hợp về phạm vi bao quát, bạn mới nên nhìn đến thời hạn: vài ngày làm việc hay một cột mốc quan trọng cần một cơ chế không phụ thuộc vào cuộc trò chuyện với agent.

Về sao chép thư mục thì nói thẳng luôn. Là một biện pháp một lần trước khi làm việc gì đó đáng sợ, nó hoạt động tốt: sao chép, xông vào phá, không ổn thì trả lại. Nhưng như một hệ thống thì nó không trụ được. Một tuần sau bạn có vài thư mục gần như giống hệt nhau, và chẳng ai còn nhớ cái nào là mới nhất.

Dòng cuối cùng là dòng duy nhất vừa lưu trạng thái lâu dài, vừa cho thấy chính xác điều gì đã thay đổi giữa các trạng thái đó. Đó là git, và đó là một chủ đề lớn riêng biệt: công cụ riêng, bộ lệnh riêng, ở đây chúng ta không đi sâu vào. Chỉ cần hiểu vị trí của nó trong bảng là đủ: tầm nhìn dài nhất, và là lá chắn duy nhất cho những gì hoàn tác không bao quát được.

Điều này thay đổi cách bạn làm việc như thế nào

Vấn đề không hẳn nằm ở bộ nút bấm. Đây là những gì rút ra được từ hoàn tác trên thực tế:

  • snapshot tự động được tạo, nhưng gần như miễn phí chỉ khi đó là thử nghiệm trên các file bình thường thông qua công cụ chỉnh sửa của Claude. Nếu cần đến lệnh trong terminal hay thay đổi ngoài phiên làm việc, hãy chọn một lưới an toàn khác trước;
  • agent không tự hoàn tác thay bạn. Nó có thể nói là đã đi sai hướng, nhưng mở menu và chọn là việc của bạn;
  • yêu cầu chạy lệnh trong terminal là một loại hành động khác với yêu cầu sửa file. Hoàn tác không bao quát cái đầu, nhưng bao quát cái sau. Khác biệt chỉ hiện ra trong nội dung yêu cầu, đó chính là lý do nên đọc kỹ nó;
  • bước càng lớn thì hoàn tác càng ít hữu ích. Khôi phục thì dễ, nhưng hiểu được từ một menu duy nhất chính xác cái gì đã quay lại càng khó khi agent càng làm nhiều việc. Các bước nhỏ lại thắng thế ở đây;
  • hoàn tác và lịch sử phiên bản không cạnh tranh nhau. Cái đầu bao quát vài phút, vài giờ trong một cuộc trò chuyện, cái sau bao quát vài ngày, vài tuần và các cột mốc của project.
Một phút trước khi sửa lớn

Trước một lượt thử nghiệm thật sự rủi ro, đáng để bỏ ra một phút và ghi lại trạng thái bằng thứ gì đó sống lâu hơn phiên làm việc. Ngay lúc này bạn có sẵn sao chép thư mục - như một biện pháp một lần trước rủi ro thì nó làm tốt việc của mình.

Nhưng công cụ thật sự cho việc này là git. Nó lưu trạng thái lâu bao nhiêu tùy ý, cho thấy chính xác điều gì đã thay đổi giữa các trạng thái, và không làm rác ổ đĩa bằng những thư mục gần như giống hệt nhau. Cách dùng nó chúng ta sẽ tìm hiểu riêng: chủ đề lớn và xứng đáng có một cuộc trò chuyện của riêng nó. Còn thói quen dừng lại một phút trước rủi ro sẽ có ích cho bạn cả khi dùng git, và cả khi chưa dùng nó.

Còn menu hoàn tác thì cứ để nó làm việc nó giỏi nhất, những thử nghiệm nhanh: trong vai trò cứu cánh cuối cùng nó làm việc kém hơn hẳn so với vai trò công cụ hàng ngày.


Nội dung menu hoàn tác và thời gian lưu trữ phụ thuộc vào phiên bản Claude Code và cài đặt của bạn, nên có thể khác với những gì mô tả ở đây. Phiên bản của bạn cung cấp gì thì menu sẽ luôn tự cho bạn thấy.