Skip to content
LangSmith 文档版本 跟随上游 源快照 96e1283c 更新于 2026-10-18

如何取消运行

通过 API 取消单个运行或多个运行,并在中断和回滚操作之间进行选择。

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

设置

创建客户端和线程:

python
from langgraph_sdk import get_client

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

取消单个运行

以下示例创建一个运行,用不同的选项取消它,并打印该运行以展示每种情况下的结果。你可以取消处于 pending 或 running 状态的运行。尝试取消不处于 pending 或 running 状态的运行会导致错误。

使用中断取消(默认)

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

  • 运行记录仍然保留(状态为 interrupted)。你可以获取它、检查输入/输出,并查看执行历史。
  • 该运行的所有检查点仍然保留。最后一个已完成步骤处的线程状态会被保留。
  • 你稍后可以从检查点恢复(例如使用时间旅行),或检查部分状态。

当你想要停止运行但为了调试、审计或从检查点恢复而保留它时,请使用中断。

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"

使用回滚取消

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

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

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

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")

使用等待取消

默认情况下,取消请求在请求取消后即返回,运行会异步取消。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"

取消多个运行

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

按线程 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"

按状态取消

取消某个部署中所有线程里匹配某一状态的所有运行。有效的状态选项有 pending、running 或 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

断开连接时取消

在使用流式传输启动运行或在等待运行时,你可以设置 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)

常见场景

  • 人在回路与中断:智能体可以在中断处暂停以等待人工输入。取消运行会停止执行;这与中断不同,中断会暂停运行并可以用新输入恢复。
  • 时间旅行:使用操作 interrupt 取消后,运行和检查点仍然可用。你可以从检查点恢复(时间旅行),以重放或分叉执行。
  • 双重输入(Double-texting):当运行正在进行时用户发送新输入,多任务策略(enqueue、reject、interrupt、rollback)会决定现有运行是被中断还是回滚,以及如何处理新运行。如需从你的应用程序中显式取消运行,请使用本页所述的取消 API。
  • Studio:在 Studio 中,使用运行 UI 中的 Cancel 按钮取消当前运行。

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。