Loading...
    • 开发者指南
    • API 参考
    • MCP
    • 资源
    • 更新日志
    Search...
    ⌘K
    入门
    Claude 简介快速开始
    模型与定价
    模型概览选择模型Claude 4.6 新特性迁移指南模型弃用定价
    使用 Claude 构建
    功能概览使用 Messages API处理停止原因提示词最佳实践
    上下文管理
    上下文窗口压缩上下文编辑
    能力
    提示缓存扩展思考自适应思考推理力度流式消息批量处理引用多语言支持Token 计数嵌入视觉PDF 支持Files API搜索结果结构化输出
    工具
    概览如何实现工具使用细粒度工具流式传输Bash 工具代码执行工具程序化工具调用计算机使用工具文本编辑器工具网页抓取工具网页搜索工具记忆工具工具搜索工具
    Agent Skills
    概览快速开始最佳实践企业级 Skills通过 API 使用 Skills
    Agent SDK
    概览快速开始TypeScript SDKTypeScript V2(预览版)Python SDK迁移指南
    流式输入实时流式响应处理停止原因处理权限用户审批与输入使用钩子控制执行会话管理文件检查点SDK 中的结构化输出托管 Agent SDK安全部署 AI 智能体修改系统提示词SDK 中的 MCP自定义工具SDK 中的子智能体SDK 中的斜杠命令SDK 中的 Agent Skills跟踪成本与用量待办事项列表SDK 中的插件
    API 中的 MCP
    MCP 连接器远程 MCP 服务器
    第三方平台上的 Claude
    Amazon BedrockMicrosoft FoundryVertex AI
    提示工程
    概览提示词生成器使用提示词模板提示词优化器清晰直接使用示例(多样本提示)让 Claude 思考(思维链)使用 XML 标签赋予 Claude 角色(系统提示词)链式复杂提示长上下文技巧扩展思考技巧
    测试与评估
    定义成功标准开发测试用例使用评估工具降低延迟
    加强安全护栏
    减少幻觉提高输出一致性防范越狱攻击流式拒绝减少提示词泄露保持 Claude 角色设定
    管理与监控
    Admin API 概览数据驻留工作空间用量与成本 APIClaude Code Analytics API零数据留存
    Console
    Log in
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    指南

    使用检查点回退文件更改

    在代理会话期间跟踪文件更改并将文件恢复到任何先前状态

    文件检查点功能会跟踪代理会话期间通过 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())
    1. 1

      设置环境变量

      文件检查点功能需要 CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING 环境变量。您可以在运行脚本之前通过命令行设置它,也可以直接在 SDK 选项中设置。

      选项 1:通过命令行设置

      Python
      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"}
      )
    2. 2

      启用检查点

      配置您的 SDK 选项以启用检查点并接收检查点 UUID:

      选项PythonTypeScript描述
      启用检查点enable_file_checkpointing=TrueenableFileCheckpointing: true跟踪文件更改以便回退
      接收检查点 UUIDextra_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")
    3. 3

      捕获检查点 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
    4. 4

      回退文件

      要在流完成后回退,请使用空提示恢复会话,然后使用您的检查点 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。

    1. 1

      创建测试文件

      创建一个名为 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
    2. 2

      运行交互式示例

      在与工具文件相同的目录中创建一个名为 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())

      此示例演示了完整的检查点工作流程:

      1. 启用检查点:使用 enable_file_checkpointing=True 和 permission_mode="acceptEdits" 配置 SDK 以自动批准文件编辑
      2. 捕获检查点数据:在代理运行时,存储第一条用户消息 UUID(您的恢复点)和会话 ID
      3. 提示回退:代理完成后,检查您的工具文件以查看文档注释,然后决定是否要撤销更改
      4. 恢复并回退:如果是,使用空提示恢复会话并调用 rewind_files() 来恢复原始文件
    3. 3

      运行示例

      设置环境变量并从与工具文件相同的目录运行脚本。

      在运行脚本之前,在 IDE 或编辑器中打开您的工具文件(utils.py 或 utils.ts)。您将看到文件在代理添加文档注释时实时更新,然后在您选择回退时恢复到原始状态。

      您将看到代理添加文档注释,然后出现提示询问您是否要回退。如果您选择是,文件将恢复到原始状态。

    限制

    文件检查点功能有以下限制:

    限制描述
    仅限 Write/Edit/NotebookEdit 工具通过 Bash 命令所做的更改不会被跟踪
    同一会话检查点与创建它们的会话绑定
    仅限文件内容创建、移动或删除目录不会通过回退撤销
    本地文件远程或网络文件不会被跟踪

    故障排除

    检查点选项未被识别

    如果 enableFileCheckpointing 或 rewindFiles() 不可用,您可能使用的是较旧的 SDK 版本。

    解决方案:更新到最新的 SDK 版本:

    • Python:pip install --upgrade claude-agent-sdk
    • TypeScript:npm install @anthropic-ai/claude-agent-sdk@latest

    用户消息没有 UUID

    如果 message.uuid 为 undefined 或缺失,说明您没有接收到检查点 UUID。

    原因:未设置 replay-user-messages 选项。

    解决方案:在选项中添加 extra_args={"replay-user-messages": None}(Python)或 extraArgs: { 'replay-user-messages': null }(TypeScript)。

    "No file checkpoint found for message" 错误

    当指定的用户消息 UUID 不存在检查点数据时,会出现此错误。

    常见原因:

    • 未设置 CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING 环境变量
    • 在尝试恢复和回退之前,会话未正确完成

    解决方案:确保您已设置环境变量(参见设置环境变量),然后使用示例中展示的模式:捕获第一条用户消息 UUID,完全完成会话,然后使用空提示恢复并调用一次 rewindFiles()。

    "ProcessTransport is not ready for writing" 错误

    当您在完成响应迭代后调用 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)
            break

    后续步骤

    • 会话:了解如何恢复会话,这是在流完成后进行回退所必需的。涵盖会话 ID、恢复对话和会话分叉。
    • 权限:配置 Claude 可以使用哪些工具以及如何批准文件修改。如果您想更好地控制编辑何时发生,这很有用。
    • TypeScript SDK 参考:完整的 API 参考,包括 query() 的所有选项和 rewindFiles() 方法。
    • Python SDK 参考:完整的 API 参考,包括 ClaudeAgentOptions 的所有选项和 rewind_files() 方法。

    Was this page helpful?

    • 用户消息没有 UUID
    • "No file checkpoint found for message" 错误
    • "ProcessTransport is not ready for writing" 错误