工作原理
请求流程
客户端(官方 SDK / curl / 你的服务)
│ Authorization: hub-xxxx
▼
AssemblyAI Hub ── 校验 Hub Key ── 选择上游账号 ──▶ AssemblyAI(api / streaming / llm-gateway / sync / dictation)
│ ▲ │
│ └── 失败换号重试 ◀──────────────┘
▼
PostgreSQL(账号、Key、任务、上传记录、用量、代理节点)- 客户端用 Hub Key 调用与官方相同的路径。
- Hub 校验 Key,记下请求次数和最后使用时间。
- 选择上游账号,替换成该账号的 AssemblyAI Key 转发请求。
- 遇到可重试的错误时换一个账号重新发送(请求体会先缓存到磁盘,保证能重放)。
- 成功后记录任务、上传和用量,把上游响应原样返回。
选号规则
- 只在「已启用」且状态不是「异常」的账号中选择;冷却中的账号跳过。
- 指定了区域(
X-Hub-Region头,或 Key 自身的区域)时,只选该区域的账号。 - 进行中任务数达到账号「并发上限」时跳过该账号。
- 剩余的候选按
权重 × 剩余并发加权随机。
失败处理
| 上游状态码 | 账号处理 | 请求处理 |
|---|---|---|
| 429 | 冷却 COOLDOWN_SECONDS 秒 | 换号重试 |
| 401 / 402 / 403 | 标记为「异常」,需在控制台处理或重置 | 换号重试 |
| 500 / 502 / 503 / 504 | 记录错误 | 换号重试 |
| 网络错误(超时、连接失败) | 记录错误 | 换号重试 |
| 其它 4xx | 不变 | 直接返回给客户端 |
每个请求最多尝试 MAX_RETRY_ACCOUNTS 个账号。没有可用账号时返回 503 {"error": "hub: No upstream account available"}。
资源绑定
AssemblyAI 的上传文件只能被同一项目的 Key 使用,转写记录也只能由创建它的账号查询。因此 Hub 会:
- 记住每个
upload_url属于哪个账号,提交转写时优先使用该账号; - 记住每个转写
id属于哪个账号,之后的查询、删除、sentences、paragraphs、srt、vtt、word-search、redacted-audio以及/llm-gateway/v1/understanding都走这个账号; - 绑定的账号不可用时,绑定请求不会换号(换号也查不到数据),而是直接返回错误。
回调与轮询
- 设置了
PUBLIC_BASE_URL时,Hub 提交转写会把webhook_url改成PUBLIC_BASE_URL/internal/aai-webhook,并带上X-Hub-Webhook: WEBHOOK_SECRET鉴权头。 - 客户端原本传的
webhook_url、webhook_auth_header_name、webhook_auth_header_value会被保存;任务完成后 Hub 用相同的方式转发给客户端。 - 后台轮询每隔
POLL_INTERVAL秒检查未完成的任务,兜底处理漏掉的回调。没有PUBLIC_BASE_URL时只靠轮询。
实时转写的两种模式
- 直连模式:客户端调用
GET /v3/token拿到 AssemblyAI 临时 token 和websocket_url,然后直接连 AssemblyAI。音频不经过 Hub,延迟最低。 - 中继模式:客户端连接 Hub 的
WS /v3/ws,Hub 再连 AssemblyAI 并双向转发。适合客户端无法直连 AssemblyAI,或需要账号走代理的场景。