跳到内容

函数式 API

entrypoint

使用 entrypoint 装饰器定义 LangGraph 工作流。

函数签名

被装饰的函数必须接受一个单一参数,该参数用作函数的输入。此输入参数可以是任何类型。使用字典向函数传递多个参数

可注入参数

被装饰的函数可以请求访问将在运行时自动注入的其他参数。这些参数包括

参数 描述
store BaseStore 的实例。用于长期记忆。
writer 用于将自定义数据写入流的 StreamWriter 实例。
config 配置对象(又名 RunnableConfig),其中包含运行时配置值。
previous 给定线程的先前返回值(仅当提供检查点程序时可用)。

entrypoint 装饰器可以应用于同步函数或异步函数。

状态管理

previous 参数可用于访问同一线程 ID 上 entrypoint 先前调用的返回值。仅当提供检查点程序时,此值才可用。

如果您希望 previous 与返回值不同,则可以使用 entrypoint.final 对象返回值,同时将不同的值保存到检查点。

参数

  • checkpointer (Optional[BaseCheckpointSaver], 默认值: None ) –

    指定检查点程序以创建可以跨运行持久化其状态的工作流。

  • store (Optional[BaseStore], 默认值: None ) –

    通用的键值存储。某些实现可能通过可选的 index 配置支持语义搜索功能。

  • config_schema (Optional[type[Any]], 默认值: None ) –

    指定将传递给工作流的配置对象的模式。

使用 entrypoint 和任务
import time

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

@task
def compose_essay(topic: str) -> str:
    time.sleep(1.0)  # Simulate slow operation
    return f"An essay about {topic}"

@entrypoint(checkpointer=MemorySaver())
def review_workflow(topic: str) -> dict:
    """Manages the workflow for generating and reviewing an essay.

    The workflow includes:
    1. Generating an essay about the given topic.
    2. Interrupting the workflow for human review of the generated essay.

    Upon resuming the workflow, compose_essay task will not be re-executed
    as its result is cached by the checkpointer.

    Args:
        topic (str): The subject of the essay.

    Returns:
        dict: A dictionary containing the generated essay and the human review.
    """
    essay_future = compose_essay(topic)
    essay = essay_future.result()
    human_review = interrupt({
        "question": "Please provide a review",
        "essay": essay
    })
    return {
        "essay": essay,
        "review": human_review,
    }

# Example configuration for the workflow
config = {
    "configurable": {
        "thread_id": "some_thread"
    }
}

# Topic for the essay
topic = "cats"

# Stream the workflow to generate the essay and await human review
for result in review_workflow.stream(topic, config):
    print(result)

# Example human review provided after the interrupt
human_review = "This essay is great."

# Resume the workflow with the provided human review
for result in review_workflow.stream(Command(resume=human_review), config):
    print(result)
访问先前的返回值

启用检查点程序后,函数可以访问同一线程 ID 上先前调用的先前返回值。

from langgraph.checkpoint.memory import MemorySaver
from langgraph.func import entrypoint

@entrypoint(checkpointer=MemorySaver())
def my_workflow(input_data: str, previous: Optional[str] = None) -> str:
    return "world"

config = {
    "configurable": {
        "thread_id": "some_thread"
    }
}
my_workflow.invoke("hello")
使用 entrypoint.final 保存值

entrypoint.final 对象允许您返回值,同时将不同的值保存到检查点。只要使用相同的线程 ID,此值将在下次调用 entrypoint 时通过 previous 参数访问。

from langgraph.checkpoint.memory import MemorySaver
from langgraph.func import entrypoint

@entrypoint(checkpointer=MemorySaver())
def my_workflow(number: int, *, previous: Any = None) -> entrypoint.final[int, int]:
    previous = previous or 0
    # This will return the previous value to the caller, saving
    # 2 * number to the checkpoint, which will be used in the next invocation
    # for the `previous` parameter.
    return entrypoint.final(value=previous, save=2 * number)

config = {
    "configurable": {
        "thread_id": "some_thread"
    }
}

my_workflow.invoke(3, config)  # 0 (previous was None)
my_workflow.invoke(1, config)  # 6 (previous was 3 * 2 from the previous invocation)

final dataclass

基类: Generic[R, S]

可以从 entrypoint 返回的原语。

此原语允许将值保存到检查点程序,这与 entrypoint 的返回值不同。

解耦返回值和保存值
from langgraph.checkpoint.memory import MemorySaver
from langgraph.func import entrypoint

@entrypoint(checkpointer=MemorySaver())
def my_workflow(number: int, *, previous: Any = None) -> entrypoint.final[int, int]:
    previous = previous or 0
    # This will return the previous value to the caller, saving
    # 2 * number to the checkpoint, which will be used in the next invocation
    # for the `previous` parameter.
    return entrypoint.final(value=previous, save=2 * number)

config = {
    "configurable": {
        "thread_id": "1"
    }
}

my_workflow.invoke(3, config)  # 0 (previous was None)
my_workflow.invoke(1, config)  # 6 (previous was 3 * 2 from the previous invocation)

value: R instance-attribute

要返回的值。即使值为 None,也将始终返回值。

save: S instance-attribute

下一个检查点的状态值。

即使值为 None,也将始终保存值。

__init__(checkpointer: Optional[BaseCheckpointSaver] = None, store: Optional[BaseStore] = None, config_schema: Optional[type[Any]] = None) -> None

初始化 entrypoint 装饰器。

__call__(func: Callable[..., Any]) -> Pregel

将函数转换为 Pregel 图。

参数

  • func (Callable[..., Any]) –

    要转换的函数。支持同步和异步函数。

返回值

  • Pregel

    Pregel 图。

task(__func_or_none__: Optional[Union[Callable[P, Awaitable[T]], Callable[P, T]]] = None, *, name: Optional[str] = None, retry: Optional[RetryPolicy] = None) -> Union[Callable[[Union[Callable[P, Awaitable[T]], Callable[P, T]]], Callable[P, SyncAsyncFuture[T]]], Callable[P, SyncAsyncFuture[T]]]

使用 task 装饰器定义 LangGraph 任务。

异步函数需要 Python 3.11 或更高版本

task 装饰器同时支持同步和异步函数。要使用异步函数,请确保您使用的是 Python 3.11 或更高版本。

任务只能从 entrypoint 或 StateGraph 中调用。可以像调用常规函数一样调用任务,但有以下区别

  • 启用检查点程序后,函数输入和输出必须是可序列化的。
  • 只能从 entrypoint 或 StateGraph 中调用被装饰的函数。
  • 调用该函数会产生一个 future。这使得并行化任务变得容易。

参数

  • retry (Optional[RetryPolicy], 默认值: None ) –

    用于任务失败时的可选重试策略。

返回值

  • Union[Callable[[Union[Callable[P, Awaitable[T]], Callable[P, T]]], Callable[P, SyncAsyncFuture[T]]], Callable[P, SyncAsyncFuture[T]]]

    用作装饰器时的可调用函数。

同步任务
from langgraph.func import entrypoint, task

@task
def add_one(a: int) -> int:
    return a + 1

@entrypoint()
def add_one(numbers: list[int]) -> list[int]:
    futures = [add_one(n) for n in numbers]
    results = [f.result() for f in futures]
    return results

# Call the entrypoint
add_one.invoke([1, 2, 3])  # Returns [2, 3, 4]
异步任务
import asyncio
from langgraph.func import entrypoint, task

@task
async def add_one(a: int) -> int:
    return a + 1

@entrypoint()
async def add_one(numbers: list[int]) -> list[int]:
    futures = [add_one(n) for n in numbers]
    return asyncio.gather(*futures)

# Call the entrypoint
await add_one.ainvoke([1, 2, 3])  # Returns [2, 3, 4]

评论