891 字
约 2 分钟
6
状态管理器:让工作流节点“记住”上下文
状态管理器:让工作流节点“记住”上下文
在一个工作流中,节点并不是独立执行的。
前一个节点产生的结果,要传给下一个节点;更早节点的数据,后面的节点有时也需要再次使用。负责管理这些数据的,就是 StateManager。
一、状态从哪里开始
工作流启动时,StateManager 会创建一个状态对象,通常包含以下信息:
inputData 原始输入
currentInput 当前节点要处理的数据
nodeOutputs 所有节点的历史输出
status 当前状态,例如 RUNNING
startTime 工作流开始时间
其中,currentInput 初始值就是原始输入,nodeOutputs 初始为空。
例如用户输入:
请把这段中文翻译成英文
初始化后的状态可以理解为:
{
"inputData": "请把这段中文翻译成英文",
"currentInput": "请把这段中文翻译成英文",
"nodeOutputs": {},
"status": "RUNNING"
}
二、状态如何在节点之间流转
每个节点执行完成后,都会生成一个新状态:
- 读取
currentInput - 执行节点逻辑
- 把输出写回
currentInput - 同时保存到
nodeOutputs
执行过程大致如下:
初始化
↓
节点 A 执行
↓
状态更新
↓
节点 B 执行
↓
状态更新
↓
提取最终结果
假设流程是:
输入 → 翻译 → 校对
翻译节点执行后:
{
"currentInput": "This is a translated sentence.",
"nodeOutputs": {
"translation": "This is a translated sentence."
}
}
校对节点继续读取 currentInput,处理完成后再次覆盖它。
因此,流程结束时,currentInput 中保存的就是最后一个节点的输出。getFinalOutput() 直接读取这个值即可。
三、为什么还需要 nodeOutputs
如果只有 currentInput,数据只能像接力一样向后传递:
A 的输出 → B 的输入 → C 的输入
这样虽然简单,但前面的数据会逐渐被覆盖。
例如在“搜索 + 总结”流程中:
- 用户提出一个问题
- Search 节点检索出三篇文档
- Summary 节点需要同时看到原始问题和检索结果
这时:
currentInput可以保存检索结果nodeOutputs可以保存原始问题和所有历史输出
后面的节点就能回头引用之前的数据,而不必依赖单一路径传递。
可以把它理解为:
currentInput:传送带上的当前数据
nodeOutputs:整个流程的历史档案
四、一个简单例子
“翻译 + 校对”流程中:
{
"currentInput": "This is a translated sentence.",
"nodeOutputs": {
"input-1": "这是一句话。",
"translation-1": "This is a translated sentence."
}
}
校对节点可以:
- 从
currentInput获取待校对的英文 - 从
nodeOutputs["input-1"]获取原始中文
这样既能处理当前结果,也能访问历史上下文。
五、总结
StateManager 管理的是工作流的完整生命周期:
初始化状态
→ 节点读取状态
→ 节点产生输出
→ 状态持续更新
→ 最后提取结果
其中:
currentInput负责节点之间的连续传递nodeOutputs负责保存所有历史结果inputData保留最初的用户输入status和startTime记录执行信息
正因为有了这套状态机制,工作流节点既能“接着上一步继续处理”,也能“回头查看之前发生了什么”。
评论
0 条
还没有评论,先写一条吧。