You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止LangGraph中条件边触发reduce函数重复执行?

问题:LangGraph条件边触发reduce函数导致斐波那契数列元素重复

作为LangGraph初学者,我在构建计算斐波那契数列的图时遇到了问题。程序包含两个节点:n1负责更新斐波那契数列,另一个条件节点控制循环。完整代码如下:

from langchain_core.runnables import Runnable
from collections.abc import Iterable
from langgraph.graph import StateGraph
from pydantic import BaseModel
from typing import Any, Dict, Annotated
from langgraph.constants import END

def append_to_list(a : list, b) -> list:
    print(f"append_to_list:{a}, {b}")
    if isinstance(b, Iterable) and not isinstance(b, str):
        a.extend(b)
    else:
        a.append(b)
    return a

class Node(Runnable):
    def __init__(self, name : str):
        self.name = name
    def invoke(self, input: Any, config: Dict | None = None) -> Any:
        c = input.a + input.b
        print(f"{self.name}:{input}")
        return {"a":input.b, "b":c, "fibonacci_list":c}

class ConditionalNode(Runnable):
    def __init__(self, name : str, threshold: int):
        self.threshold = threshold
        self.name = name

    def invoke(self, input: Any, config) -> Any:
        print(f"{self.name}:{input}")
        return {"path" : input.b >= self.threshold}

class State(BaseModel):
    a : int
    b : int
    fibonacci_list : Annotated[list[int], append_to_list]

graph = StateGraph(State)
graph.add_node("n1", Node(name = "n1"))
graph.add_conditional_edges("n1", ConditionalNode(name = "CN", threshold = 10), {True : END, False: "n1"})
graph.set_entry_point("n1")
g = graph.compile()
s = g.invoke({"a":1, "b":1, "fibonacci_list":[1, 1]})
print(s)

n1节点负责计算斐波那契数列的最新值并返回状态更新,append_to_list作为reduce函数,用于将新生成的数值添加到fibonacci_list中。我原本预期该函数仅在n1节点执行后调用一次,最终得到完整的斐波那契数列(如[1,1,2,3,5,8,13]),但实际每次条件节点执行完成后,append_to_list都会被触发,且传入参数与n1执行后一致,导致数列出现重复元素。

请问如何阻止条件边触发reduce函数?


解决方案

问题核心在于:你把条件判断逻辑封装成了Runnable节点,而LangGraph中所有Runnable节点的输出都会和当前状态进行合并,即使节点没有返回某个字段,LangGraph也会尝试用该字段的当前值触发reduce函数,最终导致重复调用。

最简单的解决方法是将条件判断逻辑改为普通路由函数,而非Runnable节点,因为add_conditional_edges的第二个参数可以直接接收一个路由函数,该函数只负责返回路径选择,不会触发状态合并操作。

修改后的代码如下:

from langchain_core.runnables import Runnable
from collections.abc import Iterable
from langgraph.graph import StateGraph
from pydantic import BaseModel
from typing import Any, Dict, Annotated
from langgraph.constants import END

def append_to_list(a : list, b) -> list:
    print(f"append_to_list:{a}, {b}")
    if isinstance(b, Iterable) and not isinstance(b, str):
        a.extend(b)
    else:
        a.append(b)
    return a

class Node(Runnable):
    def __init__(self, name : str):
        self.name = name
    def invoke(self, input: Any, config: Dict | None = None) -> Any:
        c = input.a + input.b
        print(f"{self.name}:{input}")
        return {"a":input.b, "b":c, "fibonacci_list":c}

# 替换ConditionalNode为普通路由函数
def should_end(state: State) -> str:
    print(f"should_end:{state}")
    return END if state.b >= 10 else "n1"

class State(BaseModel):
    a : int
    b : int
    fibonacci_list : Annotated[list[int], append_to_list]

graph = StateGraph(State)
graph.add_node("n1", Node(name = "n1"))
# 使用路由函数替代ConditionalNode
graph.add_conditional_edges("n1", should_end)
graph.set_entry_point("n1")
g = graph.compile()
s = g.invoke({"a":1, "b":1, "fibonacci_list":[1, 1]})
print(s)

修改后,路由函数should_end仅负责判断路径走向,不会触发状态合并,因此append_to_list只会在n1节点执行后被调用一次,最终得到正确的斐波那契数列。

若你坚持要使用Runnable作为条件节点,需确保其返回内容不包含任何状态字段,仅返回路径标识,但这种方式不如路由函数简洁可靠。

内容的提问来源于stack exchange,提问作者lei hu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 14:25:09