第 08 步:用节点组合 Agent¶
这一节学什么¶
Agent不等于单个 LLM 节点Sequence、Selector、Parallel的基本行为树语义- 已有节点怎么被放进一棵树里
- 什么时候该用节点编排,而不是继续堆 prompt
你会运行什么¶
示例代码:
examples/getting_started/step_08_compose_agent_from_nodes.py
运行:
核心概念¶
前面几步更多是在一条标准 ReAct 主路径上做增量扩展。
这一节开始进入 jianmu 更像行为树框架的一面。
重点不是写新节点,而是理解怎么自己组一棵树。
这一步只使用已有节点和行为树组合子:
ToolNodeStateConditionSequenceSelectorParallel
自定义节点会放到下一节再讲。
tick 是什么¶
行为树不是“一次函数调用把整条流程跑完”。
更准确地说,runner 会反复 tick 根节点,每次让整棵树推进一点。
所以你可以把一次运行先理解成:
- runner tick 根节点
- 根节点再 tick 它的子节点
- 子节点返回
SUCCESS / FAILURE / RUNNING - 这些状态再一路向上汇总成整棵树当前的状态
这也是为什么前面会出现 RUNNING:
- 不是流程失败了
- 而是这棵树这一步还没有完成
memory=True 是什么¶
这一节的 Sequence 和 Selector 都写了:
它的最小心智是:
- 记住上一次已经推进到哪个子节点
如果没有 memory=True,某些组合子在下一次 tick 时可能会从第一个子节点重新开始评估。
Getting Started 阶段你可以先这样理解:
memory=True更适合有明确推进顺序的流程- 它让树更像“继续执行上一步没做完的地方”
三种基础状态¶
行为树节点每次被 tick 后,最核心的返回值就是三种状态:
SUCCESS- 当前节点这一步已经完成,而且结果满足预期
FAILURE- 当前节点这一步已经完成,但条件不满足,或者这条路径不成立
RUNNING- 当前节点还没完成,需要后续 tick 继续推进
可以先把它理解成:
SUCCESS / FAILURE更像“这一步已经有结论了”RUNNING更像“这一步还没做完”
这也是为什么行为树不是普通函数调用。
普通函数通常是“一次调用,一次返回结果”。 行为树节点则可能:
- 第一次 tick 时先返回
RUNNING - 后面几次 tick 才变成
SUCCESS或FAILURE
组合子到底在组合什么¶
Sequence、Selector、Parallel 本质上都不是在组合“代码块”,而是在组合子节点返回的状态。
你可以先按下面理解:
Sequence- 子节点
SUCCESS才继续下一个 - 遇到
FAILURE就停 - 遇到
RUNNING就整体RUNNING Selector- 子节点
FAILURE才继续试下一个 - 遇到
SUCCESS就停 - 遇到
RUNNING就整体RUNNING Parallel- 同时 tick 多个子节点
- 再由
ParallelPolicy决定整体状态
所以你在这一节看到的:
Sequence status: SUCCESSPrimary child status: FAILUREFallback child status: SUCCESSBranch statuses: ['SUCCESS', 'SUCCESS']
本质上都是这些节点状态的直接体现。
Sequence¶
Sequence 表示顺序执行。
可以先理解成:
- 从左到右 tick 子节点
- 前一个成功,才继续下一个
- 有一个失败,整体就失败
本节示例里,Sequence 先运行 ToolNode 做计算,再用 StateCondition 检查结果。
Selector¶
Selector 表示按优先级选择。
可以先理解成:
- 从左到右尝试子节点
- 前一个失败,才尝试下一个
- 有一个成功,整体就成功
本节示例里,第一个 StateCondition 失败后,会走 fallback 条件分支。
Parallel¶
Parallel 表示多个分支一起 tick。
它一定要配一个 ParallelPolicy,用来决定整体什么时候算成功。
本节示例使用:
含义是:
- 所有分支都成功时,整体才成功
这里只演示了一种最常见策略,但不是唯一策略。
至少可以先知道两种直观语义:
SuccessOnAll- 所有分支都成功,整体才成功
SuccessOnOne- 只要有一个分支成功,整体就可以成功
也就是说,Parallel 的关键不只是“并行”,还包括:
- 并行之后,整体成功条件是什么
运行后观察什么¶
Sequence为什么适合“先做 A,再检查 B”Selector为什么适合 fallbackParallel为什么适合多个分支同时推进- 什么时候应该用树结构表达流程,而不是继续堆 prompt
这一节不定义新的业务节点。
示例里的所有分支都由现成节点组成:
ToolNode负责显式工具调用StateCondition负责状态条件判断- 组合子负责控制执行顺序、fallback 和并行策略
如果你发现现有节点不够表达你的流程,下一节才进入自定义 Node。