跳转至

概述

函数式 API 允许您以最小的现有代码更改,将 LangGraph 的核心功能——持久化内存人工参与流式处理——添加到您的应用程序中。

它旨在将这些功能集成到现有代码中,这些代码可能使用标准的语言原语进行分支和控制流,例如 if 语句、for 循环和函数调用。与许多需要将代码重构为显式管道或 DAG 的数据编排框架不同,函数式 API 允许您在不强制执行严格执行模型的情况下整合这些功能。

函数式 API 使用两个关键构建块:

# Python 函数式 API 的关键构建块
# @entrypoint - 将函数标记为工作流的起点,封装逻辑并管理执行流程
# @task - 表示一个独立的工作单元,可以在入口点内异步执行
  • @entrypoint – 将函数标记为工作流的起点,封装逻辑并管理执行流程,包括处理长时间运行的任务和中断。
  • @task – 表示一个独立的工作单元,例如 API 调用或数据处理步骤,可以在入口点内异步执行。任务返回一个类似 future 的对象,可以被等待或同步解析。
// JavaScript 函数式 API 的关键构建块
// entrypoint - 入口点封装工作流逻辑并管理执行流程
// task - 表示一个独立的工作单元,可以在入口点内异步执行
  • entrypoint – 入口点封装工作流逻辑并管理执行流程,包括处理长时间运行的任务和中断。
  • task – 表示一个独立的工作单元,例如 API 调用或数据处理步骤,可以在入口点内异步执行。任务返回一个类似 future 的对象,可以被等待或同步解析。

这为构建具有状态管理和流式处理的工作流提供了最小化的抽象。

Tip

有关如何使用函数式 API 的信息,请参阅使用函数式 API

函数式 API 与图 API

对于更喜欢声明式方法的用户,LangGraph 的图 API 允许您使用图范式定义工作流。这两个 API 共享相同的底层运行时,因此您可以在同一应用程序中一起使用它们。

以下是一些关键区别:

  • 控制流:函数式 API 不需要考虑图结构。您可以使用标准的 Python 结构来定义工作流。这通常会减少您需要编写的代码量。
  • 短期内存图 API 需要声明一个状态,并且可能需要定义归约器来管理图状态的更新。@entrypoint@tasks 不需要显式的状态管理,因为它们的状态限定在函数范围内,不会在函数之间共享。
  • 检查点:两个 API 都生成和使用检查点。在**图 API**中,每个超级步骤后都会生成一个新的检查点。在**函数式 API**中,当任务执行时,它们的结果会被保存到与给定入口点关联的现有检查点中,而不是创建新的检查点。
  • 可视化:图 API 可以轻松地将工作流可视化为图形,这对于调试、理解工作流以及与他人分享很有用。函数式 API 不支持可视化,因为图是在运行时动态生成的。

示例

下面我们演示一个简单的应用程序,它会写一篇作文,并中断以请求人工审阅。

API Reference: InMemorySaver | entrypoint | task | interrupt

from langgraph.checkpoint.memory import InMemorySaver
from langgraph.func import entrypoint, task
from langgraph.types import interrupt

@task
def write_essay(topic: str) -> str:
    """Write an essay about the given topic."""
    time.sleep(1) # A placeholder for a long-running task.
    return f"An essay about topic: {topic}"

@entrypoint(checkpointer=InMemorySaver())
def workflow(topic: str) -> dict:
    """A simple workflow that writes an essay and asks for a review."""
    essay = write_essay("cat").result()
    is_approved = interrupt({
        # Any json-serializable payload provided to interrupt as argument.
        # It will be surfaced on the client side as an Interrupt when streaming data
        # from the workflow.
        "essay": essay, # The essay we want reviewed.
        # We can add any additional information that we need.
        # For example, introduce a key called "action" with some instructions.
        "action": "Please approve/reject the essay",
    })

    return {
        "essay": essay, # The essay that was generated
        "is_approved": is_approved, # Response from HIL
    }