ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

尚硅谷LangGraph教程之状态简记

尚硅谷LangGraph教程之状态简记 AI Agent学习 | 在Langgraph中四种状态的讨论系统学习完langchain这个框架后听说langgraph是更为底层的框架适用于实现更复杂的智能体就又去学习了langgraph框架现在还没学完就对前面我印象比较深刻的点来讨论一下这次是对langgraph中四种状态的讨论。langgraph这个框架中state负责上下游信息等的传递是langgraph的核心部分。我自己原来没有系统学习langgraph的时候因为想实现一个multiagent的项目的demo由于对这部分不了解也好奇怎么实现的就去github上找了并花了几天时间看了一个多智能体生成相关话题报表的一个小项目那时候就对状态传递这个点感觉很有意思感觉是一个优雅的程序内的流程处理或者是信息传递的方式。首先先来介绍一下常见的状态类型全局状态输入状态输出状态私有状态。第一个是全局状态我的理解是可以作为langgraph中传递信息等字段的一个全集包括了图运行过程中需要读写的大部分字段。输入状态则是对输入进图中的信息的一个约束声明了调用图时允许输入的字段。输出状态则是选择性暴露出图运行结束后要返回的结果包含的字段。可以说输入和输出状态都是全局状态的子集它们中的字段都是来自于全局状态的字段。最后则是私有状态这个状态比较特殊刚开始看是我还不太明白它的作用后面了解清楚后才发现私有状态也是不可或缺的一个重要部分。课程给的文档中是这么描述其作用的图内部节点之间传递的临时状态通常不作为图的输入也不作为图的最终输出。它可以通过节点函数的入参类型注解声明并在节点返回值中写入。光说大家可能会难理解我把langchain官方的文档中的实例代码放过来from typing import TypedDict from langgraph.graph import END, START, StateGraph class InputState(TypedDict): user_input: str class OutputState(TypedDict): graph_output: str class OverallState(TypedDict): foo: str user_input: str graph_output: str class PrivateState(TypedDict): bar: str def node_1(state: InputState) - OverallState: # Write to OverallState return {foo: state[user_input] name} def node_2(state: OverallState) - PrivateState: # Read from OverallState, write to PrivateState return {bar: state[foo] is} def node_3(state: PrivateState) - OutputState: # Read from PrivateState, write to OutputState return {graph_output: state[bar] Lance} builder StateGraph(OverallState, input_schemaInputState, output_schemaOutputState) builder.add_node(node_1, node_1) builder.add_node(node_2, node_2) builder.add_node(node_3, node_3) builder.add_edge(START, node_1) builder.add_edge(node_1, node_2) builder.add_edge(node_2, node_3) builder.add_edge(node_3, END) graph builder.compile() graph.invoke({user_input: My}) # {graph_output: My name is Lance}可以看到这里将四个状态都做了声明PrivateState中是有bar这个字段而这个字段在全局状态OutputState是没有的。class OverallState(TypedDict): foo: str user_input: str graph_output: str class PrivateState(TypedDict): bar: str接着我们看一下节点中是怎么传递和处理状态的def node_1(state: InputState) - OverallState: # Write to OverallState return {foo: state[user_input] name} def node_2(state: OverallState) - PrivateState: # Read from OverallState, write to PrivateState return {bar: state[foo] is} def node_3(state: PrivateState) - OutputState: # Read from PrivateState, write to OutputState return {graph_output: state[bar] Lance}第一个节点入参是InputState接收了输入在节点内处理后存入到全局状态的foo字段中道理第二个节点入参变成了OverallState全局状态返回参数给到了私有状态私有状态拿到了加工后的字段数据后在最后一个节点后经过节点内的处理最后给到了输出状态。这个简短的例子就可以看到了langgraph程序内部在传递信息的时候就可以使用私有状态进行临时状态传递。其实直接使用全局状态传递上下游间的状态同样可以但是为什么要使用私有状态呢首先全局状态确实基本包含了大部分字段但是在交给节点处理信息的时候状态中的字段反而不是越多越好特别是对于模型处理的节点就要避免将涉及隐私或者机密等的字段信息传给云端的大模型导致可能的信息泄露。还有就是单独的私有状态将所需字段标出来这样到后面节点多的时候也能看出来节点所需什么字段减少节点之间的“隐式依赖”降低状态的耦合程度。除了上面这点私有状态还可以用于存储一些节点处理后的中间产物例如rag流程中的向量数据文本块数据等这些中间产物如果作为新的字段存入全局状态中会使其臃肿也较难管理使用私有状态存储后面再将最终产物传递给全局状态或者输出状态。还有很多的益处这里也不过多赘述。最后要说一下在这里定义的这些状态其实都是从langgraph提供的一个state中取的字段包括所谓的“全局变量”其是一个单一的、全局的字典来承载所有状态数据。这里定义的InputState、OutputState、PrivateState等都是对这个底层字典在不同阶段、不同节点上的“视图”或“访问权限控制”而非相互隔离的独立容器。下面是官网的说明链接Node input: always receives full state | Langgraph Beginner Course | The Neural Base这也解释了为什么虽然每个节点后都写了返回值但实际上在python中返回值没做强制校验但是在流程中下一个节点又能正常获得状态。本次对langgraph四种状态的讨论就到这里如果文章有误欢迎大家指出觉得还可以的话可以给作者一个赞和收藏吗(ˊᗜˋ)
返回列表