图定义¶
基类: Generic[StateT, ContextT, InputT, OutputT]
一种图,其节点通过读取和写入共享状态进行通信。每个节点的签名为 State -> Partial
每个状态键都可以选择性地使用一个 reducer 函数进行注解,该函数将用于聚合从多个节点接收到的该键的值。reducer 函数的签名为 (Value, Value) -> Value。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| state_schema | type[StateT] | 定义状态的模式类。 | 必填 | 
| context_schema | type[ContextT] | None | 定义运行时上下文的模式类。使用此项向您的节点暴露不可变的上下文数据,如 user_id、db_conn 等。 | None | 
| input_schema | type[InputT] | None | 定义图输入的模式类。 | None | 
| output_schema | type[OutputT] | None | 定义图输出的模式类。 | None | 
config_schema 已弃用
config_schema 参数在 v0.6.0 版本中已弃用,并将在 v2.0.0 版本中移除支持。请改用 context_schema 来指定运行范围上下文的模式。
示例
from langchain_core.runnables import RunnableConfig
from typing_extensions import Annotated, TypedDict
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import StateGraph
from langgraph.runtime import Runtime
def reducer(a: list, b: int | None) -> list:
    if b is not None:
        return a + [b]
    return a
class State(TypedDict):
    x: Annotated[list, reducer]
class Context(TypedDict):
    r: float
graph = StateGraph(state_schema=State, context_schema=Context)
def node(state: State, runtime: Runtime[Context]) -> dict:
    r = runtie.context.get("r", 1.0)
    x = state["x"][-1]
    next_value = x * r * (1 - x)
    return {"x": next_value}
graph.add_node("A", node)
graph.set_entry_point("A")
graph.set_finish_point("A")
compiled = graph.compile()
step1 = compiled.invoke({"x": 0.5}, context={"r": 3.0})
# {'x': [0.5, 0.75]}
方法
| 名称 | 描述 | 
|---|---|
| add_node | 向状态图添加一个新节点。 | 
| add_edge | 从起始节点(或起始节点列表)向结束节点添加一条有向边。 | 
| add_conditional_edges | 从起始节点向任意数量的目标节点添加条件边。 | 
| add_sequence | 添加一个将按提供顺序执行的节点序列。 | 
| compile | 将状态图编译成一个  | 
add_node(
    node: str | StateNode[NodeInputT, ContextT],
    action: StateNode[NodeInputT, ContextT] | None = None,
    *,
    defer: bool = False,
    metadata: dict[str, Any] | None = None,
    input_schema: type[NodeInputT] | None = None,
    retry_policy: (
        RetryPolicy | Sequence[RetryPolicy] | None
    ) = None,
    cache_policy: CachePolicy | None = None,
    destinations: (
        dict[str, str] | tuple[str, ...] | None
    ) = None,
    **kwargs: Unpack[DeprecatedKwargs]
) -> Self
向状态图添加一个新节点。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| node | str | StateNode[NodeInputT, ContextT] | 此节点将运行的函数或可运行对象。如果提供的是字符串,它将被用作节点名称,而 action 将被用作函数或可运行对象。 | 必填 | 
| action | StateNode[NodeInputT, ContextT] | None | 与节点关联的操作。(默认值:None)如果  | None | 
| defer | bool | 是否将节点的执行推迟到运行即将结束时。 | False | 
| metadata | dict[str, Any] | None | 与节点关联的元数据。(默认值:None) | None | 
| input_schema | type[NodeInputT] | None | 节点的输入模式。(默认值:图的状态模式) | None | 
| retry_policy | RetryPolicy | Sequence[RetryPolicy] | None | 节点的重试策略。(默认值:None)如果提供了一个序列,将应用第一个匹配的策略。 | None | 
| cache_policy | CachePolicy | None | 节点的缓存策略。(默认值:None) | None | 
| destinations | dict[str, str] | tuple[str, ...] | None | 指示节点可以路由到的目标。这对于包含返回  | None | 
示例
from typing_extensions import TypedDict
from langchain_core.runnables import RunnableConfig
from langgraph.graph import START, StateGraph
class State(TypedDict):
    x: int
def my_node(state: State, config: RunnableConfig) -> State:
    return {"x": state["x"] + 1}
builder = StateGraph(State)
builder.add_node(my_node)  # node name will be 'my_node'
builder.add_edge(START, "my_node")
graph = builder.compile()
graph.invoke({"x": 1})
# {'x': 2}
自定义名称
返回
| 名称 | 类型 | 描述 | 
|---|---|---|
| Self | Self | 状态图的实例,允许方法链式调用。 | 
从起始节点(或起始节点列表)向结束节点添加一条有向边。
当提供单个起始节点时,图将等待该节点完成后再执行结束节点。当提供多个起始节点时,图将等待所有起始节点完成后再执行结束节点。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| start_key | str | list[str] | 边的起始节点的键。 | 必填 | 
| end_key | str | 边的结束节点的键。 | 必填 | 
抛出
| 类型 | 描述 | 
|---|---|
| ValueError | 如果起始键是 'END',或者如果起始键或结束键在图中不存在。 | 
返回
| 名称 | 类型 | 描述 | 
|---|---|---|
| Self | Self | 状态图的实例,允许方法链式调用。 | 
add_conditional_edges(
    source: str,
    path: (
        Callable[..., Hashable | list[Hashable]]
        | Callable[
            ..., Awaitable[Hashable | list[Hashable]]
        ]
        | Runnable[Any, Hashable | list[Hashable]]
    ),
    path_map: dict[Hashable, str] | list[str] | None = None,
) -> Self
从起始节点向任意数量的目标节点添加条件边。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| source | str | 起始节点。此条件边将在退出此节点时运行。 | 必填 | 
| path | Callable[..., Hashable | list[Hashable]] | Callable[..., Awaitable[Hashable | list[Hashable]]] | Runnable[Any, Hashable | list[Hashable]] | 确定下一个节点或节点的可调用对象。如果未指定  | 必填 | 
| path_map | dict[Hashable, str] | list[str] | None | 可选的路径到节点名称的映射。如果省略, | None | 
返回
| 名称 | 类型 | 描述 | 
|---|---|---|
| Self | Self | 图的实例,允许方法链式调用。 | 
如果没有在 path 函数的返回值上使用类型提示(例如,-> Literal["foo", "__end__"]:)
或一个 path_map,图的可视化会假设边可以转换到图中的任何节点。
add_sequence(
    nodes: Sequence[
        StateNode[NodeInputT, ContextT]
        | tuple[str, StateNode[NodeInputT, ContextT]]
    ],
) -> Self
添加一个将按提供顺序执行的节点序列。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| nodes | Sequence[StateNode[NodeInputT, ContextT] | tuple[str, StateNode[NodeInputT, ContextT]]] | 一个 StateNodes(接受一个状态参数的可调用对象)或 (名称, StateNode) 元组的序列。如果未提供名称,将从节点对象(例如,一个可运行对象或一个可调用对象的名称)推断名称。每个节点将按提供的顺序执行。 | 必填 | 
抛出
| 类型 | 描述 | 
|---|---|
| ValueError | 如果序列为空。 | 
| ValueError | 如果序列包含重复的节点名称。 | 
返回
| 名称 | 类型 | 描述 | 
|---|---|---|
| Self | Self | 状态图的实例,允许方法链式调用。 | 
compile(
    checkpointer: Checkpointer = None,
    *,
    cache: BaseCache | None = None,
    store: BaseStore | None = None,
    interrupt_before: All | list[str] | None = None,
    interrupt_after: All | list[str] | None = None,
    debug: bool = False,
    name: str | None = None
) -> CompiledStateGraph[StateT, ContextT, InputT, OutputT]
将状态图编译成一个 CompiledStateGraph 对象。
编译后的图实现了 Runnable 接口,可以被调用、流式传输、批处理和异步运行。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| checkpointer | Checkpointer | 一个检查点保存器对象或标志。如果提供,此 Checkpointer 将作为图的完全版本化的“短期记忆”,允许它从任何点暂停、恢复和重放。如果为 None,它在用作子图时可能会继承父图的检查点保存器。如果为 False,它将不使用或继承任何检查点保存器。 | None | 
| interrupt_before | All | list[str] | None | 一个可选的节点名称列表,在这些节点之前中断。 | None | 
| interrupt_after | All | list[str] | None | 一个可选的节点名称列表,在这些节点之后中断。 | None | 
| debug | bool | 一个指示是否启用调试模式的标志。 | False | 
| name | str | None | 用于编译后图的名称。 | None | 
返回
| 名称 | 类型 | 描述 | 
|---|---|---|
| CompiledStateGraph | CompiledStateGraph[StateT, ContextT, InputT, OutputT] | 编译后的状态图。 | 
基类: Pregel[StateT, ContextT, InputT, OutputT], Generic[StateT, ContextT, InputT, OutputT]
方法
| 名称 | 描述 | 
|---|---|
| stream | 为单个输入流式传输图的步骤。 | 
| astream | 为单个输入异步流式传输图的步骤。 | 
| invoke | 使用单个输入和配置运行图。 | 
| ainvoke | 在单个输入上异步调用图。 | 
| get_state | 获取图的当前状态。 | 
| aget_state | 获取图的当前状态。 | 
| get_state_history | 获取图的状态历史记录。 | 
| aget_state_history | 异步获取图的状态历史记录。 | 
| update_state | 使用给定的值更新图的状态,就像它们来自 | 
| aupdate_state | 异步地使用给定的值更新图的状态,就像它们来自 | 
| bulk_update_state | 批量应用对图状态的更新。需要设置一个检查点保存器。 | 
| abulk_update_state | 异步地批量应用对图状态的更新。需要设置一个检查点保存器。 | 
| get_graph | 返回计算图的可绘制表示。 | 
| aget_graph | 返回计算图的可绘制表示。 | 
| get_subgraphs | 获取图的子图。 | 
| aget_subgraphs | 获取图的子图。 | 
| with_config | 创建一个具有更新配置的 Pregel 对象的副本。 | 
stream(
    input: InputT | Command | None,
    config: RunnableConfig | None = None,
    *,
    context: ContextT | None = None,
    stream_mode: (
        StreamMode | Sequence[StreamMode] | None
    ) = None,
    print_mode: StreamMode | Sequence[StreamMode] = (),
    output_keys: str | Sequence[str] | None = None,
    interrupt_before: All | Sequence[str] | None = None,
    interrupt_after: All | Sequence[str] | None = None,
    durability: Durability | None = None,
    subgraphs: bool = False,
    debug: bool | None = None,
    **kwargs: Unpack[DeprecatedKwargs]
) -> Iterator[dict[str, Any] | Any]
为单个输入流式传输图的步骤。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| input | InputT | Command | None | 图的输入。 | 必填 | 
| config | RunnableConfig | None | 运行使用的配置。 | None | 
| context | ContextT | None | 用于运行的静态上下文。 在 0.6.0 版本中添加。 | None | 
| stream_mode | StreamMode | Sequence[StreamMode] | None | 流式输出的模式,默认为  
 您可以将列表作为  有关更多详细信息,请参阅 LangGraph 流式传输指南。 | None | 
| print_mode | StreamMode | Sequence[StreamMode] | 接受与  | () | 
| output_keys | str | Sequence[str] | None | 要流式传输的键,默认为所有非上下文通道。 | None | 
| interrupt_before | All | Sequence[str] | None | 在其之前中断的节点,默认为图中的所有节点。 | None | 
| interrupt_after | All | Sequence[str] | None | 在其之后中断的节点,默认为图中的所有节点。 | None | 
| durability | Durability | None | 图执行的持久性模式,默认为“async”。选项有: -  | None | 
| subgraphs | bool | 是否从子图内部流式传输事件,默认为 False。如果为 True,事件将以  有关更多详细信息,请参阅 LangGraph 流式传输指南。 | False | 
返回
| 类型 | 描述 | 
|---|---|
| dict[str, Any] | Any | 图中每一步的输出。输出形状取决于 stream_mode。 | 
async  ¶
astream(
    input: InputT | Command | None,
    config: RunnableConfig | None = None,
    *,
    context: ContextT | None = None,
    stream_mode: (
        StreamMode | Sequence[StreamMode] | None
    ) = None,
    print_mode: StreamMode | Sequence[StreamMode] = (),
    output_keys: str | Sequence[str] | None = None,
    interrupt_before: All | Sequence[str] | None = None,
    interrupt_after: All | Sequence[str] | None = None,
    durability: Durability | None = None,
    subgraphs: bool = False,
    debug: bool | None = None,
    **kwargs: Unpack[DeprecatedKwargs]
) -> AsyncIterator[dict[str, Any] | Any]
为单个输入异步流式传输图的步骤。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| input | InputT | Command | None | 图的输入。 | 必填 | 
| config | RunnableConfig | None | 运行使用的配置。 | None | 
| context | ContextT | None | 用于运行的静态上下文。 在 0.6.0 版本中添加。 | None | 
| stream_mode | StreamMode | Sequence[StreamMode] | None | 流式输出的模式,默认为  
 您可以将列表作为  有关更多详细信息,请参阅 LangGraph 流式传输指南。 | None | 
| print_mode | StreamMode | Sequence[StreamMode] | 接受与  | () | 
| output_keys | str | Sequence[str] | None | 要流式传输的键,默认为所有非上下文通道。 | None | 
| interrupt_before | All | Sequence[str] | None | 在其之前中断的节点,默认为图中的所有节点。 | None | 
| interrupt_after | All | Sequence[str] | None | 在其之后中断的节点,默认为图中的所有节点。 | None | 
| durability | Durability | None | 图执行的持久性模式,默认为“async”。选项有: -  | None | 
| subgraphs | bool | 是否从子图内部流式传输事件,默认为 False。如果为 True,事件将以  有关更多详细信息,请参阅 LangGraph 流式传输指南。 | False | 
返回
| 类型 | 描述 | 
|---|---|
| AsyncIterator[dict[str, Any] | Any] | 图中每一步的输出。输出形状取决于 stream_mode。 | 
invoke(
    input: InputT | Command | None,
    config: RunnableConfig | None = None,
    *,
    context: ContextT | None = None,
    stream_mode: StreamMode = "values",
    print_mode: StreamMode | Sequence[StreamMode] = (),
    output_keys: str | Sequence[str] | None = None,
    interrupt_before: All | Sequence[str] | None = None,
    interrupt_after: All | Sequence[str] | None = None,
    durability: Durability | None = None,
    **kwargs: Any
) -> dict[str, Any] | Any
使用单个输入和配置运行图。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| input | InputT | Command | None | 图的输入数据。可以是一个字典或任何其他类型。 | 必填 | 
| config | RunnableConfig | None | 可选。图运行的配置。 | None | 
| context | ContextT | None | 用于运行的静态上下文。 在 0.6.0 版本中添加。 | None | 
| stream_mode | StreamMode | 可选[str]。图运行的流模式。默认为“values”。 | 'values' | 
| print_mode | StreamMode | Sequence[StreamMode] | 接受与  | () | 
| output_keys | str | Sequence[str] | None | 可选。从图运行中检索的输出键。 | None | 
| interrupt_before | All | Sequence[str] | None | 可选。在此之前中断图运行的节点。 | None | 
| interrupt_after | All | Sequence[str] | None | 可选。在此之后中断图运行的节点。 | None | 
| durability | Durability | None | 图执行的持久性模式,默认为“async”。选项有: -  | None | 
| **kwargs | Any | 传递给图运行的其他关键字参数。 | {} | 
返回
| 类型 | 描述 | 
|---|---|
| dict[str, Any] | Any | 图运行的输出。如果 stream_mode 是 "values",则返回最新的输出。 | 
| dict[str, Any] | Any | 如果 stream_mode 不是 "values",则返回一个输出块的列表。 | 
async  ¶
ainvoke(
    input: InputT | Command | None,
    config: RunnableConfig | None = None,
    *,
    context: ContextT | None = None,
    stream_mode: StreamMode = "values",
    print_mode: StreamMode | Sequence[StreamMode] = (),
    output_keys: str | Sequence[str] | None = None,
    interrupt_before: All | Sequence[str] | None = None,
    interrupt_after: All | Sequence[str] | None = None,
    durability: Durability | None = None,
    **kwargs: Any
) -> dict[str, Any] | Any
在单个输入上异步调用图。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| input | InputT | Command | None | 计算的输入数据。可以是一个字典或任何其他类型。 | 必填 | 
| config | RunnableConfig | None | 可选。计算的配置。 | None | 
| context | ContextT | None | 用于运行的静态上下文。 在 0.6.0 版本中添加。 | None | 
| stream_mode | StreamMode | 可选。计算的流模式。默认为“values”。 | 'values' | 
| print_mode | StreamMode | Sequence[StreamMode] | 接受与  | () | 
| output_keys | str | Sequence[str] | None | 可选。包含在结果中的输出键。默认为 None。 | None | 
| interrupt_before | All | Sequence[str] | None | 可选。在此之前中断的节点。默认为 None。 | None | 
| interrupt_after | All | Sequence[str] | None | 可选。在此之后中断的节点。默认为 None。 | None | 
| durability | Durability | None | 图执行的持久性模式,默认为“async”。选项有: -  | None | 
| **kwargs | Any | 额外的关键字参数。 | {} | 
返回
| 类型 | 描述 | 
|---|---|
| dict[str, Any] | Any | 计算的结果。如果 stream_mode 是 "values",则返回最新的值。 | 
| dict[str, Any] | Any | 如果 stream_mode 是 "chunks",则返回一个块的列表。 | 
get_state(
    config: RunnableConfig, *, subgraphs: bool = False
) -> StateSnapshot
获取图的当前状态。
async  ¶
aget_state(
    config: RunnableConfig, *, subgraphs: bool = False
) -> StateSnapshot
获取图的当前状态。
get_state_history(
    config: RunnableConfig,
    *,
    filter: dict[str, Any] | None = None,
    before: RunnableConfig | None = None,
    limit: int | None = None
) -> Iterator[StateSnapshot]
获取图的状态历史记录。
async  ¶
aget_state_history(
    config: RunnableConfig,
    *,
    filter: dict[str, Any] | None = None,
    before: RunnableConfig | None = None,
    limit: int | None = None
) -> AsyncIterator[StateSnapshot]
异步获取图的状态历史记录。
update_state(
    config: RunnableConfig,
    values: dict[str, Any] | Any | None,
    as_node: str | None = None,
    task_id: str | None = None,
) -> RunnableConfig
使用给定的值更新图的状态,就像它们来自节点 as_node 一样。如果未提供 as_node,它将被设置为最后更新状态的节点(如果明确的话)。
async  ¶
aupdate_state(
    config: RunnableConfig,
    values: dict[str, Any] | Any,
    as_node: str | None = None,
    task_id: str | None = None,
) -> RunnableConfig
异步地使用给定的值更新图的状态,就像它们来自节点 as_node 一样。如果未提供 as_node,它将被设置为最后更新状态的节点(如果明确的话)。
bulk_update_state(
    config: RunnableConfig,
    supersteps: Sequence[Sequence[StateUpdate]],
) -> RunnableConfig
批量应用对图状态的更新。需要设置一个检查点保存器。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| config | RunnableConfig | 应用更新的配置。 | 必填 | 
| supersteps | Sequence[Sequence[StateUpdate]] | 一个超级步骤列表,每个超级步骤包含一个要按顺序应用于图状态的更新列表。每个更新是  | 必填 | 
抛出
| 类型 | 描述 | 
|---|---|
| ValueError | 如果没有设置检查点保存器或没有提供更新。 | 
| InvalidUpdateError | 如果提供了无效的更新。 | 
返回
| 名称 | 类型 | 描述 | 
|---|---|---|
| RunnableConfig | RunnableConfig | 更新后的配置。 | 
async  ¶
abulk_update_state(
    config: RunnableConfig,
    supersteps: Sequence[Sequence[StateUpdate]],
) -> RunnableConfig
异步地批量应用对图状态的更新。需要设置一个检查点保存器。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| config | RunnableConfig | 应用更新的配置。 | 必填 | 
| supersteps | Sequence[Sequence[StateUpdate]] | 一个超级步骤列表,每个超级步骤包含一个要按顺序应用于图状态的更新列表。每个更新是  | 必填 | 
抛出
| 类型 | 描述 | 
|---|---|
| ValueError | 如果没有设置检查点保存器或没有提供更新。 | 
| InvalidUpdateError | 如果提供了无效的更新。 | 
返回
| 名称 | 类型 | 描述 | 
|---|---|---|
| RunnableConfig | RunnableConfig | 更新后的配置。 | 
get_graph(
    config: RunnableConfig | None = None,
    *,
    xray: int | bool = False
) -> Graph
返回计算图的可绘制表示。
async  ¶
aget_graph(
    config: RunnableConfig | None = None,
    *,
    xray: int | bool = False
) -> Graph
返回计算图的可绘制表示。
async  ¶
aget_subgraphs(
    *, namespace: str | None = None, recurse: bool = False
) -> AsyncIterator[tuple[str, PregelProtocol]]
获取图的子图。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| namespace | str | None | 用于过滤子图的命名空间。 | None | 
| recurse | bool | 是否递归进入子图。如果为 False,则只返回直接的子图。 | False | 
返回
| 类型 | 描述 | 
|---|---|
| AsyncIterator[tuple[str, PregelProtocol]] | AsyncIterator[tuple[str, PregelProtocol]]: 一个 (命名空间, 子图) 对的异步迭代器。 | 
with_config(
    config: RunnableConfig | None = None, **kwargs: Any
) -> Self
创建一个具有更新配置的 Pregel 对象的副本。
函数
| 名称 | 描述 | 
|---|---|
| add_messages | 合并两个消息列表,通过 ID 更新现有消息。 | 
add_messages(
    left: Messages,
    right: Messages,
    *,
    format: Literal["langchain-openai"] | None = None
) -> Messages
合并两个消息列表,通过 ID 更新现有消息。
默认情况下,这确保了状态是“仅追加”的,除非新消息与现有消息具有相同的 ID。
参数
| 名称 | 类型 | 描述 | 默认值 | 
|---|---|---|---|
| left | 消息 | 基础消息列表。 | 必填 | 
| right | 消息 | 要合并到基础列表中的消息列表(或单个消息)。 | 必填 | 
| format | Literal['langchain-openai'] | None | 返回消息的格式。如果为 None,则消息将按原样返回。如果为 'langchain-openai',则消息将作为 BaseMessage 对象返回,其内容格式化以匹配 OpenAI 消息格式,这意味着内容可以是字符串、'text' 块或 'image_url' 块,并且工具响应将作为其自己的 ToolMessages 返回。 要求 必须安装  | None | 
返回
| 类型 | 描述 | 
|---|---|
| 消息 | 一个将  | 
| 消息 | 如果  | 
| 消息 | 来自  | 
示例
from langchain_core.messages import AIMessage, HumanMessage
msgs1 = [HumanMessage(content="Hello", id="1")]
msgs2 = [AIMessage(content="Hi there!", id="2")]
add_messages(msgs1, msgs2)
# [HumanMessage(content='Hello', id='1'), AIMessage(content='Hi there!', id='2')]
msgs1 = [HumanMessage(content="Hello", id="1")]
msgs2 = [HumanMessage(content="Hello again", id="1")]
add_messages(msgs1, msgs2)
# [HumanMessage(content='Hello again', id='1')]
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph
class State(TypedDict):
    messages: Annotated[list, add_messages]
builder = StateGraph(State)
builder.add_node("chatbot", lambda state: {"messages": [("assistant", "Hello")]})
builder.set_entry_point("chatbot")
builder.set_finish_point("chatbot")
graph = builder.compile()
graph.invoke({})
# {'messages': [AIMessage(content='Hello', id=...)]}
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, add_messages
class State(TypedDict):
    messages: Annotated[list, add_messages(format='langchain-openai')]
def chatbot_node(state: State) -> list:
    return {"messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "Here's an image:",
                    "cache_control": {"type": "ephemeral"},
                },
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/jpeg",
                        "data": "1234",
                    },
                },
            ]
        },
    ]}
builder = StateGraph(State)
builder.add_node("chatbot", chatbot_node)
builder.set_entry_point("chatbot")
builder.set_finish_point("chatbot")
graph = builder.compile()
graph.invoke({"messages": []})
# {
#     'messages': [
#         HumanMessage(
#             content=[
#                 {"type": "text", "text": "Here's an image:"},
#                 {
#                     "type": "image_url",
#                     "image_url": {"url": "data:image/jpeg;base64,1234"},
#                 },
#             ],
#         ),
#     ]
# }