AI会议纪要:Whisper + Ollama免费本地管道
可免费本地运行的AI会议纪要:faster-whisper 转写、Ollama 总结、n8n 串管道,含提示词与分块策略。
AI会议纪要:Whisper + Ollama免费本地管道
会议纪要是最适合自托管的一类任务:音频本身就敏感,活儿枯燥重复,管道又简单,一个下午能搭完,之后每次开会省半小时。这套方案全程离线,录音不出机器,跑完直接输出带负责人和截止时间的行动项。
一、管道长什么样
录音文件(m4a / wav / mp3)
↓ faster-whisper 转写(带时间戳)
↓ 按时间窗切块(每 10 到 15 分钟一块)
↓ Ollama 本地模型:逐块提炼要点(map)
↓ 汇总所有要点,生成最终纪要(reduce)
↓ Markdown 输出 → n8n 推到 Slack / Notion / 邮件
为什么不用一个大模型一口气读完整场两小时的会议:上下文塞不下,硬塞也会让模型抓不住重点。分块提炼再汇总,质量稳定得多,也更省钱。
二、第一步:转写
pip install -U faster-whisper
from faster_whisper import WhisperModel
import json
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
segments, _ = model.transcribe(
"meeting.m4a",
language="zh",
vad_filter=True,
beam_size=5,
initial_prompt="以下是普通话会议记录,涉及产品排期、接口和预算。",
)
lines = []
for s in segments:
lines.append({"start": round(s.start, 1), "end": round(s.end, 1), "text": s.text.strip()})
with open("meeting.json", "w", encoding="utf-8") as f:
json.dump(lines, f, ensure_ascii=False, indent=2)
保留时间戳的价值在复盘:纪要里写"张工反对这个方案",想知道原话在哪,直接跳到对应秒数。
没有显卡就把 device 改成 "cpu"、compute_type 改成 "int8"。一小时会议在 CPU 上大约十几到几十分钟量级,显卡上通常几分钟,具体看硬件,先拿 5 分钟样本测速最靠谱。
三、第二步:按时间窗切块
WINDOW = 900 # 秒,即 15 分钟
def chunk_by_time(items, window=WINDOW):
chunks, cur, start = [], [], 0
for it in items:
if it["start"] - start > window and cur:
chunks.append(cur); cur, start = [], it["start"]
cur.append(it)
if cur:
chunks.append(cur)
return ["\n".join(f"[{x['start']:.0f}s] {x['text']}" for x in c) for c in chunks]
15 分钟一块是经验值:短会一块搞定,两小时的会切成 8 块左右,每块控制在 2000 到 3000 字,正好是 7B 到 8B 模型处理得最稳的长度。
四、第三步:本地模型提炼
ollama pull qwen3:8b
# 机器吃得住就用 14B,质量明显更好:ollama pull qwen3:14b
提炼提示词(第一层,map):
你是会议记录员。下面是会议的一段转写,可能有错字和口语重复。
只提取事实,不要评价,不要补充转写里没有的内容。
请按以下格式输出:
1. 讨论主题(一句话)
2. 形成的决定(逐条,无则写"无")
3. 行动项(格式:事项 | 负责人 | 截止时间;没提到的字段写"未定")
4. 待确认的问题
转写内容:
{chunk}
汇总提示词(第二层,reduce):把各块的输出拼起来,要求合并重复项、按主题重排、行动项去重并统一负责人写法。
import ollama, json
def summarize(chunks):
partials = []
for c in chunks:
r = ollama.chat(model="qwen3:8b", options={"temperature": 0},
messages=[{"role": "user", "content": MAP_PROMPT.format(chunk=c)}])
partials.append(r["message"]["content"])
final = ollama.chat(model="qwen3:8b", options={"temperature": 0},
messages=[{"role": "user", "content": REDUCE_PROMPT.format(parts="\n\n".join(partials))}])
return final["message"]["content"]
温度设 0,多次跑同一段录音结果基本一致。要求"没提到的字段写未定",比让它自己补更可靠,纪要里最忌讳的就是编出来的截止日期。
五、第四步:n8n 串起来
不想写调度代码就用 n8n(208,635 星):
- Local File Trigger 监听会议录音目录(比如
~/meetings/inbox)。 - Execute Command 节点调上一步的 Python 脚本做转写。
- HTTP Request 节点打到 Ollama 的
/api/chat,或用 n8n 的 Ollama 社区节点。 - Markdown 节点把结果拼成文档。
- Slack / Notion / 邮件 节点发出去,按会议日期命名。
一次配好,之后只管把录音丢进目录。要区分不同项目,就在文件名前缀里带项目代号,n8n 里按前缀路由到不同频道。
六、质量能到什么程度
- 清晰录音、单人讲话:转写词准确率通常在九成以上,纪要靠模型提炼,漏项主要发生在"随口提到的口头承诺"上。
- 多人抢话、会议室外放:准确率明显掉,必须有 VAD 分段,重要会议建议保留转写原文人工过一遍。
- 说话人区分:Whisper 本身不做,需要 WhisperX 的
--diarize(依赖 pyannote 模型,要先在 Hugging Face 接受条款),或改用 FunASR 的说话人方案。没有说话人标签时,让模型按"发言人1/2"编号也能凑合读。
七、几个提升可用性的细节
- 术语表:
initial_prompt里放参会人名、产品代号、客户名,专有名词错误率下降最明显。 - 会后 5 分钟内出稿:趁记忆新鲜,纪要的确认成本最低。
- 固定模板:决定、行动项、风险、下次会议时间,四块固定下来,团队翻历史纪要时不用重新适应。
- 存档转写原文:纪要是摘要,出争议时要能回到原话。
常见问题
Q:需要什么硬件? A:8GB 内存能跑 small 模型 + 7B 大模型,速度慢;16GB 内存 + 8GB 显存的显卡是比较舒服的配置,跑 large-v3 转写和 8B 模型总结都不卡。
Q:两小时的会议会不会爆上下文? A:会因为一次性塞入而爆,所以按 15 分钟切块。分块后每块独立提炼,最后只汇总要点,总长度可控。
Q:能自动识别"谁答应的"吗? A:没有说话人分离时,模型只能依据转写里的称呼("老王你跟进一下")判断,准确率一般。要求严格的场景加 WhisperX 做分离。
Q:数据真的不出机器吗? A:这套管道里没有外部 API 调用,模型权重下载完之后可以断网运行。注意 Ollama 默认监听 127.0.0.1,别随手改成 0.0.0.0 暴露到公网。
注:模型名称与显存占用随版本变化,具体以 Ollama 与 faster-whisper 官方文档为准。
相关文章
本站文章由编辑人工撰写,收录的工具均经过实测或公开资料核验。文中链接指向工具官网或 GitHub 仓库,仅作信息参考,不构成付费推广。