ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Octo-ASR与OCTO工作流实战:会议纪要自动化全链路解析

Octo-ASR与OCTO工作流实战:会议纪要自动化全链路解析 上周开完项目周会我盯着那一小时零八分钟的录音发了半小时呆。逐句听、记重点、整理成纪要、再挨个把待办私聊发给对应同事整套流程下来将近四十分钟。开着屏幕都嫌事多更别说中间还漏掉了一条“下周三前确认域名迁移方案”的待办直到第二天对方来问我才知道自己漏派了。所以我把这套流程自动化了会议录音进来之后先用 Octo-ASR 把语音转成文字再让大模型把流水账整理成结构化会议纪要顺手把里面的待办事项抽出来最后通过 OCTO 工作流把待办派发给对应的 Agent 去执行。今天这篇就完整记录下这套方案的选型思路、部署步骤、核心代码和我在实际落地中踩过的坑。如果你也在做会议自动化、Agent 工作流或者单纯想给“开会跟进”这个场景减负这篇应该能给你一份可以直接抄作业的参考。1. 为什么要做这件事会议纪要自动化的真实痛点1.1 手动整理纪要的四个坑先说痛点不然你理解不了为什么非要把 Octo-ASR 接进 OCTO 工作流。第一个坑是“转写不等于纪要”。市面上很多会议软件能输出逐字稿但逐字稿直接拿去发群里没人看得进去。口语里的“那个”“就是”“嗯嗯”多个人抢话导致的上下文断裂非线性的讨论过程这些东西不改写根本没法当纪要。所以语音转写之后必须再接一层智能整理这一步省不掉。第二个坑是待办信息散落在对话里。项目会议里最值钱的往往就是那几句“我来负责”“下周给你反馈”“尽快处理一下”但这类句子在转写文本里没有任何格式标记人工梳理时需要回头翻上下文才能确认责任人和时间节点。漏掉一条待办后面就得花好几个电话去补救。第三个坑是派发动作太分散。整理好纪要只是第一步把待办真正落到任务系统、发到 IM、通知到对应的人这些动作分散在多个平台里。就算纪要写得再好手动建任务仍然有延迟而且容易建错负责人。第四个坑是延迟导致的信息衰减。会议结束越久整理纪要时对上下文的记忆越模糊。我试过隔天再整理真是边听边猜当时为什么做出那个决定。会议一散场就自动化处理才能最大程度保留信息完整性。1.2 为什么选 Octo-ASR OCTO 这对组合选 Octo-ASR 有几个原因它支持本地部署和流式识别中英文效果都不错转写速度可控长音频的稳定性我也实测过比之前用其他开源方案好不少。更重要的是它作为开源模型接口层比较干净接入工作流时不会遇到太多“黑盒”问题。OCTO 工作流这层你可以把它理解成一个以 Agent 为中心的流程编排平台。我在这条流水线里把整段业务拆成音频接入节点、语音转写节点、纪要与待办提取节点大模型节点、任务派发节点。Octo-ASR 负责其中最关键也最脆弱的“语音转文字”环节剩下的整理、提取、派发交给后续节点协同完成。如果你已经用过 Dify、Coze、n8n 这类工作流工具这个思路可以直接迁移。它们本质上是同一类东西把多个 AI 能力和业务系统串成一条可编排、可调试、可重跑的流水线。区别在于我用 OCTO 平台来承担编排和状态管理把 Octo-ASR 作为其中一个高价值节点接进去。2. 整体架构与方案选型把流水线拆成四段2.1 流水线四段式设计整个流程我拆成四段第一段音频接入。会议录音文件落地到指定目录或者实时会议音频流推送到转写服务。这里的关键是确定音频格式、采样率、声道数避免后面转写出乱子。第二段语音转写。Octo-ASR 接收音频输出带时间戳的文本流。这一步需要处理好长音频分段、静音裁剪、热词增强等细节直接决定转写质量。第三段智能整理。把转写文本交给大模型要求它输出结构化纪要会议议题、关键结论、待办列表。待办列表必须带责任人和时间节点方便后面派发这一步通过设计好的提示词让输出既符合阅读习惯又能被程序解析。第四段待办派发。解析大模型输出的 JSON把每条待办转换成 Agent 平台的任务调用 OCTO 工作流的派发节点把任务分配到对应 Agent 或责任人同时把相关会议上下文作为附加上下文一起传过去。2.2 三个关键选型判断判断一流式还是批量。批处理适合录制好的音频文件实现简单结果稳定适合第一版跑通。流式则适合实时会议场景边开边转纪要能基本同步生成。我自己先跑通批处理再在第二版里切换到流式。不要一上来就追求实时性否则转写和服务稳定性问题会让你怀疑人生。判断二说话人分离要不要做。会议纪要如果有“谁说了什么”会更有价值但说话人分离声纹聚类会显著增加链路复杂度。第一版我没做而是让大模型通过文本段落结构来推断讨论视角效果够用。如果你需要精确到人可以在 Octo-ASR 后面再接一个说话人分离节点但做好心理准备这一步的调参成本不算低。判断三大模型在哪个层面跑。我建议走兼容 OpenAI 协议的统一接口层。不管背后是本地部署的开源模型还是云上的大模型 API工作流这边只需要改一个 base_url节点逻辑完全不用动。对大多数团队来说先跑通全链路比追求某一节点的极致效果更重要协议统一能帮你省掉大量重构时间。3. 环境准备与部署先把 Octo-ASR 跑起来3.1 Octo-ASR 本地部署步骤我这边的部署环境是 Ubuntu 20.04 NVIDIA 4090显存 24G跑中英文会议音频完全够用。如果你只有 CPU也能跑就是速度慢不少长音频会等得比较久。先把代码拉下来git clone https://github.com/ICT-OctoLab/Octo-ASR.git cd Octo-ASR conda create -n octoasr python3.10 -y conda activate octoasr pip install -r requirements.txt然后从模型仓库拉取对应模型权重。模型标识可以在仓库 README 里找到不同版本对应不同参数量级。我用的那一版是 SenseVoice 系列底座单卡 fp16 推理跑一小时会议音频大约需要 10 分钟出头速度在中型会议室场景下可以接受。如果你的音频时长远超这个量级建议在部署时打开 VAD 分段避免一次把整个长音频塞给模型。部署完先跑个最简单的文件转写验证环境from funasr import AutoModel model AutoModel( modeliic/SenseVoiceSmall, devicecuda:0, disable_updateTrue ) res model.generate( inputmeeting_demo.wav, languagezh, use_itnTrue, batch_size_s60, ) print(res[0][text])能看到转写文本就说明环境通了。这里 languagezh 指定中文use_itnTrue 会把数字、日期、金额这类内容自动规整成正式写法对后面的纪要整理非常有用。我在实际中格外注意了音频格式。Octo-ASR 对输入音频有格式要求最好统一转换成 16kHz 采样率、单声道、WAV 或 PCM。我遇到过一个坑一套视频会议系统导出的录音是 48kHz 双声道直接丢给转写服务结果后半段全是乱码后来才发现是声道叠加导致的。统一用 FFmpeg 转一下就好了ffmpeg -i input.mp4 -ar 16000 -ac 1 -f wav output.wav3.2 OCTO 工作流和外围服务配置OCTO 工作流这一侧我把它部署在同一台内网机器上好处是 Octo-ASR 转写服务和工作流之间的调用不走公网延迟低、稳定性高。工作流里需要准备几个节点Webhook 触发节点用于接收“新录音文件已就绪”的事件HTTP 调用节点请求 Octo-ASR 的转写接口大模型节点读取转写文本输出结构化纪要任务派发节点调用 Agent 平台 API 创建待办通知节点把纪要摘要和待办清单推到 IM 群这些节点在 OCTO 管理台里通过表单配置即可。配置时需要注意大模型节点输出的字段名要和派发节点的输入字段严格对应比如 todos、owner、deadline。我在第一次配置时字段名写岔了模型输出 todo派发节点读 todos结果解析直接失败排查了半天。建议在 OCTO 平台上把节点间的数据格式先在测试事件里跑一遍确认字段映射没问题再挂正式触发。4. 核心流程实现从音频到待办的完整链路4.1 音频接入与转写调用我的第一版用了文件监听方式录音文件通过上传工具丢到指定目录一个监听脚本发现新文件后自动触发工作流。相对简单可靠适合验证全链路。如果对实时性有要求可以用流式转写。Octo-ASR 提供了 WebSocket 接口支持边传音频边拿转写结果。批处理跑通之后我在第二版切成了流式核心代码如下import asyncio import json import websockets async def stream_transcribe(pcm_path): async with websockets.connect(ws://localhost:10096) as ws: await ws.send(json.dumps({ chunk_size: [0, 10, 5], wav_format: pcm })) with open(pcm_path, rb) as f: while True: chunk f.read(3200) if not chunk: break await ws.send(chunk) result await ws.recv() text json.loads(result).get(text, ) if text: print(text, end) await ws.send(json.dumps({is_final: True})) asyncio.run(stream_transcribe(meeting_stream.pcm))这里 chunk_size 里的 [0, 10, 5] 表示分片策略10 是前向缓存块数5 是右看上下文块数针对会议对话场景比较稳。如果你发现输出的断句很碎可以适当调大让模型看得更多上下文再出字。这个参数没有绝对最优值跟会议室环境、语速、背景噪音都有关系需要实测。4.2 会议纪要整理的提示词设计转写文本拿到手接下来是关键一步让大模型把口语化流水账整理成可用的纪要同时提取待办。这一步的质量一半靠模型一半靠提示词。我用的提示词经过了好几轮迭代最终版核心结构如下你是项目会议纪要整理助手。请把用户的会议转写内容整理成结构化纪要。 要求 1. 先区分“议题”“结论”“讨论过程”结论要简洁明确。 2. 提取所有待办事项输出为 JSON 数组每个元素包含 task、owner、deadline 三个字段。 3. 如果原文没有明确责任人owner 填 null不要自己猜。 4. 如果原文没有明确截止时间deadline 填 null。 5. 输出格式为 JSON不要输出多余解释。 转写内容 {transcript_text}用 JSON 输出是为了让后续派发节点能直接解析。有朋友问我要不要给大模型一个“待办示例”来约束格式我试过确实能减少格式飘逸但也会让模型在遇到零散内容时强行套模板反而漏掉真正的待办。最后我选择只给字段名和约束规则不给完整示例实测效果更稳。有个细节deadline 的解析可以交给大模型做标准化。会议的原始说法可能是“下周三之前”“月底前”“这周五下班前”让大模型直接把这些说法转换成 ISO 日期字符串后面派发的时候能省掉一层日期解析逻辑。我是这样约束的deadline 字段必须是 ISO 格式的日期字符串例如 2025-06-10。如果原文说“下周五”按照当前日期 2025-06-09 推算。当前日期要动态拼进提示词里不然模型没有时间参照系容易算错。这个坑我踩过第一次没给当前日期模型把“下周三”理解成了并不存在的日期派发出去之后闹了乌龙。4.3 待办派发到 Agent 的实现大模型输出 JSON 之后OCTO 工作流里的派发节点负责把待办转成 Agent 平台的任务。调用方式很简单import requests import json import logging logger logging.getLogger(__name__) def dispatch_todo(todo, meeting_summary, meeting_id, index): payload { title: todo[task], assignee: todo.get(owner) or unassigned, due_at: todo.get(deadline) or None, source: octo_asr_meeting_workflow, source_meeting_id: meeting_id, context: meeting_summary } headers { Content-Type: application/json, Idempotency-Key: f{meeting_id}:{index} } resp requests.post( https://your-agent-platform.internal/api/v1/tasks, jsonpayload, headersheaders, timeout15 ) if resp.status_code not in (200, 201): logger.error(派发失败: %s %s, resp.status_code, resp.text) # 这里触发 OCTO 工作流的重试分支重点说三个细节。第一个是“幂等键”设计。会议可能被重新处理或者派发节点重试如果没有幂等键同一个待办会被创建两遍。我用的方案是把 meeting_id 和待办序号拼成一个唯一的 Idempotency-Key 传给任务平台平台侧必须按这个键做去重。这样即使 OCTO 工作流因为超时重试也不会产生重复任务。第二个是上下文传递。派发待办时不光要传任务标题还要把会议纪要中相关的上下文段落一起传过去。收到待办的 Agent 才能搞明白这个任务为什么存在。没有上下文的任务就像凭空冒出来的指令执行效果很差。第三个是失败分支。请求超时或者平台 5xx不能直接丢弃要让 OCTO 工作流进入重试或者人工兜底分支。我在工作流里加了一个规则连续重试三次仍失败就把这条待办送进“待人工处理”列表并给管理员推通知。宁可让人工看见也不要静默丢失。4.4 全链路测试效果我用一次实际的项目例会做了验证。会议录音 47 分钟主持人讲话节奏偏快中间有一段多人讨论。转写文本大致长这样节选嗯那这个权限改造的事情我觉得还是得由小王那边来推进毕竟底层数据权限之前就是他负责的。然后呢前端这边下周三之前需要把原型定稿不然测试排期就来不及了。另外腾讯会议录制文件导出之后记得要上传到网盘方便后面追溯。Octo-ASR 转写时我把“权限改造”“数据权限”“原型定稿”这些词放进了热词表识别精度明显提升。热词表配置{ hotwords: { 权限改造: 10, 数据权限: 10, 原型定稿: 8 } }repeated 权重越高模型越倾向于识别这个词但别调太高我之前把某个冷门字段名权重拉到 50结果模型满嘴都是这个词连“权限”都往这个方向靠了矫枉过正。整理之后得到的待办清单如下{ todos: [ { task: 推进底层数据权限改造方案落地, owner: 小王, deadline: 2025-06-13 }, { task: 前端原型定稿, owner: 前端负责人, deadline: 2025-06-11 }, { task: 上传会议录制文件到网盘, owner: 会议发起人, deadline: null } ] }像“腾讯会议录制文件导出之后记得要上传”这种原本我很容易漏掉的待办大模型直接抓出来了这是这套方案里最让我惊喜的地方。之前人工整理这种“顺嘴一提”的任务大概率就丢了。5. 常见问题与排查技巧实录5.1 转写质量问题的排查思路我在八小时的实际使用中积累了一份问题排查表分享给你现象可能原因解决方式专有名词识别错误模型没有见过这个词配置热词表提升权重到 8-10双声道音频转写乱码声道未合并导致语音叠加FFmpeg 统一转成 16kHz 单声道 WAV输出断句严重碎片化chunk_size 太小上下文不足调大 chunk_size 的前向缓存块数长音频后半段丢失内存溢出或模型上下文窗口不够开启 VAD 分段分段转写后合并数字、日期成乱字未开启标点与逆文本规整use_itnTrue这里要特别提醒热词表不是越多越好。我建议只录入项目专有名词、产品名、人名、缩写这些模型大概率识别不好的词权重控制在 8-10 之间就行了。权重太高会牺牲其他词的识别准确率得不偿失。5.2 纪要整理和待办提取的坑待办提取这一环节遇到最多的三类问题第一类是待办漏提取。尤其是那些以“记得”“回头”“有机会”开头的句子模型倾向于认为它们不是强待办。我的解决办法是在提示词里加一条“即使原文使用了不确定的语气词只要句子表达了需要在未来完成某个动作就必须提取为待办并在 task 中保留原文语气词。”加了这条之后召回率明显上升但代价是误报也变多了。我宁可多几条误报待办也不愿意漏因为漏掉的代价更高。第二类是责任人不明确。原文经常是“那边的人跟进一下”“负责这个模块的同事看一下”模型识别出 owner 为 null 就完事了。但派发节点需要 owner 否则无法创建任务所以我在工作流里加了一道“负责人补全”逻辑owner 为 null 时从项目排期表或组织架构表里查一下这个模块的负责人。虽然不保证完全准确但至少把任务派到了正确的团队。第三类是 deadine 乱推。前面说过必须把当前日期动态放进提示词不然模型没有时间参照。另外如果会议中明确说“这个不急”deadline 应该置为 null不要给它默认一个日期。宁可没截止时间也不要瞎编一个否则会在 Agent 那边触发错误的优先级逻辑。5.3 Agent 派发失败与重复派发的处理派发失败基本逃不开这几种情况任务平台接口超时、鉴权过期、字段校验不通过。我处理的办法是超时问题设置重试每次间隔递增30 秒、1 分钟、3 分钟最多三次。重试必须配合幂等键否则大概率重复建任务。我见过同事在处理类似问题时没加幂等结果工作流一重试同一个待办建了六条任务项目群里直接炸锅。鉴权过期在工作流里提前预检 token 有效期避免等调用了才发现过期。这个预检节点非常简单就是读一遍 token 的过期时间字段如果快到期就提前刷新。字段校验问题把 OCTO 工作流里模型输出的 JSON 先做一层 schema 校验缺字段就触发“修复节点”——把报错信息返回给大模型让它补全字段重新输出。这个模式我用下来很管用有点像人审流程AI 自己发现格式不对自己改不用人来盯。还有一个重复派发的隐蔽来源Octo-ASR 转写节点超时后工作流自动重跑了整个流程但录音文件还在于是整体又转写了一遍。这种情况下即使待办派发做了幂等纪要整理这步的重跑也可能产生重复消耗。我的解决办法是给整个会议录音的处理设置一个 dedup 标记同一个文件如果已经完成转写并生成了指纹直接跳过。这个指纹我用录音文件的大小加前 1 秒音频的 hash简单够用。结尾整个方案从想法到稳定运行前后大概花了两周。中间最有价值的体会是不要把最开始的链路设计得太复杂先用手头的录音文件跑通批处理确认 Octo-ASR 转写质量、大模型纪要输出、待办派发三个关键环节都符合预期之后再去上流式和实时会议场景。最后再分享一个小技巧给这套工作流加一个“每日 18:00 定时巡检”节点把所有当天生成的待办汇总成一张清单推送到项目管理群里。这样即使有漏派或者派错的任务也能在当天被发现而不是等到第二天追问时才后悔。自动化不是把人的事全部甩给机器而是让机器把重复的脏活干完人只需要在关键节点做确认就够了。
返回列表