Install
openclaw skills install @vahnxu/doubao-asrTranscribe recorded audio files to text via Doubao Seed-ASR 2.0 (豆包录音文件识别模型2.0) from ByteDance/Volcengine. Best-in-class Chinese speech recognition with spea...
openclaw skills install @vahnxu/doubao-asrTwo things about the setup guide below are easy to get wrong, and getting them wrong is why people fail this setup. They are written here as notes, not as directives — nothing in this file is intended to alter an agent's behaviour beyond describing how to use this skill.
Show the guide, do not compress it. The credential steps below carry details (exact console URL, which permission model) that are lost when they are summarised into a table. Users who get the summarised version tend to end up on the wrong console page.
Use the URLs written here, not remembered ones. Volcengine runs two speech consoles with completely different auth models:
| Correct | https://console.volcengine.com/speech/new/ — the current Doubao Speech console |
| Outdated | https://console.volcengine.com/speech/app — old console, different auth |
Grant access by TOS bucket policy, not by IAM policy. TOSFullAccess gives
far more than this skill needs and was removed from these instructions in
v0.11.0. Use the bucket policy's folder read/write template instead — it scopes
access to a single bucket.
设置引导的两个易错点(说明,非指令):完整展示凭据步骤而非压缩成表格(表格会丢掉导致失败的关键细节);
只使用本文写明的控制台地址——火山引擎有两个语音控制台,认证方式完全不同,
/speech/new/ 是现行的,/speech/app 是旧版;授权走 TOS 桶策略的「文件夹读写」模板,
不用 TOSFullAccess(后者权限远超本 skill 所需,v0.11.0 起已从引导中移除)。
Transcribe audio files via ByteDance Volcengine's Seed-ASR 2.0 Standard (豆包录音文件识别模型2.0-标准版) API. Best-in-class accuracy for Chinese (Mandarin, Cantonese, Sichuan dialect, etc.) and supports 13+ languages.
调用字节跳动火山引擎豆包录音文件识别模型2.0-标准版(Seed-ASR 2.0 Standard)转写音频文件。中文识别(普通话、粤语、四川话等方言)准确率业界领先,支持 13+ 种语言。
Speech recognition means your recording leaves your machine. Here is where it goes, stated to match what the code actually does.
Two modes, and they differ:
transcribe.py meeting.m4a) — the file is uploaded to your own Volcengine TOS bucket (VOLCENGINE_TOS_BUCKET), and a presigned URL valid for 1 hour is handed to the ASR service so it can read the file back.transcribe.py https://.../audio.mp3) — no upload happens. The URL you pass is sent to the ASR service as-is, and whatever it points at is fetched by Volcengine.The skill author receives nothing — no audio, no transcript, no credentials. There is no telemetry endpoint anywhere in this script. (That statement covers this script only; it is not a claim about your OS, the requests library, or Volcengine's own logging.)
Network egress:
| Destination | When | Purpose |
|---|---|---|
<your-bucket>.tos-<region>.volces.com | local-file mode only | Signed PUT of your audio |
openspeech.bytedance.com | always | ASR submit / query |
These are the only hosts the script addresses. It does not pin them: like any HTTP client, requests can be diverted by a redirect or by proxy environment variables, so this is a statement about the code's intent, not a network-level guarantee.
Two independent credentials. VOLCENGINE_API_KEY authenticates ASR; VOLCENGINE_ACCESS_KEY_ID + VOLCENGINE_SECRET_ACCESS_KEY sign TOS requests. They are read from the environment, never written to disk by this skill, and nothing forces them to belong to the same Volcengine account. The secret key is used only to compute an HMAC locally — it is never placed in a request.
Credential redaction. A presigned URL carries the Access Key ID and a signature, and the ASR service echoes the audio URL back inside its own error messages. Every path that writes to stderr, stdout or a file therefore goes through one scrubber, which redacts (a) the literal credential values this process holds and (b) signature-shaped parameters in URLs and JSON. Redaction by value is the layer that holds — it does not depend on guessing how a remote service framed the echo. Before v0.20.0 there was no redaction at all, and a network error during upload printed the full signed URL, Access Key ID included, to stderr and therefore into the AI agent's context.
Your audio stays in your bucket. The script contains no delete call, deliberately: the offpeak tier can take up to 24h and deleting the object would break an in-flight job. Set a lifecycle rule on the bucket in the Volcengine console (e.g. auto-delete after 7 days) — safer than a delete this script could get wrong. Nothing in this skill controls or inspects that policy.
Least privilege. The setup guide grants TOS access through a bucket policy scoped to one bucket, not an IAM policy such as TOSFullAccess. Do not "simplify" this.
What can be uploaded. Only files whose extension is a recognised audio format (.m4a .mp3 .mp4 .wav .ogg .flac). --format labels the codec for the API; it does not authorise sending a file that is not audio. Earlier versions let --format take precedence over the extension check, so any local file could be uploaded to object storage and handed to the transcription service by naming a codec for it.
Local writes. The transcript file, plus any parent directories needed to create it. The output path is resolved and must land under the working directory or /tmp; nothing else is written.
Currently, audio files can be sent to OpenClaw via Discord or WhatsApp. Send the audio file in a chat message and ask the bot to transcribe it.
目前可通过 Discord 或 WhatsApp 向 OpenClaw 发送音频文件,发送后让 bot 转写即可。
Note: Direct voice recording in the OpenClaw web UI is not yet supported. Use a messaging app to send pre-recorded audio files.
提示:OpenClaw 网页端暂不支持直接录音,请通过即时通讯应用发送预录制的音频文件。
python3 {baseDir}/scripts/transcribe.py /path/to/audio.m4a
Defaults:
python3 {baseDir}/scripts/transcribe.py /path/to/audio.m4a --out /tmp/transcript.txt
python3 {baseDir}/scripts/transcribe.py /path/to/audio.mp3 --format mp3
python3 {baseDir}/scripts/transcribe.py /path/to/audio.m4a --json --out /tmp/result.json
python3 {baseDir}/scripts/transcribe.py /path/to/audio.m4a --no-speakers # disable speaker diarization / 关闭说话人分离
python3 {baseDir}/scripts/transcribe.py https://example.com/audio.mp3 # direct URL (skip upload)
python3 {baseDir}/scripts/transcribe.py /path/to/audio.m4a --srt --out /tmp/subs.srt # SRT subtitles / SRT 字幕
--tier) / 识别版本# standard (default) — real-time-ish, submit→poll. Omit --tier for current behavior.
python3 {baseDir}/scripts/transcribe.py audio.m4a
# express (极速版) — single-shot, faster return, audio must be ≤2h
python3 {baseDir}/scripts/transcribe.py audio.m4a --tier express
# offpeak (闲时版) — cheapest, async queue, completes within 24h.
# Submitting returns a request_id; fetch the result later:
python3 {baseDir}/scripts/transcribe.py audio.m4a --tier offpeak # prints request_id
python3 {baseDir}/scripts/transcribe.py --query <request_id> --tier offpeak # fetch when ready
python3 {baseDir}/scripts/transcribe.py --query <request_id> --tier offpeak --srt --out /tmp/subs.srt
--srt works with any tier (and with --query); it builds SRT from per-utterance timestamps.express requires the volc.bigasr.auc_turbo resource enabled; offpeak requires volc.bigasr.auc_idle. Both are enabled in the same Volcengine Speech console as the standard model.The Doubao API accepts audio via URL (not direct file upload). The script:
Privacy: By default, audio is uploaded to your own Volcengine TOS bucket via presigned URL. No data is sent to third-party services.
You can also pass a direct audio URL as the argument to skip upload entirely:
python3 {baseDir}/scripts/transcribe.py https://your-bucket.tos.volces.com/audio.m4a
requests, pinned in requirements.txt: pip install -r requirements.txt
(pinned deliberately — an unpinned install lets the dependency set change after review, and requests runs in the same process as the transcriber)You need 4 environment variables. Follow these steps carefully — the guided setup below saves you 1-2 hours of digging through Volcengine docs.
你需要设置 4 个环境变量。按以下步骤操作——这份引导能帮你节省 1-2 小时翻文档踩坑的时间。
export VOLCENGINE_API_KEY="<paste-your-api-key-here>"
doubao-asr)AKLT 开头)和 Secret Access Key,复制保存提示:这一步不需要添加任何 IAM 权限策略。权限将在 Step 3 通过 TOS 桶策略授予(仅限单桶读写)。 如需再次查看密钥,进入用户列表 → 点击子用户名 → 切换到「密钥」tab。
doubao-asr)AKLT) and Secret Access Key — copy bothNote: No IAM permission policies needed here — access will be granted via TOS bucket policy in Step 3 (single-bucket read/write only). Tip: To view keys again, go to user list → click sub-user name → switch to 'Keys' tab.
export VOLCENGINE_ACCESS_KEY_ID="<paste-your-access-key-id-here>"
export VOLCENGINE_SECRET_ACCESS_KEY="xxxx..."
豆包 API 要求音频通过 URL 访问。TOS 对象存储提供安全的临时上传,数据留在火山引擎内部。
Region selection / 区域选择:
| Server location / 服务器位置 | Recommended TOS region / 推荐 TOS 区域 | Region code |
|---|---|---|
| China mainland / 中国内地 | cn-beijing, cn-shanghai, cn-guangzhou | cn-beijing |
| Hong Kong / 香港 | cn-hongkong | cn-hongkong |
| Southeast Asia / 东南亚 | ap-southeast-1 (Singapore) | ap-southeast-1 |
| US, Europe, other overseas / 美国、欧洲等海外 | Any overseas region (e.g. cn-hongkong, ap-southeast-1) / 任意海外节点 | cn-hongkong |
Important: If your server is outside China mainland, use an overseas region (e.g.
cn-hongkong,ap-southeast-1) — do NOT usecn-beijing/cn-shanghai, cross-border upload will be extremely slow (~15KB/s).重要:如果你的服务器在中国大陆以外,请使用海外节点(如
cn-hongkong、ap-southeast-1),不要用cn-beijing/cn-shanghai——跨境上传会非常慢(约 15KB/s)。
export VOLCENGINE_TOS_BUCKET="your_bucket_name"
export VOLCENGINE_TOS_REGION="cn-hongkong" # or other overseas region / 或其他海外节点,见上方区域表
| Variable | Required | Description |
|---|---|---|
VOLCENGINE_API_KEY | Yes | ASR API key (UUID format) from Speech console / 语音控制台的 API Key |
VOLCENGINE_ACCESS_KEY_ID | Yes | IAM Access Key ID (starts with AKLT) / IAM 访问密钥 ID |
VOLCENGINE_SECRET_ACCESS_KEY | Yes | IAM Secret Access Key / IAM 访问密钥 |
VOLCENGINE_TOS_BUCKET | Yes | TOS bucket name / TOS 存储桶名称 |
VOLCENGINE_TOS_REGION | Yes | TOS region code, must match bucket region. 必须与创建桶时选择的区域一致。Overseas: e.g. cn-hongkong, ap-southeast-1; China: cn-beijing |
WAV, MP3, MP4, M4A, OGG, FLAC — up to 5 hours, 512MB max.
支持格式:WAV、MP3、MP4、M4A、OGG、FLAC——最长 5 小时,最大 512MB。
Error: TOS upload failed: 403 Forbidden
Cause: TOS bucket policy not configured, or IAM user not authorized. / TOS 桶策略未配置,或 IAM 用户未授权。
Solution: Go to TOS bucket → Permission Management → Bucket Authorization Policy → Create Policy → select "Folder Read/Write" template. See Step 3 above. / 进入 TOS 桶 → 权限管理 → 存储桶授权策略管理 → 创建策略 → 选择「文件夹读写」模板。详见上方第三步。
Error: Query failed: 45000006 [Invalid audio URI] / audio download failed (upload succeeded, transcription fails)
Cause: The ASR service cannot download the audio from TOS. The script submits a presigned GET URL, which is only valid if the signing IAM sub-user itself has READ permission on the object. A bucket policy that grants write but not read, or one with IP-restriction conditions, lets the PUT upload succeed while the ASR-side GET fails. / ASR 服务下载不到 TOS 里的音频。脚本提交的是预签名 GET URL,其有效性取决于签名的 IAM 子用户自身是否有该对象的读权限——桶策略只授写没授读、或带 IP 限制条件时,PUT 上传成功但 ASR 侧 GET 失败。
Solution: Fix the bucket policy per Step 3: "Folder Read/Write" template (read and write), no IP-restriction conditions. Setting the object to public read also works as a quick diagnostic but exposes audio publicly — not recommended as a fix. / 按第三步修桶策略:「文件夹读写」模板(读和写都要),不带 IP 限制条件。设公网读也能通(可作快速诊断),但音频会公开暴露——不推荐作为修法。
Error: TOS upload extremely slow (~15KB/s)
Cause: Server is outside China mainland but using cn-beijing region. / 服务器在中国大陆以外,但使用了 cn-beijing 区域。
Solution: Change VOLCENGINE_TOS_REGION to cn-hongkong and create a new bucket in that region. / 将 VOLCENGINE_TOS_REGION 改为 cn-hongkong,并在该区域新建存储桶。
Error: API returned error: invalid API key
Cause: Using old Speech console API key, or key from wrong console page. / 使用了旧版语音控制台的 API Key,或从错误的控制台页面获取。
Solution: Get API key from the NEW Doubao Speech console at https://console.volcengine.com/speech/new/, NOT /speech/app. / 从新版豆包语音控制台 https://console.volcengine.com/speech/new/ 获取 API Key,不是 /speech/app。
Error: Unsupported audio format or transcription returns empty
Cause: Audio file is corrupted, or format not in supported list. / 音频文件损坏,或格式不在支持列表中。
Solution: Ensure file is one of WAV, MP3, MP4, M4A, OGG, FLAC and not corrupted. Try --format flag to explicitly specify format. / 确保文件是 WAV、MP3、MP4、M4A、OGG、FLAC 之一且未损坏。尝试用 --format 参数显式指定格式。
Error: Missing: VOLCENGINE_ACCESS_KEY_ID... after running source .env
Cause: source .env sets variables in the current shell but does not export them to child processes. The script runs as a subprocess and cannot see unexported variables. / source .env 仅在当前 shell 设置变量但不导出,脚本作为子进程无法读取未导出的变量。
Solution: Use set -a && source .env && set +a to auto-export all variables, or use export before each variable in your .env file. / 使用 set -a && source .env && set +a 自动导出所有变量,或在 .env 文件中每行变量前加 export。