OpenOats会议格式规范详解:如何设计一份LLM与Obsidian都能读懂的Markdown会议记录
【免费下载链接】OpenOatsA meeting note-taker that talks back.项目地址: https://gitcode.com/gh_mirrors/op/OpenOats
OpenOats 是一款 Mac 上的开源会议记录 App:它坐在你的通话旁边,实时转写双方的对话,会后把内容保存为一份结构化的Markdown 会议记录。这份记录遵循一份名为 OpenOats 会议格式规范(openoats/v1)的标准——它同时做到了四件事:人眼好读、grep 可搜、Obsidian 可查询、LLM 可直接消费。本文将带你快速看懂这套会议记录格式的设计思路与关键规则。
为什么会议记录需要一套"标准"
会议笔记工具的常见困境是:输出要么是一坨没有结构的纯文本,要么是锁死在私有格式里的数据库记录。前者人读可以,但工具读不了;后者工具友好,人却看不了。
OpenOats 的答案是:把.md文件本身当作"API"来设计。规范的目标非常明确:
| 目标 | 谁受益 |
|---|---|
| 人类可读 | 你在任何编辑器 / Obsidian / 预览里打开都能懂 |
| Agent 就绪 | LLM(Claude Code、RAG 管线)无需额外解析层 |
| CLI 友好 | rg(ripgrep)一行命令就能检索全部会议 |
| Obsidian 原生 | YAML frontmatter 可被 Dataview 直接查询 |
| 增量可用 | 文件在每一个处理阶段都是完整、有效的 |
一个文件 = 四层信息
每份会议记录从上到下由四层构成,各层职责清晰:
- 文件名:唯一标识,自带时间线
- YAML Frontmatter:约 20 行以内的会议元数据
- 正文分区:
# 标题+ 若干##章节 - 转写行:每句话一行的固定格式文本
下面逐层拆解。
文件命名规范:字典序 = 时间序
文件名格式固定为:
YYYY-MM-DD-HHMM-kebab-case-title.md例如2026-03-20-1400-weekly-product-sync.md。三条规则值得注意:
- 时间取会议开始时刻(本地时间、24 小时制、时与分之间无分隔符)
- 标题部分只允许小写字母、数字和连字符(kebab-case),不超过 60 字符;无法确定标题时回退为
meeting - 文件名不允许出现空格,按文件名排序就等于按时间排序
这样ls一下目录就是会议时间线,无需 UUID 字段——文件名本身就是唯一标识。重名时自动追加-2、-3后缀避免覆盖。
YAML Frontmatter:20行以内的会议元数据
每个文件以一段 YAML frontmatter 开头。核心字段如下:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
schema | 字符串 | ✅ | 恒为openoats/v1,标识格式版本 |
title | 字符串 | ✅ | 会议标题,必须加引号,且与正文 H1 一致 |
date | ISO 8601 | ✅ | 会议开始时间,尽量带时区偏移 |
duration | 整数 | ✅ | 会议时长(分钟,≥1) |
participants | 字符串数组 | ✅ | 参与者名单,默认["You", "Them"] |
recorder | 字符串 | ❌ | 记录人,用于把You映射到真实身份 |
tags | 字符串数组 | ❌ | 主题标签,由 LLM 或用户生成 |
language | 字符串 | ❌ | BCP 47 语言码,如en、pl |
engine | 字符串 | ❌ | 转写引擎,如parakeet-tdt-v2 |
app | 字符串 | ❌ | 检测到的会议应用:zoom、meet、teams |
x_* | 任意 | ❌ | 扩展命名空间,如x_openoats_session |
规范中有几条针对"机器解析"的硬规则,每条都在防一类真实事故:
title必须加引号——否则 YAML 会把yes解析成布尔值、把#后面的内容当注释截掉- 扁平结构,禁止嵌套对象——Dataview 查嵌套 YAML 需要 DataviewJS,普通查询直接失效
- 数组用 YAML 数组语法,绝不写逗号分隔字符串
- frontmatter 里不放 wikilink,
[[链接]]只允许出现在正文 x_前缀是扩展字段——解析器必须忽略不认识的x_字段,第三方工具可安全写入自己的元数据
一个最小示例(LLM 处理前就能成立的完整文件):
--- schema: openoats/v1 title: "Meeting" date: 2026-03-20T14:00:00+01:00 duration: 32 participants: - You - Them engine: parakeet-tdt-v2 ---三阶段处理:文件在任何阶段都"可用"
这是整套格式最精妙的设计:OpenOats 分三个阶段生成同一份文件,每一阶段的产物都是完整有效的——你不需要跑 LLM 就拥有一份干净可用的会议记录。
| 阶段 | 做什么 | 产物 |
|---|---|---|
| ① 转写 | 原始 ASR 输出 | frontmatter +# 标题+## Transcript |
| ② 后处理 | 去语气词(um/uh)、修标点、纠正说话人 | 就地清洗,结构不变 |
| ③ 智能层 | 插入 LLM 生成的章节 | 新增 Summary / Action Items / Decisions |
正文章节顺序固定为:
# 标题 ## Summary ← 仅阶段③(LLM 生成) ## Action Items ← 仅阶段③(LLM 生成) ## Decisions ← 仅阶段③(可选) ## Transcript ← 始终存在摘要在上、转写在底并非随意安排:LLM 对上下文窗口开头和结尾的权重更高("lost in the middle" 效应),人扫读文件也想先看高信号内容。而阶段③只插入新章节、绝不改动转写原文,保证原始记录可追溯。
转写行格式:每句话一行,正则即解析器
## Transcript章节里,每句话(utterance)独占一行,格式严格统一:
[HH:MM:SS] **说话人:** 这句话的内容。| 部件 | 规则 | 示例 |
|---|---|---|
| 时间戳 | 相对会议开始时刻,零填充,可超 24h | [00:05:23] |
| 说话人 | 粗体 Markdown + 冒号 | **You:** |
| 文本 | 自由文本,单行不折行 | I think we should launch earlier. |
规范给出了参考解析正则(^\[(\d{2}:\d{2}:\d{2})\] \*\*(.+?):\*\* (.*)$),三个捕获组直接对应时间、说话人、文本。相关实现可参考 MarkdownMeetingWriter.swift 中的转写行组装与相对时间戳计算逻辑。
两个关键设计决策:
- 时间戳用相对时间而非墙上时钟——
[00:01:24]表示"会议进行到 1 分 24 秒",音频回放工具直接可用;绝对开始时间已存在 frontmatter 的date字段里 - 说话人用完整粗体名而非 ID——
**Alice Chen:**自解释、grep 友好,LLM 无需查表;句间空行只是排版,解析器应忽略
说话人模型目前很简单:麦克风流 →You,系统音频流(所有远端参会者)→Them,不做多方分离。但格式已为未来留好口子——当接入日历标注或说话人分离后,participants里换成真实姓名即可,转写行结构零改动。
Obsidian 视角:行动项即数据库行
## Action Items是格式与 Obsidian 生态咬合最深的地方。每条行动项是标准 Markdown 复选框,行尾带 Dataview 内联字段:
- [ ] Finalize launch announcement blog post [owner:: You] [due:: 2026-03-25] - [x] Run load testing on SQLite concurrency [owner:: Them]规则很克制:owner必须取自participants数组;due必须是 ISO 8601 日期、没有就整个省略;owner必须排在due前面;每项单行。
在 Obsidian 里,一行 Dataview 查询就能跨全部会议聚合任务:
TASK FROM "OpenOats" WHERE !completed AND contains(text, "owner:: You")非 Obsidian 用户打开文件时,这些中括号也只是"略带装饰的复选框",阅读零障碍——这就是格式对生态的宽容度。
LLM 视角:grep 友好的 Agent 接口
对 LLM Agent 来说,这套格式等于送上了现成的检索接口。几条常用rg命令感受一下:
# 所有会议中还没完成的行动项 rg '^- \[ \]' ~/Documents/OpenOats/ # 分配给"我"的未完成任务 rg '\[ \].*\[owner:: You\]' ~/Documents/OpenOats/ # 用过 Zoom 的会议 rg '^app: zoom' ~/Documents/OpenOats/因为文件名即时间线、行格式即正则、frontmatter 即扁平键值对,Agent 不需要理解任何私有协议,用文本工具就能完成"列出我本周的所有待办"这类请求。规范甚至明确了兼容性承诺:新增可选字段不改schema版本号,破坏性变更才会升到openoats/v2并附迁移说明——这让其他工具敢于把它当作共享标准来依赖。
上手参考:从规范到源码
| 想做的事 | 去哪看 |
|---|---|
| 读完整格式规范(字段、正则、解析指南) | docs/meeting-format-spec.md |
看一份完整的openoats/v1会议记录示例 | docs/example-transcript.md |
| 看生成文件的写入器实现 | MarkdownMeetingWriter.swift |
| 看格式的自动化测试保障 | MarkdownMeetingWriterTests.swift |
一句话总结:OpenOats 会议格式的核心哲学是"把 Markdown 文件当 API 设计"——命名带时间线、元数据扁平、行格式可正则、未知字段可忽略。于是同一份.md,人读是会议纪要,grep 读是日志库,Dataview 读是任务数据库,LLM 读是结构化上下文。这正是它值得其他工具采纳的原因。
【免费下载链接】OpenOatsA meeting note-taker that talks back.项目地址: https://gitcode.com/gh_mirrors/op/OpenOats
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考