跳到内容

图定义

StateGraph

基类: Generic[StateT, InputT, OutputT]

一个图,其节点通过读写共享状态进行通信。每个节点的签名是 State -> Partial.

每个状态键都可以选择使用一个 reducer 函数进行注释,该函数将用于聚合从多个节点接收到的该键的值。reducer 函数的签名是 (Value, Value) -> Value。

参数

名称 类型 描述 默认值
state_schema type[StateT]

定义状态的模式类。

必填
config_schema type[Any] | None

定义配置的模式类。使用此项可在您的 API 中公开可配置参数。

None
示例
from langchain_core.runnables import RunnableConfig
from typing_extensions import Annotated, TypedDict
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph

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 ConfigSchema(TypedDict):
    r: float

graph = StateGraph(State, config_schema=ConfigSchema)

def node(state: State, config: RunnableConfig) -> dict:
    r = config["configurable"].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()

print(compiled.config_specs)
# [ConfigurableFieldSpec(id='r', annotation=<class 'float'>, name=None, description=None, default=None, is_shared=False, dependencies=None)]

step1 = compiled.invoke({"x": 0.5}, {"configurable": {"r": 3.0}})
# {'x': [0.5, 0.75]}

方法

名称 描述
add_node

向状态图添加一个新节点。

add_edge

从起始节点(或起始节点列表)向结束节点添加有向边。

add_conditional_edges

从起始节点向任意数量的目标节点添加条件边。

add_sequence

添加一个将按所提供顺序执行的节点序列。

compile

将状态图编译为 CompiledStateGraph 对象。

add_node

add_node(
    node: str | StateNode[StateT],
    action: StateNode[StateT] | None = None,
    *,
    defer: bool = False,
    metadata: dict[str, Any] | None = None,
    input_schema: type[Any] | 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[StateT]

此节点将运行的函数或可运行对象。如果提供字符串,它将用作节点名称,并且 action 将用作函数或可运行对象。

必填
action StateNode[StateT] | None

与节点关联的操作。(默认:None)如果 node 是字符串(节点名称),则将用作节点函数或可运行对象。

None
defer bool

是否将节点的执行延迟到运行即将结束时。

False
metadata dict[str, Any] | None

与节点关联的元数据。(默认:None)

None
input_schema type[Any] | None

节点的输入模式。(默认:图的状态模式)

None
retry_policy RetryPolicy | Sequence[RetryPolicy] | None

节点的重试策略。(默认:None)如果提供序列,则将应用第一个匹配的策略。

None
cache_policy CachePolicy | None

节点的缓存策略。(默认:None)

None
destinations dict[str, str] | tuple[str, ...] | None

指示节点可以路由到的目标。这对于返回 Command 对象的无边图非常有用。如果提供字典,则键将用作目标节点名称,值将用作边的标签。如果提供元组,则值将用作目标节点名称。注意:这仅用于图渲染,对图执行没有任何影响。

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}
自定义名称
builder = StateGraph(State)
builder.add_node("my_fair_node", my_node)
builder.add_edge(START, "my_fair_node")
graph = builder.compile()
graph.invoke({"x": 1})
# {'x': 2}

返回

名称 类型 描述
Self Self

状态图的实例,允许方法链式调用。

add_edge

add_edge(start_key: str | list[str], end_key: str) -> Self

从起始节点(或起始节点列表)向结束节点添加有向边。

当提供单个起始节点时,图将等待该节点完成后再执行结束节点。当提供多个起始节点时,图将等待所有起始节点完成后再执行结束节点。

参数

名称 类型 描述 默认值
start_key str | list[str]

边的起始节点键。

必填
end_key str

边的结束节点键。

必填

抛出

类型 描述
ValueError

如果起始键是 'END',或者起始键或结束键不在图中。

返回

名称 类型 描述
Self Self

状态图的实例,允许方法链式调用。

add_conditional_edges

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,它应返回一个或多个节点。如果它返回 END,图将停止执行。

必填
path_map dict[Hashable, str] | list[str] | None

路径到节点名称的可选映射。如果省略,path 返回的路径应为节点名称。

None

返回

名称 类型 描述
Self Self

图的实例,允许方法链式调用。

path 函数的返回值上没有类型提示(例如,-> Literal["foo", "__end__"]:

或一个 path_map,图可视化假定该边可以转换到图中的任何节点。

add_sequence

add_sequence(
    nodes: Sequence[
        StateNode[StateT] | tuple[str, StateNode[StateT]]
    ],
) -> Self

添加一个将按所提供顺序执行的节点序列。

参数

名称 类型 描述 默认值
nodes Sequence[StateNode[StateT] | tuple[str, StateNode[StateT]]]

一个 StateNodes 序列(接受状态参数的可调用对象)或 (name, StateNode) 元组。如果未提供名称,则名称将从节点对象(例如,可运行对象或可调用对象的名称)推断。每个节点将按提供的顺序执行。

必填

抛出

类型 描述
ValueError

如果序列为空。

ValueError

如果序列包含重复的节点名称。

返回

名称 类型 描述
Self Self

状态图的实例,允许方法链式调用。

compile

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, InputT, OutputT]

将状态图编译为 CompiledStateGraph 对象。

编译后的图实现了 Runnable 接口,可以被调用、流式传输、批量处理和异步运行。

参数

名称 类型 描述 默认值
checkpointer Checkpointer

一个检查点保存对象或标志。如果提供,此 Checkpointer 可作为图的完整版本“短期记忆”,允许从任何点暂停、恢复和重播。如果为 None,则在用作子图时可能会继承父图的 checkpointer。如果为 False,则不会使用或继承任何 checkpointer。

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, InputT, OutputT]

编译后的状态图。

CompiledStateGraph

基类: Pregel[StateT, InputT, OutputT], Generic[StateT, 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

stream(
    input: InputT | Command | None,
    config: RunnableConfig | 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,
    checkpoint_during: bool | None = None,
    debug: bool | None = None,
    subgraphs: bool = False
) -> Iterator[dict[str, Any] | Any]

为单个输入流式传输图步骤。

参数

名称 类型 描述 默认值
input InputT | Command | None

图的输入。

必填
config RunnableConfig | None

运行使用的配置。

None
stream_mode StreamMode | Sequence[StreamMode] | None

流式输出的模式,默认为 self.stream_mode。选项包括

  • "values":在每个步骤后发出状态中的所有值,包括中断。与函数式 API 一起使用时,值在工作流结束时一次性发出。
  • "updates":仅在每个步骤后发出节点或任务名称以及由节点或任务返回的更新。如果同一步骤中进行了多次更新(例如运行了多个节点),则这些更新将单独发出。
  • "custom":使用 StreamWriter 从节点或任务内部发出自定义数据。
  • "messages":逐个令牌地发出 LLM 消息,以及节点或任务内部任何 LLM 调用的元数据。将以 2 元组 (LLM token, metadata) 的形式发出。
  • "checkpoints":在创建检查点时发出事件,格式与 `get_state()` 返回的相同。
  • "tasks":在任务开始和结束时发出事件,包括其结果和错误。

您可以将列表作为 stream_mode 参数传递,以同时流式传输多种模式。流式输出将是 (mode, data) 元组。

有关更多详细信息,请参阅LangGraph 流式传输指南

None
print_mode StreamMode | Sequence[StreamMode]

接受与 stream_mode 相同的值,但仅将输出打印到控制台,用于调试目的。不以任何方式影响图的输出。

()
output_keys str | Sequence[str] | None

要流式传输的键,默认为所有非上下文通道。

None
interrupt_before All | Sequence[str] | None

中断前的节点,默认为图中的所有节点。

None
interrupt_after All | Sequence[str] | None

中断后的节点,默认为图中的所有节点。

None
checkpoint_during bool | None

是否检查点中间步骤,默认为 False。如果为 False,则仅保存最终检查点。

None
subgraphs bool

是否从子图内部流式传输事件,默认为 False。如果为 True,事件将以元组 (namespace, data) 的形式发出,或者如果 stream_mode 是列表,则为 (namespace, mode, data),其中 namespace 是一个元组,包含调用子图的节点的路径,例如 ("parent_node:", "child_node:")

有关更多详细信息,请参阅LangGraph 流式传输指南

False

返回

类型 描述
dict[str, Any] | Any

图中每一步的输出。输出形状取决于 stream_mode。

astream async

astream(
    input: InputT | Command | None,
    config: RunnableConfig | 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,
    checkpoint_during: bool | None = None,
    debug: bool | None = None,
    subgraphs: bool = False
) -> AsyncIterator[dict[str, Any] | Any]

异步流式传输单个输入的图步骤。

参数

名称 类型 描述 默认值
input InputT | Command | None

图的输入。

必填
config RunnableConfig | None

运行使用的配置。

None
stream_mode StreamMode | Sequence[StreamMode] | None

流式输出的模式,默认为 self.stream_mode。选项包括

  • "values":在每个步骤后发出状态中的所有值,包括中断。与函数式 API 一起使用时,值在工作流结束时一次性发出。
  • "updates":仅在每个步骤后发出节点或任务名称以及由节点或任务返回的更新。如果同一步骤中进行了多次更新(例如运行了多个节点),则这些更新将单独发出。
  • "custom":使用 StreamWriter 从节点或任务内部发出自定义数据。
  • "messages":逐个令牌地发出 LLM 消息,以及节点或任务内部任何 LLM 调用的元数据。将以 2 元组 (LLM token, metadata) 的形式发出。
  • "debug":为每一步发出尽可能多的调试事件。

您可以将列表作为 stream_mode 参数传递,以同时流式传输多种模式。流式输出将是 (mode, data) 元组。

有关更多详细信息,请参阅LangGraph 流式传输指南

None
print_mode StreamMode | Sequence[StreamMode]

接受与 stream_mode 相同的值,但仅将输出打印到控制台,用于调试目的。不以任何方式影响图的输出。

()
output_keys str | Sequence[str] | None

要流式传输的键,默认为所有非上下文通道。

None
interrupt_before All | Sequence[str] | None

中断前的节点,默认为图中的所有节点。

None
interrupt_after All | Sequence[str] | None

中断后的节点,默认为图中的所有节点。

None
checkpoint_during bool | None

是否检查点中间步骤,默认为 False。如果为 False,则仅保存最终检查点。

None
subgraphs bool

是否从子图内部流式传输事件,默认为 False。如果为 True,事件将以元组 (namespace, data) 的形式发出,或者如果 stream_mode 是列表,则为 (namespace, mode, data),其中 namespace 是一个元组,包含调用子图的节点的路径,例如 ("parent_node:", "child_node:")

有关更多详细信息,请参阅LangGraph 流式传输指南

False

返回

类型 描述
AsyncIterator[dict[str, Any] | Any]

图中每一步的输出。输出形状取决于 stream_mode。

invoke

invoke(
    input: InputT | Command | None,
    config: RunnableConfig | 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,
    **kwargs: Any
) -> dict[str, Any] | Any

使用单个输入和配置运行图。

参数

名称 类型 描述 默认值
input InputT | Command | None

图的输入数据。它可以是字典或任何其他类型。

必填
config RunnableConfig | None

可选。图运行的配置。

None
stream_mode StreamMode

可选 [str]。图运行的流模式。默认为 "values"。

'values'
print_mode StreamMode | Sequence[StreamMode]

接受与 stream_mode 相同的值,但仅将输出打印到控制台,用于调试目的。不以任何方式影响图的输出。

()
output_keys str | Sequence[str] | None

可选。要从图运行中检索的输出键。

None
interrupt_before All | Sequence[str] | None

可选。在图运行中断前的节点。

None
interrupt_after All | Sequence[str] | None

可选。在图运行中断后的节点。

None
**kwargs Any

要传递给图运行的额外关键字参数。

{}

返回

类型 描述
dict[str, Any] | Any

图运行的输出。如果 stream_mode 是 "values",则返回最新输出。

dict[str, Any] | Any

如果 stream_mode 不是 "values",则返回输出块列表。

ainvoke async

ainvoke(
    input: InputT | Command | None,
    config: RunnableConfig | 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,
    **kwargs: Any
) -> dict[str, Any] | Any

异步调用图以处理单个输入。

参数

名称 类型 描述 默认值
input InputT | Command | None

计算的输入数据。它可以是字典或任何其他类型。

必填
config RunnableConfig | None

可选。计算的配置。

None
stream_mode StreamMode

可选。计算的流模式。默认为 "values"。

'values'
print_mode StreamMode | Sequence[StreamMode]

接受与 stream_mode 相同的值,但仅将输出打印到控制台,用于调试目的。不以任何方式影响图的输出。

()
output_keys str | Sequence[str] | None

可选。结果中要包含的输出键。默认为 None。

None
interrupt_before All | Sequence[str] | None

可选。中断前的节点。默认为 None。

None
interrupt_after All | Sequence[str] | None

可选。中断后的节点。默认为 None。

None
**kwargs Any

额外关键字参数。

{}

返回

类型 描述
dict[str, Any] | Any

计算结果。如果 stream_mode 是 "values",则返回最新值。

dict[str, Any] | Any

如果 stream_mode 是 "chunks",则返回块列表。

get_state

get_state(
    config: RunnableConfig, *, subgraphs: bool = False
) -> StateSnapshot

获取图的当前状态。

aget_state async

aget_state(
    config: RunnableConfig, *, subgraphs: bool = False
) -> StateSnapshot

获取图的当前状态。

get_state_history

get_state_history(
    config: RunnableConfig,
    *,
    filter: dict[str, Any] | None = None,
    before: RunnableConfig | None = None,
    limit: int | None = None
) -> Iterator[StateSnapshot]

获取图的状态历史记录。

aget_state_history async

aget_state_history(
    config: RunnableConfig,
    *,
    filter: dict[str, Any] | None = None,
    before: RunnableConfig | None = None,
    limit: int | None = None
) -> AsyncIterator[StateSnapshot]

异步获取图的状态历史记录。

update_state

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,则在不模糊的情况下,它将设置为最后更新状态的节点。

aupdate_state 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

bulk_update_state(
    config: RunnableConfig,
    supersteps: Sequence[Sequence[StateUpdate]],
) -> RunnableConfig

批量应用更新到图状态。需要设置一个检查点器。

参数

名称 类型 描述 默认值
config RunnableConfig

应用更新的配置。

必填
supersteps Sequence[Sequence[StateUpdate]]

一个超步列表,每个超步包含一个要顺序应用于图状态的更新列表。每个更新都是 (values, as_node, task_id) 形式的元组,其中 task_id 是可选的。

必填

抛出

类型 描述
ValueError

如果未设置检查点器或未提供更新。

InvalidUpdateError

如果提供了无效的更新。

返回

名称 类型 描述
RunnableConfig RunnableConfig

更新后的配置。

abulk_update_state async

abulk_update_state(
    config: RunnableConfig,
    supersteps: Sequence[Sequence[StateUpdate]],
) -> RunnableConfig

异步批量应用更新到图状态。需要设置一个检查点器。

参数

名称 类型 描述 默认值
config RunnableConfig

应用更新的配置。

必填
supersteps Sequence[Sequence[StateUpdate]]

一个超步列表,每个超步包含一个要顺序应用于图状态的更新列表。每个更新都是 (values, as_node, task_id) 形式的元组,其中 task_id 是可选的。

必填

抛出

类型 描述
ValueError

如果未设置检查点器或未提供更新。

InvalidUpdateError

如果提供了无效的更新。

返回

名称 类型 描述
RunnableConfig RunnableConfig

更新后的配置。

get_graph

get_graph(
    config: RunnableConfig | None = None,
    *,
    xray: int | bool = False
) -> Graph

返回计算图的可绘制表示。

aget_graph async

aget_graph(
    config: RunnableConfig | None = None,
    *,
    xray: int | bool = False
) -> Graph

返回计算图的可绘制表示。

get_subgraphs

get_subgraphs(
    *, namespace: str | None = None, recurse: bool = False
) -> Iterator[tuple[str, PregelProtocol]]

获取图的子图。

参数

名称 类型 描述 默认值
namespace str | None

用于过滤子图的命名空间。

None
recurse bool

是否递归进入子图。如果为 False,则只返回直接子图。

False

返回

类型 描述
Iterator[tuple[str, PregelProtocol]]

Iterator[tuple[str, PregelProtocol]]:(命名空间,子图) 对的迭代器。

aget_subgraphs 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

with_config(
    config: RunnableConfig | None = None, **kwargs: Any
) -> Self

创建 Pregel 对象的副本,并使用更新的配置。

函数

名称 描述
add_messages

合并两个消息列表,按 ID 更新现有消息。

add_messages

add_messages(
    left: Messages,
    right: Messages,
    *,
    format: Literal["langchain-openai"] | None = None
) -> Messages

合并两个消息列表,按 ID 更新现有消息。

默认情况下,这会确保状态是“仅追加”的,除非新消息与现有消息具有相同的 ID。

参数

名称 类型 描述 默认值
left Messages

消息的基础列表。

必填
right Messages

要合并到基础列表中的消息列表(或单个消息)。

必填
format Literal['langchain-openai'] | None

返回消息的格式。如果为 None,则消息将按原样返回。如果为 'langchain-openai',则消息将作为 BaseMessage 对象返回,其内容格式与 OpenAI 消息格式匹配,这意味着内容可以是字符串、'text' 块或 'image_url' 块,并且工具响应作为其自己的 ToolMessages 返回。

要求

必须安装 langchain-core>=0.3.11 才能使用此功能。

None

返回

类型 描述
Messages

一个新消息列表,其中 right 中的消息合并到 left 中。

Messages

如果 right 中的消息与 left 中的消息具有相同的 ID,则

Messages

right 中的消息将替换 left 中的消息。

示例
基本用法
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')]
在 StateGraph 中使用
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=...)]}
使用 OpenAI 消息格式
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"},
#                 },
#             ],
#         ),
#     ]
# }