18—sentry-static 入口收敛:从多能力检查到 1 个静态分析入口

前两篇分别处理了 LLM 调用太多和 subagent 切换太贵的问题。效率专题的第三个问题出现在工具入口上:如果用户每次都要判断该跑 lint、trigger 还是 check,系统依然不够顺手。

sentry-static 的入口收敛,解决的不是"少一个命令名"这么简单,而是把用户的一次完整静态分析意图收进一个稳定入口。本文讨论的原则是:工具边界应该按用户意图划分,而不是按内部检查项划分。

回顾:三个版本,三种形态

版本 工具形态 用户操作
v5.x-v6.x sentry-lint + sentry-trigger(两个独立工具) 说两次、跑两次、看两份报告
v7.1 sentry-check(两者合并) 说一次、跑一次、看一份报告(含两部分)
稳定形态 sentry-static(Lint + Trigger + Summary + 后续检查组) 说一次、跑一次、看一份报告 + 发布建议

表面看只是改了名字、合了入口、加了检查维度,但每次变形背后都有一个工程决策点。


第一次合并:sentry-lint + sentry-trigger → sentry-check(v7.1)

合并前的痛点

v6.x 里 lint 和 trigger 是两个完全独立的工具:

arduino 复制代码
sentry-lint    → 静态结构检查,~30s
sentry-trigger → 触发率 AI 模拟(TP/TN),~2min

实际使用中发现三个问题:

1. 几乎没有人只跑一个

我们复盘过 20+ 次真实测评的调用模式,内部统计显示:

  • 92% 的情况:用户同时需要两者
  • 5% 的情况:只跑 lint(快速检查结构)
  • 3% 的情况:只跑 trigger(微调 description 后重测)

两个工具意味着两次 spawn、两次 yield/resume、两份回执------但用户 92% 的时间里只有一个意图:「帮我看看这个 Skill 写得好不好」。

2. 报告割裂导致用户需要自行关联

lint 报告说「description 太短,缺少不触发场景」,trigger 报告说「TN 不触发率只有 40%」。

这两个结论之间有因果关系------正是因为 description 缺少「不触发场景」描述,导致 AI 在判断是否触发时没有足够的排除信号。但两份独立报告里看不到这种关联。

3. 编排器需要额外逻辑决定先后

主编排器需要先跑 lint、再跑 trigger(因为如果 description 都不存在,trigger 跑了也没意义)。这种「先后依赖 + 条件跳过」逻辑增加了编排器的复杂度。

合并后的设计

xml 复制代码
sentry-check:
  Part 1: 静态检查,~30s
  Part 2: 触发率评估(TP/TN),~2min

  支持子模式:
    lint <Skill名>    → 只跑 Part 1
    测触发率 <Skill名> → 只跑 Part 2
    check <Skill名>   → 两项都跑

向后兼容------旧的 lint测触发率 命令继续有效。

合并判断标准:如果两个工具 >80% 的调用场景里总是一起出现,且它们的输入相同(都是读 SKILL.md),合并通常是正确的。


第二次演进:sentry-check → sentry-static(状态机阶段)

为什么不继续叫 sentry-check

v7.1 的 sentry-check 本质上是「把两个工具的输出拼在一起」。用户看到的是:

makefile 复制代码
## Part 1 · 静态检查
L1: ✅ / ⚠️ / ...
L2: ...
L3: ...
L4: ...
L5: ...

## Part 2 · 触发率评估
TP: 80%
TN: 67%

然后用户自己判断:「L1 说 description 没问题,但 TN 只有 67%,说明不触发场景虽然有,但写得不够精准。」

问题在于:这个推理应该由工具自动完成。

状态机阶段 新增 Sub-step 3:综合建议

vbnet 复制代码
sentry-static:
  Sub-step 1: Lint(静态规则检查)
  Sub-step 2: Trigger(TP/TN 触发率评估)
  Sub-step 3: Summary(交叉分析 + 综合发布建议)

Sub-step 3 的逻辑:

Lint 信号 Trigger 信号 综合建议
L1 description 完整 TP ≥ 80%, TN ≥ 80% ✅ 静态检查通过,建议进入测评
L1 description 完整 TP ≥ 80%, TN < 80% ⚠️ 触发精度不足:补充不触发场景描述
L1 description 不完整 TP < 80% ❌ 根源:description 信息不足,先补完再测
L2 缺少 HiL --- ❌ 安全问题:不可逆操作必须加确认节点
L3 复杂度 > 20 --- ⚠️ 建议拆分,否则执行稳定性难保证

关键改变:从「给两组数据」变成「给一个判断 + 理由」。用户不需要自己关联两份报告------工具帮你做了。

为什么改名

sentry-check 的语义是「检查」------暗示输出是一堆检查项。sentry-static 的语义是「静态分析」------暗示输出是分析结论。

名字的改变反映了工具定位的变化:从「数据展示」到「分析判断」。


旧 sentry-check 怎么处理

现在的实现里,原 sentry-check 是兼容入口,不是推荐入口:

markdown 复制代码
# sentry-check(兼容入口)

此工具已被 sentry-static 替代。
如果你是通过旧命令到达这里,请改用 sentry-static。

所有旧命令仍然有效:
- lint <Skill名> → sentry-static --lint-only
- 测触发率 <Skill名> → sentry-static --trigger-only
- check <Skill名> → sentry-static(完整模式)

为什么保留兼容入口而不直接删除?因为用户(和 AI 编排器)可能对 sentry-check 有肌肉记忆。兼容入口起到重定向作用,零成本地处理旧路径。


独立模式仍然保留

合并不意味着失去精细控制:

arduino 复制代码
sentry-static --lint-only     → 只跑 Sub-step 1(~30s)
sentry-static --trigger-only  → 只跑 Sub-step 2(~2min)
sentry-static                 → 三步全跑(~2.5min)

保留独立模式的场景:

  • 微调后快速验证:改了 description 后只想验触发率,不需要重跑全部 lint
  • CI 集成:CI 环境只需要 lint(确定性检查),trigger 涉及 AI 推理,耗时且结果波动
  • 调试单项:某一项不通过时,重跑单项比等全部快

设计决策框架:何时该合并、何时该拆分

从 sentry-lint/trigger → sentry-check → sentry-static 的演进中,我总结出一套判断标准:

合并的信号

信号 强度
>80% 调用场景里一起使用 强信号
输入完全相同(同一份文件) 强信号
输出之间有因果关系需要交叉分析 强信号
合并后可以减少 1 次 spawn/yield 中信号
用户分不清两个工具的区别 弱信号

拆分的信号

信号 强度
执行时间差异 >10x 强信号
一个失败不应阻止另一个执行 强信号
不同的输入来源 中信号
权限要求不同 中信号
复用场景完全不同(被不同上游调用) 弱信号

应用到 SkillSentry 的例子

为什么 sentry-staticcases 步骤合并?

  • 输入不同:static 只读 SKILL.md,cases 还需要 inputs/ 素材
  • 失败独立:static 失败(结构有问题)时,用户可能选择修复后才跑 cases
  • 时间差异:static ~2.5min,cases ~5-8min
  • 调用场景不同:用户可能只想 lint 不想设计用例

三个拆分信号都命中------不合并是正确的。


对 Pipeline 状态机的影响

sentry-static 的引入对 状态机阶段 Pipeline 设计有一个关键影响:

Pipeline 数组的第一步从 check 变成 static

json 复制代码
// v7.x(非正式 pipeline)
["check", "cases", "executor", "grader", "report"]

// 状态机阶段+ 正式 Pipeline
["static", "cases", "sync-pull", "sync-push-cases",
 "executor-with", "grader", "sync-push-results", "report", "publish"]

状态机只认 Pipeline 数组里的 step name。当工具改名时,Pipeline 数组必须同步更新。这就是为什么当前主流程只写 static,不再把 linttriggercheck 写成正式 pipeline step。


工具链演进的一般规律

回顾 SkillSentry 从 v5.x 到稳定形态的工具演进:

ini 复制代码
v5.x: 5 个独立工具(lint, trigger, cases, executor, grader)
v6.x: 5 个 + sync + report = 7 个
v7.1: 合并 → check + cases + executor + grader + report = 5 个
状态机阶段: 重组 → static + cases + executor + grader(含report) + report(独立)
      + comparator + analyzer + openclaw = 8 个
稳定形态: 收敛 → static 是推荐入口;grader-report 是主流程评分报告;
      sentry-report 仅用于已有 grading 后独立重出报告

工具数量不是越少越好,也不是越多越好。判断标准是:每个工具对应一个「用户意图的最小完整单元」

  • v6.x 的 7 个工具太碎------lint 和 trigger 不是独立意图
  • 如果把所有工具合成 1 个------那就是把「工具」做成了「应用」,失去了可组合性

最终形态是在「原子可组合」和「意图完整」之间找到平衡点。


后续扩展:规则组 6------规范合规检查

入口收敛解决的是"用户只需要记一个静态分析入口":Lint、Trigger、Summary 和后续检查组都收进 sentry-static。下面的 L6 不是新增入口,而是在这个稳定入口内部继续增加的检查维度,用来回答一个更基础的问题:SKILL.md 的结构是否完整?

一个真实案例:某个 Skill 通过了 L1-L5 全部检查,但新人接手时完全不知道它解决什么问题、依赖哪些环境变量、输入输出格式是什么、覆盖/不覆盖哪些场景。这些不是"规则",是"结构"------决定了 Skill 能不能被团队理解和维护。

为什么结构完整度也是质量指标

对照《MIT AI Skill 撰写规范 V1.1-beta》,一份标准 SKILL.md 应该覆盖 13 个章节。每个章节对应一个实际问题:

章节 对应的实际问题
问题描述 新人看不懂这个 Skill 为什么存在
触发场景 AI 不知道什么时候该激活
交互契约 Agent 可能自作主张执行危险操作
架构概览 维护者不知道改哪个文件影响什么
端到端示例 开发者不知道"跑一次"长什么样
输入/输出契约 集成方不知道传什么、收什么
健壮性能力 没人知道失败了会怎样
限制与边界 用户以为它什么都能做

缺一个章节,就多一个"凭感觉"的环节。

L6 的三层检查

L6a:Frontmatter 9 字段------name、display_name、version、description、author、track、platform、spec、tags。缺 name/version 会影响 CI 缓存命中(sentry_preflight.py 用 name + hash 判断复用)。

L6b:13 章节覆盖率------逐项检查是否存在对应内容(不是看标题,是看实质内容):

  • ✅ 存在且实质性
  • ⚠️ 散落在其他章节中(建议独立)
  • ❌ 完全缺失

L6c:合规度评级

erlang 复制代码
≥ 90% → ✅ 合规    70-89% → ⚠️ 基本合规
50-69% → ⚠️ 部分合规    < 50% → ❌ 不合规

和 L1-L5 的关系

L6 不替代 L1-L5。一个 Skill 可以 L1-L5 全绿但 L6 只有 35%------能跑,但别人接不住。反过来 L6 100% 但 L2 红(写操作没确认),也不能发布。六组一起看才是完整的静态质量画像。

CI 中的定位

L6 评级可以写入结构化诊断产物或报告,但不作为 PASS/FAIL 的否决项------它是参考指标,帮助发布决策者判断"这个 Skill 是否已经准备好交给别人用"。已有的、能正常工作的 Skill 不应该因为"文档不全"被卡住。


FAQ

Q:sentry-static 的 Sub-step 3 会不会引入 AI 判断的不确定性?

Sub-step 3 的判断逻辑是规则化的------基于静态检查项和 TP/TN 的数值阈值,不是让 AI 自由发挥。AI 只负责生成自然语言的解释文本,判断本身是确定性的。

Q:从 sentry-check 迁移到 sentry-static 需要改什么?

用户侧:推荐入口统一成 sentry-staticlint测触发率check 这类旧说法可以继续被兼容或重定向,但不再作为正式入口推荐。

Pipeline 侧:如果你有自定义的 pipeline 配置,把 step name 从 check 改成 static 即可。

Q:兼容入口会一直保留吗?

当前仍保留兼容入口。是否删除不应按版本号拍脑袋,而应看日志中是否还有旧命令调用;只要仍有调用,就应保留重定向并在文档里明确当前推荐入口是 sentry-static


来源:sentry-static 设计文档、SkillSentry contract、历史 sentry-check/SKILL.md。

相关推荐
To_OC1 天前
别再跟 AI 死磕 prompt 了,我写了个 Loop 让它自己改到满意为止
人工智能·aigc·agent
悟空码字1 天前
【高德开放平台skill】从拍脑袋到看数据,我是如何把一个“选址直觉“做成 AI Skill 的
aigc·openai·ai编程
Gatlin1 天前
当你告诉AI“帮我搞定这件事”——AI Agent正在改变规则
aigc
怕浪猫1 天前
第一章:AI Agent概览:开启智能体时代
aigc·agent·ai编程
leeyi1 天前
Multi-Agent:让多个 AI 分工协作完成复杂任务
后端·aigc·agent
Alson_Code1 天前
人机协作项目文档--HITL-AgentScope
后端·aigc·ai编程
leeyi2 天前
Prompt 模板:用变量组装发给 AI 的消息
aigc·agent·ai编程
用户5191495848452 天前
libcurl Headers API 释放后重利用漏洞:跨请求复用头句柄导致堆内存安全风险
人工智能·aigc