record2note - 语音转结构化笔记
将手机录音自动转录为结构化 Markdown 笔记,包含摘要、关键要点、待办事项和说话人标记。输出兼容 Obsidian、Notion、Logseq 等笔记软件。
Skill 目录
本 skill 的根目录为 SKILL.md 所在的 record2note/ 目录。所有脚本路径均相对于此目录。
前置检查
当用户首次使用本 skill 时,按以下顺序执行:
1. 检测平台
uname -s
# Darwin = macOS, 其他判断是否为 Windows(通过 WSL 或 PowerShell 环境变量)
2. 检查配置
配置文件路径:<skill_folder>/config.json(与 SKILL.md 同目录)。如果不存在,进入 Setup 向导。
3. 检查依赖
python3 <skill_folder>/scripts/common/deps_manager.py check
依赖层级:
| 层级 | 内容 | 大小 | 何时需要 |
|---|---|---|---|
| L1 基础转录 | ffmpeg + whisper 二进制 + base 模型 | ~200MB | 首次转录时自动下载 |
| L2 高质量 | large-v3 模型 | ~3GB | 用户主动升级 |
| L3 说话人分离 | pyannote-audio + torch | ~2GB | diarization=true 时 |
首次转录时 process.sh/ps1 会自动调用 deps_manager.py ensure L1,但建议在 Setup 向导中提前下载。
> 重要: 首次下载前 Agent 必须说明:base 模型约 148MB,medium 约 1.5GB,large-v3 约 3GB;macOS 上 whisper 二进制会尝试 brew 安装,如失败则从源码编译(需 git 和 cmake);国内网络可在 config.json 设置 "mirror": "cn"。
>
> 进度条: 下载时会逐行输出进度(如 [████░░░░] 20%)。Agent 必须实时展示进度行,不要截断或省略。
仍需用户手动安装的依赖:
- fswatch(仅 macOS 自动监控模式):
brew install fswatch - Python 3: macOS 通常系统自带,Windows:
choco install python - git + cmake(仅 macOS 且 Homebrew 不可用时):
brew install git cmake
手动安装命令(如需):
python3 <skill_folder>/scripts/common/deps_manager.py install-whisper
python3 <skill_folder>/scripts/common/deps_manager.py install-ffmpeg
python3 <skill_folder>/scripts/common/deps_manager.py download-model # base (148MB)
python3 <skill_folder>/scripts/common/deps_manager.py download-model ggml-medium.bin # medium (1.5GB)
python3 <skill_folder>/scripts/common/deps_manager.py download-model ggml-large-v3.bin # large-v3 (3GB)
python3 <skill_folder>/scripts/common/deps_manager.py ensure L3 # 说话人分离
python3 <skill_folder>/scripts/common/deps_manager.py mirror # 检测镜像源
镜像配置: mirror: "auto"(默认,自动检测)/ "cn"(国内加速)/ "intl"(国际源)
Setup 向导
配置参数分为两类:
- 必要配置:必须提供(vault 路径、同步方式、模型选择)
- 高级配置:有合理默认值,仅用户要求时展示
标准模式
record2note 需要以下配置:
1. Obsidian Vault 路径: 【必填,例如 /Users/me/Documents/ObsidianVault】
2. 同步方式: iCloud / Syncthing / 手动(macOS 默认: iCloud,Windows 默认: Syncthing)
3. Whisper 模型: base(148MB,速度快)/ medium(1.5GB)/ large-v3(3GB,最佳质量)(默认: base)
如果需要调整更多选项,可以说「显示高级选项」。
高级模式
以下是所有高级配置项:
1. 监控目录: ~/Recordings/raw(默认)
2. 归档目录: ~/Recordings/archive(默认)
3. Vault 子目录: 日记/转录(默认)
4. Whisper 可执行文件: whisper-cli(默认)
5. Whisper 模型路径: /usr/local/share/whisper-models(默认)
6. 转录语言: zh(默认)
7. 说话人分离: 启用(默认)/ 不启用
8. 说话人数: 0(默认,自动检测)/ 2 / 3 / ...(手动指定)
9. 音频降噪: 启用(默认)/ 不启用
10. VAD 语音检测: 不启用(默认)/ 启用(跳过静音)
11. 镜像源: auto(默认)/ cn / intl
12. iCloud watch 子目录: VoiceRecordings(默认,iCloud Drive 下的子目录名)
13. Agent CLI: auto(默认,自动检测)/ opencode / claude / codex / gemini / none
14. 笔记模式: markdown(默认)/ obsidian(使用 Obsidian 双链和 callout)
15. Obsidian 索引页: 录音索引(默认,仅 obsidian 模式生效)
写入配置
macOS:
bash scripts/macos/setup.sh --vault "$VAULT" --sync "$SYNC" --model "$MODEL" [其他项...]
Windows:
powershell -ExecutionPolicy Bypass -File scripts\windows\setup.ps1 -Vault "$VAULT" -Sync "$SYNC" -Model "$MODEL" -IcloudWatchSubdir "$ICLOUD_SUBDIR" -AgentCli "$AGENT_CLI" [其他项...]
同步配置引导
setup.sh 执行后会根据选择的同步方式输出对应指引。Agent 需要引导用户完成同步配置:
iCloud Drive 同步
iCloud Drive 实现 iPhone → Mac 的文件自动同步。录音文件通过 iCloud 落地到 macOS
监控目录,处理完毕后自动移出 iCloud Drive 到本地归档,不占用 iCloud 存储空间。
数据流:
iPhone录音 → iCloud Drive/VoiceRecordings/ → macOS fswatch → process.sh → 本地归档
iPhone 端设置(三选一):
A. Shortcuts 自动化(推荐):
1. iPhone 打开「快捷指令」App
2. 底部「自动化」tab → 右上角 + → 「创建个人自动化」
3. 选择「App」→ 选取「语音备忘录」→ 勾选「完成录音」
4. 关闭「运行前询问」→ 选择「立即运行」
5. 点击「下一步」→ 添加操作:
- 搜索「获取最新的录音」→ 添加
- 搜索「存储文件」→ 添加
- 点击「存储文件」中的「文件」→ 选择「iCloud Drive/VoiceRecordings/」
- 确保「显示文档选取器」处于关闭状态
6. 点击「完成」
B. 第三方录音 app:
使用支持 iCloud Drive 的录音 app,在设置中将存储路径设为
iCloud Drive/VoiceRecordings/。推荐: Just Press Record, Voice Recorder & Audio Editor
C. 手动:
通过 Files app 或 AirDrop 手动复制到 iCloud Drive/VoiceRecordings/
> 确认用户理解如何将录音同步到 iCloud Drive 的 watch 目录。如果用户使用第三方录音 app,需确认该 app 能将音频保存到 iCloud Drive 的 VoiceRecordings 目录。
Syncthing 同步
Syncthing 在手机和电脑之间通过局域网或中继服务器实时同步文件,无需云服务。
设备安装:
| 设备 | 安装方式 |
|---|---|
| macOS | brew install syncthing |
| Windows | syncthing.net/downloads → 下载 syncthing-windows-amd64-v*.zip → 解压即用 |
| Android | Google Play / F-Droid 搜索 Syncthing |
| iOS | App Store 搜索 Möbius Sync(付费) |
首次配对步骤:
- 电脑端启动 — macOS:
syncthing终端运行;Windows: 双击syncthing.exe。自动打开http://127.0.0.1:8384 - 手机端启动 — 打开 Syncthing App,允许后台运行
- 获取设备 ID — 两端都在 Web UI/App「操作」→「显示 ID」,复制 52 位的设备标识符
- 互添设备 — 电脑 Web UI「添加远程设备」→ 粘贴手机 ID;手机同样添加电脑 ID
- 配置共享文件夹 — 电脑 Web UI「添加文件夹」→ 文件夹路径设为
watch_dir→ 在「共享」tab 中勾选手机设备 - 手机确认 — 手机会收到文件夹共享请求,确认并设置本地接收目录(如 Android:
Internal storage/Recordings/) - 配对完成 — 两端状态显示「已同步」,测试录音是否自动传输
Syncthing 配置建议(可选,打开 Web UI 后设置):
| 配置项 | 路径 | 说明 |
|---|---|---|
| 发送限速 | 文件夹 → 编辑 → 高级 | 限制上传速度,避免占满网络 |
| 版本控制 | 文件夹 → 编辑 → 文件版本控制 | 防止误删,建议"简易版本控制" |
| 忽略模式 | 文件夹 → 编辑 → 忽略模式 | 过滤不需要同步的文件(如 .lock) |
常见问题排查:
| 现象 | 原因 | 解决 |
|---|---|---|
| 设备显示「断开连接」 | 不在同一网络或中继被禁用 | 确认两端网络连通,检查设置 → 连接 → 启用中继 |
| 文件夹显示「同步中」但无文件 | 忽略模式过滤了音频文件 | 检查文件夹编辑 → 忽略模式 |
| 手机端显示「文件夹未共享」 | 电脑端未勾选共享给该设备 | 电脑 Web UI 文件夹 → 共享 → 勾选手机 |
| 文件传输慢 | 正在通过中继服务器中转 | 确保两端在同一局域网,或使用 TCP 直连 |
| 两个设备都有同名文件冲突 | Syncthing 默认保留新版 | 手动删除旧版本,或在版本控制中恢复 |
> 确认用户已安装 Syncthing 并成功配对设备。首次配对建议在同一局域网内完成(更快),之后支持跨网络同步。
手动模式
将录音文件手动传送到电脑监控目录,不依赖自动同步服务。
传输入口(任选其一):
- USB 连接: 手机连接电脑 → 复制录音文件到 watch_dir
- 云盘中转: 百度网盘 / OneDrive / Google Drive 上传 → 电脑下载到 watch_dir
- 共享文件夹: 设置局域网共享 → 手机通过文件管理器上传到 watch_dir
- 直接指定: 在「处理录音」时直接提供文件路径,无需放入 watch 目录
参数表:
| 参数 | 默认值 | 类别 |
|---|---|---|
| --vault / -Vault | 必填 | 必要 |
| --sync / -Sync | icloud | 必要 |
| --model / -Model | ggml-base.bin | 必要 |
| --watch-dir / -WatchDir | ~/Recordings/raw | 高级 |
| --archive-dir / -ArchiveDir | ~/Recordings/archive | 高级 |
| --subdir / -Subdir | 日记/转录 | 高级 |
| --whisper-bin / -WhisperBin | whisper-cli | 高级 |
| --model-path / -ModelPath | /usr/local/share/whisper-models | 高级 |
| --sync-delay-icloud / -SyncDelayIcloud | 60 | 高级 |
| --sync-delay-syncthing / -SyncDelaySyncthing | 10 | 高级 |
| --sync-delay-manual / -SyncDelayManual | 10 | 高级 |
| --icloud-watch-subdir / -IcloudWatchSubdir | VoiceRecordings | 高级 |
| --speakers / -Speakers | 0(自动检测) | 高级 |
| --language / -Language | zh | 高级 |
| --diarization / -Diarization | true | 高级 |
| --denoise / -Denoise | true | 高级 |
| --vad / -Vad | false | 高级 |
| --vad-model-path / -VadModelPath | $WHISPER_MODEL_PATH/ggml-silero-v6.2.0.bin | 高级 |
| --mirror / -Mirror | auto | 高级 |
| --agent-cli / -AgentCli | auto | 高级 |
| --note-mode / -NoteMode | markdown | 高级 |
| --obsidian-index / -ObsidianIndex | 录音索引 | 高级 |
下载模型(建议立即执行)
配置完成后,主动询问用户是否现在下载 whisper 模型:
配置已完成!是否现在下载 whisper 所需的依赖?
- whisper 二进制: ~5MB
- base 模型: ~148MB(如选了 medium/large 则更大)
输入「是」立即下载,输入「否」等到首次处理音频时再自动下载。
用户同意则执行 deps_manager.py install-whisper 和 deps_manager.py download-model。用户选 medium/large-v3 时额外下载对应模型。下载完成后再次运行 deps_manager.py check 确认。
完成配置
报告配置文件位置、监控/归档目录,告知用户可随时修改 config.json,然后询问模式选择。
配置文件格式
{
"platform": "macos",
"watch_dir": "~/Recordings/raw",
"archive_dir": "~/Recordings/archive",
"obsidian_vault": "/path/to/vault",
"obsidian_subdir": "日记/转录",
"whisper_binary": "whisper-cli",
"whisper_model": "ggml-base.bin",
"whisper_model_path": "/usr/local/share/whisper-models",
"sync_method": "icloud",
"icloud_watch_subdir": "VoiceRecordings",
"sync_delay_icloud": 60,
"sync_delay_syncthing": 10,
"sync_delay_manual": 10,
"speaker_count": 0,
"language": "zh",
"diarization": true,
"denoise": true,
"vad": false,
"vad_model_path": "/usr/local/share/whisper-models/ggml-silero-v6.2.0.bin",
"mirror": "auto",
"agent_cli": "auto",
"note_mode": "markdown",
"obsidian_index": "录音索引"
}
> 笔记模板在 <skill_folder>/templates/ 下,note-template.md(中文)/ note-template-en.md(英文)/ note-template-obsidian.md(中文 Obsidian)/ note-template-obsidian-en.md(英文 Obsidian)。note_mode=obsidian 时自动使用 Obsidian 模板。
> 配置迁移: 新增字段(如 icloud_watch_subdir、agent_cli)在旧配置中不存在时,read_config.py 会使用默认值兜底(icloud_watch_subdir: "VoiceRecordings",agent_cli: "auto")。无需手动迁移,但可通过重新运行 setup.sh / setup.ps1 更新配置。platform 字段由 setup 脚本自动设置:macOS 写入 "macos",Windows 写入 "windows"。手动编辑 config.json 时请根据操作系统填写。
模式选择
自动监控模式
用户说「开启自动监控」。执行 install.sh / install.ps1 后加载后台守护进程(macOS: launchd,Windows: 任务计划),开机自动启动,监控 watch 目录。
手动处理模式
用户说「处理录音」「检查录音」「处理 pending」。
子模式:
1. 指定文件: 提供文件路径,直接转录并生成笔记
2. 批量处理: 列出 watch 目录中的音频文件,逐个处理
3. 处理 pending: 扫描 $archive_dir/pending/ 中已有转录结果,直接生成笔记
# macOS
bash scripts/macos/process.sh "/path/to/audio.m4a"
# Windows
powershell -ExecutionPolicy Bypass -File scripts\windows\process.ps1 -InputFile "C:\path\to\audio.m4a"
转录机制
处理流程
- 格式转换 — ffmpeg 转为 16kHz 单声道 16-bit WAV
- 语音检测(可选) —
vad: true时用 Silero-VAD 跳过静音段 - 降噪(可选) —
denoise: true时应用afftdnFFT 降噪 - 转录 — whisper-cli 四级降级策略(详见错误处理)
- 超时保护 — 根据音频时长和模型大小自动计算 timeout(见下方)
- 说话人分离(可选) —
diarization: true时运行 pyannote-audio - 合并输出 — 转录文本 + 说话人标记合并为 Markdown
- 保存 pending — JSON 格式保存到
$archive_dir/pending/ - 触发 Agent — 如果
agent_cli不是none,自动调用 Agent CLI
Whisper 超时机制
转录时根据音频时长和模型大小自动计算超时时间,防止 whisper 卡死阻塞整个 pipeline:
公式: timeout = 音频时长 × 模型倍数 + 600秒
| 模型 | 倍数 | 5 分钟音频 | 30 分钟音频 |
|---|---|---|---|
| base | 3x | 25 分钟 | 100 分钟 |
| medium | 5x | 35 分钟 | 160 分钟 |
| large-v3 | 8x | 50 分钟 | 250 分钟 |
600 秒缓冲用于模型加载和 4 次降级重试开销。超时后 whisper 进程被终止,pipeline 继续处理下一个文件。
文件去重(自动监控模式)
fswatch 会在文件创建和写入时各触发一次事件。watch 模式使用两层去重:
1. 文件锁 — 每个音频文件处理时创建 .lock 文件,同名文件不会重复处理
2. 稳定性检查 — 确认文件写入完成再开始处理:
- macOS iCloud 模式:检测 placeholder 下载状态 + 等待 10 秒后比较文件大小
- macOS 其他模式:等待 3 秒后比较文件大小
- Windows:等待 5 秒后比较文件大小
Pending 目录机制
转录完成后,元数据和转录文本以 JSON 保存到 $archive_dir/pending/:
- 路径:
$archive_dir/pending/YYYY-MM-DD_文件名.json - 内容:
metadata(标题候选、日期、时长、源文件路径、说话人、语言)+transcript(转录文本)
| 模式 | pending 行为 |
|---|---|
| 手动模式 | Agent 实时生成笔记,pending 文件作为备份 |
| 自动监控模式 | pending 是 Agent 处理的唯一入口 |
Agent CLI 自动触发
配置中 agent_cli 控制转录完成后是否自动调用 Agent:
| 值 | 行为 |
|---|---|
"auto" |
自动检测(优先级:opencode > claude > codex > gemini) |
"opencode" / "claude" / "codex" / "gemini" |
指定 CLI |
"none" |
不触发,仅保存 pending |
trigger_agent.sh 在后台调用 CLI,包含完整的配置信息和模板内容,Agent 无需加载 skill 即可处理。触发日志写入 /tmp/record2note-agent.log。
> 注意: launchd 环境下可能缺少用户 session 权限(keychain 认证等),如遇认证问题可改用 "none" 手动处理。
> Windows 注意: trigger_agent.sh 需要 bash 环境。Windows 上需安装 Git Bash(随 Git for Windows 自动安装)或 WSL。如无可用的 bash,Agent 触发将被跳过。
Obsidian 模式
当 note_mode 设为 obsidian 时,生成的笔记使用 Obsidian 特有格式:
| 特性 | markdown 模式 | obsidian 模式 |
|---|---|---|
| 摘要/要点/待办 | 普通 Markdown | Obsidian Callout (> [!abstract] 等) |
| source 字段 | 普通路径 | Wikilink [[路径]] |
| 标签 | frontmatter tags | frontmatter tags + 自动追加 录音/recording |
| 索引页 | 无 | 自动维护索引页,每条笔记包含反向链接 |
索引页位于 $obsidian_vault/$obsidian_subdir/$obsidian_index.md(默认: vault/日记/转录/录音索引.md),按日期分组列出所有录音笔记的双链。
Agent 处理 Pending 文件
当用户说「处理录音」「检查录音」「处理 pending」或 Agent CLI 被自动触发时,执行以下流程:
- 扫描
$archive_dir/pending/目录 - 逐个处理每个 JSON 文件:
- 读取 metadata 和 transcript
- 按「摘要生成」章节生成结构化笔记(含转录修正和段落时间戳)
- 按「笔记生成与归档」章节写入 Obsidian vault
- 归档原始音频到$archive_dir/YYYY-MM-DD/
- 更新笔记source字段为归档路径
- 删除 watch 目录中的原始音频
- 删除已处理的 pending JSON - 批量处理时逐个报告结果
- pending 目录为空时告知用户「当前没有待处理的录音」
摘要生成
Agent 收到转录内容后使用以下 prompt 生成结构化笔记:
请根据以下语音转录内容生成结构化笔记。
转录文本:
{{transcript}}
要求:
1. 生成一个简洁的标题(15字以内)
2. 写一段摘要(100-200字),概括核心内容
3. 列出关键要点(3-5条)
4. 如果有可执行的待办事项,列出为 checkbox 格式
5. 为内容打上 1-3 个标签
6. **修正转录错误**:语音识别可能产生同音字错误(如"实音"应为"石英"、"碰盐"应为"模块"等),根据上下文语义修正,使文本通顺可读
7. **完整转录格式**:将转录文本整理为段落,每个段落前标注 `[MM:SS]` 时间戳,不需要每行都标注
输出格式:
标题:<标题>
摘要:<摘要>
要点:
- <要点1>
待办:
- [ ] <任务1>
标签:<tag1>, <tag2>
language 非 zh 时使用英文 prompt:
Please generate structured notes from the following voice transcript.
Transcript:
{{transcript}}
Requirements:
1. Generate a concise title (within 15 characters)
2. Write a summary (100-200 characters), covering the core content
3. List key points (3-5 items)
4. If there are actionable items, list them as checkboxes
5. Add 1-3 tags
6. **Fix transcription errors**: Correct homophone errors based on context.
7. **Transcript format**: Organize into paragraphs with `[MM:SS]` timestamps at the start of each paragraph only.
Output format:
Title: <title>
Summary: <summary>
Key Points:
- <point1>
Todos:
- [ ] <task1>
Tags: <tag1>, <tag2>
笔记生成与归档
- 读取模板(
note-template.md中文 /note-template-en.md英文) - 替换模板变量:
-{{title}}— 标题
-{{date}}— YYYY-MM-DD
-{{duration}}— HH:MM:SS
-{{source}}— 归档后的音频路径
-{{speakers}}— 说话人(甲, 乙...)
-{{language}}— 语言代码
-{{tags}}— 标签
-{{summary}}— 摘要
-{{keypoints}}— 关键要点
-{{todos}}— 待办事项
-{{transcript}}— 完整转录 - 写入 Obsidian vault:
$obsidian_vault/$obsidian_subdir/YYYY-MM-DD-<标题>.md - 归档音频:
$archive_dir/YYYY-MM-DD/<标题>.<ext> - 更新笔记
source字段为归档路径 - 删除 watch 目录中的原始音频和 pending JSON
错误处理
常见错误
| 场景 | 处理 |
|---|---|
| whisper GPU 内存不足 | 四级降级:GPU → -nfa → -nfa -t 2 → -ng(CPU) |
| whisper 超时 | 根据音频时长和模型自动计算 timeout,超时后终止并跳过 |
| 模型文件缺失 | 检查 whisper_model_path,提示重新下载 |
| pyannote 加载失败 | 检查 pip show pyannote-audio 和 HuggingFace 登录 |
| ffprobe 失败 | 跳过时长字段,继续处理 |
| ffmpeg 转换失败 | 检查 ffmpeg 安装和音频文件完整性 |
| 文件未同步完成 | 等待 sync_delay 后处理 |
| 目标路径不存在 | 自动创建 |
| Agent CLI 未找到 | 静默跳过,仅保存 pending |
恢复机制
- 使用临时目录处理,成功后才执行归档和清理
- 处理失败的文件保留在 watch 目录,不删除
- pending 文件不会被删除,可重新触发处理
卸载
macOS: bash scripts/macos/uninstall.sh
Windows: powershell -ExecutionPolicy Bypass -File scripts\windows\uninstall.ps1
卸载时停止并移除守护进程和脚本,不删除配置文件、录音文件、Obsidian 笔记。