当前位置:首页>排行榜>AI Skill 测评长流程防跳步:SkillSentry Pipeline 状态机与统一契约(21)

AI Skill 测评长流程防跳步:SkillSentry Pipeline 状态机与统一契约(21)

  • 更新时间 2026-11-11 13:04:05
AI Skill 测评长流程防跳步:SkillSentry Pipeline 状态机与统一契约(21)
点击蓝字,关注我们

从本文开始,系列进入 SkillSentry 的架构可靠性专题。

前一组文章解决的是效率:更少的 LLM 调用、更少的切换、更清楚的入口、更可控的 token 用量。效率问题处理完,AI Skill 测评系统会暴露出另一个更底层的问题:长流程能不能稳定跑完,断了之后能不能恢复,多个工具之间的契约会不会分叉。

这一组会依次讲五件事:

状态机 → 断点续跑 → 代码化 → 工具箱 → 演进史

本文先讲第一件事:为什么 SkillSentry 需要 Pipeline 状态机,以及为什么 session.json 、 grader-report 、 sentry-static 、 authoritative_pass_rate 、 PASS / CONDITIONAL PASS / FAIL 这些名字必须收敛成统一契约。

在做这次架构收敛之前,SkillSentry 在 standard/full 模式下反复遇到同一类问题:

AI 编排器的上下文疲劳。

具体表现:

  1. 跳步 :跑到 executor 后直接跳到 report,忘了中间的 grader
  2. 凭记忆执行 :不重读 SKILL.md,凭上文的「印象」调度,产物路径写错
  3. 步骤合并 :把 Step 0/1/2 的输出合并成一条消息,用户看不到中间过程
  4. sync 遗忘 :飞书同步是"附加动作",不在强制执行路径上,经常被跳过

这不是 prompt 写得不好的问题——是 LLM 应用的结构性问题: 长对话中,编排器的注意力会衰减,导致非强制路径的步骤被静默跳过。

在做这次架构收敛之前,我们反复被同一类问题困扰:流程被跳过、产物被遗忘、口径发生分叉。最后我们发现,这三个问题其实对应了 LLM 编排系统架构收敛的三个判断条件:

  1. 流程不被跳过 :LLM 上下文疲劳时,会选择性忽略某些步骤。需要状态机强制路径,而不是靠提示词提醒。
  2. 产物不被遗忘 :跨轮次的数据必须写到文件,不能只活在对话上下文里。
  3. 口径不发生分叉 :pipeline 定义、评分阈值、发布结论必须来自同一处,不能在多个地方各自维护。

以下记录了 SkillSentry 如何用具体改动逐一解决这三个问题。

我们从这次重构中提炼了三条对任何 LLM 编排系统都适用的教训:

1. 文件状态 > 上下文记忆

LLM 的上下文窗口不是数据库。长对话中任何依赖「AI 记得之前做了什么」的设计都不可靠。用文件(session.json、active-pipeline.json)作为 single source of truth。

2. 强制路径 > 提醒标记

⛔ 禁止跳过 这种 prompt 级约束,在短对话中有效,长对话中失效。要保证某个步骤一定执行,唯一靠谱的方式是把它放进状态机的合法转移路径里。

3. 降级 > 终止

AI 系统的超时和错误是常态。设计时把「失败后怎么办」想清楚(一级→二级→三级降级),比设计「怎么不失败」更有工程价值。


先给结论

SkillSentry 当前这次收敛不是一次继续加功能的版本,而是一次架构收敛:

Pipeline 状态机已经有了,下一步是让所有文档、工具和文章说同一套 contract。

当前版本的当前契约:

主题
稳定契约
稳定版本
SkillSentry 统一契约
主流程评分报告
grader-report
独立报告再生成
sentry-report
静态检查入口
sentry-static
核心通过率
authoritative_pass_rate
发布结论
PASS / CONDITIONAL PASS / FAIL
质量等级
S / A / B / C / D / F

所以这篇文章现在应按"旧版奠定架构基础,当前版完成契约收敛"来读。

为什么旧版架构不够了

旧版架构(「薄编排器 + 5 个原子工具 + 文件契约」)在短测评(smoke/quick)中运行良好,但在 standard/full 模式下暴露了前文描述的上下文疲劳问题——跳步、凭记忆执行、sync 遗忘。


Pipeline 状态机阶段的解法:四大设计支柱

支柱一:Pipeline(管道)

每个步骤有独立的输入/输出契约。步骤间不能跳线——缺失前置产物时触发降级,而不是静默跳过。

旧版的做法:

编排器凭记忆决定下一步是什么

当前 Pipeline 架构的做法:

session.json.pipeline = ["static", "cases", "case-quality-check", "sync-pull",                         "sync-push-cases", "executor-with", "grader-report",                         "sync-push-results", "publish"]

Pipeline 数组在 Step 2 写入后就是铁律 ——不在数组里的步骤 = 不存在。编排器不需要"记得"下一步是什么,只需要查数组。

支柱二:State Machine(状态机)

session.json.last_step 是唯一的流转依据。不靠上下文记忆。

合法状态转移:idle → step-0 → step-1 → step-2 → [pipeline per mode] → publish → idle

非法转移(如从 cases 直接跳到 report)→ abort + 告警。

支柱三:Graceful Degradation(降级兜底)

超时和失败有三级降级机制:

降级级别
触发条件
行为
一级:正常流转
subagent 正常完成
正常流转
二级:快速重试
subagent 900s 超时
切换为批量快速模式重试
三级:统计兜底
二级重试仍超时
纯统计模式,标注 [DEGRADED-STAT]

降级产物仍然推进 Pipeline ——标注降级标记,但不终止。

支柱四:Idempotent(幂等)

同 SKILL.md hash + 同模式 + 同天 → 提示复用已有结果,跳过重复执行。

这避免了用户多次说「测评」导致的重复消耗。


核心改造:无状态调度循环

当前 Pipeline 架构的主编排器做了一个根本性的改变: 每一轮调度都是无状态的。

每一轮循环:1. 读 session.json → 取 last_step2. 查 pipeline 数组 → 确定 next_step3. 读取 next_step 对应子工具的 SKILL.md(必须 read,不能凭记忆)4. spawn subagent5. 写入 active-pipeline.json(断点持久化)6.yield 等待7.resume 后验收产物(检查文件是否存在)8. 通知用户 + 更新 session.json9. 删除 active-pipeline.json10. 回到 1(不靠记忆,靠文件状态)

核心原则:主会话只调度,不执行。 所有复杂逻辑都委派给 subagent。契约收敛后,主流程里的评分和报告生成统一叫 grader-report ;独立 sentry-report 只用于已有 grading 后重新生成报告。


sentry-static 入口收敛

历史上有三个工具处理静态分析:

  • sentry-lint(结构检查)
  • sentry-trigger(触发率评估)
  • sentry-check(合并了前两者)

当前稳定入口是 sentry-static ,包含三步:

Sub-step 1: Lint(静态规则检查)Sub-step 2: Trigger(TP/TN 触发率评估)Sub-step 3: Summary(综合两者,输出发布建议)

这里的 Lint 是历史命名延续,当前对外不再使用 L0-L5 作为质量等级。静态检查关注的是 description、HiL、复杂度、冗余规则、可测试性和触发风险。

支持 --lint-only 和 --trigger-only 子模式,用于兼容旧命令和局部验证。

为什么不继续叫 sentry-check?因为增加了 Sub-step 3 的综合判断逻辑——不再是简单的「两个工具合在一起跑」,而是「分析两者的交叉信号后给出一个整合判断」。


Sync 步骤纳入 Pipeline

这是从旧版到当前架构阶段最容易被忽视但最重要的改造。

旧版的问题 :飞书同步是「步骤间隙的附加动作」,用 ⛔ 标记提醒编排器「别忘了」。但 ⛔ 标记 ≠ 执行保障——AI 在长对话中照样忘。

当前解法:把 sync 提升为 Pipeline 正式步骤。

Pipeline 数组:["static", "cases", "case-quality-check", "sync-pull", "sync-push-cases", "executor-with", "grader-report", "sync-push-results", "publish"]

状态机强制执行——sync 步骤必须被状态机「走过」,哪怕结果是 skipped_no_config 。


grader-report 合并架构

另一个大改动是 Grader 和 Report 合并为单个 subagent:

历史分离口径 :grader 评完 → 主编排器读结果 → spawn report subagent 稳定契约 : grader-report subagent 完成评审、汇总和报告生成

为什么合并?

  1. 减少上下文切换 :Grader 已经完整读过所有 transcript 和断言,它生成报告时不需要重新理解
  2. Batch 机制 :>12 个 eval 时分批处理(batch size 8),避免单 subagent 上下文过载
  3. Run-stratified 并行 :每个 subagent 处理一个 run 的全部 eval(而非一个 eval 的全部 run),提升并行效率

独立的 sentry-report 仍然保留,但只用于「grading 已完成,只想重新生成报告」的场景。它不在主 pipeline 中。


Token 计量

当前版新增每步 token 消耗记录:

spawn 前:before_usage = session_status().usage.total_tokenssubagent 完成后:after_usage = session_status().usage.total_tokens差值写入:cost[step_name] = after_usage - before_usage

写入 token 诊断结构,最终可以汇总到 diagnostics、timing 或报告产物中。

这解决了「测评到底消耗了多少 token」的透明度问题——用户可以看到每步的 token 消耗,再决定是否需要调整模式或用例数。


版本演进总结

(以下为内部版本演进记录,正文中统一用"旧版/当前版"描述)

版本
核心改动
解决的问题
v7.1
sentry-check 合并 lint+trigger,grader 独立化
工具碎片化
状态机阶段
四大支柱 + Pipeline 数组 + sentry-static + token 计量
上下文疲劳跳步
v8.2
数据隔离 + workspace 路径分离
inputs 和 sessions 混放
v8.4
sync 纳入 Pipeline + sentry_ci.py
sync 遗忘 + CI 可执行性
v8.5
active-pipeline.json + watchdog 自动恢复
主会话断裂后 Pipeline 丢失
稳定契约
current-contract + grader-report + baseline 规则收敛 + config 卫生
文档、工具、文章口径分叉

给架构设计者的启示

三条架构教训(详见文章前半部分): 文件状态 > 上下文记忆 、 强制路径 > 提醒标记 、 降级 > 终止 。

这三条教训在 SkillSentry 的每一个具体设计改动中都有体现:Pipeline 数组解决跳步(强制路径)、session.json 解决记忆丢失(文件状态)、三级降级解决超时(降级优先终止)。


FAQ

Q:为什么这篇还要单独讲旧版状态机阶段?

旧版状态机阶段解决"流程会不会被漏掉",当前版解决"工具和文章是否说同一套契约"。前者是架构基础,后者是口径收敛,不是替代关系——详见文章正文。

Q:这里的 Pipeline 状态机和传统 DAG 调度器(如 Airflow)有什么本质区别?

关键差异一句话:Airflow 节点是确定性函数,SkillSentry 节点是 AI subagent——输出非确定性,因此必须设计三级降级和产物完整性验收。这是传统调度器框架不内置的。

Q:为什么 sync 步骤要走 Pipeline,而不是主编排器顺手执行?

核心教训:任何"顺手附加"的动作在长对话中都会被遗忘。放进 Pipeline = 状态机强制经过。详见正文"Sync 步骤纳入 Pipeline"一节。

Q:active-pipeline.json 的 watchdog 多久检查一次?会不会有性能问题?

每 10 分钟一次心跳。检查动作只是读一个 JSON 文件(< 1KB),如果文件不存在(无活跃 Pipeline)直接跳过。性能影响可忽略。

Q:这套方案在 Claude Code CLI 模式下完全适用吗?有哪些差异?

基本适用。主要差异在于 CLI 模式下没有 websocket 长连接维持主会话,session.json 的持久化尤为重要——每次重新启动 CLI 进程时,主编排器必须先读 session.json 恢复状态,而不能依赖对话历史。active-pipeline.json 的 watchdog 在 CLI 模式下同样有效,因为它基于文件而非对话上下文。


延伸问题:状态机如何恢复

状态机解决的是"流程不分叉"。如果继续追问长任务中断后怎么恢复,就会进入另一个工程问题:如何用 active-pipeline.json 记录当前步骤、前置产物和恢复策略,避免 executor 已经跑完却因为对话中断而全量重跑。

更多相关阅读推荐

《Token 计量与效率优化:每次测评消耗了多少 token(20)》《MD5 缓存让测评系统学会了推断,而不是询问(19)》《sentry-static测评入口收敛:从多能力检查到1个静态分析入口(18)》《grader-report:为什么AI测评里的评分和报告应该是同一个subagent(17)》《SkillSentry 提速实战:三个改动让 AI 测评少调 70% 的 LLM(16)》《从离线门禁到线上回流:Skill 上线后的质量怎么守(15)》

END

链接:https://juejin.cn/post/7655148316922986531

本文为51Testing经授权转载,转载文章所包含的文字来源于作者。如因内容或版权等问题,请联系51Testing进行删除

点点赞
点分享
点推荐

随机文章