if 语句、for 循环和函数调用)进行分支和控制流的现有代码中。与许多需要将代码重构为显式管道或 DAG 的数据编排框架不同,功能 API 允许您在不强制执行严格执行模型的情况下整合这些能力。
功能 API 使用两个关键构建块:
@entrypoint:将函数标记为工作流的起点,封装逻辑并管理执行流程,包括处理长时间运行的任务和中断。@task:表示一个离散的工作单元,例如 API 调用或数据处理步骤,可以在入口点内异步执行。任务返回一个类似 future 的对象,可以被等待或同步解析。
功能 API 与图 API
对于更喜欢声明式方法的用户,LangGraph 的图 API 允许您使用图范式定义工作流。两种 API 共享相同的底层运行时,因此您可以在同一应用程序中结合使用它们。 以下是一些关键区别:- 控制流:功能 API 不需要考虑图结构。您可以使用标准 Python 构造来定义工作流。这通常会减少您需要编写的代码量。
- 短期记忆:图 API 需要声明一个状态,并且可能需要定义归约器来管理图状态的更新。
@entrypoint和@task不需要显式的状态管理,因为它们的状态作用域限于函数内部,不会在函数间共享。 - 检查点机制:两种 API 都会生成和使用检查点。在图 API 中,每个超级步骤后都会生成一个新的检查点。在功能 API 中,当任务执行时,其结果会保存到与给定入口点关联的现有检查点中,而不是创建新的检查点。
- 可视化:图 API 可以轻松地将工作流可视化为图,这对于调试、理解工作流以及与他人共享非常有用。功能 API 不支持可视化,因为图是在运行时动态生成的。
示例
下面我们演示一个简单的应用程序,它撰写一篇文章并中断以请求人工审核。详细说明
详细说明
此工作流将撰写一篇关于主题“猫”的文章,然后暂停以获取人工审核。工作流可以中断任意长的时间,直到提供审核。当工作流恢复时,它会从最开始执行,但由于 一篇文章已经写好,准备接受审核。一旦提供审核,我们就可以恢复工作流:工作流已完成,审核已添加到文章中。
writeEssay 任务的结果已经保存,任务结果将从检查点加载,而不是重新计算。入口点
@entrypoint 装饰器可用于从函数创建工作流。它封装工作流逻辑并管理执行流程,包括处理 长时间运行的任务 和中断。
定义
入口点通过使用@entrypoint 装饰器装饰函数来定义。
该函数必须接受一个位置参数,作为工作流的输入。如果需要传递多条数据,请使用字典作为第一个参数的输入类型。
使用 entrypoint 装饰函数会生成一个 Pregel 实例,该实例有助于管理工作流的执行(例如,处理流式传输、恢复和检查点机制)。
您通常需要向 @entrypoint 装饰器传递一个 checkpointer,以启用持久化并使用人机协作等功能。
- 同步
- 异步
可注入参数
声明entrypoint 时,您可以请求访问在运行时自动注入的额外参数。这些参数包括:
请求可注入参数
请求可注入参数
执行
使用@entrypoint 会生成一个 Pregel 对象,可以使用 invoke、ainvoke、stream 和 astream 方法执行。
- 调用
- 异步调用
- 流式处理
- 异步流式处理
恢复
在中断后恢复执行,可以通过向Command 原语传递一个 resume 值来完成。
- 调用
- 异步调用
- 流式处理
- 异步流式处理
None 和相同的 thread id (config) 运行 entrypoint。
这假设底层的错误已解决,执行可以成功继续。
- 调用
- 异步调用
- 流式处理
- 异步流式处理
短期记忆
当使用checkpointer 定义 entrypoint 时,它会在同一 thread id 的连续调用之间,在检查点中存储信息。
这允许使用 previous 参数访问上一次调用的状态。
默认情况下,previous 参数是上一次调用的返回值。
entrypoint.final
entrypoint.final 是一个特殊的原语,可以从入口点返回,并允许将保存在检查点中的值与入口点的返回值解耦。
第一个值是入口点的返回值,第二个值是将保存在检查点中的值。类型注解为 entrypoint.final[return_type, save_type]。
任务
任务表示一个离散的工作单元,例如 API 调用或数据处理步骤。它有两个关键特征:- 异步执行:任务设计为异步执行,允许多个操作并发运行而不阻塞。
- 检查点机制:任务结果保存到检查点,从而可以从最后保存的状态恢复工作流。(更多详情请参阅持久化)。
定义
任务使用@task 装饰器定义,该装饰器包装一个普通的 Python 函数。
执行
任务只能从入口点、另一个任务或状态图节点内部调用。 任务_不能_直接从主应用程序代码调用。 当您调用一个任务时,它会_立即_返回一个 future 对象。Future 是一个占位符,代表稍后可用的结果。 要获取任务的结果,您可以同步等待(使用result())或异步等待(使用 await)。
- 同步调用
- 异步调用
何时使用任务
任务在以下场景中很有用:- 检查点机制:当您需要将长时间运行的操作结果保存到检查点时,这样在恢复工作流时就不需要重新计算它。
- 人机协作:如果您正在构建需要人工干预的工作流,您必须使用任务来封装任何随机性(例如,API 调用),以确保工作流可以正确恢复。更多详情请参阅确定性部分。
- 并行执行:对于 I/O 密集型任务,任务支持并行执行,允许多个操作并发运行而不阻塞(例如,调用多个 API)。
- 可观测性:将操作包装在任务中提供了一种使用 LangSmith 跟踪工作流进度和监控单个操作执行的方式。
- 可重试工作:当工作需要重试以处理失败或不一致时,任务提供了一种封装和管理重试逻辑的方式。
序列化
LangGraph 中的序列化有两个关键方面:entrypoint的输入和输出必须是 JSON 可序列化的。task的输出必须是 JSON 可序列化的。
确定性
要利用人机协作等功能,任何随机性都应封装在任务内部。这保证了当执行暂停(例如,为了人机协作)然后恢复时,它将遵循相同的_步骤序列_,即使任务结果是非确定性的。 LangGraph 通过在执行过程中持久化任务和子图结果来实现此行为。精心设计的工作流确保恢复执行遵循_相同的步骤序列_,从而可以正确检索先前计算的结果,而无需重新执行它们。这对于长时间运行的任务或具有非确定性结果的任务特别有用,因为它避免了重复先前完成的工作,并允许从本质上相同的状态恢复。 虽然工作流的不同运行可能产生不同的结果,但恢复特定运行应始终遵循相同的已记录步骤序列。这使得 LangGraph 可以高效地查找在图中断之前执行的任务和子图结果,并避免重新计算它们。幂等性
幂等性确保多次运行相同操作会产生相同的结果。这有助于防止因步骤重新运行(例如,由于失败)而导致的重复 API 调用和冗余处理。始终将 API 调用放在任务函数内以进行检查点机制,并设计它们在重新执行时是幂等的。如果任务开始但未成功完成,则可能发生重新执行。然后,如果工作流恢复,任务将再次运行。使用幂等键或验证现有结果以避免重复。常见陷阱
处理副作用
将副作用(例如,写入文件、发送电子邮件)封装在任务中,以确保在恢复工作流时不会多次执行它们。- 错误
- 正确
在此示例中,副作用(写入文件)直接包含在工作流中,因此在恢复工作流时将第二次执行。
非确定性控制流
每次可能产生不同结果的操作(如获取当前时间或随机数)应封装在任务中,以确保在恢复时返回相同的结果。- 在任务中:获取随机数 (5) → 中断 → 恢复 → (再次返回 5) → …
- 不在任务中:获取随机数 (5) → 中断 → 恢复 → 获取新的随机数 (7) → …
interrupt 调用可能会与错误的 resume 值匹配,导致结果不正确。
请阅读确定性部分以获取更多详情。
- 错误
- 正确
在此示例中,工作流使用当前时间来确定执行哪个任务。这是非确定性的,因为工作流的结果取决于其执行的时间。
了解更多
将这些文档连接到 Claude、VSCode 等,通过 MCP 获取实时答案。

