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 8 — Session, resume và checkpointing

Session là đơn vị công việc của Claude Code: cách đặt tên, resume, branch, và picker cùng phím tắt của nó. Cộng checkpoint — thứ hoàn tác được và bốn trường hợp nó không hoàn tác được.

Một session là cuộc hội thoại được lưu, gắn với một thư mục project. Claude Code lưu nó liên tục trong lúc bạn làm, nên bạn quay lại được chỗ đang dở, rẽ nhánh để thử hướng khác, hoặc chuyển qua lại giữa nhiều task.

Checkpoint là lớp thứ hai: ảnh chụp file trước mỗi prompt, để bạn tua ngược khi mọi thứ đi chệch. Hai cơ chế này bổ sung cho nhau, và cả hai đều có những chỗ không phủ tới — đó là phần đáng đọc kỹ nhất của bài.

Resume một session

LệnhTác dụng
claude --continueResume session gần nhất trong thư mục hiện tại
claude --resumeMở session picker
claude --resume <name>Resume thẳng session theo tên
claude --from-pr <number>Mở picker đã lọc theo pull request đó
/resumeChuyển sang hội thoại khác ngay từ trong phiên đang chạy

Session tạo bằng claude -p hoặc Agent SDK không hiện trong picker, nhưng vẫn resume được bằng cách truyền session ID cho claude --resume <session-id>.

Bạn chạy claude --resume <session-id> được từ bất kỳ thư mục nào: Claude Code tìm ID trong project hiện tại và các git worktree của nó trước, rồi mới tìm sang mọi project khác trên máy.

Session resume khôi phục những gì

Không phải mọi thứ đều quay lại. Đây là chỗ hay gây bất ngờ:

Trạng tháiCó được khôi phục?
Lịch sử hội thoạiCó, đầy đủ, gồm cả tool call và kết quả
ModelCó, trừ khi model đã bị khai tử, bị availableModels chặn, hoặc bạn truyền --model lúc launch
Agent (--agent)Có, kèm system prompt, giới hạn tool và model của nó
Permission modeCó, trừ plan và bypassPermissions — hai mode này không bao giờ được khôi phục
Goal đang hoạt độngCó; nhưng số lượt, đồng hồ và mốc token bị reset
Scheduled task chưa hết hạnCó
Background Bash và monitor taskKhông

Và một nhóm flag cấu hình không được khôi phục — nếu session phụ thuộc chúng, bạn phải truyền lại khi resume: --mcp-config, --settings, --plugin-dir, --fallback-model, và các thư mục thêm bằng --add-dir. Ngược lại, các file settings chuẩn như settings.json được đọc lại lúc launch nên không cần truyền lại.

Resume từ bản tóm tắt

Trên gói Pro hoặc Max, khi bạn resume một session đã im lặng hơn khoảng một giờ và lớn hơn 100.000 token, Claude Code khôi phục hội thoại rồi mở một hộp thoại trước khi bạn gửi tin nhắn đầu tiên.

Lý do có hộp thoại này nằm ở phần 3: prompt cache đã hết hạn, nên request kế tiếp sẽ xử lý lại toàn bộ lịch sử dù bạn chọn gì. Ba lựa chọn khác nhau ở chỗ mỗi request sau đó mang theo bao nhiêu:

  • Resume from summary — chạy /compact ngay. Lịch sử được thay bằng bản tóm tắt, vài lượt gần nhất, và tối đa năm file vừa đọc. Các request sau mang bản tóm tắt thay vì toàn bộ lịch sử.
  • Resume full session as-is — nạp nguyên hội thoại. Sau tin nhắn đầu tiên, Claude Code xử lý lại và cache lại toàn bộ, rồi đọc từ cache ở các request sau khi cache còn ấm.
  • Don’t ask me again — resume đầy đủ và không hỏi lại ở các lần sau.

Đánh đổi rõ ràng: resume as-is giữ mọi chi tiết với chi phí mỗi request tỉ lệ với độ dài hội thoại; resume from summary rẻ hơn ở mỗi request sau, nhưng thứ bản tóm tắt bỏ sót thì không còn trong context của Claude nữa.

Đặt tên session

Đặt tên có mô tả để tìm lại được trong picker và resume theo tên. Việc này quan trọng nhất khi bạn chạy nhiều task song song.

Lúc nàoCách đặt
Lúc khởi độngclaude -n auth-refactor
Trong phiên/rename auth-refactor. Tên cũng hiện trên thanh prompt
Từ session pickerChọn một session rồi bấm Ctrl+R
Khi duyệt planDuyệt plan tự đặt tên session theo nội dung plan, trừ khi bạn đã đặt tên

Nếu bạn không đặt tên, Claude Code sinh một session title — bản tóm tắt ngắn prompt đầu tiên của bạn, do một request nền tới model nhỏ/nhanh viết ra. Session tương tác chưa đặt tên cũng nhận một default display name ghép tên thư mục làm việc với hậu tố hai ký tự, ví dụ my-app-3f.

Cả session title lẫn default display name đều không phải handle để resume. claude --resume <name> và picker chỉ khớp với tên bạn tự đặt.

Khi bạn khởi động hoặc resume một session tương tác trùng tên với một session đang sống khác trên máy, Claude Code giữ tên cho session có trước và đổi tên session của bạn thành biến thể có hậu tố hai từ, ví dụ auth-refactor-graceful-unicorn.

Session picker

Chạy /resume trong phiên, hoặc claude --resume không tham số.

PhímTác dụng
↑ / ↓Di chuyển giữa các session
→ / ←Mở rộng hoặc thu gọn nhóm session
EnterResume session đang chọn
SpaceXem trước nội dung session
Ctrl+RĐổi tên session đang chọn
/ hoặc ký tự bất kỳVào chế độ tìm kiếm. Dán URL của một pull request để tìm session đã tạo ra nó
Ctrl+AHiện session từ mọi project trên máy này
Ctrl+WHiện session từ mọi worktree của repo hiện tại
Ctrl+BLọc theo git branch hiện tại
EscThoát picker hoặc thoát chế độ tìm

Mặc định picker hiện session của worktree hiện tại (background session được đánh dấu bg), cộng các session khởi động ở nơi khác nhưng đã thêm thư mục hiện tại bằng /add-dir.

Mỗi dòng hiện tên session, thời gian từ lần hoạt động cuối, git branch, và kích thước file. Khi chọn một session từ worktree khác cùng repo, Claude Code resume tại chỗ; chọn session từ một project không liên quan, Claude Code copy lệnh cd kèm resume vào clipboard cho bạn.

Branch một session

Branch tạo bản copy của hội thoại tới thời điểm hiện tại và chuyển bạn vào bản copy, giữ nguyên bản gốc.

/branch try-streaming-approach

Từ command line, kết hợp --continue hoặc --resume với --fork-session.

Điểm tinh tế: /branch copy transcript rồi chuyển tiến trình Claude Code đang chạy sang ghi vào bản mới. Chính điều đó quyết định branch thừa hưởng gì:

Trạng tháiSau /branch
Lịch sử hội thoạiĐược copy tới điểm bạn chạy /branch
Quyền đã cấp dạng “Allow for this session”Được giữ — branch chạy cùng tiến trình. Nhưng nếu bạn fork sang tiến trình riêng bằng --fork-session thì tiến trình mới không có, phải duyệt lại
Background subagent và background Bash đang chạyVẫn chạy. Output của chúng hiện ở branch mới, không phải session gốc
Kết nối Remote ControlVẫn nối. Điện thoại hoặc trình duyệt đang nối sẽ đi theo bạn vào branch

Nếu bạn resume cùng một session ở hai terminal mà không fork, tin nhắn từ cả hai trộn vào chung một transcript.


Checkpointing

Checkpointing tự động chụp trạng thái code của bạn trước mỗi prompt.

  • Mỗi prompt tạo một checkpoint mới
  • Claude Code giữ ảnh chụp file cho 100 checkpoint gần nhất trong một session
  • Checkpoint được lưu cùng hội thoại, nên bạn vẫn chạy /rewind được sau khi resume
  • Checkpoint bị xoá cùng session sau 30 ngày, theo cleanupPeriodDays

Chạy /rewind, hoặc bấm Esc hai lần khi ô nhập rỗng. Nếu ô nhập có chữ, Esc Esc xoá chữ thay vì mở menu — chữ đó được lưu vào lịch sử nhập, bấm Up để lấy lại.

Menu liệt kê từng prompt bạn đã gửi. Chọn một điểm rồi chọn hành động:

  • Restore code and conversation — tua cả code lẫn hội thoại về điểm đó
  • Restore conversation — tua hội thoại, giữ nguyên code hiện tại
  • Restore code — tua file, giữ nguyên hội thoại
  • Summarize from here — nén hội thoại từ điểm này trở đi thành tóm tắt, giải phóng context
  • Summarize up to here — nén phần hội thoại trước điểm này, giữ nguyên phần sau
  • Never mind — quay lại, không đổi gì

Hai lựa chọn restore code chỉ hiện khi checkpoint được chọn thực sự có thay đổi file để hoàn tác.

Sau khi restore hội thoại hoặc chọn Summarize from here, prompt gốc của tin nhắn đã chọn được đưa lại vào ô nhập để bạn gửi lại hoặc sửa.

Hướng bản tóm tắt: tô sáng một lựa chọn Summarize bằng phím mũi tên rồi gõ chỉ dẫn ở chỗ ghi add context (optional), sau đó bấm Enter. Chọn bằng phím số thì nó tóm tắt ngay, không kèm chỉ dẫn.

Rewind vượt qua một lần /clear: nếu bạn đã chạy /clear trước đó trong cùng tiến trình Claude Code, menu rewind hiện thêm một mục ở đầu danh sách dạng /resume <session-id> (previous session). Chọn nó để quay về hội thoại trước lúc /clear. Mục này còn tới khi bạn thoát Claude Code hoặc resume một session khác.

Bốn thứ checkpoint KHÔNG hoàn tác được

Đây là phần quan trọng nhất. Đừng coi checkpoint là git.

1. Thay đổi do lệnh Bash. Checkpointing không theo dõi file bị sửa bởi lệnh bash. Nếu Claude Code chạy rm file.txt, mv old.txt new.txt hay cp source.txt dest.txt, những thay đổi đó không hoàn tác được qua rewind. Chỉ các lần sửa trực tiếp qua tool sửa file của Claude mới được theo dõi.

2. Thay đổi của subagent. Subagent sửa file bằng đúng tool đó, nhưng Claude Code thường không ghi các thay đổi ấy vào checkpoint của session bạn. Ngoại lệ duy nhất: một skill chạy dạng fork ở foreground — nó sửa working tree trong chính lượt của bạn nên rewind khôi phục được. Mọi subagent khác, gồm cả forked skill chạy ở nền (mặc định) và /code-review --fix chạy nền, thì phải dùng git để hoàn tác.

3. Thay đổi từ bên ngoài. Checkpointing chỉ theo dõi file đã được sửa trong phiên hiện tại. Bạn tự sửa file ngoài Claude Code, hoặc một phiên khác chạy song song sửa, đều không được ghi nhận.

4. File symlink và hard link. Khi bạn chọn Restore code, Claude Code bỏ qua mọi path được theo dõi là symlink hoặc hard link, và hiện cảnh báo Restored the code, but skipped N files. Các file bị bỏ qua giữ nguyên nội dung hiện tại. File config được dotfile manager symlink vào project, và file pnpm hard-link vào chỗ, đều rơi vào nhóm này. Bật /debug trước khi restore để log ở ~/.claude/debug/<session-id>.txt ghi tên từng path bị bỏ qua.

Checkpoint không thay thế version control. Nó dành cho phục hồi nhanh ở mức phiên làm việc. Lịch sử lâu dài và cộng tác vẫn là việc của git.


Bốn lệnh, bốn tình huống

Bốn lệnh dưới đây hay bị dùng nhầm chỗ. Đây là cách phân biệt:

LệnhDùng khi
/clearChuyển sang việc hoàn toàn khác. Context về rỗng, hội thoại cũ vẫn resume được
/compactCần giữ mạch công việc nhưng hết chỗ trong context
/rewindĐã đi sai đường và muốn quay lại một điểm cụ thể — kèm hoàn tác code
/branchMuốn thử hướng khác mà vẫn giữ nguyên hướng đang đi để quay lại được

Nhớ thêm hai điều từ phần 3: /rewind giữ được prompt cache vì nó cắt về một prefix đã cache sẵn, còn /compact dựng prefix mới. Và Summarize trong menu rewind chính là một /compact có nhắm đích — nó giữ bạn ở cùng session.

Nơi transcript được lưu

Mặc định ở ~/.claude/projects/<project>/<session-id>.jsonl, trong đó <project> là đường dẫn thư mục làm việc với ký tự không phải chữ-số thay bằng -.

Mỗi dòng là một JSON object cho một tin nhắn, tool use, hoặc metadata. Định dạng này là nội bộ của Claude Code và đổi giữa các phiên bản, nên script parse thẳng file có thể vỡ ở bất kỳ bản phát hành nào. Muốn xây dựng trên dữ liệu session thì dùng /export hoặc các interface dành cho script:

claude -p --resume <session-id> --output-format json "summarize what we changed" | jq -r '.result'

Bốn thứ chỉnh được:

MuốnĐặt
Chuyển chỗ lưu khỏi ~/.claudeBiến môi trường CLAUDE_CONFIG_DIR
Đổi thời hạn giữ 30 ngàycleanupPeriodDays trong settings.json
Không ghi transcript ở mọi chế độBiến môi trường CLAUDE_CODE_SKIP_PROMPT_HISTORY
Không ghi cho một lần chạy non-interactiveFlag --no-session-persistence với claude -p

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.