> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-zh.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用服务端API进行时间旅行

LangGraph 提供了 [**时间旅行**](/oss/python/langgraph/use-time-travel) 功能，可以从先前的检查点恢复执行，既可以重放相同的状态，也可以修改它以探索替代方案。在所有情况下，恢复过去的执行都会在历史中产生一个新的分支。

要通过 LangSmith 部署 API（通过 LangGraph SDK）进行时间旅行：

1. **运行图**：使用 [LangGraph SDK](/langsmith/langgraph-python-sdk) 的 [client.runs.wait](https://reference.langchain.com/python/langsmith/deployment/sdk/#langgraph_sdk.client.RunsClient.wait) 或 [client.runs.stream](https://reference.langchain.com/python/langsmith/deployment/sdk/#langgraph_sdk.client.RunsClient.stream) API 运行图并传入初始输入。
2. **在现有线程中识别检查点**：使用 [client.threads.get\_history](https://reference.langchain.com/python/langsmith/deployment/sdk/#langgraph_sdk.client.ThreadsClient.get_history) 方法检索特定 `thread_id` 的执行历史，并定位所需的 `checkpoint_id`。
   或者，在希望执行暂停的节点之前设置一个 [断点](/oss/python/langgraph/interrupts)。然后，您可以找到记录到该断点的最近检查点。
3. **（可选）修改图状态**：使用 [client.threads.update\_state](https://reference.langchain.com/python/langsmith/deployment/sdk/#langgraph_sdk.client.ThreadsClient.update_state) 方法修改图在检查点处的状态，并从替代状态恢复执行。
4. **从检查点恢复执行**：使用 [client.runs.wait](https://reference.langchain.com/python/langsmith/deployment/sdk/#langgraph_sdk.client.RunsClient.wait) 或 [client.runs.stream](https://reference.langchain.com/python/langsmith/deployment/sdk/#langgraph_sdk.client.RunsClient.stream) API，输入为 `None`，并指定相应的 `thread_id` 和 `checkpoint_id`。

## 在工作流中使用时间旅行

<Accordion title="示例图">
  ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  from typing_extensions import TypedDict, NotRequired
  from langgraph.graph import StateGraph, START, END
  from langchain.chat_models import init_chat_model
  from langgraph.checkpoint.memory import InMemorySaver

  class State(TypedDict):
      topic: NotRequired[str]
      joke: NotRequired[str]

  model = init_chat_model(
      "claude-sonnet-4-6",
      temperature=0,
  )

  def generate_topic(state: State):
      """LLM调用，为笑话生成一个主题"""
      msg = model.invoke("给我一个有趣的笑话主题")
      return {"topic": msg.content}

  def write_joke(state: State):
      """LLM调用，根据主题编写笑话"""
      msg = model.invoke(f"写一个关于 {state['topic']} 的短笑话")
      return {"joke": msg.content}

  # 构建工作流
  builder = StateGraph(State)

  # 添加节点
  builder.add_node("generate_topic", generate_topic)
  builder.add_node("write_joke", write_joke)

  # 添加边以连接节点
  builder.add_edge(START, "generate_topic")
  builder.add_edge("generate_topic", "write_joke")

  # 编译
  graph = builder.compile()
  ```
</Accordion>

### 1. 运行图

<Tabs>
  <Tab title="Python">
    ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    from langgraph_sdk import get_client
    client = get_client(url=<DEPLOYMENT_URL>)

    # 使用部署时命名为 "agent" 的图
    assistant_id = "agent"

    # 创建一个线程
    thread = await client.threads.create()
    thread_id = thread["thread_id"]

    # 运行图
    result = await client.runs.wait(
        thread_id,
        assistant_id,
        input={}
    )
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    import { Client } from "@langchain/langgraph-sdk";
    const client = new Client({ apiUrl: <DEPLOYMENT_URL> });

    // 使用部署时命名为 "agent" 的图
    const assistantID = "agent";

    # 创建一个线程
    const thread = await client.threads.create();
    const threadID = thread["thread_id"];

    // 运行图
    const result = await client.runs.wait(
      threadID,
      assistantID,
      { input: {}}
    );
    ```
  </Tab>

  <Tab title="cURL">
    创建线程：

    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request POST \
    --url <DEPLOYMENT_URL>/threads \
    --header 'Content-Type: application/json' \
    --data '{}'
    ```

    运行图：

    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request POST \
    --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/wait \
    --header 'Content-Type: application/json' \
    --data "{
      \"assistant_id\": \"agent\",
      \"input\": {}
    }"
    ```
  </Tab>
</Tabs>

### 2. 识别检查点

<Tabs>
  <Tab title="Python">
    ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    # 状态按时间倒序返回。
    states = await client.threads.get_history(thread_id)
    selected_state = states[1]
    print(selected_state)
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    // 状态按时间倒序返回。
    const states = await client.threads.getHistory(threadID);
    const selectedState = states[1];
    console.log(selectedState);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request GET \
    --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/history \
    --header 'Content-Type: application/json'
    ```
  </Tab>
</Tabs>

<a id="optional" />

### 3. 更新状态

[`update_state`](https://reference.langchain.com/python/langgraph/graphs/#langgraph.graph.state.CompiledStateGraph.update_state) 将创建一个新的检查点。新的检查点将与同一个线程关联，但会有一个新的检查点 ID。

<Tabs>
  <Tab title="Python">
    ```python {highlight={4}} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    new_config = await client.threads.update_state(
        thread_id,
        {"topic": "chickens"},
        checkpoint_id=selected_state["checkpoint_id"]
    )
    print(new_config)
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    const newConfig = await client.threads.updateState(
      threadID,
      {
        values: { "topic": "chickens" },
        checkpointId: selectedState["checkpoint_id"]
      }
    );
    console.log(newConfig);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request POST \
    --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state \
    --header 'Content-Type: application/json' \
    --data "{
      \"assistant_id\": \"agent\",
      \"checkpoint_id\": <CHECKPOINT_ID>,
      \"values\": {\"topic\": \"chickens\"}
    }"
    ```
  </Tab>
</Tabs>

### 4. 从检查点恢复执行

<Tabs>
  <Tab title="Python">
    ```python {highlight={4,5}} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    await client.runs.wait(
        thread_id,
        assistant_id,
        input=None,
        checkpoint_id=new_config["checkpoint_id"]
    )
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript {highlight={5,6}} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    await client.runs.wait(
      threadID,
      assistantID,
      {
        input: null,
        checkpointId: newConfig["checkpoint_id"]
      }
    );
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request POST \
    --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/wait \
    --header 'Content-Type: application/json' \
    --data "{
      \"assistant_id\": \"agent\",
      \"checkpoint_id\": <CHECKPOINT_ID>
    }"
    ```
  </Tab>
</Tabs>

## 了解更多

* [**LangGraph 时间旅行指南**](/oss/python/langgraph/use-time-travel)：了解更多关于在 LangGraph 中使用时间旅行的信息。

***

<div className="source-links">
  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/i18n\zh-CN\langsmith\human-in-the-loop-time-travel.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>

  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>
</div>
