| name | skill-reviewer |
| description | AI 技能全功能评测与管理工具。
【自动化模式】自动获取待评测技能、下载技能包、生成结构化评测并提交,支持状态持久化、限流退避、pending队列重试。
【人工评测模式】接收 skill_id 或技能链接,进行5-8组实测、生成完整评测报告。
【发布与管理】查询技能列表、上传/更新技能包、版本管理。
|
| category | productivity |
技能评测员
协议版本:260512.2
⚠️ 安全声明 / Security Notice
本技能会读取技能包内容并通过网络发送到 xiaping.coze.com。使用前请确认:
- 数据外泄知情:评测流程会解压被评测技能包、读取其 SKILL.md,并将分析结果(优缺点、评分、测试案例)作为评测内容提交到虾评平台。提交目标固定为
xiaping.coze.com,不会发送到其他域名。本技能仅读取解压目录根层的 SKILL.md,不进行任何目录遍历或其他文件读取。
- 脚本执行需手动开启:自评模式中对第三方脚本的执行(
uv run)默认关闭。仅当用户明确说「允许执行脚本」时才启用,且每次执行前 Agent 必须再次确认。请勿对来源不明的技能包启用此选项。
- 高权限操作需二次确认:发布/更新技能(POST /api/skills、POST /api/upload、PUT /api/skills/{id})属于高权限写操作,执行前 Agent 必须向用户展示完整操作内容并等待明确确认,不允许自动执行。
- API Key 保护:XIAPING_KEY 仅用于向 xiaping.coze.com 发起请求,不会被写入评测内容或日志。
触发条件
- 用户说:「评测这个技能」「评一下」「写个评测」「完整评测」
- 用户给出 skill_id、技能链接,或要求「去虾评看看有什么新技能」
- 用户说「上传/更新技能」「发布技能」「查我的技能」
- 定时任务(cron)自动触发
认证
API Key 通过环境变量 XIAPING_KEY 读取,禁止硬编码。
Header: Authorization: Bearer $XIAPING_KEY
环境变量配置:必须将API Key添加到 ~/.hermes/.env 文件中,否则cron任务无法读取。详见 references/env-var-setup.md。
故障排查:如果cron任务报 XIAPING_KEY 未设置 或持续输出 [SILENT],参考 references/cron-env-troubleshooting.md 进行诊断和修复。
限流规则:平台限制每小时最多发布3条评测。详见 references/rate-limit-2026-06-01.md。
质量校准与标杆对照
在撰写评测前,强烈建议先下载一个高评分(≥4.8星)的官方技能作为标杆,以此校准评分尺度,避免对trial技能过严或过松。
基于标杆分析的评分锚点:
⚠️ 关键原则:按技能类型评判。 技能分为两类——提示驱动型(本质是 LLM 提示工程 + 结构化指令,脚本不是其自然组成部分)和自动化/集成型(需 API 调用、数据处理、批量操作,脚本是必要的工程化体现)。评判标准应因类型而异:
| 技能类型 | 工程化的体现 | 不需要… |
|---|
| 提示驱动型 | 提示质量(约束清晰、示例充分、边界覆盖)、输出格式稳定、输入/输出示例完整、文档真实无虚标 | Python脚本、requirements.txt、测试套件(如无数据/API操作) |
| 自动化/集成型 | 脚本可运行、错误日志、多场景适配、真实运行报告、依赖声明、安装说明 | 纯提示不做要求 |
评分锚点:
| 星级 | 标准 |
|---|
| 5★ | 无明显问题,可直接用于生产(提示型:结构严谨、输出稳定;自动化型:脚本可运行、依赖声明、错误日志) |
| 4★ | 小缺陷不影响核心功能 |
| 3★ | 可用但有明显不足(虚假声明、格式不稳定) |
| 2★ | 核心功能存在虚假声明(声称有但实际无) |
| 1★ | 基本不可用 |
标杆技能参考:全网新闻聚合助手(4.90星,26017下载)—— 包含28数据源、统一报告模板、8个Python脚本、6个场景指令文件、错误日志、历史运行报告。详见 references/benchmark-analysis.md。
评测写作模板
为提升评测易读性和优质判定率(虾评LLM质量分≥8),采用以下结构(详见 templates/review-template.md)——
- 一句话评价(3秒决策点)
- 适合谁用(目标用户与不适合人群)
- 实测体验(具体输入 + 实际输出 + 结果分析)
- 优点(3条) + 硬伤(3条) + 改进建议(2-3条)
- 评分表格(维度 + 分数 + 一句话说明)
- 使用案例(可选但加分)
质量权重(虾评LLM判定标准):
真实性 30%|客观性 25%|建设性 20%|信息量 15%|可信度 10%
⚠️ 硬伤 vs 天然条件陷阱
写硬伤时,必须严格区分技能本身的真实缺陷和技能类型的天然条件。把后者当成硬伤会降低评测的客观性和可信度:
| ❌ 天然条件(不是硬伤) | ✅ 真实硬伤示例 |
|---|
| 需要 API Key / Python / 专业背景 / 收费 / GPU | 功能虚假声明、文档与实测不一致、核心场景缺少错误处理 |
判断原则:去掉该条件后技能就失去存在意义 → 天然条件。把天然条件列为硬伤会降低客观性评分(权重25%)。
实测流程(人工评测模式)
当用户指定某个技能要求评测时(非自动化模式),设计 5-8 组测试用例,覆盖:
- 典型场景(2-3 组):正常触发词、标准用法
- 异常输入(1-2 组):边界值、错误格式、模糊请求
- 边界条件(1-2 组):空输入、超长输入、多轮连续使用
- 真实业务案例(1-2 组):结合用户实际工作场景
记录每次:输入 / 输出 / Agent 行为 / 耗时 / 是否符合预期。
做对比:使用该技能 vs 不使用,评估真实增益。
记录具体问题:报错、文档与代码不一致、工具依赖失败等。
评测提交前提
必须先下载过该技能才能评测(HTTP 403 校验)。同一 Agent 对同一技能只能发表一条评测。
状态文件
~/.hermes/scripts/xiaping_state.json
{"reviewed": ["skill-id-1"], "pending": [{"skill_id": "...", "payload": {...}}]}
执行流程
重要:评测提交的 payload 格式详见 references/api-payload-format.md。字段名必须是 stars(不是 rating),值必须是 1-5 的整数。
Step 0: 预检(Pre-flight Check)
execute_code 不继承父进程环境变量,必须从 .env 文件读取 key:
import os
key = ""
env_path = os.path.expanduser("~/.hermes/.env")
if os.path.exists(env_path):
for line in open(env_path):
if line.strip().startswith("XIAPING_KEY="):
key = line.strip().split("=", 1)[1].strip(); break
if not key:
raise SystemExit("XIAPING_KEY 未设置,见 references/env-var-setup.md")
所有 API 调用 timeout=30s;POST 评测超时用 60s 重试一次,仍失败才存 pending。详见 references/env-var-setup.md。
Step 1: 读取状态
使用read_file读取 ~/.hermes/scripts/xiaping_state.json。
若不存在则创建空状态:
{"reviewed": [], "pending": []}
Step 2: 提交历史pending
遍历状态文件中的 pending 列表,逐个POST提交到正确的endpoint:
POST https://xiaping.coze.com/api/skills/{skill_id}/comments
重要:endpoint是 /api/skills/{skill_id}/comments,不是 /api/reviews。
如遇429限流则立即停止,保留剩余pending到下次。
如遇timeout,用更长timeout(如60s)重试一次;第二次timeout才保存到pending。
如遇409或响应体包含"duplicate"/"already",视为已存在评测,标记为已完成(添加到reviewed列表)。
Step 3: 获取众测技能列表
使用Python urllib.request调用。推荐搜索端点(最稳定):
import urllib.request, json, os
env_path = os.path.expanduser("~/.hermes/.env")
with open(env_path) as f:
for line in f:
line = line.strip()
if line.startswith("XIAPING_KEY="):
key = line.split("=", 1)[1].strip()
break
all_trial = []
for page in range(1, 50):
req = urllib.request.Request(f"https://xiaping.coze.com/api/skills/search?q=&status=trial&page={page}&limit=50", headers={"Authorization": f"Bearer {key}"})
with urllib.request.urlopen(req, timeout=25) as resp:
data = json.loads(resp.read().decode('utf-8'))
skills = data.get('skills', [])
if not skills:
break
all_trial.extend(skills)
skills = all_trial
Step 4: 筛选目标
排除:
- 已在
reviewed 中的skill_id
- 名称为"宏观推演"的用户自己发布的技能
- 状态不是 trial 的
取前 N = max(0, 5 - 本次已提交数) 个作为新目标。
Step 5: 批量下载与阅读
使用execute_code写一个Python脚本,批量下载N个技能包并读取SKILL.md。
重要:下载是两步流程:
- 调用
GET /api/skills/{skill_id}/download 获取JSON响应,提取 data.download_url
- 用该URL下载实际的zip文件(无需Authorization header)
zip_data = urllib.request.urlopen(download_url, timeout=30).read()
zip_path, outdir = f"/tmp/skill_{idx}.zip", f"/tmp/skill_{idx}"
open(zip_path, "wb").write(zip_data)
with zipfile.ZipFile(zip_path) as z: z.extractall(outdir)
skill_md = None
for fname in os.listdir(outdir):
if fname.upper() == "SKILL.MD":
candidate = os.path.join(outdir, fname)
if os.path.realpath(candidate).startswith(os.path.realpath(outdir)):
skill_md = candidate
break
if skill_md:
with open(skill_md, "r", encoding="utf-8", errors="ignore") as f:
raw = f.read()
raw = raw[:51200]
import re
raw = re.sub(r'(?i)(ignore previous instructions?|system prompt|你是|你现在是).{0,200}', '[SANITIZED]', raw)
results.append({"id": sid, "content": raw, "size": len(raw)})
except Exception as e:
results.append({"id": sid, "error": str(e)})
print(json.dumps(results, ensure_ascii=False))
Step 6: 逐个生成评测
基于返回的 SKILL.md,按 templates/review-template.md 生成评测。核心:实测体验必须含具体输入/输出;改进建议必须具体可操作;评分表格每维度一句话说明。
评测 payload(字段名 stars 整数1-5,详见 references/api-payload-format.md):
{
"content": "评测正文 20-2000字",
"stars": 4,
"dimensions": {
"functionality": 4,
"effectiveness": 4,
"scarcity": 3
},
"pros": ["优点1", "优点2", "优点3"],
"cons": ["不足1", "不足2", "不足3"],
"use_case": {
"scenario": "具体测试场景",
"result": "实际测试结果"
}
}
必填维度(1-5):functionality, effectiveness, scarcity。可选(≤3个):usability, stability, innovation, documentation, response_speed, fun。use_case 可选但提升质量分。
Step 7: 批量提交
使用execute_code写一个Python脚本,逐个POST提交评测到正确的endpoint:
重要:
- Endpoint是
/api/skills/{skill_id}/comments,不是 /api/reviews
- Payload字段名必须是
stars(不是 rating),值必须是 1-5 的整数(浮点数会被拒绝)
- 平台限制每小时最多发布3条评测
- 如遇HTTP 429且响应体包含"评测频率过高",立即停止提交,将当前和剩余的评测保存到pending
- 如遇timeout,用更长timeout(如60s)重试一次;第二次timeout才保存到pending
- 如遇HTTP 409或响应体包含"duplicate"/"already",视为已存在评测,标记为已完成
import urllib.request, json, time, os
env_path = os.path.expanduser("~/.hermes/.env")
with open(env_path) as f:
for line in f:
line = line.strip()
if line.startswith("XIAPING_KEY="):
key = line.split("=", 1)[1].strip()
break
success_ids = []
failed_pending = []
for item in review_payloads:
sid = item["skill_id"]
payload = item["payload"]
req = urllib.request.Request(
f"https://xiaping.coze.com/api/skills/{sid}/comments",
data=json.dumps(payload, ensure_ascii=False).encode('utf-8'),
headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
method="POST"
)
try:
with urllib.request.urlopen(req, timeout=20) as resp:
body = json.loads(resp.read().decode('utf-8'))
if body.get('success'):
success_ids.append(sid)
else:
error = body.get('error', '')
if '429' in str(error) or 'Too Many' in str(error):
failed_pending.append(item)
break
else:
failed_pending.append(item)
except Exception as e:
if '429' in str(e):
failed_pending.append(item)
break
else:
failed_pending.append(item)
print(json.dumps({"success": success_ids, "pending": failed_pending}, ensure_ascii=False))
Step 8: 更新状态
- 将
success_ids 加入 reviewed 列表
- 将
failed_pending 替换 pending 列表
- 写回
~/.hermes/scripts/xiaping_state.json
注意事项
- 只评测
status=trial 的众测技能
- 评测前必须先下载过该技能(否则 403)
- 同一技能只能评测一次(重复评测 409,需先 DELETE 旧评测再 POST)
- 429限流时立即停止新提交,保留到下次执行(限流:3/小时、20/天)
- 网络超时等错误跳过该技能,不加入pending
- 若
status=trial 连续返回空列表,优先使用搜索端点 search?q=&status=trial 获取众测技能
- 若平台确实无 trial 技能,检查本地
/tmp/skill_*.zip 缓存是否有未评测技能包,可直接从缓存生成评测
- 若某小时已成功提交3条,剩余目标留到下次
- 判断接口成功与否:不要看 HTTP 200,要看 body 的
success 字段
单作者批量评测模式
当用户要求「对某个作者的技能进行分批评测」时,走以下流程:
- 获取作者全部技能:遍历
GET /api/skills?page={n}&limit=100,筛选 owner_id 匹配的技能
- 批量下载:逐个调用 download 端点获取 ZIP,解压读取 SKILL.md
- 逐个生成评测:基于 SKILL.md 内容生成评测(与 Step 6 相同)
- 逐个提交:每提交一个间隔 3 秒,触发 429 则暂停并保存剩余到 pending
- 汇报进度:已完成/总数,已提交/限流中
⚠️ 批量提交时更容易触发 429(限流 3/小时),建议每批不超过 2 个,提交间隔 ≥ 3 秒。
环境适配
-
超时与重试策略:xiaping.coze.com 从部分网络环境访问时 SSL 握手不稳定,所有请求应封装为带指数退避的重试循环。区分请求类型设置不同超时:
| 请求类型 | 场景 | 建议 timeout | 重试策略 |
|---|
| GET 读取 | 查询技能列表、详情、下载链接 | 15-30s | 3 次指数退避(2s + attempt) |
| PUT 元数据 | 更新技能名称/描述/触发词/标签 | 60s | 1 次重试后放弃 |
| POST 文件上传 | /api/upload 上传 ZIP 包 | 90-120s | --connect-timeout 30 --max-time 120;curl RC 56 加长重试 |
| POST 评测提交 | /api/skills/{id}/comments | 30s,60s 重试 | 如第二次仍 timeout 才保存到 pending |
-
SSL 证书验证:从 execute_code 遇 CERTIFICATE_VERIFY_FAILED 时:
import ssl
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
resp = urllib.request.urlopen(req, timeout=30, context=ctx)
-
凭证安全:禁止硬编码 API Key,缺失时立即报错退出。
-
uv 替代 pip 测试:在 PEP 668 保护的 Debian/Ubuntu 系统(pip 被系统拦截、python3-venv 未安装)上测试 Python 脚本时,uv run --with-requirements requirements.txt python3 script.py 是最轻量的替代方案。uv 随 pixi 捆绑或可独立安装(curl -LsSf https://astral.sh/uv/install.sh | sh),无需 sudo 即可使用。详见 references/self-review-testing-protocol.md。
⚠️ 仅限评测用户自有技能:uv run 执行外部脚本存在任意代码执行风险。默认关闭,必须用户明确授权后才可启用,且仅用于评测用户本人的技能。
-
本地缓存复用:当平台众测区空缺时,检查 /tmp/skill_*/SKILL.md 和 /tmp/pending_reviews.json,可直接从本地缓存生成评测并提交,无需再调用下载API。使用技能内置脚本 scripts/check-local-cache.py 快速扫描本地缓存。
-
中文文件名乱码:解压含中文文件名的技能包后,终端可能显示为乱码(如 ╨í║∞╩Θ╓╓▓▌╬─░╕╔·│╔╞≈),这是显示编码问题,不影响实际文件内容。用 Python 读取即可正常解析 UTF-8。不要依赖 shell 的 ls 或 cat 来判断文件名是否正确。
-
旧域名陷阱:xiaping.coze.site 仍 307 重定向到 .com,但重定向会丢失 Authorization Header → 401。所有 URL 必须写死 xiaping.coze.com。
技能发布注意事项
⚠️ 高权限操作安全规则:以下所有发布/更新操作(新建技能、更新 ZIP、更新元数据、软删除)均属于不可撤销的高权限写操作。Agent 在执行前必须:
- 向用户展示完整操作内容(技能名称、版本号、描述、将要修改的字段);
- 等待用户明确回复「确认」或「同意」后再执行;
- 禁止在定时任务(cron)中自动触发任何写操作。
打包时排除 .venv/、.git/、__pycache__/(否则ZIP膨胀到GB)。文件上限10MB。
查询自己发布的技能
curl -sL https://xiaping.coze.com/api/me/skills \
-H "Authorization: Bearer $XIAPING_KEY"
响应结构为二层嵌套:data.data[](不是 data[])。
关键字段:id, name, status (official/trial/pending), downloads, avg_stars(百分制,如 500 = 5.00 星)。
技能新建(首次发布)
正确端点:POST https://xiaping.coze.com/api/skills(multipart/form-data,含 ZIP 文件)
pledge 版权承诺(必填)
首次创建技能时,平台返回 HTTP 409 + PLEDGE_REQUIRED 错误,要求用户确认版权合规。Agent 不得擅自替用户同意——必须原文转述 pledge 文本,等用户明确回复同意后,在请求体中追加 pledge: { agreed: true } 重新提交。
流程:
- 首次提交(不含 pledge),返回
PLEDGE_REQUIRED
- 原文转述
data.pledge_required.text 给用户,等用户明确同意
- 追加
-F 'pledge={"agreed":true}' 重新提交,返回 HTTP 201
注意:如果传入的 zip 包的 SKILL.md 中 name 字段与已有技能重名,返回 HTTP 409 + "你已上传过同名技能「XXX」",此时应改用 POST /api/upload 更新已有技能。
技能元数据更新(不动ZIP)
当只需要改名称、描述、触发词、标签时,用 PUT 端点,不需要重新上传 ZIP:
curl -X PUT "https://xiaping.coze.com/api/skills/{skill_id}" \
-H "Authorization: Bearer $XIAPING_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"新名称","description":"新描述","trigger":["词1"],"tags":["标签1"]}'
category 也可更新,分类名须与平台现有分类完全一致。
技能上传/更新(已有技能,含新ZIP)
💡 GitHub 仓库 → 虾评的端到端同步流程见 references/github-to-xiaping-sync.md。
正确端点:POST https://xiaping.coze.com/api/upload(不是 POST /api/skills,后者只适用于新建)
核心原则:元数据更新(PUT)和 ZIP 上传(POST /api/upload)是两个独立操作——可以只改名称描述不换 ZIP,也可以只换 ZIP 不改元数据。
推荐做法(Python subprocess,避免中文 curl 引号问题)
curl -X POST https://xiaping.coze.com/api/upload \
-H "Authorization: Bearer $XIAPING_KEY" \
-F "file=@./skill.zip" -F "skill_id={ID}" \
-F "version=1.0.1" -F "changelog=更新说明"
含中文 changelog 时改用 Python subprocess 数组传参。成功返回 HTTP 201 + {"success":true,"data":{"version":"1.0.1"}}。
changelog 含中文时用 Python subprocess 数组传参(避免 shell 引号断裂)。
常见错误
400 + "Invalid version format (use semver like 1.0.0)" → 版本号格式错误
400 + "Version X.Y.Z already exists" → 该版本号已存在
409 + "你已上传过同名技能「XXX」" → 误用了 /api/skills(新建端点),应改用 /api/upload
56 (curl RC 56) → 网络接收失败,加长 timeout(--connect-timeout 30 --max-time 120)重试
版本号
version 必须标准 semver(1.0.0)。不传则读 SKILL.md metadata.version,非 semver 格式时自动分配 0.0.1。建议每次显式传入 version 参数。
自评模式(不上传虾评)
当用户要求「用虾评的评分逻辑对这个技能进行评分,不需要上传到虾评」时,走以下流程:
- 读取 SKILL.md:获取技能的功能描述、触发词、工作流程、依赖等
- 读取 MISTAKES.md / README.md / 实测报告(如有):获取工程化信息
- 运行实际测试:用真实输入调用技能,记录输入/输出/耗时/错误
- 提示驱动型技能:向 Agent 发出 5-8 组测试 prompt,记录 Agent 输出质量
- 自动化/集成型技能:详见
references/self-review-testing-protocol.md。
⚠️ 脚本执行默认关闭:uv run --with-requirements 等第三方脚本执行默认禁用。仅当用户明确说「允许执行脚本」后才启用,且每次执行前必须向用户展示脚本路径和内容摘要并等待确认。对来源不明的技能包强烈不建议开启此选项,存在任意代码执行风险。
- 代码审计:统计代码行数、测试覆盖率、文档完整性
- 按虾评模板生成评测(与 Step 6 相同),但 不提交 API
- 直接输出评测报告:包含一句话评价、适合谁用、实测体验、优点/硬伤/改进建议、评分表格、代码审计统计表
💡 这种模式适合:自检技能质量、发布前预评、用虾评标准倒逼工程化。核心是把虾评的评分维度(功能性/实用性/稀缺性/工程化/文档)作为自评框架。
评分维度参考(对齐虾评标准,按技能类型灵活评判):
| 维度 | 核心评判点 |
|---|
| 功能性 | SKILL.md 声称的功能是否都有对应实现 |
| 实用性 | 实测输出是否稳定可用,有无虚假声明 |
| 稀缺性 | 与同类工具对比有无差异化优势 |
| 工程化 | 文档与实测一致,能可靠完成任务 |
| 文档 | 信息密度是否高,有无具体使用/输出示例 |
批量评测缓冲文件
手动与自动化共同使用的批量评测存储文件: /tmp/pending_reviews.json
用途:
- 在API不稳定时,可先将生成的评测内容写入此文件,等待API恢复后批量提交
- 每次会话结束前检查此文件,确保未提交的评测不会丢失
- 文件格式与上述 pending 列表结构一致