关于 stepfun-asr
stepfun-asr 是使用 StepFun `stepaudio-3-asr-max` 转写音频的技能,面向需要命令行或脚本转录的用户。它封装了 SSE 请求、音频编码和时间戳解析,并说明端点与密钥类型等常见问题。
主要功能
- 01转写长音频且无需分块
- 02输出逐词时间戳
- 03支持 JSON 用量信息
- 04解析 SSE 转写与错误事件
- 05支持多种音频格式
适用场景
- 01将本地音频转为文字
- 02生成带时间戳的机器可读转录
- 03排查端点或 API 密钥错误
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ daymade/ claude-code-skills --skill stepfun-asr安装后在 Claude Code 中输入/stepfun-asr确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api_reference.mdknown_issues.mdscripts/asr_file.pyasr_transcribe.pycheck_params.py详细介绍
StepFun stepaudio-3-asr-max
使用 StepFun 的 stepaudio-3-asr-max 转录音频(StepAudio 3,于 2026-09-15 发布,2026-09-16 验证;在同一端点上取代 stepaudio-2.5-asr)。一次调用即可处理长音频,无需分块——但前提是请求发送到了正确的端点,且请求体格式正确。错误的端点会返回与“模型不存在”完全相同的错误,这也是本技能存在的首要原因。
配套技能:若要使用同系列模型
stepaudio-3-tts进行 TTS,请使用stepfun-tts技能——它们共用一个 API 密钥,但端点不同,请求体格式也不同。
此技能存在的原因——三个耗费数小时的陷阱
-
端点错误,错误信息也具有误导性。
stepaudio-3-asr-max不在/v1/audio/transcriptions上(该端点服务较旧的step-asr系列),而是在/v1/audio/asr/sse上——使用 SSE 流式传输、JSON 请求体和 base64 音频。将请求发送到错误的端点会返回{"error":{"message":"model stepaudio-3-asr-max not supported"}},其结构与模型名称确实不存在时完全相同。许多人因此浪费数小时提交白名单工单。 -
Plan 密钥与 Normal 密钥,静默失败。StepFun 的“Plan”订阅密钥(价格低廉,仅支持文本)无法调用音频端点,但失败时会返回 4xx,且没有任何类似鉴权错误的信息。如果你的账户订阅了 Plan,就需要从同一个控制台单独获取一个“Normal”密钥。
-
SSE 错误事件确实会出现。ASR 端也可能触发内容审核(虽然很少)。不要以为只会收到
transcript.text.delta和transcript.text.done事件——要处理流中的type: error事件,否则这些错误会被静默丢弃。
配置和身份验证
API 密钥按以下顺序解析(快速失败,不使用默认值):
$STEPFUN_API_KEY环境变量${CLAUDE_PLUGIN_DATA}/config.json,内容为{"api_key": "..."}(可跨会话持久保存)
首次设置:
mkdir -p "${CLAUDE_PLUGIN_DATA}" && cat > "${CLAUDE_PLUGIN_DATA}/config.json" <<EOF
{"api_key": "<paste Normal key here>"}
EOF
如果用户尚未设置密钥,请让他们粘贴密钥——不要猜测或使用占位符。请前往 https://platform.stepfun.com/ → API Keys 获取密钥。请使用 Normal 密钥,而非 Plan 密钥。
快速开始——单个文件
python3 scripts/asr_transcribe.py /path/to/audio.mp3
输出:标准输出中的纯文本转录结果。
如需包含用量和耗时的机器可读输出:
python3 scripts/asr_transcribe.py /path/to/audio.mp3 --json
处理非中文音频:
python3 scripts/asr_transcribe.py /path/to/audio.mp3 --language en
无需设置任何标志即可获取逐词时间戳——--json 始终包含 segments:
"segments": [{"text": "Understand ", "start_ms": 228, "end_ms": 1108}, ...]
每个词对应一条记录,时间戳单调递增。少数词会与前一个词共用时间戳(服务端会分块刷新),这有助于定位某个时间点,但不适用于强制对齐。
如需使用旧版模型:
python3 scripts/asr_transcribe.py /path/to/audio.mp3 --model stepaudio-2.5-asr
该脚本会处理 base64 编码、嵌套的 {audio: {data, input: {transcription, format}}} 请求体、SSE 解析,以及端点错误导致的误导性问题。除非要集成到更大的流水线中,否则请优先使用该脚本,而不要手动编写 HTTP 请求。
决策表
| 场景 | 操作 |
|---|---|
| 短音频片段(< 5 min),中文或英文,mp3/wav/ogg/opus | python3 scripts/asr_transcribe.py audio.mp3 |
| 长音频(5-30 min) | 使用同一脚本——32K 上下文可在单次调用中处理,无需分块 |
| 音频 > 30 min | 发送前使用 ffmpeg 分割;API 会拒绝过大的负载 |
| 需要用量/账单数据 | 添加 --json,从 transcript.text.done 中提取 usage.input_tokens / usage.total_tokens |
| 需要知道每个词的说话时间 | 使用 --json,读取 segments。默认开启 |
| 需要说话人标签(谁说了什么) | python3 scripts/asr_file.py <public-url>——使用不同的异步端点。需要 URL,而非本地文件:base64 和 StepFun 自有文件存储都会被拒绝,因此由运行脚本的人决定将音频托管在可供获取的位置 |
--model stepaudio-2-asr-pro 返回 internal error | 该模型无法用于 /v1/audio/asr/sse(2026-09-18 测得);请使用默认模型或 stepaudio-2.5-asr |
| 高度重复的内容(同一句短语重复 5 次以上,时长 > 90s) | 使用 step-asr-1.1 进行交叉验证——参见 references/known_issues.md 中的重复内容幻觉问题(2.5 时代的问题,在 v3 上尚未验证) |
遇到 model stepaudio-3-asr-max not supported | 端点错误。请从 /v1/audio/transcriptions 切换到 /v1/audio/asr/sse |
| 遇到无提示的 4xx 身份验证失败 | 确认你的密钥为“Normal”而非“Plan”——Plan 密钥无法调用音频端点 |
| 需要编写原始 HTTP(不使用 Python) | 阅读 references/api_reference.md,了解准确的 JSON 请求体和 SSE 事件结构 |
说话人标签 — scripts/asr_file.py
/v1/audio/asr/sse 上的 stepaudio-3-asr-max 完全不具备说话人识别能力(14 个候选请求字段均经测试无效)。说话人分离功能位于异步文件端点:
python3 scripts/asr_file.py https://example.com/talk.mp3
# [ 6.61- 8.43] speaker_0: Hello. Hello. Oh,
# [ 8.21- 10.11] speaker_1: hello! I didn't know you were there.
2026-09-18 在双说话人样本上完成了端到端验证:轮次边界正确,每段话语内均有逐词时间戳,每个任务最多支持 10 位说话人。使用 stepaudio-2.5-asr——此端点不提供 v3。
硬性限制:它只会获取 URL,不接受其他输入。 Base64 会被拒绝,StepFun 自有的 stepfile:// 文件存储也会被拒绝,因此若不先将本地文件放到可公开获取的位置,就无法向其提供该文件。将文件放在哪里由调用方决定。references/known_issues.md 介绍了三种行不通的方法以及重试/重定向行为。
参数不收费——绝不要默默省略参数
发送更多请求参数不增加费用:计费依据是音频时长。因此默认做法是发送所有有用参数,而每个未发送的字段都必须在 scripts/asr_transcribe.py 顶部的 REQUEST_PARAMS 中写明理由。
python3 scripts/check_params.py # diff official field table vs REQUEST_PARAMS
python3 scripts/check_params.py --selftest # calibrate the check before trusting it
两个检查器,分别覆盖两个方向:
- 请求端——
check_params.py获取官方字段表;若其中列出的字段未在REQUEST_PARAMS中提及,就会报错。--selftest会双向校准:实际清单必须通过(不能误报),移除了enable_timestamp的清单必须被检出(这是实际发生过的历史疏漏——由于只读取了响应字段表,逐词时间戳曾缺失数月)。 - 响应端——对于服务器发送但解析器未处理的任何字段,解析器都会报告
unhandled_response_fields。这正是从这一侧看时间戳疏漏时的情况:每个增量事件都带有start_time/end_time,但这些字段被丢弃了。
支持的音频格式
脚本会根据扩展名自动检测格式;传入 --format 可覆盖:
| 扩展名 | 格式标记 | 说明 |
|---|---|---|
.mp3 | mp3 | 最常见,默认格式 |
.wav | wav | 无损 |
.ogg | ogg | OGG 容器 |
.opus | ogg | OGG 容器中的 Opus 编码;原样传递 |
.pcm | pcm | 原始 PCM——还需传入 --rate、--bits、--channel(以及 --codec) |
对于 mp4/m4a/webm 等格式,先通过 ffmpeg 转码为以上格式之一。生产流水线通常会预先将所有音频转码为 OGG/Opus、16kHz、单声道,以尽量缩小 base64 负载。
容量与性能
v3 实测数据(已于 2026-09-16 验证):10s 音频片段 → 1.1s,53s 真实场景音频片段 → 2.6s(约 20× RTF)。供参考的 v2.5 时代基线数据(2026-04-23,同一端点):32K 上下文窗口,处理 17.4 min 音频时约为 85-101× RTF,单次调用上限 ≈ 30 min——在重新测试前,将 30 min 视为 v3 的工作上限;引用长音频数据前请重新测量。
常见错误模式
| 错误响应 | 实际原因 | 修复方法 |
|---|---|---|
在 /v1/audio/transcriptions 上出现 "model stepaudio-3-asr-max not supported" | 端点错误 | 切换到 /v1/audio/asr/sse(脚本会自动执行此操作) |
| 4xx 响应无提示信息 | 在音频端点上使用了 "Plan" 密钥 | 从 StepFun 控制台获取 "Normal" 密钥 |
| ASR 返回的字符数是预期值的 3-4× | 高度重复的音频导致重复幻觉 | 使用 step-asr-1.1 交叉验证;参见 references/known_issues.md |
流传输过程中出现 data: {"type":"error","message":"content blocked..."} | 用户上传的内容触发了审查 | 明确处理 SSE error 事件;不要假设只会收到 delta/done |
更多边缘情况请参见 references/known_issues.md。
设计不变量(不得破坏)
- 始终透传 SSE——不要尝试使用非流式客户端缓冲响应。对于长音频,模型会输出
transcript.text.delta;transcript.text.done携带权威的完整文本和usage。完全拒绝 SSE 格式会导致什么也得不到。 - 从
transcript.text.done.text获取最终文本——在边缘情况下,拼接增量文本可能出现偏差。增量文本用于渐进式 UI;done事件才是可信来源。 - 处理流中的
error事件——不要将 SSE 流视为只会收到成功事件。内容被拦截时,流中会返回一个type: error事件,且不会有done事件。transcribe()的返回字典始终包含原始错误事件负载组成的errors列表(未触发错误时为空),即使ok为True也是如此;因此,若调用方需要保留旧版严格语义(任何错误事件 ⇒ 失败),必须自行检查errors。 - 缺少 API 密钥时立即失败——绝不要默认使用占位符或空字符串。脚本会执行此检查;任何包装器都必须保留这一行为。
何时阅读参考资料
references/api_reference.md— 精确的 JSON 请求正文、所有字段、所有 SSE 事件类型及响应示例。使用内置脚本以外的方式编写原始 HTTP 调用时,请阅读此文档。references/known_issues.md— 重复幻觉详情、错误端点的诊断过程、Plan 与 Normal 密钥的注意事项、ASR 端内容审查处理方式及定价不透明问题。调试异常输出或评估是否从step-asr-1.1迁移时,请阅读此文档。
定价(已于 2026-09-16 验证,可能变动)
stepaudio-3-asr-max:2.8 元/小时(官方模型页面,2026-09-16)。较早的 stepaudio-2.5-asr 仍在同一端点提供,可作为备用方案。向利益相关方引用前,请访问 https://platform.stepfun.com/docs/zh/guides/pricing/details 重新确认。
下一步
ASR 转录文本几乎总能从以下两种后续步骤之一中受益。生成转录文本后,建议采用自然衔接的下一项技能:
Transcription complete. The output is raw text from the model — common next steps:
Options:
A) transcript-fixer — clean up ASR errors (homophones, segmentation, filler words). Recommended if the recording is a real-world conversation, podcast, or interview rather than read-aloud text
B) meeting-minutes-taker — turn the transcript into structured minutes with decisions, action items, and speaker attribution. Recommended if the recording is a meeting
C) No thanks — the raw transcript is what I needed
如果用户已经指定了后续工具,或转录显然只是一次性查询(例如:“这段 15 秒的音频说了什么?”),则跳过建议。