Reducer归约器是一个函数它定义了“当多个节点都想修改同一个 State 字段时如何把这些修改合并成一个最终结果”。或者说Reducer 决定了 State 中某个字段的更新策略——是覆盖是追加是累加还是其他自定义规则从问题出发理解 Reducer核心矛盾多个节点都要写同一个字段在 LangGraph 中多个节点会依次执行每个节点都可能修改 State。这就产生了一个问题如果节点 A 把counter设为 1节点 B 又把counter设为 2那最终counter应该是多少有两个答案2后一个覆盖前一个—— 这是默认行为31 2 累加起来—— 这是 Reducer 改变后的行为Reducer 就是用来回答这个问题的工具。默认行为 vs Reducer 行为默认行为覆盖Override如果不指定 ReducerLangGraph 的默认行为是覆盖class MyState(TypedDict): counter: int # 没有 Reducer name: str # 没有 Reducer执行流程初始状态counter 0 节点 A 返回{counter: 1} → 状态变为counter 1 节点 B 返回{counter: 2} → 状态变为counter 2 覆盖了节点 A 的 1 最终结果counter 2适用于只需要最终值的场景比如用户名、当前状态标志等。Reducer 行为合并Merge指定 Reducer 后行为变为合并class MyState(TypedDict): counter: Annotated[int, operator.add] # 使用加法 Reducer执行流程初始状态counter 0 节点 A 返回{counter: 1} → 状态变为counter 1 节点 B 返回{counter: 2} → 状态变为counter 3 1 2 3累加了 最终结果counter 3适用于需要累积的场景比如计数器、总分、消息列表等。Reducer 的本质一个普通函数Reducer 并没有什么魔法它就是一个普通的 Python 函数接收两个参数def reducer_func(current_value, new_value) - final_value: current_value当前 State 中该字段的值 new_value节点返回的该字段的新值 return合并后的最终值 # 在这里定义你的合并逻辑 return merged_resultLangGraph 内置了几个常用的 ReducerReducer 函数效果等价于operator.add数值相加lambda a, b: a boperator.set集合合并lambda a, b: a | badd_messages消息列表追加特殊处理含 ID 去重不指定覆盖lambda a, b: b用生活例子彻底搞懂场景记账本你和室友共用一本账本记录每天的开销。没有 Reducer覆盖模式周一小明记了吃饭 50元 → 账本[吃饭 50元] 周二小红记了打车 30元 → 账本[打车 30元] ← 周一的内容被覆盖了 周三你们吵架了因为周一的账找不到了有 Reducer追加模式周一小明记了吃饭 50元 → 账本[吃饭 50元] 周二小红记了打车 30元 → 账本[吃饭 50元, 打车 30元] ← 追加在后面 周三月底算账清清楚楚在这个例子里add就是一个 Reducer它的规则是新来的记录追加到旧记录的后面而不是替换它。为什么 LangGraph 需要 Reducer原因一图不是线性执行的在 LangGraph 中图可能有分支和循环┌→ 节点 B ─→┐ START ─→┤ ├→ 节点 D └→ 节点 C ─→┘节点 B 和节点 C 都可能修改同一个字段。如果没有 Reducer后执行的节点会抹掉前一个节点的修改。有了 Reducer两者的贡献可以共存。原因二循环需要累积节点 A → 条件判断 → 未满足 → 回到节点 A循环在循环中每次经过节点 A 都可能产生新数据。Reducer 确保这些数据是累积的而不是每次循环都重置。原因三可预测的状态变化Reducer 让状态变化变得透明和可预测。你知道每个字段的更新规则是什么不会出现“咦这个值怎么不见了”的困惑。实战自定义 Reducer内置 Reducer 不能满足需求时可以自己写示例1限制列表长度def last_n_reducer(n: int): 只保留最近 n 条记录 def reducer(old: list, new: list) - list: combined old new return combined[-n:] return reducer class MyState(TypedDict): recent_logs: Annotated[List, last_n_reducer(10)] # 只保留最近10条示例2字典合并def dict_merge(old: dict, new: dict) - dict: 合并两个字典新值覆盖旧值 merged old.copy() merged.update(new) return merged class MyState(TypedDict): metadata: Annotated[Dict, dict_merge] # 字典合并Reducer 的完整工作流程为了让你彻底明白这里是 LangGraph 内部处理 Reducer 的完整流程1. 节点执行完毕返回一个字典比如 {counter: 5} 2. LangGraph 遍历这个字典的每个键值对 3. 对于每个键比如 counter a. 查找 State 定义中这个键有没有 Reducer b. 如果有 Reducer - 获取当前 State 中 counter 的旧值比如 3 - 调用 Reducer 函数reducer(旧值3, 新值5) - 把 Reducer 的返回值比如 8写入 State c. 如果没有 Reducer - 直接用新值5覆盖旧值3 4. 更新后的 State 传递给下一个节点面试级总结问题答案Reducer 是什么一个定义 State 字段更新规则的函数默认行为是什么覆盖新值替换旧值Reducer 改变什么从覆盖变成合并/累加/自定义Reducer 的参数(current_value, new_value) → merged_value为什么需要它因为图有分支和循环需要累积而非覆盖内置的有哪些operator.add、operator.set、add_messages能自己写吗能任何符合签名的函数都可以一句话记住没有 Reducer 的 State 字段后浪直接把前浪拍死在沙滩上有 Reducer 的字段后浪和前浪汇合在一起变成更大的浪。现在你应该能理解为什么messages: Annotated[List, add_messages]这么重要了吧没有它你的聊天 Agent 永远只能记住最后一句话。学习资源推荐如果你想更深入地学习大模型以下是一些非常有价值的学习资源这些资源将帮助你从不同角度学习大模型提升你的实践能力。一、全套AGI大模型学习路线AI大模型时代的学习之旅从基础到前沿掌握人工智能的核心技能​因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获取二、640套AI大模型报告合集这套包含640份报告的合集涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师还是对AI大模型感兴趣的爱好者这套报告合集都将为您提供宝贵的信息和启示​因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获取三、AI大模型经典PDF籍随着人工智能技术的飞速发展AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型如GPT-3、BERT、XLNet等以其强大的语言理解和生成能力正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获取四、AI大模型商业化落地方案作为普通人入局大模型时代需要持续学习和实践不断提高自己的技能和认知水平同时也需要有责任感和伦理意识为人工智能的健康发展贡献力量。