在把纪要交给 Notion AI 整理前后,先用本地规则抽出「决策/待办」行,便于对照 AI 输出是否漏项。
先看清成品
- 样例笔记抽出 ≥2 决策与 ≥2 待办(含日期)。
- 1 项 pytest 通过。
合规提醒:Notion AI / Custom Agents 只能看到你有权限的页面;回答会过时若资料过时。会议录音前告知参会者。企业需确认管理员的 AI 与数据设置。Agent API 为 public beta,能力与套餐(Business/Enterprise)以官方为准。本文不编造价格。
运行说明:无正式 NOTION_API_KEY / AGENT_ID。A 用 mock sessions;对 api.notion.com 无效 token 实测 HTTP 401。B 本地纪要抽取;C 提示词泄密扫描。2026-10-23(Asia/Shanghai)pytest 通过。
做完之后你会得到什么?
| 成果 | 说明 |
|---|---|
meeting_actions.py |
抽取脚本 |
sample_notes.txt |
样例 |
test_112b.py |
测试 |
需要准备哪些环境?
| 项目 | 说明 |
|---|---|
| Python | 3.10+ |
关键事实
| 事实 | 来源 |
|---|---|
| 产品侧可录音转写并生成纪要 | Notion AI 功能表 |
| 本脚本不调用 Notion,只做结构预检 | 重要 |
| 录音前告知参会者 | 合规 |
文件结构
112-notion-ai-B-src/
├── meeting_actions.py
├── sample_notes.txt
└── test_112b.py
第 1 步:抽取
#!/usr/bin/env python3
"""Extract decisions and todos from meeting notes (local stand-in for Notion AI meeting summary).
Looks for lines starting with 决策/决定/Decision and 待办/TODO/@owner patterns.
Does not call Notion — use before or after inserting AI-generated notes.
"""
from __future__ import annotations
import argparse, json, re, sys
from pathlib import Path
DEC_RE = re.compile(r"^(?:决策|决定|Decision)\s*[::]\s*(.+)$", re.I | re.M)
TODO_RE = re.compile(
r"^(?:待办|TODO|Action)\s*[::]\s*(.+?)(?:\s*[—\-]\s*(?P<owner>[^\d@]+))?(?:\s*@(?P<at>\S+))?(?:\s+(?P<due>\d{4}-\d{2}-\d{2}))?\s*$",
re.I | re.M,
)
def extract(text: str) -> dict:
decisions = [m.group(1).strip() for m in DEC_RE.finditer(text)]
todos = []
for m in TODO_RE.finditer(text):
todos.append({
"task": m.group(1).strip(),
"owner": (m.group("owner") or m.group("at") or "").strip() or None,
"due": m.group("due"),
})
return {"decisions": decisions, "todos": todos, "decision_count": len(decisions), "todo_count": len(todos)}
def main(argv=None) -> int:
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("notes_file")
args = ap.parse_args(argv)
text = Path(args.notes_file).read_text(encoding="utf-8")
print(json.dumps(extract(text), ensure_ascii=False, indent=2))
return 0
if __name__ == "__main__":
raise SystemExit(main())
第 2 步:测试
import json, subprocess, sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
def test_extract():
r = subprocess.run([sys.executable, str(HERE/"meeting_actions.py"), str(HERE/"sample_notes.txt")],
capture_output=True, text=True, check=True)
data = json.loads(r.stdout)
assert data["decision_count"] >= 2
assert data["todo_count"] >= 2
assert any(t.get("due") for t in data["todos"])
第 3 步:运行
$ pytest 112b
. [100%]
1 passed in 0.03s
怎么检查结果?
- decision_count≥2、todo_count≥2。
- 至少一条 todo 含 due。
调试示例
AI 把闲聊当成待办。 先统一「待办:」前缀,再用本脚本 diff AI 结果。
常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
| 多语言 | 扩正则 | 按团队模板 |
| 数据库填充 | 另一产品能力 | 用 AI 属性 |
| 要不要 API | 先本地 | 再 Agent |
模板规则
- 录音先征得同意。
- 待办必须有负责人。
- AI 输出人工确认。
项目资源
| 用途 | 地址 |
|---|---|
| Notion AI | https://www.notion.com/product/ai |
| AI 帮助指南 | https://www.notion.com/help/guides/category/ai |
| API Intro | https://developers.notion.com/reference/intro |
纪要结构化,AI 总结才验得出来。