파일 체크포인팅은 에이전트 세션 중 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"}
)체크포인팅 활성화
체크포인팅을 활성화하고 체크포인트 UUID를 수신하도록 SDK 옵션을 구성합니다:
| 옵션 | 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)를 캡처합니다. 이 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@latestmessage.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() 메서드를 포함한 전체 API 참조입니다.ClaudeAgentOptions의 모든 옵션과 rewind_files() 메서드를 포함한 전체 API 참조입니다.Was this page helpful?