5.5 KiB
5.5 KiB
Meeting ASR
独立的会议/通话录音转写与整理 Web 应用(asrservice + asrpipe)。支持本地 GPU 声纹服务(qwen3cam)与云端多模型语音识别(soniox、gemini、openai、grok),可通过 Arcane 部署到本地 VM(tools-pve)或外网 VPS。
核心架构
-
Web 控制与审核面(
asrservice.web)- 极简零构建服务端渲染 HTML + 原生 JS(深浅色自适应)。
- 上传录音时可按任务切换 ASR 引擎(
qwen3cam/soniox/gemini/openai/grok)。 - 任务详情页内置支持 HTTP Range 的音频播放器、失败一键切换模型重试、草稿与纪要 Markdown 在线编辑。
/review/提供低置信度词语、关系确认与说话人身份确认(本地qwen3cam自动注册声纹至:10099,线上多说话人模型直接更新草稿与词库而不依赖:10099)。/lexicon提供热词、同音纠错、人物关系管理与 Obsidian 词库一键同步。/settings展示引擎是否就绪。网关地址和 API 密钥只显示「已配置 / 未配置」,页面不回显内网地址或密钥片段。- 浏览器界面默认关闭。必须设置
ASR_WEB_PASSWORD后才能上传、审核和改配置。未设置口令时页面只提示需要配置该变量,不会整站可写。ASR_WEB_ALLOW_ANON=1仅用于跑在本机且不可被其他主机访问的调试进程。状态变更还要带 CSRF 令牌。/api/v1/*继续使用ASR_AGENT_TOKEN。
-
后台消费与修订队列(
asrservice.worker)- 监控
ASR_DATA_DIR/inbox(容器内/data/inbox)并认领intake.db任务。旧的meeting-watch.py仍监听recordings/inbox并桥接到 vault.asr-inbox。两者共用ASR_STATE_DIR/consumer.lock,第二个进程直接退出,避免同一盘录音被消费两次。 - 调用统一多引擎层
asrpipe.providers.transcribe_audio()生成带结构化注释头的原始转写。 - 执行
asr-refine draft:结合 SQLite 词库、Obsidian Vault(People/、Companies/、Projects/、minutes/、_glossary.md)与 Hindsight(personal-context)进行分段去口语化、保真检查与会议纪要生成。 - 监控
state/revision-queue/处理 Web 审核提交的修订重跑请求,确认通过后发布正式纪要至 Obsidian 并可选执行 Git 自动提交推送。
- 监控
-
语音识别(ASR)与大模型网关边界
- LLM 后处理:彻底移除 ZenMux,统一通过 LiteLLM(内网
http://192.168.50.49:4000/v1/ 外网https://api.opfo.xyz/v1)调用:ASR_CLEAN_MODEL/ASR_KEYWORD_MODEL:默认aistudio/gemini-flash-lite-latestASR_DRAFT_MODEL:默认codex/gpt-sol-latest
- ASR 引擎:
qwen3cam(内网默认):对接局域网 GPUQwen3-ASR 1.7B + CAM++(http://192.168.50.100:10099/asr),支持声纹特征比对与增量注册。soniox(线上高精度首选):因 LiteLLM 同步/v1/audio/transcriptions不支持 Soniox 异步 Files API、结构化context热词注入与逐词speaker分离且有 180s 超时限制,由asrpipe.providers通过SONIOX_API_KEY直连 Sonioxstt-async-v5(自动注入 SQLite 词库热词与任务背景,完成后自动清理云端临时音频)。gemini:通过 LiteLLM 统一网关调用aistudio/gemini-3.5-transcribe(长音频自动ffmpeg切片)。openai:通过 LiteLLM 统一网关调用openai/gpt-4o-transcribe-diarize(支持diarized_json角色分离与 >23MB 自动压缩切片)。grok:通过XAI_API_KEY调用 xAIgrok-voice-transcribe-2.0(支持多说话人分离)。
- LLM 后处理:彻底移除 ZenMux,统一通过 LiteLLM(内网
目录结构
asrpipe/:核心转写引擎适配(providers.py)、词库召回(lexicon.py)、分段去口语化(segment.py、refine.py)、审核流(review.py)与 Obsidian/Hindsight 集成。asrservice/:容器化 Web 服务(web.py)、后台 Worker(worker.py)、SQLite 任务状态机(db.py)、Webhook 通知(notify.py)与健康检查(healthcheck.py)。recordings/bin/:录音监听与 CLI 转写脚本(兼容MEETING_ASR_BACKEND多引擎调度)。termbank/:专业词库源数据。tests/:核心管线、多引擎契约与 Web 服务单元测试。Dockerfile&compose.yaml:面向 Arcane 部署的单镜像双角色(asr-web+asr-worker)容器编排。
本地开发与测试
python3 -m venv .venv
.venv/bin/pip install -e .
ASR_NOTIFY=0 ASR_GIT_SYNC=0 .venv/bin/python -m unittest discover -s tests -v
Arcane 部署(内网 VM / 外网 VPS)
- 复制
.env.example为.env,按环境配置:- 内网 VM(
tools-pve):MEETING_ASR_BACKEND=qwen3cam(同时可配SONIOX_API_KEY等以便在 Web UI 按需切换)、LITELLM_BASE_URL=http://192.168.50.49:4000/v1、HINDSIGHT_URL=http://192.168.50.47:8888。 - 外网 VPS:
MEETING_ASR_BACKEND=soniox(或gemini/openai/grok)、LITELLM_BASE_URL=https://api.opfo.xyz/v1,并且必须设置ASR_WEB_PASSWORD。代码不会按部署位置自动加锁。HTTPS 站点再设ASR_WEB_COOKIE_SECURE=1。
- 内网 VM(
ASR_GIT_SYNC与ASR_NOTIFY缺省为关。要推送 vault 或发通知时显式设为1,并配置ASR_NOTIFY_BACKEND。- 使用
compose.yaml启动asr-web(默认:8788)与asr-worker。deploy/systemd/是现网单元快照,路径仍指向旧工作目录,不要原样安装到本仓库。