给 Agent 技能(Skill)立质量规范:静态扫描、八维评分与发布门禁

给 Agent 技能(Skill)立质量规范:静态扫描、八维评分与发布门禁

导读:这篇文章讨论 Agent 平台向第三方开放 Skill(技能包)后,如何用一套质量门禁体系拦截"坏包"——覆盖上传结构校验、静态扫描到发布后对话质检三个阶段。核心方法是确定性硬检 + LLM 八维结构化评分(七条硬门禁、红旗清单、红黄绿三档灯色),基础分 ≥90 才放行,且最终裁决由代码而非模型自评决定。适合负责 Agent 平台治理或 Skill 开发规范的工程师阅读,门禁设计与原则可直接迁移落地。 分类:AI评测 | 标签:Agent、Skill、质量门禁、规范

为什么需要质量规范:开放技能,意味着开放风险

当 Agent 平台把「技能开发」开放给合作方与第三方开发者时,质量控制就从团队内部纪律,变成了平台的系统性责任。所谓 Skill(技能),是 Agent 的能力单元——通常是一个 zip 包,内含一份 SKILL.md(人设、工具声明、执行顺序、语言要求、调用示例)以及可选的配套文件(references/、knowledge/ 等)。

开放之后,平台上会出现各种"坏包":

  • 结构坏:不是 zip、缺 SKILL.md、frontmatter 非法,包都存不进去;
  • 写法坏:多环境让 Agent 自选、引导裸执行 shell、塞大量登录/Cookie 废文、漏声明 HTTP 工具;
  • 安全坏:明文密钥、引导用户把 Cookie / token 贴进对话;
  • 运行坏:发布后根本调不到这个 Skill,或调到了却答非所问。

所以需要一个「质量门禁」体系。本文把一份内部开发规范与一份门禁实现文档合并成一篇,前一半讲「Skill 怎么写才算好」(规范侧),后一半讲「平台怎么拦」(门禁侧),最后给出可迁移的设计原则与落地建议。

整套体系目标只有三句话:

  1. 上传阶段尽早拦住坏包(结构非法、缺必填字段);
  2. 发布前必须绿灯:静态规则 + LLM 结构化评分,只有绿灯才放行;
  3. 发布后用真实对话链路做质检,验证"能不能调到对应 Skill"以及回答质量。

一、Skill 质量怎么评:双段检查、七条硬门禁、八维评分与红旗

技能广场:技能上传与分享

1.1 确定性硬检 + LLM 结构化评分

上传或更新 Skill 后,若平台开启了静态扫描,会对包内可读文本(.md / .txt / .json / .yaml / .yml / .prompt 等)做两段检查:

  1. 确定性硬检(不调模型):基于客观规则的命中即失败,命中后不再调用 LLM。适合处理那些"白名单 / 黑名单"式的明确问题。
  2. LLM 结构化评分:按七条硬门禁、八维基础分、红旗清单出结构化报告。

关键设计:平台不采信模型自写的 passed 或高分结论,最终灯色由代码综合判定——LLM 只负责"评审",不负责"裁决"。

Skill zip → 确定性硬检 →(通过)→ LLM 评分(D1–D8 / 红旗)→ 综合判定
                ↓失败                                    ↓
              未通过                              绿灯才允许发布

通过条件(同时满足):

  • 确定性硬检全部通过;
  • 无硬红旗(R9 / R11 / R12);
  • 七条硬门禁无 fail;
  • 基础分 base_score ≥ 90(及格线可配置,默认 90);
  • 无仍为 critical 的真实安全问题(如明文密钥)。

灯色按基础分划分:≥90 绿(可发布)/ 80–89 黄(须修订)/ <80 红(禁止)。平台只放行绿灯。

1.2 七条硬门禁(LLM 评审,必须过)

门禁 1 · 声明 HTTP 工具(对应硬红旗 R9) 有 HTTP / URL / 接口调用意图时,必须在正文声明对应 HTTP 工具并按语义选用 GET / POST 形态,同时给出带参数的 JSON 调用示例,不要只甩裸 URL。纯知识咨询包(无接口意图)可不声明。

门禁 2 · 禁止无用内容 不要大段写登录流程、Cookie、BFF、MCP 百科、源码路径、环境对照大表。只保留 Agent 执行本 Skill 真正需要的信息。

门禁 3 · 单一环境 Base URL(对应红旗 R4) 一个发布包只允许一套环境(一个 Base URL)。禁止写「测试 / 线上 / 沙箱请 Agent 自选」或环境对照表让模型切换;不同环境打不同包、走不同发布流。合规写法(不要判不过):写明「本包为生产/线上环境」「全文 URL 一致」「Agent 无需选择环境」——这是单一环境声明,不是多环境自选。硬检会把「无需/不用/不必选择环境」视为合规,只有「自行选择环境 / 测试与线上任选 / 环境对照表供选」才失败。

门禁 4 · 配套必要 references/ / knowledge/ 里每个文件都要能回答:"删掉后 Agent 缺什么?" 冗余说明、复制粘贴的废文会拉低 D8、触发 R10。

门禁 5 · Shell 脚本受控(对应硬红旗 R11) 需要脚本时:在 SKILL.md 的 frontmatter 声明 sandbox.shell.scripts,路径限 scripts/*.sh,正文用受控脚本执行指令(skill_shell_run)调用。禁止:未声明白名单的 .sh(含根目录 run.sh)、正文引导裸执行(bash xxx.sh / chmod +x / #!/bin/bash)。不需要脚本的包不要打进任何 .sh。

合规示例(frontmatter):

sandbox:
  shell:
    scripts:
      - path: scripts/check.sh
        timeout_sec: 6

正文只写"调用 skill_shell_run 跑上述声明脚本",不要写 bash scripts/check.sh。

门禁 6 · 独立「语言要求」 必须有独立小节(建议标题就叫「语言要求」),明确:用户可见回复一律中文。独立成条款可拿 B1 加分(+3);仅在示例里顺带提到只得 +1。

门禁 7 · 知识读取方式(对应硬红旗 R12) zip 内确实存在 references/ 或 knowledge/ 文件时,必须声明配套文件读取(推荐 read_file(file_path="…"),历史写法 skill_view("技能标识", "相对路径") 仍兼容)。正文仅提到路径、包内并无对应文件时,不作硬拦。禁止引导用外部知识库检索工具替代包内知识;写出「禁止使用知识库检索工具」这类合规说明是允许的,不是违规。

易误报提醒:扫描器已做纠偏——「禁止使用知识库检索工具」「无需选择环境」、以及已声明 sandbox.shell 的合规 .sh 都不会误拦。若仍因这三类文案失败,需要升级含纠偏的扫描器后重跑。

1.3 八维评分(满分 100,带权重)

维度 分值 开发关注点
D1 可发现性 8 名称、简介、何时启用写清楚
D2 身份边界 15 业务终端用户的适用角色边界写清;勿与运行时"内部员工"混淆
D3 执行顺序与工具 15 先查后写、工具调用先后顺序明确
D4 接口与参数 20 Base URL、path、参数、示例完整且可执行
D5 内容精简 12 无冗长无关段落
D6 输出规范 13 对用户说什么、不说什么;勿泄露内部过程
D7 业务排障 12 常见错误码 / 无数据时怎么办
D8 配套必要性 5 配套文件精炼必要

另有 B1 加分:独立中文语言条款 +3;仅举例 +1;未声明 0。

综合分 score = base_score + b1_bonus(上限 100);门禁看的是基础分 base_score。

1.4 错误红旗清单(R1–R12)

红旗是"一票否决 / 封顶"式的信号,按严重程度分两类:硬红旗(R9 / R11 / R12)直接门禁不过,任何分数都进不了发布;其余为软红旗(拉低分数或封顶)。

编号 含义 后果
R1 不同业务线的接口混用(角色/场景错配) 基础分封顶 70
R2 未禁止「未调接口就断言无数据」 封顶 70
R3 大段登录 / Cookie / BFF 封顶 65,且 D5=0
R4 多环境供选 封顶 65,且 D4≤50%;硬检也会直接失败
R5 未写清适用的业务终端用户角色边界 封顶 70
R6 对用户泄露内部过程(鉴权细节、推理链等) D6≤50%
R7 业务品类标识错误 封顶 70
R8 编造接口能力 封顶 60
R9 未声明 HTTP 工具 门禁不过(硬红旗)
R10 冗余配套 D8=0
R11 未声明沙盒白名单的 .sh / 引导裸执行(已声明 + 合规调用不拦) 门禁不过(硬红旗)
R12 包内有配套未声明读取方式 / 引导使用外部知识库检索(写「禁止使用」合规) 门禁不过(硬红旗)

1.5 安全与密钥纪律

允许写在包里的:

  • 业务域名与 API path(业务 URL 文档本身合规,不算密钥泄露);
  • HTTP 工具调用的 JSON 示例;
  • 员工端 Skill 使用内网 / 办公域接口(员工专属技能,不算「内部 URL 泄露」)。

绝对禁止写在包里的:

  • 明文 API_KEY / Secret / Token / 密码;
  • 「环境变量未注入则用本包默认密钥」之类的回退写法;
  • 引导用户把 Cookie / access_token 贴进对话。

正确姿势:密钥走运行时环境变量 / 配置中心 / 平台注入 / 服务端代发;包里只写变量名与用法(如 ${ENV_NAME} 占位),不得出现任何真实密钥样例。扫描器对"仍为 critical 级别的明文密钥"是一票否决的。

1.6 身份边界:两套"三身份"别混用

D2 / R5 评的是业务边界——写清 Skill 适用的业务终端用户角色(如客户侧、服务侧);而开放平台运行时还有另一套运行时角色(客户 / 服务提供方 / 内部员工),用于配置应用可见范围。两者分工:

  • 写 Skill 适用对象 → 用业务边界描述;
  • 配应用可见范围 → 用运行时角色。

可见范围配置注意:

  • 空 = 谁都看不见(fail-closed,默认拒绝);
  • 内部员工专用 Skill → 只勾选「内部员工」;
  • 勿把仅含内部制度 / 内网运营能力的 Skill 对终端用户可见;
  • 静态扫描不会因为「员工 Skill 写了内网接口」而判不过;真正的隔离靠应用可见范围。

1.7 上传前自检清单

  • 有独立「语言要求」段(用户可见一律中文);
  • 有 HTTP 意图则已声明 HTTP 工具(GET / POST)+ 带 URL 的 JSON 示例;
  • 包内只有一套 Base URL;可写「Agent 无需选择环境」,不要写「自选测试/线上」;
  • 无未声明的 .sh;若有脚本则已声明 sandbox.shell.scripts(scripts/*)且正文用 skill_shell_run,不引导裸 bash;
  • zip 内有 references/knowledge 则已声明 read_file(...) 或 skill_view(...);可写「禁止使用知识库检索工具」,不要引导调用;
  • 无明文密钥;密钥走环境变量 / 平台注入;
  • 配套文件均可回答「删掉缺什么」;
  • 身份边界清晰;应用可见范围与 Skill 受众一致;
  • 自估基础分能到 90+(绿灯)。

1.8 常见失败与改法

现象 改法
未声明 HTTP 工具(R9) 在 SKILL.md 写明工具名 + 带 URL 的 JSON 示例
未声明沙盒 .sh / 裸执行(R11) 删除未声明脚本,或补上 sandbox.shell.scripts + 改用 skill_shell_run;无脚本需求则流程改走 HTTP 工具
有配套未声明读取方式 / 引导外部知识库检索(R12) 补 read_file(file_path="…/references/xxx.md") 或 skill_view(...);仅写「禁止使用」被误拦 → 升级扫描器后重扫
门禁 3 多环境 拆成不同环境的多个包;合规可写「本包生产环境,Agent 无需选择环境」
明文 API Key 删密钥,改为 ${ENV} + 运维注入
基础分 80–89 黄灯 按报告 reasons 修 D4 / D2 / D5 等,复评至 ≥90
「内部接口 URL 暴露」 一般为误报,平台已降级处理;业务 URL 文档本身合规
「禁止使用知识库检索」却报 R12、"无需选择环境"却报门禁 3/R4 多为旧规则误伤与多环境文案误判,属于已知纠偏项,升级后重扫

二、门禁怎么拦:四道关卡的分阶段实现

门禁挂在 Agent 开放平台侧,覆盖上传、发布、线上三个阶段。整条链路共四道关卡,按"拦在哪"分两类:硬门禁(上传结构、静态扫描拦发布、发布配置)与软门禁(发布后对话质检,只告警)。

阶段 做什么 不通过后果 性质
上传 Zip / SKILL.md 结构校验 上传失败(400),包不入库 硬门禁(始终)
上传后异步 静态扫描(确定性硬规则 + LLM D1–D8) 发布被拒(409) 硬门禁
点发布 发布配置校验(§2.3) 发布被拒 硬门禁(始终)
发布成功后 对话质检(skill-qc) 通知负责人 + 平台徽标;不自动下线 软门禁(观测 + 告警)

开关口径:上传结构校验始终生效;「静态扫描拦发布」与「发布后对话质检」受平台总开关 + 应用级开关控制,且静态扫描还需配置评分模型。关掉开关会跳过扫描拦截与对话质检,但结构校验与发布配置校验仍在。

2.1 门禁一:上传结构校验(硬门禁,始终生效)

技能上传门禁与版本管理

上传 Skill zip → 上传校验器。任一校验失败返回 400 skill_validation_failed:<code>,包不能进入 validated 状态,后续谈不上发布。

包体与 Zip 布局(错误码可作排查线索,解释已中性化):

错误码 含义
skill_file_must_be_zip 文件名必须以 .zip 结尾
skill_file_empty 空文件
skill_file_too_large 超过 10MB
skill_zip_invalid 无法解析为合法 zip
skill_zip_path_unsafe 路径含 ..(防目录穿越)
skill_zip_mixed_layout 根目录与子目录混放 SKILL.md,或多根目录布局
skill_missing_skill_md 缺少 SKILL.md
skill_file_index_too_many / _too_large 文件索引过多(>100)或序列化过大

合法布局二选一:zip 根目录直接放 SKILL.md;或单一文件夹包住全部文件。忽略 .DS_Store、__MACOSX/、._* 等杂项。

SKILL.md frontmatter / 正文:

错误码 含义
skill_md_empty 文件为空
skill_md_missing_frontmatter / _unclosed / _invalid_yaml / _not_mapping 必须以 --- 包裹的 YAML,且为 mapping
skill_md_missing_name / _missing_description 缺少必填 name / description
skill_md_name_invalid name 须匹配小写字母数字开头、允许 . _ - 的命名规则
skill_md_name_too_long name 超过 64 字符
skill_md_description_too_long description 超过 1024 字符
skill_md_body_empty frontmatter 后无正文

通过后 Skill 状态变为 validated,触发异步静态扫描(前提:开关打开且评分模型已配置)。

2.2 门禁二:静态扫描(发布硬门禁)

Skill 静态扫描结果:基础分 90/门槛、未通过原因 D4

先跑确定性硬规则(不调 LLM,命中即 fail),再跑 LLM 七条硬门禁 + D1–D8 打分;LLM 对部分条款的误报由代码层纠偏(reconcile)处理。

确定性硬规则(命中即 fail,不调 LLM):

  • 包内有 .sh,但未在 frontmatter sandbox.shell.scripts 白名单声明,或不在 scripts/ 下;
  • 正文引导裸执行 bash / chmod / 直接跑 .sh(教 skill_shell_run 跑已声明脚本不拦);
  • 像 HTTP API 类 Skill,却未声明 HTTP 工具(对应 R9 / 门禁 1);
  • 包内确有 references/knowledge 文件路径,却未声明 read_file(...) 或 skill_view(...)(对应 R12 / 门禁 7);
  • 正文引导使用外部知识库检索工具(「禁止使用」类合规说明不拦);
  • 多环境文案让 Agent 自行选择测试 / 线上 / 沙箱(「Agent 无需选择环境 / 本包为生产环境」不拦,对应门禁 3 / R4)。

常见误报 ↔ 合规写法(必读):

  • 知识库检索:写「禁止调用外部知识库检索」「禁止误用」+ 用 read_file / skill_view 读配套 → 通过;只有明确要求「调用 / 使用」才判 fail;
  • 单一环境:写「本包为生产环境;全文 URL 一致;Agent 无需选择环境」→ 通过;不要写「请选择测试/线上/沙箱」供 Agent 自选;
  • 配套目录:以 zip 内真实路径为准;仅正文提到 references/ 等、却无对应文件 → 不因缺 read_file / skill_view 硬拦;
  • Shell 脚本:需要脚本时声明 sandbox.shell.scripts(路径 scripts/*.sh)+ 正文 skill_shell_run → 通过;未声明的 .sh 或引导裸 bash/chmod → fail;不需要脚本的包不要打进 .sh。

发布拦截:当平台总开关打开、且 App 开启评测、且评分模型已配置时,发布前会执行「发布资格断言」(assertPublishAllowed)。无有效扫描、扫描中、扫描出错、未通过、指纹过期——一律 409 拒绝发布。

开发者闭环:打开该 Skill 的静态扫描报告(灯色 / 硬门禁 / 红旗 / reasons)→ 先消确定性硬规则(§2.2)→ 再改 LLM 硬门禁与低分维度 → 重新打 zip 上传 → 等异步扫描出绿灯 → 再点发布。通过结果默认 24 小时内有效,过期需重扫。

发布时常见拦截错误(解释中性化):

错误 含义
qc_required:<slug> 尚无有效的静态扫描结果
qc_running:<slug> 扫描进行中,请稍候
qc_error:<slug> 扫描任务出错
qc_failed:<headline> 未通过(分数 / 硬门禁 / 红旗)
qc_stale:<slug> zip 指纹已变,或通过结果超过有效期(默认 24h)需重扫

2.3 门禁三:发布配置校验(硬门禁,始终)

与评测 / 扫描开关无关,每次点发布都会检查:

  • 至少一个 enabled + validated 的 Skill(否则 no_validated_skill);
  • Agent 配置完整(非空白、非泛化「应用介绍」);
  • 鉴权配置完整(非系统内置鉴权模式须有回调地址);
  • 安全域名白名单非空(security_domains_required);
  • 配置中心上传 → 提交 → 强制发布 → online 全链路成功(失败则整次发布失败,无半成功)。

另有若干软警告(单独不硬拦,只在发布预览里提示):技能描述缺失或过于泛化、服务范围未写清、建议补充技能选型策略。

2.4 软门禁:发布后对话质检(只告警,不下线)

正式发布且 online 成功后,平台对本次改动的 Skill 异步入队对话质检(skill-qc),用真实对话链路验证"能不能调到对应 Skill"以及回答质量。

阶段 在测什么
queued 任务排队
resolving(匹配 Skill) 用户意图能否被路由 / 解析到目标 Skill;匹配失败记 error 并可自动重试(技能热更延迟是常见原因)
planning 能否读懂 SKILL.md / 配套文档,规划出合理调用步骤
chatting(多轮对话) 默认最多 3 轮,置信度门槛 0.7;按应用可见身份选评测受众
evaluating 综合是否正确调到 Skill、工具调用是否合理、回答是否达标,产出报告

失败后怎么办:

  • 通知负责人 + 平台报告抽屉展示徽标与明细(进度、轮次、结论);
  • 根据报告改 SKILL.md / 配套 / 接口声明后重新上传 → 再过静态门禁 → 再发布;
  • 发布本身已成功,线上版本仍可用;是否回滚或强制下线由人工决定——这就是"线上不误杀"。

三、设计原则:早失败、绿灯放行、线上不误杀

把这套门禁抽象成原则,一共五条,任何 Agent 平台都能照抄:

  1. 早失败:结构问题在上传即拦,避免脏包进入发布流;
  2. 发布前必须绿灯:静态扫描灯色 ≥90(绿)才允许发布;黄 / 红一律拦截;
  3. 线上不误杀:对话质检失败只告警,避免误判把已上线的包自动下线——稳定性与质量提升解耦;
  4. 按改动增量质检:发布后只对本次变更的 Skill 入队对话质检,不重扫全量;
  5. 可开关:平台总开关 + App 级开关;关闭后跳过静态扫描发布拦截与对话质检,但结构校验与发布配置校验仍在——关闭不等于裸奔。

开关与配置一览(中性化):

配置项 作用
评测总开关 平台级总开关
应用级评测开关 单应用开关(可配默认值 / 是否允许 UI 切换)
评测服务与回调配置 外部评测服务接入与回调
静态扫描模型配置 评分所用大模型
静态扫描及格线 默认 90(灯色分界)
扫描结果有效期 默认 24 小时
热更等待与匹配重试 发布后技能热更等待与路由匹配重试

四、落地建议

4.1 开发者日常工作流(建议)

  1. 按规范写好 SKILL.md(frontmatter、工具声明、单一环境、中文语言段、知识读取方式);
  2. 打 zip 上传 → 看结构校验是否立刻通过;
  3. 等静态扫描出结果(绿灯才继续)→ 黄 / 红按报告修包重传;
  4. 补齐 Agent 配置 / 鉴权 / 域名白名单 → 点发布;
  5. 发布后关注对话质检通知与徽标;匹配失败优先查热更与 Skill 可发现性(D1)。

4.2 可迁移到其他平台的通用做法

  • 客观规则优先,LLM 只做结构化评估且不信任其自评:确定性硬检管"明确是非",LLM 管"综合评审",passed 由代码判定,杜绝模型放水;
  • 门禁分级、逐级前置:结构(上传拦)→ 规格(发布拦)→ 运行(发布后观测),问题越早暴露成本越低;
  • 红灯硬拦、黄灯可修:分数不够不是"再点一次",而是按报告回炉;通过结果设有效期,防止"改完包用旧报告";
  • 红旗分级:硬红旗一票否决(脚本、HTTP 声明、知识读取),软红旗封顶降权(废文、多环境、编造接口)——既守住安全底线,又给质量问题留出弹性;
  • "只告警不下线" 让线上稳定性与质量提升解耦,是这套门禁敢长期跑下去的关键;
  • 开关粒度:总开关兜底 + 应用级开关灰度,方便新规则逐步放量,出问题一秒钟全局关停。

附录:门禁对照速查表

按"问题拦在哪"归类,便于开发时对号入座:

问题类型 拦在哪 典型表现
zip 坏了 / 缺 SKILL.md / name 非法 上传 400,包都存不进去
未声明沙盒 .sh、多环境自选、未声明 HTTP 工具、引导裸 bash 静态扫描 确定性硬规则直接 fail
分数 <90、硬门禁 fail、critical 安全项 静态扫描 → 发布 409,平台界面显示红/黄灯
Agent 介绍空、域名白名单空 发布配置 发布预览 / 提交失败
热更未完成、描述不可发现、调不到 Skill 对话质检 resolving error / 报告失败徽标
调到了但多轮答非所问、工具乱用 对话质检 chatting / evaluating failed

一句话收尾:好的技能规范是"写好的人不难受、写坏的人过不去"——确定性硬检守住底线,LLM 评分给出标尺,分阶段门禁把风险拦在离用户最远的地方,而"只告警不下线"让整个体系敢于长期迭代。这套打法是 Agent 平台从"能跑"走向"可信"的必经之路。