AI菜鸟向前飞 — LangGraph系列之一:深入浅出解读Graph(一)

前言

LangGraph是一个使用 LLM 和 LangChain 构建有状态多参与者应用程序的库。

LangChain 允许您使用 LCEL(LangChain 表达式语言)构建链

AI菜鸟向前飞 — LangChain系列之六 - 深入浅出LCEL与Chain(上篇)

AI菜鸟向前飞 — LangChain系列之七 - 深入浅出LCEL与Chain(中篇)

AI菜鸟向前飞 — LangChain系列之八 - 深入浅出LCEL与Chain(下篇)


但是,用它只能构建一个DAG(有向无环图),不能有环。

例如,在这种情况下,使用 RAG 的应用程序可能无法正常工作。
这是因为,即使在第一个数据获取步骤中返回无用信息,处理也不会重新获取数据而继续到下一步。

这个问题的解决方案LangGraph,它扩展了 LCEL,能够循环调整跨越多个步骤的 Chain(或 Actor)。

如何更好地理解Graph

接下来,我会用一种易于大家理解的方式来介绍,
首先,本篇将两个重要要素:Node(节点)和Edge(边),如图所示:

这样就可以“组装”所谓的“graph”,即LangGraph的“原始”形态

一个最简单的形态

图片

看图说话:

node_1、node_2顾名思义,即为Node(节点)

通常用add_node来为graph添加节点

带方向的连接线为边Edge(边)

通常用add_edge来连接各个节点,进而形成“边”

代码如下

from langgraph.graph import Graph

def node1(input1: str) -> str:
    return f"Hello, {input1}"

def node2(input2: str) -> str:
    return f"{input2},有什么我可以帮忙的吗?"

graph = Graph()
graph.add_node("node1", node1)
graph.add_node("node2", node2)
graph.add_edge("node1", "node2")
graph.set_entry_point("node1")
graph.set_finish_point("node2")

app = graph.compile()
app.invoke("Song榆钱儿")

输出结果

Hello, Song榆钱儿, 有什么我可以帮忙的吗?

🏁小技巧:可以把程序稍微改动一下,可以看到程序在每一个Node(节点)的输出结果

for output in app.stream("Song榆钱儿"):
    for key, value in output.items():
        print(key ,"----", value)

输出结果

node1 ---- Hello, Song榆钱儿
node2 ---- Hello, Song榆钱儿,有什么我可以帮忙的吗?

当看到这里,大家会想用这个与用传统方式(如:正常写一段LLM代码逻辑,或采用LCEL)有什么区别?

不就是顺序执行,只不过强行套了一个“Graph”壳子而已...上面的例子确实是这样,不过你往下看:

再看一种“分支”“选择”模式,看过我之前发的这篇文档的读者,可能会想到这篇RouterChain.

AI菜鸟向前飞 — LangChain系列之九 - RouterChain的四种实现方式

在graph中称作“条件边”,即add_conditional_edges

图片

代码如下所示:

from langgraph.graph import Graph, END

def node_entry(input: str) -> str:
    return f"{input}"

def decide_which(input: str) -> str:
    if "你好" in input:
        return "greeting"
    elif "家乡" in input:
        return "hometown"
    return "end"

def node_greeting(input: str) -> str:
    return f"你说的是:{input}\n我回答你:你好啊,我的朋友"


def node_hometown(input: str) -> str:
    return f"你所提到的内容是: {input}\n我回答你:家乡在通化市"


graph = Graph()
graph.add_node("entry", node_entry)
graph.add_node("node_greeting", node_greeting)
graph.add_node("node_hometown", node_hometown)

graph.set_entry_point("entry")

graph.add_conditional_edges(
    source="entry",
    path=decide_which,
    path_map={
        "greeting": "node_greeting",
        "hometown": "node_hometown",
        "end": END
    },
)

graph.add_edge("node_greeting", END)
graph.add_edge("node_hometown", END)

app = graph.compile()
app.invoke("家乡")

输出结果

图片

请思考

最后,让我们再看这样一种结构,并试着把写出代码。
注意:node_greeting和node_hometown各有一条往回指的Edge,为什么会有它的存在呢?

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值