stepfun-asr
Transcribe audio with StepFun's stepaudio-2.5-asr — an SSE endpoint (NOT /v1/audio/transcriptions) with 32K context, ~85-101x RTF on long audio, and a single-call ceiling around 30 minutes (no client-side chunking). Use when transcribing Chinese / English audio with StepFun, when long-form recordings (5-30 min) need to land in one request, when migrating from step-asr / step-asr-1.1, or when hitting the misleading `model stepaudio-2.5-asr not supported` error (which actually means wrong endpoint). Triggers on 阶跃 ASR, StepFun ASR, stepaudio-2.5-asr, 转录, 语音识别, 长音频转写, 语音转文字. For TTS with the sibling stepaudio-2.5-tts model, use the stepfun-tts skill instead.
1How It Works & Mechanism
The premise of this skill is uncovering three pitfalls that look like unrelated issues: deceptive errors from the wrong endpoint, silent failures from Plan keys, and error events delivered inside the SSE stream.
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.
A single-file script encapsulates proper requests: reads the audio file → base64-encodes it → wraps it in a nested JSON body → POSTs to the SSE endpoint, fetching the Authorization Bearer token from 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 parsing discipline: avoid buffering into non-streaming responses, collect deltas, treat the text in transcript.text.done as the authoritative full text and usage source, and explicitly handle error events.
if t == "transcript.text.delta": deltas += 1 elif t == "transcript.text.done": text = ev.get("text", "") usage = ev.get("usage")
Fail-fast API key resolution: prioritizes $STEPFUN_API_KEY, falling back to api_key in ${CLAUDE_PLUGIN_DATA}/config.json; aborts immediately with an error if missing, never using placeholders.
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"
Capacity and performance boundary management: the 32K context cap allows ≈30 minutes of audio per single request; split with ffmpeg prior to requests for audio exceeding 30 minutes; formats are auto-detected by extension (mp3/wav/ogg/opus/pcm).
| Audio > 30 min | Split with ffmpeg before sending; the API rejects oversized payloads |
Failure modes translated into an actionable remediation matrix: misleading 412s, silent 4xx errors, sudden spikes of repeating characters, and censorship events each have dedicated handling.
| `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 |
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| network | api.stepfun.com(StepAudio ASR SSE 端点) |
| network | platform.stepfun.com(文档/定价/取 key,仅指引) |
| cli | python3(stdlib urllib,无第三方包) |
| cli | ffmpeg(仅 >30 分钟切分建议,非脚本依赖) |
4Recommended Governance & Evidence
- scripts/: Executes local script or command: daymade-audio/stepfun-asr/scripts/asr_transcribe.py
- 网络端点: Declares outbound network access: POST https://api.stepfun.com/v1/audio/asr/sse (payload contains full base64 audio + Bearer authorization)
5Second-Pass Verification
- [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。
6Verdict & Scenarios
6954122ed209d0d4…