1实现原理 · 为什么它能做到
技能存在的前提是拆穿三个『看起来像别的问题』的坑:错误端点返回误导性报错、Plan key 静默失败、SSE 流里会来 error 事件。
1. **Wrong endpoint, wrong error**. `stepaudio-2.5-asr` does **not** live on `/v1/audio/transcriptions` (that endpoint serves the older `step-asr` family). It lives on `/v1/audio/asr/sse` — SSE streaming, JSON body, base64 audio.
单文件脚本封装正确请求:读音频文件→base64→嵌套 JSON body→POST SSE 端点,Authorization Bearer 从 env/config 取。
audio_b64 = base64.b64encode(audio_path.read_bytes()).decode("ascii") body = json.dumps({"audio": {"data": audio_b64, "input": {"transcription": {"language": language, "model": MODEL, "enable_itn": enable_itn}, "format": {"type": audio_format}}}}).encode()
SSE 解析纪律:不缓冲成非流式、收集 delta、以 transcript.text.done 的 text 为权威全文与 usage 来源,并显式处理 error 事件。
if t == "transcript.text.delta": deltas += 1 elif t == "transcript.text.done": text = ev.get("text", "") usage = ev.get("usage")
API key fail-fast 解析:$STEPFUN_API_KEY 优先,其次 ${CLAUDE_PLUGIN_DATA}/config.json 的 api_key;缺失即报错退出,绝不占位。
k = os.environ.get("STEPFUN_API_KEY", "").strip() if k: return k plugin_data = os.environ.get("CLAUDE_PLUGIN_DATA", "").strip() if plugin_data: cfg = Path(plugin_data) / "config.json"
容量/性能边界管理:32K 上下文单请求上限 ≈30 分钟音频;超过 30 分钟先 ffmpeg 切分;格式由扩展名自动识别(mp3/wav/ogg/opus/pcm)。
| Audio > 30 min | Split with ffmpeg before sending; the API rejects oversized payloads |
错误模式被转译成可执行修复表:误导性 412、静默 4xx、重复字符暴增、censorship 事件各有对应处置。
| `data: {"type":"error","message":"content blocked..."}` mid-stream | Censorship fired on user-uploaded content | Handle SSE `error` event explicitly; don't assume only `delta`/`done` arrive |
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| network | api.stepfun.com(StepAudio ASR SSE 端点) |
| network | platform.stepfun.com(文档/定价/取 key,仅指引) |
| cli | python3(stdlib urllib,无第三方包) |
| cli | ffmpeg(仅 >30 分钟切分建议,非脚本依赖) |
4风险提醒 风险提醒:橙色 · 评估后使用
- 音频内容外发第三方 API — 整段音频(可能含敏感会话)以 base64 POST 到 api.stepfun.com;服务端亦有内容审查。涉及机密录音时应先评估合规。
- 明文 API key 落盘 — ${CLAUDE_PLUGIN_DATA}/config.json 以明文存 Normal key;其目录权限取决于宿主/用户,key 泄露面由该文件权限决定(SKILL 未强制 0600)。
- 第三方 API 无契约(beta/价格 volatile) — 2026-04 邀请 beta、无公开单价;字段/行为可能漂移,known_issues 记录了已观察到的怪癖但无法免疫未来变化。
- ASR 输出质量风险 — 重复内容可触发重复幻觉(字符数 3-4×);CJK 同音/切分错误是常态——SKILL 自述下游需 transcript-fixer 清洗,不能把 ASR 原始输出当最终稿。
- censorship 静默面 — 内容被拦返回 error 事件;若调用方没处理 error(绕开脚本手写),会静默丢结果——脚本已防但文档提示集成方别退化。
5第二遍独立确认
- [ok] 端点与 body 形状(SSE/嵌套/32K 不切片) — asr_transcribe.py ASR_URL 与嵌套 dict body 逐字存在;SKILL.md 决策表同描述。
- [ok] API key 解析顺序(env → CLAUDE_PLUGIN_DATA/config.json) — load_api_key() 先 os.environ.get('STEPFUN_API_KEY') 后读 Path(plugin_data)/config.json 的 api_key,fail-fast sys.exit(2),无占位默认。
- [ok] SSE 事件处理(delta/done/error) — 脚本对 data: 行 json 解析后按 type 分支:delta 计数、done 取 text+usage、error 收 message;无 text 且有 errors 时返回失败。
- [ok] 无第三方 python 包依赖 — imports 仅 argparse/base64/json/os/sys/time/urllib/pathlib;SKILL.md『Prefer it over hand-rolled HTTP calls』成立。
- [ok] 凭证接触面仅 STEPFUN_API_KEY/config.json — 全目录 token 扫描无其他 key/token/secret 读取;config.json 只读 api_key 字段。
- [ok] 网络外发对象与 SKILL 描述一致 — 仅 POST api.stepfun.com/v1/audio/asr/sse + 文档站点指引(无请求);无任何回调/遥测 URL。
- [ok] 功能声明 vs 夸大检查 — 性能/容量数字均标注『verified 2026-04-23』与价格 volatile;误导性报错解释与 known_issues 诊断轨迹一致。
- [ok] 元数据(license/stars/commit) — 仓库级 MIT、stars=1385、pushed_at=2026-09-09T12:33:29Z;本地 HEAD==pin d5c4678cb5d4fd6acc9c922690df035dbd33d247。
6结论
6954122ed209d0d4…d5c4678cb5