给 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 怎么写才算好」(规范侧),后一半讲「平台怎么拦」(门禁侧),最后给出可迁移的设计原则与落地建议。
整套体系目标只有三句话:
- 上传阶段尽早拦住坏包(结构非法、缺必填字段);
- 发布前必须绿灯:静态规则 + LLM 结构化评分,只有绿灯才放行;
- 发布后用真实对话链路做质检,验证"能不能调到对应 Skill"以及回答质量。
一、Skill 质量怎么评:双段检查、七条硬门禁、八维评分与红旗

1.1 确定性硬检 + LLM 结构化评分
上传或更新 Skill 后,若平台开启了静态扫描,会对包内可读文本(.md / .txt / .json / .yaml / .yml / .prompt 等)做两段检查:
- 确定性硬检(不调模型):基于客观规则的命中即失败,命中后不再调用 LLM。适合处理那些"白名单 / 黑名单"式的明确问题。
- 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 门禁二:静态扫描(发布硬门禁)

先跑确定性硬规则(不调 LLM,命中即 fail),再跑 LLM 七条硬门禁 + D1–D8 打分;LLM 对部分条款的误报由代码层纠偏(reconcile)处理。
确定性硬规则(命中即 fail,不调 LLM):
- 包内有
.sh,但未在 frontmattersandbox.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 平台都能照抄:
- 早失败:结构问题在上传即拦,避免脏包进入发布流;
- 发布前必须绿灯:静态扫描灯色 ≥90(绿)才允许发布;黄 / 红一律拦截;
- 线上不误杀:对话质检失败只告警,避免误判把已上线的包自动下线——稳定性与质量提升解耦;
- 按改动增量质检:发布后只对本次变更的 Skill 入队对话质检,不重扫全量;
- 可开关:平台总开关 + App 级开关;关闭后跳过静态扫描发布拦截与对话质检,但结构校验与发布配置校验仍在——关闭不等于裸奔。
开关与配置一览(中性化):
| 配置项 | 作用 |
|---|---|
| 评测总开关 | 平台级总开关 |
| 应用级评测开关 | 单应用开关(可配默认值 / 是否允许 UI 切换) |
| 评测服务与回调配置 | 外部评测服务接入与回调 |
| 静态扫描模型配置 | 评分所用大模型 |
| 静态扫描及格线 | 默认 90(灯色分界) |
| 扫描结果有效期 | 默认 24 小时 |
| 热更等待与匹配重试 | 发布后技能热更等待与路由匹配重试 |
四、落地建议
4.1 开发者日常工作流(建议)
- 按规范写好 SKILL.md(frontmatter、工具声明、单一环境、中文语言段、知识读取方式);
- 打 zip 上传 → 看结构校验是否立刻通过;
- 等静态扫描出结果(绿灯才继续)→ 黄 / 红按报告修包重传;
- 补齐 Agent 配置 / 鉴权 / 域名白名单 → 点发布;
- 发布后关注对话质检通知与徽标;匹配失败优先查热更与 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 平台从"能跑"走向"可信"的必经之路。