关于 meeting-brief
meeting-brief 是处理会议录音并生成归档报告的技能,也支持以音频而非文字回复。它包含私有 S3 收件箱录音的导入流程,并强调转录归档、说话人核对和录音隐私保护。
主要功能
- 01转录并整理会议报告
- 02按说话人分组并标注时间
- 03将原始录音与转录归档
- 04从私有 S3 收件箱导入录音
- 05以音频形式回复
适用场景
- 01将会议录音整理成行动项与决策
- 02处理浏览器扩展上传的会议录音
- 03为重要会议建立可核验的归档
- 04需要音频回复而非文字时使用
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ marks97/ meeting-brief --skill meeting-brief安装后在 Claude Code 中输入/meeting-brief确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
keyterms.txtextension/background.jscapture.main.jscontent.jsmanifest.jsonoffscreen.htmloffscreen.jsoptions.htmloptions.jspopup.htmlpopup.jsREADME.mdui.cssingest/ingest.shingest/presign-lambda/deploy.shindex.mjspackage.jsonscripts/aws-env.shextension-icons.mjsformat-transcript.mjslib.shsay.shshare.shtranscribe.shunshare.sh详细介绍
会议简报
两项功能相结合:将录音转换为归档会议报告,并用音频而非文字回复你。
两者也可以单独使用。在包含 .m4a 文件的文件夹上运行 /meeting-brief 可完成第一项。说“以后用音频回答我”可完成第二项。
严格规则
- 绝不将用户的音频上传到公共主机。 不能上传到 tmpfiles、0x0.st、transfer.sh,也不能使用临时隧道。这些录音可能包含机密信息:薪资谈判、股权条款、收入、客户姓名。唯一获准的渠道是私有存储桶中的预签名 S3 URL。之所以设定这条规则,是因为之前曾有人违反过。
- 只能使用预签名 URL,ACL 必须为私有。 绝不使用
--acl public-read,绝不更改存储桶策略,也绝不使用名称中包含public或assets的存储桶。 - 用户回复后,删除对应片段。 用户的下一条消息表示他们已经听过。该轮处理任何其他事项之前,先对上一个对象运行
unshare.sh。 - 绝不在转录文本中输出 API 密钥或机密。 脚本从环境变量或
.env读取这些内容,绝不会将它们打印出来。
AWS 凭证来自项目,绝不来自全局配置文件
项目可以使用自己的 .env 和 AWS 账户,因此凭证会从项目而非全局配置文件解析。scripts/aws-env.sh 会从工作目录向上查找,直到找到第一个能提供有效凭证的 .env。
变量名并不总是标准化的。解析器会先尝试标准的 AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY,然后尝试简写形式 AWS_ACCESS_KEY / AWS_ACCESS_SECRET。区域默认为 us-east-1,之后会通过 get-bucket-location 按存储桶进行校正。
将 MEETING_BRIEF_BUCKET 设为要存放音频的私有存储桶。该存储桶必须禁用公共访问;此技能使用私有 ACL 上传,并仅通过预签名 URL 分享,绝不会将任何内容设为全网可读。
流程 A:将录音转为归档报告
S=.claude/skills/meeting-brief/scripts
OUT=/tmp/claude/<project>/meeting-<date>
$S/transcribe.sh $OUT *.m4a # parallel, diarised, resumable
$S/format-transcript.mjs $OUT/raw-<x>.json \
--map speaker_0=Alice,speaker_1=Bob # speaker-grouped, timestamped
然后阅读转录文本,根据上下文辨认各人身份,并撰写报告。
务必传入关键词。 keyterms.txt 随此技能一同提供,transcribe.sh 会自动发送其中的内容。如果没有这些关键词,Scribe v2 会把不常见的产品、公司或工具名称误听成发音相似的常见词,进而影响后续所有摘要。遇到项目相关名词时,将其添加到该文件中。
说话人分离会给出 speaker_0、speaker_1 等标签,而不是姓名。撰写内容前,先根据上下文确定标签与人物的对应关系。对于重要事实(谁负责跟进、谁明天休假、个人背景),如果对应关系有任何不确定之处,请在保存前向用户确认身份,并将草稿写成“我把 X 认作 speaker A,把 Y 认作 speaker B;如果反了,请调换”,方便他们快速纠正。
配额(quota_exceeded)
Scribe v2 每秒音频约消耗 1.1 个额度。遇到 quota_exceeded 时,不要放弃:大多数长会议都包含无声间隔(会前准备、静默片段、长时间停顿)。使用 ffmpeg 去除静音后重试:
ffmpeg -y -i input.m4a \
-af "silenceremove=stop_periods=-1:stop_duration=2:stop_threshold=-40dB" \
-c:a aac -b:a 64k trimmed.m4a
这样可以缩短 20-40% 的时长,同时不损失任何语音。重新检查时长(ffprobe),并重新计算所需额度,然后再提交。归档原始音频,绝不能归档裁剪后的副本:裁剪只是转录时的处理产物,并非事实来源。
录音归档(确定日期、排序、优先归档)
录音会以项目提供的各种方式送达:放在工作区根目录、导出到 ~/Downloads、手机文件,或自动上传到 S3 收件箱。文件名通常很普通(meet.m4a、rec.m4a、audio 3.m4a),不包含可靠的日期。无论来源如何,都要遵守以下四条规则:
- 始终先归档,再总结。 转录成功后,立即将
<audio>+.txt文件对写入arch/transcripts/,然后再撰写报告、行动事项或处理其他内容,即使用户只问了“他们决定了什么”也不例外。绝不能让用户开口索要归档。要验证文件已归档(将副本与源文件进行校验和比对),不要想当然。 - 日期必须是录制日期,绝不是今天,也不是下载日期。 文件的修改时间是复制或导出时间:如果是当天收到的新文件,它可能与会议日期一致,但导出的文件或重新分享的文件可能相差数天,而且同一时段导出的多个文件修改时间都相同。要结合转录内容交叉核对(提到的星期几、“昨天我们发布了 X”、近期变更日志),并与
arch/transcripts/中上一份文件的间隔比较。只有在证据相互矛盾时才询问用户。如果源文件是 Apple Voice Memos 原件(20260806 104557.m4a),文件名就是录制开始时间:按字节大小再按校验和,将共享副本与原件匹配;匹配即为证明,无需询问。 - 序号: 找出
arch/transcripts/中最大的现有rec-NNN序号,并使用下一个整数;在聊天中说明这一点,以便用户纠正跳过的序号。如果导出文件名中已有序号(Mi grabación 202.m4a->rec-202),则保留该序号。绝不能仅因序号不确定就不归档录音。 - 投放目录不是存储空间。 录音放入共享投放位置(工作区根目录、Downloads 文件夹、S3 收件箱)后,归档副本通过校验和验证后,就将文件移入
arch/transcripts/,然后删除源文件,确保下一次投放时不会产生歧义。如果同时有两个或更多音频文件待处理,说明有多场会议:按时间从早到晚处理,或询问用户要处理哪一个,绝不能合并。
归档约定
归档是一种可选约定。在工作区根目录下保留一个 arch/ 目录树,涵盖该工作区中的所有仓库。如果项目中已有 arch/README.md,请遵循其布局;否则,可以采用以下默认布局:
arch/
README.md
meetings/ YYYY-MM-DD-<counterpart>-<topic>.md
transcripts/ YYYY-MM-DD-rec-<N>.txt + the original .m4a alongside
reports/ YYYY-MM-DD-<topic>.md
报告通常包含以下部分:TL;DR、行动事项、决策、需记住的事项、待解决问题、已完成 / 进行中事项、主题。以下两项约定值得遵守:
- 任何地方都不要使用 em dash。 使用连字符、冒号、句号或括号。
- 每项行动都必须指定明确的负责人。 “应该有人做”不算行动事项。
- 绝不要将完整转录稿粘贴到报告中。请链接到
transcripts/下的文件。
使用 ffprobe 获取实际时长,不要根据文件大小估算:
ffprobe -v error -show_entries format=duration -of csv=p=0 file.m4a
Flow C:从 S3 收件箱导入(浏览器扩展)
此处的 extension/ 文件夹是一个浏览器扩展,可自动录制网络会议(Google
Meet、Zoom 网页版、Teams 网页版),并将其上传到私有 S3 收件箱,因此你无需用手机录音或移交文件。录音会以 inbox/<workspace>/<ts>-<title>.webm
及其 .json 伴随文件的形式存入(平台、标题、会议 URL、参与者、开始/结束时间、是否采集麦克风、contentType)。录制相关内容请参阅 extension/README.md,端点请参阅
ingest/presign-lambda/。
每当用户提到通话时,收件箱都是首要查找位置,不只是用户说“检查收件箱”时才查。“我刚开完一个会”“我们在会上决定了什么” “转录我最近的会议”“处理我的会议”都应从这里开始,然后再询问文件。只有收件箱里没有合适的内容时,才回退到项目的文件投放位置(Flow A),然后再询问。
I=.claude/skills/meeting-brief/ingest/ingest.sh # set MEETING_INBOX_BUCKET + AWS creds (env or AWS_PROFILE)
$I list # pending clips, newest first: title | start | participants
$I pull inbox/<ws>/<file>.webm /tmp/claude/<project>/meeting-in
首先按时间挑选片段(“刚开完”的通话结束时间在最近一两个小时内;
startedAt/endedAt 位于伴随文件中),然后再根据标题/参与者是否与用户提到的人匹配来挑选。如果有两个或更多片段符合条件,列出来并询问用户选哪一个,不要猜。
始终先转换为 .m4a,然后对 .m4a 执行常规 Flow A:
ffmpeg -v error -i clip.webm -vn -c:a aac -b:a 64k clip.m4a # then transcribe clip.m4a
这不是可选步骤,原因有两个。如果通话期间关闭了标签页(伴随文件中的 reason: tab_closed 或 stalled),收到的 webm 会没有正常结尾(“文件提前结束”):ffmpeg 可以正常解码,但 Scribe 可能不行。而手动录制如果开启了视频,格式会是
video/webm;-vn 会去掉视频。只有用户想重看时才保留原始视频。伴随文件中的 capture 说明录制方式:page 表示自动录制(在会议页面内采集通话音频和用户的麦克风音频),tab 表示通过弹出窗口手动录制。
路由:由会议主题决定归档位置,而不是当前所在的会话,也不是标签。 workspace 标签只是录制会议的浏览器上设置的默认值(一个浏览器可以录制多个项目的通话),因此通话很容易被打上错误的标签。根据会议内容判断:参会人员、标题、转录文本中的主题。在聊天中说明你将其归档到哪个项目以及原因,然后直接归档到该项目的 arch/。
如果无法根据伴随文件判断,又不想花费额度在错误的项目中转录,请原样移交:$I retag <key> <workspace>。归档前先用 ffmpeg 转码为 .m4a,使归档符合常用的 .m4a 规范。配对文件归档并通过校验和验证后:
$I done inbox/<ws>/<file>.webm # deletes the clip + sidecar from the inbox
收件箱是投递箱,不是存储空间(与 Flow A 中任何投放的录音遵循同一规则):
只有在确认 arch/transcripts/ 中的副本无误后,才删除每个片段。
录制端:安装、发布更改、调试
-
录制方式,以及唯一不可撤销的更改。 自动录制发生在会议页面内(
extension/capture.main.js,一个包装RTCPeerConnection和getUserMedia的world: MAIN内容脚本)。绝不要把自动启动改回chrome.tabCapture:Chrome 只允许在点击扩展程序后进行标签页录制,因此它无法自行启动;v0.1/v0.2 正是因此在第一次真实 Meet 通话中什么都没录到。标签页录制仅用于弹出窗口中的手动启动,也是获取视频的唯一方式。完整设计见extension/README.md。 -
安装或更新: 运行部署输出的安装单行命令(
curl -fsSL <your-endpoint>/install | sh),然后前往chrome://extensions-> 加载已解压的扩展程序(首次安装;按Cmd+Shift+G并粘贴),或点击重新加载箭头(更新)。从稳定文件夹加载已解压的扩展程序后,更新时扩展程序会保持相同的 ID,因此 Options 中的令牌会保留。绝不要从 Downloads 加载。 -
发布扩展程序更改: 编辑
extension/,递增manifest.json中的version,然后运行cd ingest/presign-lambda && BUCKET=<your-inbox-bucket> TOKEN=<current> ./deploy.sh(环境中需有你账户的 AWS 凭据;令牌位于 Lambda 环境变量中,参见extension/README.md)。这会重新打包/extension提供的 zip 文件;重新运行安装命令并点击重新加载。完成前,务必在真实 WebRTC 通话中验证录制器更改(README 中介绍了 Chromium 测试环境)。 -
“我的通话录下来了吗?”但收件箱是空的: 检查端点,而不是代码。
aws cloudwatch get-metric-statistics --region us-east-1 --namespace AWS/ApiGateway \ --metric-name Count --dimensions Name=ApiId,Value=<your-api-id> --statistics Sum --period 300 \ --start-time $(date -u -d '-3 hours' +%FT%TZ) --end-time $(date -u +%FT%TZ)通话期间没有请求:浏览器从未尝试录制(自动录制关闭、没有令牌、仍在使用基于标签页录制的旧版本,或页面钩子未捕获到通话)。4xx:令牌或端点有误。生成了预签名 URL,但 S3 中没有文件:PUT 失败。弹出窗口中的最近上传状态行也会显示浏览器端的同一情况。
-
状态: 已在真实 Google Meet 通话中确认(2026-10-01,v0.3.0):无需点击即可启动(即使通话中只有自己),捕获麦克风音频,挂断时停止,完成上传,并成功转录。Zoom 网页版和 Teams 网页版使用相同的录制器,但尚未在实际通话中确认。对于
meet.new通话,标题只有会议代码;日历会议会显示会议名称。参与者姓名尽力获取,但通常为空,因此请从转录内容中识别参会者。
流程 B:音频回复模式
用户会用手机阅读,通常无法快速浏览长篇回复。在此模式下,每条实质性回复都会以语音播报。
S=.claude/skills/meeting-brief/scripts
# 1. delete the clip from the previous turn; they have replied so they have heard it
$S/unshare.sh "s3://<bucket>/<previous-key>" <project-dir> <previous-local-file>
# 2. write the reply as a SPOKEN script, then
$S/say.sh reply.txt /tmp/claude/<project>/reply-<n>.mp3 1.5
# 3. private link
$S/share.sh /tmp/claude/<project>/reply-<n>.mp3 <project-dir>
然后发布 URL,附上最多两三行文字:说明音频涵盖的内容,以及他们必须采取的行动。不要附上音频转录稿。此模式的目的就是让他们不必阅读。
记下返回的 s3:// URI 和本地路径,以便下一轮删除它们。
默认语速为 1.5。 ElevenLabs 自带的 speed 设置最高为 1.2,因此 say.sh 会以正常速度渲染,再通过 ffmpeg atempo 调整速度;对于超出 0.5-2.0 范围的值,会串联多个滤镜。音高会保持不变。
撰写适合聆听的内容
大声朗读 Markdown 会让人难以忍受。调用 say.sh 前请先转换:
- 将数字写成单词:“每月四百九十九”,不要写成“$499/mo”。
- 不要包含文件路径、URL 或代码标识符。应将这些内容放在链接旁的文字消息中。
- 不要使用项目符号、标题或粗体。改用“第一”“第二”“接下来”等表达。
- 对于通常按字母念出的缩写,逐个字母读出:“M R R”“U X”“U I”。
- 如果摘要依赖的内容存在已知转录错误,开头就要提醒。
- 段落之间留空行。
say.sh会按这些边界分段,并使用previous_text/next_text拼接,让语调在衔接处保持连贯。
默认语音是平静的广播式朗读(onwK4e9ZLuTAKqWW03F9)。使用 MEETING_BRIEF_VOICE 覆盖。模型默认通过 MEETING_BRIEF_MODEL 设为 eleven_multilingual_v2。
脚本
| 脚本 | 功能 |
|---|---|
scripts/transcribe.sh <outdir> <audio>... | 使用 Scribe v2 转录,区分说话人、添加关键词、并行处理,并跳过已有输出 |
scripts/format-transcript.mjs <raw.json> [--map s0=Name,...] | 带时间戳、按说话人分组的转录文本 |
scripts/say.sh <script.txt> <out.mp3> [speed] [voice] | 分块进行 TTS,拼接音频并调整语速 |
scripts/share.sh <file> [project-dir] [expires] | 上传到私有 S3,并生成预签名 URL(最长 7 天) |
scripts/unshare.sh <s3-uri> [project-dir] [local-file] | 删除对象,并可选择删除本地文件 |
scripts/aws-env.sh | 按项目解析凭据,由上述脚本加载 |
scripts/lib.sh | 加载 ElevenLabs 密钥 |
scripts/extension-icons.mjs | 重新生成扩展程序的工具栏图标(闲置和录制状态) |
ingest/ingest.sh {list,pull,done,retag} | S3 会议收件箱(Flow C) |
ingest/presign-lambda/deploy.sh | 重新部署端点,并重新打包在 <your-endpoint>/extension 提供的扩展程序 zip 文件 |
从环境中读取 ELEVENLABS_API_KEY。如果环境中尚未定义该变量,可以通过 ELEVENLABS_ENV_FILE 指定一个定义了该变量的本地 .env 文件。
环境说明
- 使用
&或nohup进行后台运行可能无法在工具调用结束后继续运行。 请改用 Bash 工具的run_in_background,这是可靠地保持进程运行的方法。 - 预签名 URL 按 HTTP 方法签名。 对由 GET 签名的 URL 执行
curl -I会返回 403,这是正常现象,并不代表失败。请使用带范围的 GET 请求验证:curl -r 0-2000 "$URL"。 - 需要
ffmpeg和ffprobe(请使用包管理器安装)。 - 请将临时文件放在仓库之外(例如
/tmp/claude/<project>/)。
不适用场景
- 简短的事实性回答。不要让用户为了听一句话而播放音频片段。
- 用户需要复制粘贴的任何内容:路径、URL、命令和 ID 都必须以文本提供。
- 代码审查或差异内容。音频不适合阅读代码。