利用CosyVoice和n8n构建高效语音处理自动化流程
语音文件一多,人工点“播放→暂停→誊写→归档”的循环能把人逼疯。把 CosyVoice 的识别能力与 n8n 的可视化编排拼在一起,一条流水线就能让“上传-识别-后处理-通知”全自动跑通。下面把我在内部小工具落地的全过程拆给你看,尽量说人话,顺带把踩过的坑一次填平。
1. 语音自动化常见痛点
- 处理延迟:单文件 10 min 的录音,靠本地 CPU 跑 Whisper 动辄 20 min,业务方等不了。
- 资源消耗:GPU 机器贵,一次性任务占满显卡,利用率低。
- 流程割裂:上传、转写、关键词提取、推送结果散落在不同脚本,维护全靠“口口相传”。
- 异常难查:网络抖动、ASR 返回空文本、回调丢失,排错像大海捞针。
2. CosyVoice vs. n8n:各自解决哪一段
| 维度 | CosyVoice(ASR 引擎) | n8n(工作流编排) |
|---|---|---|
| 核心能力 | 多语种、高并发、秒级返回文字与置信度 | 零代码拖拽,200+ 集成节点,内建队列 |
| 部署形态 | 公有云 API / 私有化容器 | 单容器或 K8s,轻量 |
| 扩展性 | 提供 gRPC+HTTP,支持自定义热词 | 能写原生 JS 代码块,随意调用内外部服务 |
| 适用场景 | 语音→文本 | 文本→任何后续系统(DB、Slack、飞书、Webhook) |
一句话总结:CosyVoice 负责“听得快、写得准”,n8n 负责“把结果送到该去的地方,且可重、可重试、可告警”。
3. 整体架构
┌-----------┐ ┌---------┐ ┌----------┐ ┌----------┐ │ 文件上传 │ --> │ n8n 触发器 │ --> │ CosyVoice │ --> │ 下游业务节点 │ └-----------┘ └---------┘ └----------┘ └----------┘ ▲ │ └---------------- 异常重试 & 通知 ---------------┘- 触发器:n8n 的 Local File Trigger / S3 Webhook,监控新文件。
- 预处理:统一转码 16 kHz 16 bit mono,降低带宽。
- 识别:调用 CosyVoice
/v2/transcribe接口,流式上传,分片 10 MB。 - 后处理:正则提取关键词、情绪打分、写 MySQL。
- 通知:Slack block + 文件直链,失败走企业微信告警。
4. 核心实现细节
4.1 API 集成要点
- 鉴权:CosyVoice 使用短期 JWT,在 n8n 里用“HTTP Request”节点预置
{{$credentials.cosyVoiceJwt}},过期前 5 min 自动刷新。 - 分片上传:文件 > 5 MB 时开启 multipart,避免单 POST 超时。
- 回调地址:若走异步模式,一定给公网可解析的 https 地址,n8n 的 Webhook 路径形如
/webhook/transcribe-finished。
4.2 数据处理流程设计
- 文件落地即生成 UUID,写入 Redis “处理中”。
- 识别结果回包后对比
confidence阈值 < 0.85 的段落,打上“低置信”标签,人工复核队列。 - 整条文本写入 ElasticSearch,方便后续语义检索。
5. 代码示例(Python 版,可嵌入 n8n Function 节点)
# 依赖:requests, redis, pydub import os, json, requests, uuid, redis from pydub import AudioSegment UPLOAD_CHUNK = 5 * 1024 * 1024 JWT_REFRESH_DELTA = 300 # 提前 5 min 刷新 def refresh_jwt(cred): url = f"{cred['host']}/v2/auth/token" r = requests.post(url, json={"ak": cred["ak"], "sk": cred["sk"]}) r.raise_for_status() return r.json()["jwt"] def ensure_valid_jwt(cred): r = redis.Redis(host="redis", port=6379, decode_responses=True) exp = int(r.get("cv_jwt_exp") or 0) import time if time.time() + JWT_REFRESH_DELTA > exp: jwt = refresh_jwt(cred) r.set("cv_jwt", jwt, ex=3600) r.set("cv_jwt_exp", int(time.time()) + 3600) return r.get("cv_jwt") def transcribe(file_path): cred = {"host": "https://api.cosyvoice.example", "ak": $env("CV_AK"), # n8n 会把环境变量注入 "sk": $env("CV_SK")} jwt = ensure_valid_jwt(cred) # 1. 转码 sound = AudioSegment.from_file(file_path) sound = sound.set_frame_rate(16000).set_channels(1) mono_path = "/tmp/m_" + os.path.basename(file_path) sound.export(mono_path, format="wav") # 2. 上传+识别 url = f"{cred['host']}/v2/transcribe?lang=zh&output=json" headers = {"Authorization": f"Bearer {jwt}"} with open(mono_path, "rb") as f: files = {"file": (os.path.basename(mono_path), f, "audio/wav")} r = requests.post(url, files=files, headers=headers) r.raise_for_status() return r.json() # {"text": "...", "confidence": 0.92, "duration": 120} if __name__ == "__main__": result = transcribe("/data/record_20240518_001.wav") print(json.dumps(result, ensure_ascii=False))在 n8n 的 Function 节点里,把文件路径作为
items[0].json.inputFile传入,即可直接复用上面函数。返回值挂到items[0].json.transcribe供下游节点消费。
6. 性能测试与优化
测试音频:总时长 500 min,单文件平均 5 min,16 kHz WAV。
| 方案 | 并发路数 | 总耗时 | 平均 CPU 占用 | GPU 占用 | 备注 |
|---|---|---|---|---|---|
| 本地 Whisper CPU | 4 | 210 min | 380% | 0% | 风扇起飞 |
| 本地 Whisper GPU | 4 | 38 min | 60% | 65% | 需 CUDA 维护 |
| CosyVoice API | 20 | 29 min | 20% | 0% | 网络带宽 35 Mbps |
优化经验:
- 文件提前转 mono,能再降 8% 流量。
- n8n 的“Split In Batches”节点控制并发≤20,否则 CosyVoice 会返回 429。
- 打开 n8n 的
EXECUTIONS_PROCESS=main模式,避免 serverless 频繁冷启动。
7. 生产环境避坑指南
错误分级:
- 可重试:网络超时、5xx,指数退避 3 次。
- 不可重试:4xx 鉴权失败、文件格式错误,直接进死信队列。
重试机制:
n8n 的“Retry Error Workflow”默认只跑 1 次,把重试次数改成 3,并设置retryInterval=60,120,240。监控:
- CosyVoice 侧利用
X-Request-Id回写日志,ELK 统一收集。 - n8n 暴露
/metrics给 Prometheus,重点看n8n_task_failed_total。
- CosyVoice 侧利用
安全:
- Webhook 路径加随机串,如
/webhook-abc123,并在最外层 Nginx 限 IP。 - 回包敏感字段脱敏,正则
s/\d{6,}/****/g。
- Webhook 路径加随机串,如
成本控制:
- 对置信度 > 0.9 的文本,跳过人工复核节点,节省 30% 工时。
- 夜间低峰期跑批量历史文件,利用 CosyVoice 夜间折扣价(如有)。
8. 一张实际跑起来的截图
图中绿色节点是文件预处理,蓝色为 CosyVoice 调用,橙色是后处理写库,红色箭头表示异常重试分支。跑 1000 个文件零人工值守,第二天上班看报告即可。
9. 可继续深挖的方向
- 把“低置信段落”自动切片,二次送入更大模型精细矫正,实现级联 ASR。
- 在 n8n 里接入 LLM Function,直接对文本生成摘要,做到“录音 5 min,纪要 30 秒”。
- 用 n8n 的 Wait 节点实现“人机协同”——机器先跑,人工在 Web 界面点“确认”才继续下游,兼顾准确与效率。
10. 小结
CosyVoice 解决“听写”速度,n8n 解决“流程”可靠,两者相加等于把重复体力活外包给机器。整套路我花了两个周末从 0 到上线,现在 90% 的语音工单已无需人工介入。你可以先拿最小流程跑通——“文件落地→n8n→CosyVoice→Slack 通知”,再逐步加转码、置信过滤、重试、监控。等流水线稳定后,把节点换成自己的业务系统,就能让任何“语音进、文字出”的场景快速落地。下一步你准备把哪段重复劳动交给这对组合?