Agent Skill
为 AI Agent(Claude Code、Codex、Cursor、Hark 等支持 Agent Skills 的工具)准备的技能包,教 Agent 通过你自部署的 Hub 实例完成转写、字幕、实时转写、LLM 调用,以及部署和排查 Hub 服务器。
技能包与项目版本同步,当前为 v3.4.0。源码在仓库的 skills/assemblyai-hub/ 目录。
下载
assemblyai-hub/
├── SKILL.md # 入口:何时使用、怎么调用、错误处理
├── scripts/transcribe.py # 零依赖转写脚本:上传、提交、轮询、输出文本 / 说话人 / SRT / VTT / JSON
└── references/
├── api.md # Hub 与官方 API 的差异、全部接口、错误码
└── operations.md # 部署、配置、升级、备份、故障排查安装
解压到 Agent 的技能目录,例如:
# Claude Code(个人)
unzip assemblyai-hub-skill.zip -d ~/.claude/skills/
# Claude Code(项目内)
unzip assemblyai-hub-skill.zip -d .claude/skills/其它工具请放到它们读取技能的目录,或把 SKILL.md 内容加入 Agent 的系统提示。
配置
技能从环境变量读取实例地址和 Key,不会写死在技能里:
export HUB_URL=https://hub.example.com
export HUB_KEY=hub-xxxx # 在控制台「API Key」生成没有设置时,Agent 会向你询问。建议给 Agent 单独生成一个 Key,方便在「用量」页区分和随时停用。
试一下
python3 ~/.claude/skills/assemblyai-hub/scripts/transcribe.py meeting.mp3 --speakers --format utterances或直接对 Agent 说:「用 AssemblyAI Hub 把 meeting.mp3 转成带说话人的文字稿,再导出 SRT」。
SKILL.md 全文
AssemblyAI Hub is a self-hosted gateway in front of several AssemblyAI accounts. It exposes the same paths and parameters as the official AssemblyAI API, authenticated with a Hub key (hub-...) instead of an AssemblyAI key. Anything the official docs show works against the Hub once you swap the host and the key.
Skill version: 3.4.0 (matches AssemblyAI Hub v3.4.0). Full docs: https://assemblyai-hub-docs.pages.dev
What you need
Ask the user for these if they are not in the environment; never guess them and never print the key back:
HUB_URL: base URL of their instance, e.g.https://hub.example.com(no trailing slash, no/v2)HUB_KEY: a Hub key created in the instance's console under "API Key"
Check the instance first:
curl -s "$HUB_URL/healthz" # {"ok": true, "version": "3.4.0"}; no auth needed
curl -s "$HUB_URL/hub/usage" -H "Authorization: $HUB_KEY" # 200 means the key worksTranscribe a file (the common task)
Use the bundled script; it only needs Python 3 standard library:
python3 scripts/transcribe.py meeting.mp3 # prints the text
python3 scripts/transcribe.py meeting.mp3 --speakers --format utterances
python3 scripts/transcribe.py https://example.com/a.mp3 --lang zh --format srt -o a.srt
python3 scripts/transcribe.py call.wav --opt '{"redact_pii": true, "redact_pii_policies": ["phone_number"]}' --format jsonIt reads HUB_URL / HUB_KEY from the environment (or --url / --key), uploads local files, submits, polls until completed or error, and prints the result. Run --help for all flags. It uses urllib, which honours HTTP_PROXY / HTTPS_PROXY; if your sandbox proxy blocks the Hub, run it with those unset.
Doing it by hand:
POST $HUB_URL/v2/uploadwith the raw bytes (Content-Type: application/octet-stream) →{"upload_url": ...}. Skip for public URLs.POST $HUB_URL/v2/transcriptwith JSON{"audio_url": ..., ...options}→{"id": ..., "status": "queued"}.- Poll
GET $HUB_URL/v2/transcript/{id}every 3 to 5 s untilstatusiscompletedorerror. Or passwebhook_urland wait for{"transcript_id", "status"}to be POSTed to it. - Exports:
/v2/transcript/{id}/srt,/vtt,/sentences,/paragraphs,/word-search?words=a,b,/redacted-audio.
Useful options (all official AssemblyAI parameters, passed through untouched):
| Need | Body fields |
|---|---|
| Unknown language | "language_detection": true |
| Known language | "language_code": "zh" (or en, ja, ...) |
| Who said what | "speaker_labels": true, optional "speakers_expected": 2 |
| Mixed languages | "language_detection": true, "language_detection_options": {"code_switching": true} |
| Model | "speech_models": ["universal-3-5-pro", "universal-2"] (first that supports the language wins) |
| Domain words | "keyterms_prompt": ["Kubernetes", "AssemblyAI"] |
| Remove PII | "redact_pii": true, "redact_pii_policies": [...] |
| Translate / name speakers | "speech_understanding": {"request": {"translation": {"target_languages": ["en"]}}} |
Do not send speech_model (singular), summarization, auto_chapters, summary_model, summary_type: AssemblyAI rejects or has retired them. For summaries, use the LLM gateway below on the finished transcript text.
Official SDKs
import assemblyai as aai
aai.settings.api_key = HUB_KEY
aai.settings.base_url = HUB_URL
text = aai.Transcriber().transcribe("meeting.mp3").textconst client = new AssemblyAI({ apiKey: HUB_KEY, baseUrl: HUB_URL })Real-time speech-to-text
- Direct (preferred):
GET $HUB_URL/v3/token?expires_in_seconds=60with the Hub key →{"token", "websocket_url"}. Connect towebsocket_url?token=<token>&sample_rate=16000exactly like the official v3 streaming API. Never ship the Hub key to a browser; fetch the token server-side. - Relay: connect to
wss://<hub>/v3/ws?sample_rate=16000&token=$HUB_KEY. All query params and messages pass through. Close code4001= bad key,4003= no upstream account.
Details: references/api.md.
LLM gateway
OpenAI-compatible, needs a paid AssemblyAI account behind the Hub:
curl -s "$HUB_URL/llm-gateway/v1/chat/completions" -H "Authorization: $HUB_KEY" -H "Content-Type: application/json" \
-d '{"model": "claude-sonnet-4-6", "messages": [{"role": "user", "content": "Summarize: ..."}]}'GET /llm-gateway/v1/models lists models. The OpenAI SDK works with base_url=$HUB_URL/llm-gateway/v1.
Errors
| Response | Meaning | What to do |
|---|---|---|
401 {"detail": {"error": "Invalid API key"}} | Hub key missing or disabled | Ask the user for a valid Hub key |
404 {"detail": {"error": "Transcript not found"}} | The id was not created through this Hub | Use ids returned by this Hub only |
503 {"error": "hub: No upstream account available"} | Every AssemblyAI account is disabled, cooling down (429) or at its concurrency limit | Wait a minute and retry once; if it persists tell the user to check "Upstream accounts" in the console |
| Other 4xx | AssemblyAI's own error, body untouched | Fix the request (usually a parameter) |
The Hub already retries 429 / 401-403 / 5xx on other accounts, so do not hammer it with retries.
Operating an instance
For deploying, configuring, upgrading, backing up, or troubleshooting the server itself, read references/operations.md.
Rules
- Keep
HUB_KEY, admin passwords and upstream AssemblyAI keys out of output, files and commits. - Usage numbers from
/hub/usageare the Hub's own estimates, not the AssemblyAI bill. - All Hub keys currently see all transcripts on the instance; do not assume isolation between keys.