Agent SDK のファイルチェックポイントで変更を巻き戻す

Claude Agent SDK エンジニアリング 8分で読めます

エージェントにコードを書かせていると、「ここまでは良かったのに、この先で壊れた」という場面が必ず来ます。Claude Agent SDK のファイルチェックポイントは、エージェントが Write / Edit / NotebookEdit で加えたファイル変更を記録しておき、任意の時点のファイル内容へ戻すための機能です。

このページでは、SDK でチェックポイントを有効にする書き方、戻り先となる UUID の受け取り方、rewindFiles()(TypeScript)と rewind_files()(Python)の呼び方、CLI から戻す方法、そして何が追跡されないかまでを扱います。Claude Code CLI の /rewindCheckpointing。会話ごと戻せる対話機能)とは別物なので、混同しないでください。

ファイルチェックポイントとは何か

ファイルチェックポイントは、エージェントのセッション中に WriteEditNotebookEdit の各ツールが行ったファイル変更を追跡し、任意の過去の状態へファイルを戻せるようにする仕組みです。公式ドキュメントは用途として次の3つを挙げています。

仕組みは単純で、上記3ツールでファイルを変更する前に SDK がバックアップを作ります。そしてレスポンスストリームに流れるユーザーメッセージに、戻り先として使えるチェックポイント UUID が付くという形です。

ここで最も重要な区別を先に押さえてください。巻き戻すのはディスク上のファイルだけで、会話そのものは巻き戻りません。rewindFiles() / rewind_files() を呼んだあとも、会話履歴とコンテキストはそのまま残ります。

巻き戻し時の挙動も具体的です。Claude Code はそのチェックポイント以降に作成したファイルを削除し、変更したファイルをその時点の内容に戻します。ただし、追跡対象のパスがシンボリックリンク・ハードリンク・その他の通常ファイルでないもの、親ディレクトリがチェックポイント時点の場所に解決できなくなったもの、バックアップを安全に読めないものはスキップされます。スキップされたパスの数は RewindFilesResultskippedLinks フィールドに入ります。なおこのスキップ動作は Claude Code v2.1.216 以降で、それ以前はリンク越しに書き込み・削除をしていました。

有効化してチェックポイントUUIDを受け取る

必要な設定は2つだけです。1つはチェックポイント自体の有効化、もう1つはUUID をストリームに流させるための追加引数です。後者を忘れると、有効化しただけでは戻り先が手に入りません。

目的PythonTypeScript
チェックポイントを有効化enable_file_checkpointing=TrueenableFileCheckpointing: true
UUID を受け取るextra_args={"replay-user-messages": None}extraArgs: { 'replay-user-messages': null }

TypeScript での指定は次のようになります。permissionMode"acceptEdits" を入れているのは、確認を挟まずに編集を進めさせるためで、チェックポイント自体の要件ではありません。

const response = query({
  prompt: "Refactor the authentication module",
  options: {
    enableFileCheckpointing: true,
    permissionMode: "acceptEdits" as const,
    extraArgs: { "replay-user-messages": null }
  }
});

Python では ClaudeAgentOptions に同じ内容を渡します。

options = ClaudeAgentOptions(
    enable_file_checkpointing=True,
    permission_mode="acceptEdits",
    extra_args={"replay-user-messages": None},
)

async with ClaudeSDKClient(options) as client:
    await client.query("Refactor the authentication module")

次に、ストリームを回しながら UUID を拾います。replay-user-messages が設定されていれば、ストリーム上の各ユーザーメッセージが UUID を持ち、それがそのままチェックポイントになります。多くの用途では最初のユーザーメッセージの UUIDmessage.uuid)を掴んでおけば十分で、そこへ戻せば追跡対象のファイルは元の状態に復帰します。

let checkpointId: string | undefined;
let sessionId: string | undefined;

for await (const message of response) {
  if (message.type === "user" && message.uuid && !checkpointId) {
    checkpointId = message.uuid;
  }
  if ("session_id" in message && !sessionId) {
    sessionId = message.session_id;
  }
}

セッションID(message.session_id)の取得は任意です。必要になるのは「ストリームが終わったあとで戻したい」場合だけで、メッセージを処理している最中にその場で rewindFiles() を呼ぶなら不要です。

巻き戻す(rewindFiles / rewind_files)

ストリームが完了したあとに戻す場合は、空のプロンプトでセッションを再開してから、チェックポイント UUID を指定して rewindFiles()(TypeScript)または rewind_files()(Python)を呼びます。空プロンプトは接続を開くためのもので、質問を投げるためではありません。

const rewindQuery = query({
  prompt: "", // 接続を開くための空プロンプト
  options: { ...opts, resume: sessionId }
});

for await (const msg of rewindQuery) {
  await rewindQuery.rewindFiles(checkpointId);
  break;
}
async with ClaudeSDKClient(
    ClaudeAgentOptions(enable_file_checkpointing=True, resume=session_id)
) as client:
    await client.query("")  # 接続を開くための空プロンプト
    async for message in client.receive_response():
        await client.rewind_files(checkpoint_id)
        break

再開側のオプションにも enable_file_checkpointing / enableFileCheckpointing を入れている点に注意してください。再開したセッション側で有効になっていないと巻き戻しは通りません(後述の「File rewinding is not enabled」の原因になります)。

ループを break で1回だけ回しているのも意図的です。イテレーションを最後まで回し切ってから呼ぶと接続が閉じており、エラーになります。

使い分けの型とCLIからの巻き戻し

公式ドキュメントは、UUID の持ち方として2つの型を示しています。

危険な操作の前に1点だけ確保する

各ターンの開始時に UUID を上書きし続け、最新の1つだけを持つ型です。処理中に問題を検知したら、その場で直前の安全な状態へ戻してループを抜けます。

for await (const message of response) {
  if (message.type === "user" && message.uuid) {
    safeCheckpoint = message.uuid;  // 直前の1点だけを保持する
  }
  if (yourRevertCondition && safeCheckpoint) {
    await response.rewindFiles(safeCheckpoint);
    break;
  }
}

yourRevertCondition は公式の例でもプレースホルダであり、定義されていません。エラー検知や検証失敗など、自分の判断ロジックに置き換えて使います。

複数の戻り先を持つ

ターン1でリファクタリング、ターン2でテスト追加、というように変更が複数ターンにまたがるとき、「リファクタは残してテストだけ取り消す」ことをしたくなります。その場合は UUID を配列にメタデータつきで貯め、あとから任意の1点を選んで戻します。

CLI から戻す

セッションIDとチェックポイントIDを控えてあれば、CLI からも戻せます。ただしこの方法には注意点が2つあります。

CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=true claude -p --resume <session-id> --rewind-files <checkpoint-uuid>

1つめは、claude 実行ファイルはSDK パッケージには含まれないということです。Claude Code のインストールが別途必要です。2つめは、SDK 経由なら自動で設定される CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING を、素の CLI では自分で指定しなければならないことです。

なお --rewind-filesclaude --help の出力には現れませんが、CLI はこの形を受け付けます。成功すると Files rewound to state at message <checkpoint-uuid> と表示され、プロンプトを送らずに終了します。

追跡されないもの・よくあるエラー

ここを誤解したまま本番の作業に使うと、戻せると思っていたものが戻りません。公式が挙げる制限は次のとおりです。

制限内容
対象は3ツールのみWrite / Edit / NotebookEdit 経由の変更だけ。echo > file.txtsed -i のような Bash 経由の変更は追跡されない
サブエージェントの編集サブエージェントが加えた編集は追跡も復元もされない(前面で動く context: fork のスキルは例外)。取り消しには git を使う
同一セッション内チェックポイントは、それを作ったセッションに紐づく
ファイル内容のみディレクトリの作成・移動・削除は巻き戻しで元に戻らない
ローカルファイルのみリモートやネットワーク上のファイルは追跡されない

つまり、ファイルチェックポイントは git の代わりにはなりません。Bash でのファイル操作やサブエージェントの編集を含む作業では、git のコミットを併用してください。

よくあるエラーと原因

本ページは Rewind file changes with checkpointing の内容に基づく非公式の日本語解説です(確認日 2026-09-22)。オプション名・メソッド名・エラー文言は公式表記のまま記載しています。最新の仕様は公式ドキュメントを確認してください。