跳转至

第 10 步:构建 BT Skill

这一节学什么

  • 为什么 BT skill 适合放到节点和树之后再讲
  • 一个最小 BT skill 目录由什么组成
  • SKILL.md、tree.py 和运行时状态键分别负责什么
  • 上层 agent 正常会怎样调用 BT skill

你会运行什么

示例代码:

  • examples/getting_started/step_10_build_bt_skill.py

这个步骤会配套查看:

  • examples/getting_started/skills/bt_echo/SKILL.md
  • examples/getting_started/skills/bt_echo/tree.py

运行:

python examples/getting_started/step_10_build_bt_skill.py

为什么放到这里

BT skill 本质上不是“再写一段 prompt”。

它更像:

  • 把一个子行为树打包成 skill

所以在理解它之前,先学完下面两件事会更顺:

  • 节点怎么组合成树
  • 自定义 Node 怎么读写 state / port

这也是为什么这一节放在 Step 08 和 Step 09 后面。

一个 BT skill 最少需要什么

这个最小例子里有两部分:

  1. SKILL.md
  2. 声明名字、描述和执行模式
  3. tree.py
  4. 提供真正执行的行为树构造函数

可以把它们理解成:

  • SKILL.md 负责“声明这是一个什么 skill”
  • tree.py 负责“这个 skill 运行时实际做什么”

结构化结果桥接现在不该再简单理解成“在 SKILL.md 里声明 output key”。按当前 runtime,更关键的是:

  • BT 子树把结构化结果写到 ctx.skill_result_key 指向的命名空间内状态键
  • 这个键通常来自 SkillNodeConfig.keys.skill_result

这一节现在演示的主路径

这一节不再把 BT skill 直接当成“整个 demo 的根树”来理解。

更接近真实使用方式的是:

  1. 先定义一个 BT skill
  2. 再让一个上层 agent 在需要时调用它

这个上层 agent 仍然是通过 SkillNode 接 skill,但因为这里提供了 model_client:

  • 外层会先走一轮 ReAct
  • ReAct 看见可用的 BT skill 后,会调用 run_bt_skill
  • run_bt_skill 再去执行这个 skill 的 tree.py

所以你在这一节看到的,不是“BT skill 必须用 Agent 封装”,而是:

  • Agent 是最外层 demo 宿主
  • 本例中的 SkillNode 是 skill 接入层和外层 ReAct 宿主
  • BT skill 真正的执行体还是 tree.py -> build_tree(ctx)

本例使用缺省的 orchestration: react。如果 BT skill 声明 orchestration: direct,并且是唯一加载的技能,SkillNode 会直接运行它并发布正式 skill_result,不再经过外层 ReAct 总结。

Prompt Skill 和 BT Skill 的边界

可以先按这个标准区分:

  • prompt skill
  • 主要靠一段 skill prompt 驱动模型
  • BT skill
  • 主要靠显式节点、状态和树结构驱动执行

所以当你发现自己已经开始需要:

  • 稳定控制顺序
  • 确定性状态写回
  • 非模型驱动的局部逻辑

通常就该考虑 BT skill,而不是继续给 prompt skill 叠说明。

运行后观察什么

  • 外层 assistant 会出现一次 run_bt_skill(...) 调用痕迹
  • 这个 BT skill 返回的结果会被上层 agent 消费
  • BT skill 会把结构化结果写入 ctx.skill_result_key 桥接到的 runtime key(通常就是 SkillNodeConfig.keys.skill_result),run_bt_skill 再把这个值暴露为 tool output,而外层宿主仍然可以单独生成自己的 final_answer
  • skill 的打包形式已经从“一个 prompt 文件”升级成“一个可运行子树”

怎么理解这一层分工

可以先按下面记:

  • SKILL.md
  • 声明这个 skill 的名字、模式和元数据
  • tree.py
  • 定义这个 skill 真正执行的行为树
  • SkillNode
  • 把 skill 接到 agent 主路径里,并把 BT skill 暴露成 run_bt_skill
  • 对单个 orchestration: direct BT,不创建外层 ReAct
  • Agent
  • 驱动整个示例运行,但不是 BT skill 自身的封装层

下一步