LangGraph中的Reducer作用
在 LangGraph 中,Reducer(归约器/聚合器)的核心作用是定义“如何将节点产生的新数据合并到图的全局状态(State)中”。
为了让你更容易理解,我们可以从以下几个方面来拆解 Reducer 的作用和机制:
1. 为什么需要 Reducer?
LangGraph 是基于状态(State)运行的。当图(Graph)中的一个节点(Node)执行完毕后,它会返回一个字典(dict)作为状态更新。
- 默认情况(没有 Reducer):如果一个状态字段没有配置 Reducer,LangGraph 默认会用新值覆盖(Overwrite)旧值。
- 有 Reducer 的情况:很多时候我们不希望覆盖。比如在聊天应用中,我们希望把新的消息追加(Append)到历史消息列表中,而不是替换掉之前的聊天记录。Reducer 就是用来告诉 LangGraph 如何进行这种追加或合并操作的函数。
2. Reducer 是如何工作的?
Reducer 本质上是一个接收两个参数的函数:当前状态值 (old_value) 和 节点返回的新值 (new_value),并返回一个更新后的值 (updated_value)。
在 LangGraph 中,我们通常使用 Python 的 typing.Annotated 来为特定的状态字段绑定 Reducer。
3. 常见的使用场景与代码示例
场景一:直接覆盖(无 Reducer)
适用于保存当前状态、当前任务名等只需要最新值的场景。
python
from typing import TypedDict
class State(TypedDict):
current_task: str # 默认行为:节点返回的值会直接覆盖当前值
场景二:列表追加(使用 operator.add 作为 Reducer)
适用于收集日志、保存执行步骤等场景。
python
import operator
from typing import Annotated, TypedDict
class State(TypedDict):
# 使用 operator.add 作为 Reducer
# 作用:old_list + new_list -> updated_list
execution_steps: Annotated[list[str], operator.add]
场景三:聊天消息管理(使用内置的 add_messages)
这是 LangGraph 中最常见的用法。LangGraph 提供了一个专门处理消息的 Reducer 叫 add_messages。它不仅能追加消息,还能根据消息的 ID 进行去重或更新。
python
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
from langchain_core.messages import BaseMessage
class State(TypedDict):
# 使用官方专门为消息设计的 Reducer
messages: Annotated[list[BaseMessage], add_messages]
场景四:自定义复杂逻辑(自定义 Reducer 函数)
如果你需要更复杂的合并逻辑,比如合并两个字典、或者只保留最新的 5 条记录,你可以自己写一个函数。
python
from typing import Annotated, TypedDict
# 自定义 Reducer 函数
def merge_dicts(old_dict: dict, new_dict: dict) -> dict:
if old_dict is None:
return new_dict
# 合并字典,新值覆盖旧字典中的同名键
merged = old_dict.copy()
merged.update(new_dict)
return merged
class State(TypedDict):
# 绑定自定义 Reducer
user_profile: Annotated[dict, merge_dicts]
总结
在 LangGraph 中,Reducer 就是状态更新的“交通警察”。
- 没有它,新数据直接撞飞(覆盖)老数据。
- 有了它,你可以规定新数据是排在老数据后面(追加)、与老数据融合(合并字典)、还是按照特定规则互相替换(如
add_messages)。