Case 01712
A fast, offline static risk analysis CLI for AI agent skill files. Detects malicious instructions, steganographic payloads, and dangerous capability chains.
npx -y skills add knownasnaffy/prompthound --skill case_01712Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
VoScript self-hosted speech transcription API skill. Covers the full workflow: submit audio, poll job status, fetch results, export subtitles (SRT/TXT/JSON), manage voiceprints, assign speakers, and rebuild AS-norm cohorts. Works with Claude Code, OpenClaw, Hermes, Codex, Gemini CLI, Trae, Cursor, Cline, Roo Code, CodeBuddy, Qwen Code, and any agent with a skills directory.
The file declares its own license as SEE LICENSE IN LICENSE. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
16.3 KB, ~5.3k tokens by cl100k_base, as published. Nobody here has run it
VoScript API 技能包
VoScript 是一个自托管的语音转写服务,支持多说话人分离、声纹识别、降噪、 多格式导出。本技能包封装了其 REST API 的全部主要工作流。
重要:本技能与代理无关(agent-agnostic),同等适用于 Claude、Codex、 Trae、Hermes、OpenClaw 等任何 AI 代理,不依赖任何厂商专属特性。
1. 配置说明
VoScript 通过两个参数进行访问配置:
VOSCRIPT_URL:服务地址,例如http://localhost:7880VOSCRIPT_API_KEY:调用 API 所需的鉴权密钥
推荐通过环境变量设置,所有脚本也支持 --url / --api-key 命令行参数覆盖。
当 VOSCRIPT_URL 或 VOSCRIPT_API_KEY 未配置时,代理必须:
- 先向用户索要服务地址与 API Key;
- 告知用户配置方式:
- 环境变量:
export VOSCRIPT_URL=.../export VOSCRIPT_API_KEY=... - 或使用脚本的
--url <URL>/--api-key <KEY>参数。
- 环境变量:
详见 ${SKILL_PATH}/references/configuration.md。
2. 提交音频转写
上传音频文件并创建转写任务。
接口: POST /api/transcribe(multipart/form-data)
请求参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
file | file | 是 | — | 待转写音频文件 |
language | string | 否 | 自动 | 语言代码,如 zh / en |
min_speakers | int | 否 | 1 | 最少说话人数 |
max_speakers | int | 否 | 10 | 最多说话人数 |
denoise_model | string | 否 | none | 可选 none / deepfilternet / noisereduce |
snr_threshold | float | 否 | 10.0 | 信噪比阈值 |
no_repeat_ngram_size | int | 否 | 0 | 解码时抑制 n-gram 重复 |
curl -X POST "$VOSCRIPT_URL/api/transcribe" \
-H "X-API-Key: $VOSCRIPT_API_KEY" \
-F "file=@/path/to/audio.wav" \
-F "language=zh" \
-F "min_speakers=1" \
-F "max_speakers=10"
响应字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 任务 / 转写 ID(形如 tr_xxx),后续接口均以此为主键 |
status | string | 初始状态,一般为 queued;若命中去重则为 completed |
deduplicated | bool | 可选字段,出现且为 true 表示命中 SHA-256 去重,直接返回既有结果 |
❗
deduplicated: true不是错误,是正常响应。VoScript 对音频内容计算 SHA-256, 若已处理过相同文件,直接返回已有结果。此时status为"completed", 无需再次轮询,直接用返回的id获取结果。
错误响应表:
| HTTP | 含义 | 排查 |
|---|---|---|
| 401 | API Key 无效 | 检查 VOSCRIPT_API_KEY 是否正确、有无多余空格 |
| 413 | 文件过大 | 超过服务端 MAX_UPLOAD_BYTES 限制(默认 2 GiB) |
| 422 | 参数校验失败 | 检查 min_speakers/max_speakers/denoise_model 值是否合法 |
| 500 | 服务端错误 | 查看容器日志 docker logs voscript |
执行脚本:
python ${SKILL_PATH}/scripts/submit_audio.py \
--file <PATH> \
[--language zh] \
[--min-speakers 1] \
[--max-speakers 10]
3. 轮询任务状态
接口: GET /api/jobs/{job_id}
curl -X GET "$VOSCRIPT_URL/api/jobs/tr_xxx" \
-H "X-API-Key: $VOSCRIPT_API_KEY"
状态机: queued → converting → denoising → transcribing → identifying → completed | failed
状态含义与典型耗时:
| 状态 | 含义 | 典型耗时 |
|---|---|---|
| queued | 等待 GPU 资源 | 即时~数秒 |
| converting | ffmpeg 格式转换 | 数秒 |
| denoising | DeepFilterNet 降噪 | 10-30 秒(可选步骤) |
| transcribing | Whisper + pyannote 转写 | 音频时长的 20-50% |
| identifying | 声纹匹配 | 数秒 |
| completed | 完成 | — |
| failed | 失败 | 查看 error 字段 |
⚠️ 轮询建议间隔 5 秒,首次加载模型需 2-5 分钟(仅首次), 轮询超时不代表失败,可继续等待或检查
/healthz。
常见错误:
| HTTP | 含义 | 排查 |
|---|---|---|
| 401 | API Key 无效 | 检查 VOSCRIPT_API_KEY |
| 404 | job_id 不存在 | 确认 ID 拼写,或任务可能已被清理 |
执行脚本:
python ${SKILL_PATH}/scripts/poll_job.py --job-id tr_xxx
详细状态机与阶段耗时:${SKILL_PATH}/references/job-lifecycle.md
4. 获取转写结果
接口: GET /api/transcriptions/{tr_id}
curl -X GET "$VOSCRIPT_URL/api/transcriptions/tr_xxx" \
-H "X-API-Key: $VOSCRIPT_API_KEY"
返回内容包括:segments、speaker_map、params 等完整结果。
Segment 字段表:
| 字段 | 类型 | 说明 |
|---|---|---|
id | int | 片段序号 |
start / end | float | 起止时间(秒) |
text | string | 转写文本 |
speaker_label | string | pyannote 原始标签(如 SPEAKER_00),注册声纹时使用此值 |
speaker_id | string|null | 已绑定的声纹 ID,null 表示未注册 |
speaker_name | string | 显示名(已注册则为姓名,否则同 speaker_label) |
similarity | float|int | AS-norm z-score,非概率,典型范围 -1 到 2,匹配阈值 ~0.5 |
words | array|null | 词级对齐(强制对齐成功时存在) |
❗
similarity是 AS-norm 归一化的 z-score,不是 [0,1] 之间的概率。 值可能超过 1.0(最高观测值约 1.79)。若用similarity > 0.5判断是否匹配, 这是合理的经验值,但不能理解为"50% 置信度"。
常见错误:
| HTTP | 含义 | 排查 |
|---|---|---|
| 404 | tr_id 不存在 | 核对 ID;确认任务已 completed |
| 409 | 任务尚未完成 | 先通过 /api/jobs/{id} 轮询到 completed |
执行脚本:
python ${SKILL_PATH}/scripts/fetch_result.py --tr-id tr_xxx
5. 导出转写
接口: GET /api/export/{tr_id}?format=srt|txt|json
curl -X GET "$VOSCRIPT_URL/api/export/tr_xxx?format=srt" \
-H "X-API-Key: $VOSCRIPT_API_KEY" \
-o transcript.srt
支持格式:
| format | 用途 | MIME |
|---|---|---|
srt | 标准字幕文件,带时间轴 | application/x-subrip |
txt | 带说话人前缀的纯文本 | text/plain |
json | 完整结构化数据(segments + speaker_map) | application/json |
常见错误:
| HTTP | 含义 | 排查 |
|---|---|---|
| 404 | tr_id 不存在 | 核对 ID |
| 422 | format 参数非法 | 只能是 srt / txt / json |
格式细节:${SKILL_PATH}/references/export-formats.md
执行脚本:
python ${SKILL_PATH}/scripts/export_transcript.py --tr-id tr_xxx --format srt
6. 转写列表
接口: GET /api/transcriptions
curl -X GET "$VOSCRIPT_URL/api/transcriptions" \
-H "X-API-Key: $VOSCRIPT_API_KEY"
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 转写 ID |
filename | string | 原始文件名 |
created_at | string | ISO 8601 创建时间 |
segment_count | int | 片段数量 |
speaker_count | int | 说话人数量 |
执行脚本:
python ${SKILL_PATH}/scripts/list_transcriptions.py
7. 注册声纹
从已有转写中抽取某个 speaker_label 对应片段作为样本,注册或更新声纹。
接口: POST /api/voiceprints/enroll
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
tr_id | string | 是 | 来源转写 ID |
speaker_label | string | 是 | pyannote 原始标签,如 SPEAKER_00(不是显示名!) |
speaker_name | string | 是 | 说话人姓名(显示用) |
speaker_id | string | 否 | 传入已有声纹 ID 则更新该声纹 |
curl -X POST "$VOSCRIPT_URL/api/voiceprints/enroll" \
-H "X-API-Key: $VOSCRIPT_API_KEY" \
-F "tr_id=tr_xxx" \
-F "speaker_label=SPEAKER_00" \
-F "speaker_name=张三"
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
action | string | created(新建)或 updated(更新已有声纹) |
speaker_id | string | 声纹 ID,后续可用于绑定 |
❗ 最常见错误:
speaker_label填写了显示名而非原始标签
- ✗ 错误:
--speaker-label "张三"- ✓ 正确:
--speaker-label "SPEAKER_00"
speaker_label必须是 pyannote 的原始标签(SPEAKER_00,SPEAKER_01等), 来自转写结果的segment.speaker_label字段。注册成功后,后续转写中识别出的同一说话人会自动匹配到
speaker_name。
错误响应表:
| HTTP | 含义 | 排查 |
|---|---|---|
| 404 | Embedding not found for this speaker label | speaker_label 在该转写中不存在。检查大小写、确认使用的是 SPEAKER_XX 格式 |
| 422 | 参数缺失 | 确认 tr_id、speaker_label、speaker_name 均已提供 |
| 401 | API Key 无效 | 检查 VOSCRIPT_API_KEY |
执行脚本:
python ${SKILL_PATH}/scripts/enroll_voiceprint.py \
--tr-id tr_xxx \
--speaker-label SPEAKER_00 \
--speaker-name "张三"
8. 声纹列表
接口: GET /api/voiceprints
curl -X GET "$VOSCRIPT_URL/api/voiceprints" \
-H "X-API-Key: $VOSCRIPT_API_KEY"
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 声纹 ID |
name | string | 显示姓名 |
sample_count | int | 已累积的样本数量 |
sample_spread | float|null | 样本间余弦相似度的标准差;单样本时为 null;数值越小表示样本一致性越高 |
created_at | string | ISO 8601 创建时间 |
updated_at | string | ISO 8601 最后更新时间 |
⚠️
sample_spread偏大(例如 > 0.3)说明样本之间差异大,可能混入了错误片段, 建议通过manage_voiceprint.py --action get查看详情并考虑清理。
执行脚本:
python ${SKILL_PATH}/scripts/list_voiceprints.py
9. 分配说话人
手动为某个 segment 指定说话人(用于纠正分离错误或补齐未识别片段)。
接口: PUT /api/transcriptions/{tr_id}/segments/{seg_id}/speaker
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
speaker_name | string | 是 | 新的说话人显示名 |
speaker_id | string | 否 | 若要绑定已注册声纹,传入声纹 ID |
curl -X PUT "$VOSCRIPT_URL/api/transcriptions/tr_xxx/segments/5/speaker" \
-H "X-API-Key: $VOSCRIPT_API_KEY" \
-F "speaker_name=李四"
💡 当你发现某个片段的说话人识别有误,或想手动覆盖自动识别结果时使用。 手动分配不影响声纹库,仅修改该片段的显示名。
常见错误:
| HTTP | 含义 | 排查 |
|---|---|---|
| 404 | tr_id 或 seg_id 不存在 | 核对 ID;seg_id 为 segment 在该转写中的序号 |
| 422 | 参数缺失 | 至少提供 speaker_name |
执行脚本:
python ${SKILL_PATH}/scripts/assign_speaker.py \
--tr-id tr_xxx \
--seg-id 5 \
--speaker-name "李四"
10. 管理声纹
| 操作 | 端点 | 参数 |
|---|---|---|
| 查看详情 | GET /api/voiceprints/{speaker_id} | — |
| 重命名 | PUT /api/voiceprints/{speaker_id}/name | 表单字段 name |
| 删除 | DELETE /api/voiceprints/{speaker_id} | — |
curl -X GET "$VOSCRIPT_URL/api/voiceprints/<SPEAKER_ID>" \
-H "X-API-Key: $VOSCRIPT_API_KEY"
常见错误:
| HTTP | 含义 | 排查 |
|---|---|---|
| 404 | speaker_id 不存在 | 通过 /api/voiceprints 确认 ID |
| 422 | 重命名时缺少 name 字段 | 提供表单字段 name |
执行脚本:
python ${SKILL_PATH}/scripts/manage_voiceprint.py \
--action [get|rename|delete] \
--speaker-id xxx \
[--name "新名字"]
11. 重建声纹 cohort
AS-norm 评分依赖 cohort(对比样本集)。
接口: POST /api/voiceprints/rebuild-cohort
curl -X POST "$VOSCRIPT_URL/api/voiceprints/rebuild-cohort" \
-H "X-API-Key: $VOSCRIPT_API_KEY"
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
cohort_size | int | 重建后 cohort 内样本数量 |
skipped | int | 被跳过的样本数(质量不达标或重复) |
saved_to | string | cohort 文件保存路径 |
💡 何时执行重建:
- 注册满 10 个说话人后首次执行
- 每新增 10-20 个说话人后更新一次
- cohort 大小 ≥ 50 时 AS-norm 评分最为稳定
重建前无需停止服务,操作为后台非阻塞任务。
执行脚本:
python ${SKILL_PATH}/scripts/rebuild_cohort.py
声纹完整工作流与阈值说明见 ${SKILL_PATH}/references/voiceprint-guide.md。
错误响应规范
VoScript 返回标准 HTTP 状态码,代理在处理响应时应按下表做分支:
| 状态码 | 含义 | 处理建议 |
|---|---|---|
| 200 | 成功 | 正常解析响应 |
| 401 | API Key 无效 | 提示用户检查 VOSCRIPT_API_KEY |
| 404 | 资源不存在 | 核对 tr_id / speaker_id / job_id |
| 409 | 资源状态冲突 | 例如任务尚未 completed 就请求结果 |
| 413 | 文件过大 | 检查服务端 MAX_UPLOAD_BYTES(默认 2 GiB) |
| 422 | 请求参数校验失败 | 根据返回 detail 字段检查参数,常见于缺少 file |
| 500 | 服务端错误 | 收集 error 字段,必要时检查服务端日志 |
诊断检查清单
遇到问题时,按以下顺序排查:
- 服务可达性:
curl $VOSCRIPT_URL/healthz是否 200 - 鉴权:
X-API-Key是否与容器环境变量VOSCRIPT_API_KEY一致,有无多余空格 - 任务状态:先通过
/api/jobs/{id}确认completed,再拉结果 - 声纹标签:注册声纹时使用
SPEAKER_XX原始标签,不是显示名 - similarity 语义:不是概率,是 AS-norm z-score,阈值 ~0.5 为经验值
- 去重响应:
deduplicated: true是正常返回,不是错误 - 首次冷启动:模型加载耗时 2-5 分钟,轮询超时不等于失败
- 容器日志:
docker logs voscript查看详细栈回溯
典型使用序列
- 配置
VOSCRIPT_URL/VOSCRIPT_API_KEY。 submit_audio.py上传音频,拿到tr_id。poll_job.py轮询到completed。fetch_result.py获取 segments,审阅 speaker 分离结果。- 对每个
SPEAKER_xx调用enroll_voiceprint.py注册真实姓名。 - 累计 10+ 声纹后运行
rebuild_cohort.py刷新 AS-norm 基线。 - 后续新音频转写会自动识别已注册说话人。
- 需要字幕文件时使用
export_transcript.py导出 SRT/TXT/JSON。
参考文档
${SKILL_PATH}/references/configuration.md—— 配置与鉴权${SKILL_PATH}/references/job-lifecycle.md—— 任务状态机${SKILL_PATH}/references/voiceprint-guide.md—— 声纹与 AS-norm${SKILL_PATH}/references/export-formats.md—— 导出格式
What ships with it: 15 files
87.5 KB alongside SKILL.md, 11 of them executable
references/
- configuration.md2.7 KB
- export-formats.md3.0 KB
- job-lifecycle.md4.7 KB
- voiceprint-guide.md4.2 KB
scripts/
- assign_speaker.pyruns2.5 KB
- common.pyruns28.5 KB
- enroll_voiceprint.pyruns4.2 KB
- export_transcript.pyruns3.3 KB
- fetch_result.pyruns6.5 KB
- list_transcriptions.pyruns4.1 KB
- list_voiceprints.pyruns4.9 KB
- manage_voiceprint.pyruns3.7 KB
- poll_job.pyruns5.6 KB
- rebuild_cohort.pyruns2.8 KB
- submit_audio.pyruns6.8 KB