以编程方式使用文档

本指南介绍如何通过 LangSmith Deployment API取消您的智能体的运行。您可以通过 ID 取消单个运行,或按线程或状态取消多个运行。取消操作可用于停止长时间运行或卡住的运行,或在用户放弃请求时使用。

设置

创建客户端和线程:

Python

    from langgraph_sdk import get_client

    client = get_client(url=)
    assistant_id = "agent"
    thread = await client.threads.create()
    

Javascript

    const client = new Client({ apiUrl:  });
    const assistantID = "agent";
    const thread = await client.threads.create();
    

CURL

    curl --request POST \
      --url /threads \
      --header 'Content-Type: application/json' \
      --data '{}'
    

取消单个运行

以下示例创建一个运行,使用不同选项取消它,并打印运行结果以显示每种情况下获得的内容。您可以取消 pending or running 状态的运行。尝试取消不在 pending or running 状态的运行将导致错误。

使用中断取消(默认)

中断 停止执行运行的 worker,并将运行标记为 interrupted。不会删除任何内容:

  • - 运行记录保留(状态为 interrupted). You can fetch it, inspect inputs/outputs, and see the execution history.
  • - 该运行的所有检查点仍然存储。最后完成的步骤的线程状态被保留。
  • - 您稍后可以从检查点恢复(例如,使用 时间旅行)或检查部分状态。

使用 **中断** 当您想停止运行但希望保留它用于调试、审计或从检查点恢复时。

Python

    run = await client.runs.create(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "Long task"}]},
    )
    await client.runs.cancel(thread["thread_id"], run["run_id"])

    run_after = await client.runs.get(thread["thread_id"], run["run_id"], wait=True)
    print(run_after["status"])   # "interrupted"
    

Javascript

    const run = await client.runs.create(
        thread["thread_id"],
        assistantID,
        { input: { messages: [{ role: "user", content: "Long task" }] } }
    );
    await client.runs.cancel(thread["thread_id"], run["run_id"], wait=true);

    const runAfter = await client.runs.get(thread["thread_id"], run["run_id"]);
    console.log(runAfter["status"]);   // "interrupted"
    

CURL

    # Create a run (use the run_id and thread_id from the response)
    curl --request POST \
      --url /threads//runs \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "Summarize the docs"}]}}'

    # Cancel with default action (interrupt)
    curl --request POST \
      --url /threads//runs//cancel?wait=true

    # Get the run to see status "interrupted" and that the run still exists
    curl --request GET \
      --url /threads//runs/
    

使用回滚取消

回滚 停止运行,然后从存储中删除它及其检查点:

  • - 运行记录被删除。该运行不再出现在该线程的运行列表或历史记录中。
  • - 该运行创建的所有检查点都被删除。线程的状态回滚到运行开始之前的状态(就好像运行从未被执行过)。
  • - 回滚后您无法恢复或检查该运行。

使用 **回滚** 当您想完全丢弃一个运行及其效果时(例如,在用户放弃请求且不需要保留部分工作时)。

Python

    run = await client.runs.create(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "Long task"}]},
    )
    await client.runs.cancel(thread["thread_id"], run["run_id"], action="rollback", wait=True)

    # Throws an error because the run is deleted
    try:
        await client.runs.get(thread["thread_id"], run["run_id"])
    except Exception:
        print("Run was correctly deleted")
    

Javascript

    const run = await client.runs.create(
        thread["thread_id"],
        assistantID,
        { input: { messages: [{ role: "user", content: "Long task" }] } }
    );
    await client.runs.cancel(thread["thread_id"], run["run_id"], wait=true, action="rollback");

    // Throws an error because the run is deleted
    try {
        await client.runs.get(thread["thread_id"], run["run_id"]);
    } catch (e) {
        console.log("Run was correctly deleted");
    }
    

CURL

    # Create a run, then cancel with rollback
    curl --request POST \
      --url /threads//runs \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "Summarize the docs"}]}}'

    curl --request POST \
      --url "/threads//runs//cancel?action=rollback"

    # Throws an error because the run is deleted
    curl --request GET \
      --url /threads//runs/
    

使用等待取消

默认情况下,取消请求在请求取消后返回,运行被异步取消。 wait=True 使取消请求阻塞,直到运行完全取消。当您想知道取消后运行的最终状态时这很有用(例如,创建了哪些检查点,最终输出是什么)。

Python

    run = await client.runs.create(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "Long task"}]},
    )
    # Cancel the run asynchronously
    await client.runs.cancel(thread["thread_id"], run["run_id"])
    # Get the status of the run
    run_after = await client.runs.get(thread["thread_id"], run["run_id"])
    print(run_after["status"])  # "pending" or "running"

    # Wait for the run to be properly cancelled
    await client.runs.join(thread["thread_id"], run["run_id"])
    run_after = await client.runs.get(thread["thread_id"], run["run_id"])
    print(run_after["status"])  # "interrupted"
    

Javascript

    const run = await client.runs.create(
        thread["thread_id"],
        assistantID,
        { input: { messages: [{ role: "user", content: "Long task" }] } }
    );
    // Cancel the run asynchronously
    await client.runs.cancel(thread["thread_id"], run["run_id"]);
    // Get the status of the run
    const runRunning = await client.runs.get(thread["thread_id"], run["run_id"])
    console.log(runRunning["status"])  // "pending" or "running"

    // Wait for the run to be properly cancelled
    await client.runs.join(thread["thread_id"], run["run_id"])
    const runInterrupted = await client.runs.get(thread["thread_id"], run["run_id"])
    console.log(runInterrupted["status"])  // "interrupted"
    

CURL

    # Create a run
    curl --request POST \
      --url /threads//runs \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "Summarize the docs"}]}}'

    # Cancel the run asynchronously
    curl --request POST \
      --url "/threads//runs//cancel"

    # Get the status of the run, should be "pending" or "running" until cancellation completes, then "interrupted"
    curl --request GET \
      --url /threads//runs/
    

取消多个运行

使用批量取消端点在一个请求中取消多个运行。支持中断和回滚两种操作。

按线程 ID 和运行 ID 取消

通过传递 ID 取消特定的运行。

Python

    run1 = await client.runs.create(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "First request"}]},
    )
    run2 = await client.runs.create(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "Second request"}]},
        multitask_strategy="enqueue",
    )

    await client.runs.cancel_many(
        thread_id=thread["thread_id"],
        run_ids=[run1["run_id"], run2["run_id"]]
    )

    # Wait for the runs to be cancelled
    await client.runs.join(thread["thread_id"], run2["run_id"])
    runs_after = await client.runs.list(thread["thread_id"])
    for run in runs_after:
        if run["run_id"] in (run1["run_id"], run2["run_id"]):
            print(run["run_id"], run["status"])  # "interrupted"
    

Javascript

    // Bulk delete by run IDs is not supported in the Javascript SDK
    

CURL

    # Create two runs (capture run_id from each response)
    curl --request POST \
      --url /threads//runs \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "First request"}]}}'

    curl --request POST \
      --url /threads//runs \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "Second request"}]}}'

    # Cancel both by run IDs
    curl --request POST \
      --url "/runs/cancel?action=interrupt" \
      --header 'Content-Type: application/json' \
      --data '{"thread_id": "", "run_ids": ["", ""]}'

    # List runs to confirm
    curl --request GET \
      --url /threads//runs
    

按状态取消

取消部署中所有线程中匹配特定状态的所有运行。有效的状态选项为 pending, running, or all.

Python

    run1 = await client.runs.create(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "First request"}]},
    )
    thread2 = await client.threads.create()
    run2 = await client.runs.create(
        thread2["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "Second request"}]},
    )

    await client.runs.cancel_many(
        status="running",
    )

    # Wait for the runs to be cancelled
    await client.runs.join(thread2["thread_id"], run2["run_id"])
    run_after = await client.runs.get(thread["thread_id"], run1["run_id"])
    print(run_after["status"])  # running run is now "interrupted"
    run_after2 = await client.runs.get(thread2["thread_id"], run2["run_id"])
    print(run_after2["status"])  # runs are cancelled across all threads
    

Javascript

    // Bulk delete by status is not supported in the Javascript SDK
    

CURL

    # Create a run
    curl --request POST \
      --url /threads//runs \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "First request"}]}}'

    # Create a second thread
    curl --request POST \
      --url /threads \
      --header 'Content-Type: application/json' \
      --data '{}'

    # Create a run in the second thread
    curl --request POST \
      --url /threads//runs \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "Second request"}]}}'

    # Cancel all running runs
    curl --request POST \
      --url "/runs/cancel?action=interrupt" \
      --header 'Content-Type: application/json' \
      --data '{"status": "running"}'

    # Get the status of the runs to confirm
    curl --request GET \
      --url /threads//runs/
    curl --request GET \
      --url /threads//runs/
    

断开时取消

使用流式启动运行或等待运行时,您可以设置 on_disconnect="cancel" 以便在客户端断开连接时取消运行。这可以避免在用户关闭应用或失去连接时留下正在进行的运行。

Python

    # With runs.wait: run is cancelled if the client disconnects
    result = await client.runs.wait(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "Long task"}]},
        on_disconnect="cancel",
    )

    # With runs.stream: run is cancelled if the client disconnects
    async for chunk in client.runs.stream(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "Long task"}]},
        on_disconnect="cancel",
    ):
        print(chunk)

    # With runs.join: wait for an existing run; cancel if client disconnects
    run = await client.runs.create(
        thread["thread_id"],
        assistant_id,
        input={"messages": [{"role": "user", "content": "Long task"}]},
    )
    await client.runs.join(
        thread["thread_id"],
        run["run_id"],
        on_disconnect="cancel",
    )

    # With runs.join_stream: join an existing run and stream; cancel if client disconnects
    async for chunk in client.runs.join_stream(
        thread["thread_id"],
        run["run_id"],
        on_disconnect="cancel",
    ):
        print(chunk)
    

Javascript

    // With runs.wait: run is cancelled if the client disconnects
    const result = await client.runs.wait(
        thread["thread_id"],
        assistantID,
        { input: { messages: [{ role: "user", content: "Long task" }] }, onDisconnect: "cancel" }
    );

    // With runs.stream: run is cancelled if the client disconnects
    const streamResponse = client.runs.stream(
        thread["thread_id"],
        assistantID,
        { input: { messages: [{ role: "user", content: "Long task" }] }, onDisconnect: "cancel" }
    );
    for await (const chunk of streamResponse) {
        console.log(chunk);
    }

    // With runs.join does not support cancel on disconnect in the Javascript SDK

    // With runs.joinStream: join an existing run and stream; cancel if client disconnects
    const joinStreamResponse = client.runs.joinStream(
        thread["thread_id"],
        run["run_id"],
        { cancelOnDisconnect: true }
    );
    for await (const chunk of joinStreamResponse) {
        console.log(chunk);
    }
    

CURL

    # runs.wait: create run and wait for output; cancel if client disconnects
    curl --request POST \
      --url /threads//runs/wait \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "Long task"}]}, "on_disconnect": "cancel"}'

    # Create and stream a run; cancel if client disconnects
    curl --request POST \
      --url "/threads//runs/stream?on_disconnect=cancel" \
      --header 'Content-Type: application/json' \
      --data '{"assistant_id": "agent", "input": {"messages": [{"role": "user", "content": "Long task"}]}}'

    # runs.join: wait on an existing run; cancel if client disconnects
    curl --request GET \
      --url "/threads//runs//join?cancel_on_disconnect=cancel"

    # runs.join_stream: join an existing run and stream; cancel if client disconnects
    curl --request GET \
      --url "/threads//runs//stream?cancel_on_disconnect=cancel"
    

常见场景

  • 人机交互和中断:代理可以在 中断 处暂停以等待人工输入。取消运行会停止执行;这与中断不同,中断时运行处于暂停状态,可以在新输入后恢复。
  • 时间穿越:使用操作取消后, interrupt运行和检查点仍然可用。您可以 从检查点恢复 (时间穿越)来重放或分支执行。
  • Double-texting:当用户在运行进行中发送新输入时, 多任务策略 (入队、拒绝、中断、回滚)决定了现有运行是否被中断或回滚,以及如何处理新运行。如需从应用中显式取消运行,请使用本页描述的取消 API。
  • Studio: In Studio,请使用 **取消** 按钮来取消当前运行。