檔案檢查點功能會追蹤在代理工作階段中透過 Write、Edit 和 NotebookEdit 工具所做的檔案修改,讓您可以將檔案回溯到任何先前的狀態。想要試試看嗎?跳到互動範例。
透過檢查點功能,您可以:
只有透過 Write、Edit 和 NotebookEdit 工具所做的變更會被追蹤。透過 Bash 命令(如 echo > file.txt 或 sed -i)所做的變更不會被檢查點系統捕獲。
當您啟用檔案檢查點功能時,SDK 會在透過 Write、Edit 或 NotebookEdit 工具修改檔案之前建立備份。回應串流中的使用者訊息包含一個檢查點 UUID,您可以將其用作還原點。
檢查點功能與代理用來修改檔案的這些內建工具搭配使用:
| 工具 | 說明 |
|---|---|
| Write | 建立新檔案或以新內容覆寫現有檔案 |
| Edit | 對現有檔案的特定部分進行針對性編輯 |
| NotebookEdit | 修改 Jupyter 筆記本(.ipynb 檔案)中的儲存格 |
檔案回溯會將磁碟上的檔案還原到先前的狀態。它不會回溯對話本身。在呼叫 rewindFiles()(TypeScript)或 rewind_files()(Python)後,對話歷史和上下文會保持不變。
檢查點系統追蹤:
當您回溯到某個檢查點時,已建立的檔案會被刪除,已修改的檔案會還原到該時間點的內容。
要使用檔案檢查點功能,請在選項中啟用它,從回應串流中擷取檢查點 UUID,然後在需要還原時呼叫 rewindFiles()(TypeScript)或 rewind_files()(Python)。
以下範例展示完整的流程:啟用檢查點、從回應串流中擷取檢查點 UUID 和工作階段 ID,然後稍後恢復工作階段以回溯檔案。每個步驟都在下方詳細說明。
import asyncio
import os
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, UserMessage, ResultMessage
async def main():
# 步驟 1:啟用檢查點
options = ClaudeAgentOptions(
enable_file_checkpointing=True,
permission_mode="acceptEdits", # 自動接受檔案編輯,無需提示
extra_args={"replay-user-messages": None}, # 必須設定才能在回應串流中接收檢查點 UUID
env={**os.environ, "CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING": "1"}
)
checkpoint_id = None
session_id = None
# 執行查詢並擷取檢查點 UUID 和工作階段 ID
async with ClaudeSDKClient(options) as client:
await client.query("Refactor the authentication module")
# 步驟 2:從第一個使用者訊息中擷取檢查點 UUID
async for message in client.receive_response():
if isinstance(message, UserMessage) and message.uuid and not checkpoint_id:
checkpoint_id = message.uuid
if isinstance(message, ResultMessage) and not session_id:
session_id = message.session_id
# 步驟 3:稍後,透過以空提示恢復工作階段來回溯
if checkpoint_id and session_id:
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
print(f"Rewound to checkpoint: {checkpoint_id}")
asyncio.run(main())設定環境變數
檔案檢查點功能需要 CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING 環境變數。您可以在執行腳本之前透過命令列設定,或直接在 SDK 選項中設定。
選項 1:透過命令列設定
export CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=1選項 2:在 SDK 選項中設定
在配置 SDK 時透過 env 選項傳遞環境變數:
import os
options = ClaudeAgentOptions(
enable_file_checkpointing=True,
env={**os.environ, "CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING": "1"}
)啟用檢查點
配置您的 SDK 選項以啟用檢查點並接收檢查點 UUID:
| 選項 | Python | TypeScript | 說明 |
|---|---|---|---|
| 啟用檢查點 | enable_file_checkpointing=True | enableFileCheckpointing: true | 追蹤檔案變更以供回溯 |
| 接收檢查點 UUID | extra_args={"replay-user-messages": None} | extraArgs: { 'replay-user-messages': null } | 必須設定才能在串流中取得使用者訊息 UUID |
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 和工作階段 ID
設定 replay-user-messages 選項後(如上所示),回應串流中的每個使用者訊息都有一個 UUID 作為檢查點。
對於大多數使用情境,擷取第一個使用者訊息 UUID(message.uuid);回溯到它會將所有檔案還原到原始狀態。要儲存多個檢查點並回溯到中間狀態,請參閱多個還原點。
擷取工作階段 ID(message.session_id)是可選的;只有在您想要在串流完成後稍後回溯時才需要它。如果您在仍在處理訊息時立即呼叫 rewindFiles()(如在風險操作前建立檢查點中的範例所做的那樣),您可以跳過擷取工作階段 ID。
checkpoint_id = None
session_id = None
async for message in client.receive_response():
# 在每個使用者訊息上更新檢查點(保留最新的)
if isinstance(message, UserMessage) and message.uuid:
checkpoint_id = message.uuid
# 從結果訊息中擷取工作階段 ID
if isinstance(message, ResultMessage):
session_id = message.session_id回溯檔案
要在串流完成後回溯,請以空提示恢復工作階段,並使用您的檢查點 UUID 呼叫 rewind_files()(Python)或 rewindFiles()(TypeScript)。您也可以在串流期間回溯;請參閱在風險操作前建立檢查點了解該模式。
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如果您擷取了工作階段 ID 和檢查點 ID,您也可以從 CLI 回溯:
claude --resume <session-id> --rewind-files <checkpoint-uuid>這些模式展示了根據您的使用情境擷取和使用檢查點 UUID 的不同方式。
此模式只保留最新的檢查點 UUID,在每個代理回合之前更新它。如果在處理過程中出現問題,您可以立即回溯到最後的安全狀態並跳出迴圈。
import asyncio
import os
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, UserMessage
async def main():
options = ClaudeAgentOptions(
enable_file_checkpointing=True,
permission_mode="acceptEdits",
extra_args={"replay-user-messages": None},
env={**os.environ, "CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING": "1"}
)
safe_checkpoint = None
async with ClaudeSDKClient(options) as client:
await client.query("Refactor the authentication module")
async for message in client.receive_response():
# 在每個代理回合開始前更新檢查點
# 這會覆寫先前的檢查點。只保留最新的
if isinstance(message, UserMessage) and message.uuid:
safe_checkpoint = message.uuid
# 根據您自己的邏輯決定何時還原
# 例如:錯誤偵測、驗證失敗或使用者輸入
if your_revert_condition and safe_checkpoint:
await client.rewind_files(safe_checkpoint)
# 回溯後退出迴圈,檔案已還原
break
asyncio.run(main())如果 Claude 在多個回合中進行變更,您可能想要回溯到特定的時間點,而不是一路回溯到最初。例如,如果 Claude 在第一回合重構了一個檔案,在第二回合新增了測試,您可能想要保留重構但復原測試。
此模式將所有檢查點 UUID 與中繼資料一起儲存在陣列中。工作階段完成後,您可以回溯到任何先前的檢查點:
import asyncio
import os
from dataclasses import dataclass
from datetime import datetime
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, UserMessage, ResultMessage
# 儲存檢查點中繼資料以便更好地追蹤
@dataclass
class Checkpoint:
id: str
description: str
timestamp: datetime
async def main():
options = ClaudeAgentOptions(
enable_file_checkpointing=True,
permission_mode="acceptEdits",
extra_args={"replay-user-messages": None},
env={**os.environ, "CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING": "1"}
)
checkpoints = []
session_id = None
async with ClaudeSDKClient(options) as client:
await client.query("Refactor the authentication module")
async for message in client.receive_response():
if isinstance(message, UserMessage) and message.uuid:
checkpoints.append(Checkpoint(
id=message.uuid,
description=f"After turn {len(checkpoints) + 1}",
timestamp=datetime.now()
))
if isinstance(message, ResultMessage) and not session_id:
session_id = message.session_id
# 稍後:透過恢復工作階段回溯到任何檢查點
if checkpoints and session_id:
target = checkpoints[0] # 選擇任何檢查點
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(target.id)
break
print(f"Rewound to: {target.description}")
asyncio.run(main())這個完整的範例會建立一個小型工具檔案,讓代理新增文件註解,向您展示變更,然後詢問您是否要回溯。
在開始之前,請確保您已安裝 Claude Agent SDK。
建立測試檔案
建立一個名為 utils.py(Python)或 utils.ts(TypeScript)的新檔案,並貼上以下程式碼:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b執行互動範例
在與您的工具檔案相同的目錄中建立一個名為 try_checkpointing.py(Python)或 try_checkpointing.ts(TypeScript)的新檔案,並貼上以下程式碼。
此腳本會要求 Claude 為您的工具檔案新增文件註解,然後讓您選擇是否回溯並還原原始檔案。
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, UserMessage, ResultMessage
async def main():
# 配置 SDK 並啟用檢查點
# - enable_file_checkpointing:追蹤檔案變更以供回溯
# - permission_mode:自動接受檔案編輯,無需提示
# - extra_args:必須設定才能在串流中接收使用者訊息 UUID
options = ClaudeAgentOptions(
enable_file_checkpointing=True,
permission_mode="acceptEdits",
extra_args={"replay-user-messages": None}
)
checkpoint_id = None # 儲存使用者訊息 UUID 以供回溯
session_id = None # 儲存工作階段 ID 以供恢復
print("Running agent to add doc comments to utils.py...\n")
# 執行代理並從回應串流中擷取檢查點資料
async with ClaudeSDKClient(options) as client:
await client.query("Add doc comments to utils.py")
async for message in client.receive_response():
# 擷取第一個使用者訊息 UUID - 這是我們的還原點
if isinstance(message, UserMessage) and message.uuid and not checkpoint_id:
checkpoint_id = message.uuid
# 擷取工作階段 ID 以便稍後恢復
if isinstance(message, ResultMessage):
session_id = message.session_id
print("Done! Open utils.py to see the added doc comments.\n")
# 詢問使用者是否要回溯變更
if checkpoint_id and session_id:
response = input("Rewind to remove the doc comments? (y/n): ")
if response.lower() == "y":
# 以空提示恢復工作階段,然後回溯
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
print("\n✓ File restored! Open utils.py to verify the doc comments are gone.")
else:
print("\nKept the modified file.")
asyncio.run(main())此範例展示了完整的檢查點工作流程:
enable_file_checkpointing=True 和 permission_mode="acceptEdits" 配置 SDK 以自動核准檔案編輯rewind_files() 來還原原始檔案執行範例
設定環境變數並從與您的工具檔案相同的目錄執行腳本。
在執行腳本之前,在您的 IDE 或編輯器中開啟您的工具檔案(utils.py 或 utils.ts)。您會看到檔案在代理新增文件註解時即時更新,然後在您選擇回溯時恢復到原始狀態。
您會看到代理新增文件註解,然後出現提示詢問您是否要回溯。如果您選擇是,檔案會還原到原始狀態。
檔案檢查點有以下限制:
| 限制 | 說明 |
|---|---|
| 僅限 Write/Edit/NotebookEdit 工具 | 透過 Bash 命令所做的變更不會被追蹤 |
| 同一工作階段 | 檢查點與建立它們的工作階段綁定 |
| 僅限檔案內容 | 建立、移動或刪除目錄不會被回溯復原 |
| 本機檔案 | 遠端或網路檔案不會被追蹤 |
如果 enableFileCheckpointing 或 rewindFiles() 不可用,您可能使用的是較舊的 SDK 版本。
解決方案:更新到最新的 SDK 版本:
pip install --upgrade claude-agent-sdknpm install @anthropic-ai/claude-agent-sdk@latest如果 message.uuid 是 undefined 或缺失,表示您沒有收到檢查點 UUID。
原因:未設定 replay-user-messages 選項。
解決方案:在您的選項中新增 extra_args={"replay-user-messages": None}(Python)或 extraArgs: { 'replay-user-messages': null }(TypeScript)。
當指定的使用者訊息 UUID 不存在檢查點資料時,會發生此錯誤。
常見原因:
CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING 環境變數解決方案:確保您已設定環境變數(請參閱設定環境變數),然後使用範例中顯示的模式:擷取第一個使用者訊息 UUID,完整完成工作階段,然後以空提示恢復並呼叫 rewindFiles() 一次。
當您在完成回應迭代後呼叫 rewindFiles() 或 rewind_files() 時,會發生此錯誤。當迴圈完成時,與 CLI 程序的連線會關閉。
解決方案:以空提示恢復工作階段,然後在新的查詢上呼叫回溯:
# 以空提示恢復工作階段,然後回溯
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)
breakquery() 的所有選項和 rewindFiles() 方法。ClaudeAgentOptions 的所有選項和 rewind_files() 方法。Was this page helpful?