🐳 第四章 从Skill、Tool到Hook
📄 一句话概括

一次工具调用要过六道关:挂载期(有效性)→ 注册期(依赖分组)→ 调用前(审批)→ 调用中(沙箱)→ 执行中(超时/溢出)→ 执行后(观察与留痕),关关都有真身。

📝 本节和前面几节的关系

4.3 讲了规则是插件,这一节把它们按时间排成一队——管线 = 关卡顺序,规则 = 每道关卡的判断。

一、六道关,按时间排

前两道关在【挂载阶段】就过完了,跟具体调用无关;后四道才是一次调用真正走过的路。

二、实测数字:挂载期就有 20 处条件

配置里 disabled 一共 58 行,其中 20 处是条件表达式(平台判断、作用域判断),不是写死的布尔值。

典型两处:tool-bash 带 platform === 'win32'、tool-pwsh 带 platform !== 'win32'。

这说明【能力在不在】在挂载期就定了,不是运行时才决定的——排查问题时,这一步先看配置树,比看日志快。

三、分组就是关卡的落点

实测有 10 处 cordis:group(group: true),它们把子能力圈在一起,还带 isolate 声明,例如:

分组的价值是隔离:某一组换实现、开关,影响不到别的组。关卡要能独立开关,就得先有边界——又是 3.2.2 那个道理。

四、为什么要有管线

因为动手的路径必须唯一。如果每个工具各自决定【要不要问人、能改哪些文件】,权限就散了。

管线把这件事收成一条:所有工具调用从同一道门进来,规则在这一层统一判断。

于是 4.6 的问题自然就有了答案:程序编排也不能绕开这道门。

五、动手 Demo:一次工具调用要过几道关

六道关,每道关配上配置里的真身:

stages = [
    ("挂载期", "这个插件在此平台/作用域有效吗", "disabled 条件"),
    ("注册期", "名字、依赖、分组对不对", "cordis:group"),
    ("调用前", "这一次要不要先问人", "user-approval"),
    ("调用中", "能在多大范围里动手", "sandbox-policy"),
    ("执行中", "多久算超时、结果太大怎么办", "timeout/spill"),
    ("执行后", "要不要留证据、要不要提醒", "观察策略"),
]
for a, b, c in stages:
    print("  %-6s %-24s %s" % (a, b, c))
print()
print("  disabled 行 58 处,其中有条件的 20 处")
print("  cordis:group 分组 10 个")

实跑输出:

--------------------------------------------------------------------
一次工具调用要过几道关
--------------------------------------------------------------------
  把关卡通按时间顺序摆出来,每一关在配置里都有真身:

  阶段       过关时看什么                       配置里的真身
  ------------------------------------------------------------------------
  挂载期     这个插件在此平台/作用域有效吗     disabled 条件
  注册期     名字、依赖、分组对不对             cordis:group
  调用前     这一次要不要先问人                 user-approval
  调用中     能在多大范围里动手                 sandbox-policy
  执行中     多久算超时、结果太大怎么办         timeout/spill policy
  执行后     要不要留证据、要不要提醒           观察策略/repeat-reminder
  ------------------------------------------------------------------------

  实测数字:

    配置里 disabled 的行数        58
    其中【有条件】的 disabled      20     <- 平台或作用域决定,不是写死
    cordis:group 分组数           10

  那 20 处条件说明一件事:挂载期就有判断,
  所以【能力在不在】不是运行时才决定的。

前两道关和调用无关:它们在挂载时就过完了——所以【能力在不在】要在配置树里查。 20 处条件表达式是【挂载期判断】的实证,也是 4.1.2 那个实验只多 1 行的原因。 分组带的 isolate 是隔离声明:关卡的边界,就是分组的作用域(3.2.2 的复现)。

30 秒实验

  1. 在配置里数一数 disabled 有多少处、其中有条件的有多少处。
  2. 找出一处 cordis:group,看它的 isolate 声明隔离了什么。
  3. 按六道关的顺序复述一遍:哪几道在挂载时过、哪几道在调用时过?

常见误区

  1. 错误:工具调用就是【模型说、工具跑】两步。——纠正:要过六道关,前两道在挂载期,后四道在调用期。
  2. 错误:能力在不在要运行起来才知道。——纠正:挂载期就定了——看配置树里的 disabled 条件。
  3. 错误:分组只是排版好看。——纠正:分组带 isolate,是隔离与独立开关的单位。
自测三问(点开对答案) 1. 六道关分别是什么? —— 挂载期、注册期、调用前、调用中、执行中、执行后。 2. `disabled` 58 处、其中 20 处有条件,说明什么? —— **能力在不在挂载期就定了**(平台/作用域判断),不是运行时决定的。 3. 为什么要有管线? —— **动手的路径必须唯一**:所有工具调用从同一道门进来,规则统一判断。

相关笔记