文章剪藏到 Notion
将 $ARGUMENTS 中的单篇文章剪藏到 Notion 的 文章剪藏 根页面下。根页面下每个分类是一个独立的 Notion 数据库(data source),文章作为该数据库的一行写入。根据文章内容自动选择最匹配的分类数据库并生成标签。
结构假定
- 文章剪藏:根页面,其下挂载多个分类数据库。
- 分类数据库:每个分类是一个 Notion 数据库(通过
fetch 获取其 data_source_id,即 collection://... URL)。文章是该数据库的行。
- 公共字段:每个分类数据库通常有
标题(title)、URL/来源(url)、标签(multi_select);部分分类可能还有 作者、发布日期、摘要 等字段。不维护文章计数,不需要"数量"字段。
- 若实际结构与上述不符,以
fetch 返回的 schema 为准,按实际字段名和类型映射;不要臆造字段;schema 中缺失的字段(如作者、发布日期)信息并入摘要,不单独成块。
约束
- 只接受一个
http:// 或 https:// 文章 URL。多个 URL、空参数或非 URL 参数时,要求用户提供一个链接。
- 不绕过登录、付费墙、robots 限制或其他访问控制。公开页面无法取得完整正文时,说明原因并停止,不要用搜索摘要冒充文章正文。
- 保留原文标题、作者和发布日期(若能取得)以及来源链接,用于归属和追溯。
- 不复制页面中与正文无关的广告、追踪链接或推荐内容;不要删除正文中的必要风险提示、赞助披露或作者署名。
- 只能通过本会话已安装、已授权的 Notion 插件/MCP 工具写入 Notion。 不使用浏览器自动化、Notion 网页手动操作、邮件转发、第三方中转或本地导出文件替代插件写入。
- Notion 插件不可用、未授权,或缺少搜索/读取/创建页面能力时,明确告知用户需要连接或授权插件,并停止;不得声称已保存。
- 不覆盖、移动或删除任何已有 Notion 页面。
- 正文只放正文:
content 的"正文"部分只保留清理后的原文正文,不要在正文顶部或任何位置插入作者、来源、发布日期、规范链接等归属信息块(来源 URL 已存于 URL 属性;作者/日期可在摘要中自然提及,不单独成块)。
性能原则(重要)
剪藏一篇文章应在合理时间内完成(目标:单次剪藏 ≤ 15 个工具调用)。遵循以下原则避免不必要的往返:
- 批量 fetch:一次
fetch 根页面即可拿到所有分类数据库的 collection:// URL;不要逐个分类 fetch。只在需要确认某个分类的 schema 时才 fetch 该 data source,且同一分类的 schema 在一次剪藏内只 fetch 一次。
- 用 SQL 去重:去重用
notion-query-data-sources 的 SQL 模式一次完成,不要逐行 search。
- 标签复用 schema:multi_select 的可选项已在
fetch 返回的 schema 中,不需要额外查询;直接从 schema 读取已有标签复用。
- 限制图片数量:正文图片最多上传 10 张,按出现顺序取前 10 张;超出部分保留原外链占位说明。此上限源于早期批量上传失败的经验,目的是兼顾"图片可用"与"速度",不要为了提速而进一步砍掉已转存的图片。
- 异步创建:创建页面时设置
allow_async: true,让 Notion 后台完成正文写入,工具快速返回。
- 不要读取分类正文:分类名通常已足够判断语义,不要 fetch 分类数据库的内容来"理解分类含义"。
- 单次抓取 + 单次解析:正文与图片只抓取一次。优先用
curl 直接拉取页面 HTML(带桌面 UA),再用一个脚本(如 Python + bs4)一次性提取标题、作者、日期、正文块与图片直链;不要先 WebFetch 再单独 curl、再多次试探性解析。微信公众号(mmbiz 图床)的图片直链就在 img[data-src] 属性里,curl 即可拿到,不需要浏览器渲染。
- 分批上传图片:待转存图片按 2–3 张一批调用
notion-create-attachment,批与批之间等待约 3 秒。实测一次并发 10 张会触发接口限流、返回错误并被迫重试,反而更慢。不要先抽样 curl 测试可达性,直接传,失败按回退规则处理。
- 明确工具名,不反复检索:本次用到的工具固定为
notion-search、notion-fetch、notion-query-data-sources、notion-create-attachment、notion-create-pages;直接调用,不要反复用 ToolSearch 试探。
操作流程
1. 获取并清理文章
- 优先用
curl(桌面 UA)直接拉取页面 HTML 作为唯一信息源;仅当站点依赖 JS 渲染才退回到浏览器工具。优先采用规范链接(canonical URL),可从 HTML 的 <link rel="canonical"> 或 og:url 读取。
- 提取:标题、作者、发布日期、站点名、规范来源 URL、正文、正文内有意义的标题层级、代码、表格、图片及其说明、关键引用链接。
- 仅保留主文章内容。至少移除以下内容:
- 顶部/侧边导航、页脚、Cookie 横幅、登录/订阅弹窗;
- 广告、推广、联盟营销模块、赞助卡片及其行动按钮;
- “推荐阅读”“相关文章”“猜你喜欢”“更多内容”、评论区、社交分享控件;
- 作者的其他文章列表、标签云、站内搜索、重复页眉/页脚和无关脚本样式文本。
- 保持原始的段落、列表、标题和代码逻辑。不要为了缩短内容而改写或概括正文;只移除非文章元素。
- 收集正文图片(单次解析):用同一个解析脚本一次性提取所有
<img> 的真实 src(优先 data-src,回退 src)与说明文字,按出现顺序取前 10 张。微信公众号(mmbiz 图床)的直链就在 img[data-src] 中,curl 拉到的 HTML 即可读到,不需要浏览器渲染;只有当确证某站点必须渲染才暴露直链时,再退回浏览器工具,但不要默认走渲染。不要为了拿图而单独再抓一遍页面。
若无法可靠地区分正文和页面噪声,先向用户说明并提供可剪藏范围,不要把整页 HTML 或导航文字写入 Notion。
2. 定位分类数据库并去重
-
fetch 根页面 文章剪藏,从返回结果中收集所有分类数据库的 <data-source url="collection://..."> 及其显示名称。只 fetch 一次根页面。
-
根据文章主题、对象和内容形式,在现有分类中选取语义最接近的一项。优先复用分类:不要仅因名称不完全一致而新建分类。
-
SQL 去重:对选中的分类 data source 执行一次查询,按规范 URL 精确匹配,URL 命中不到时再按标题精确匹配:
SELECT "标题", "URL", id FROM "collection://<data_source_id>"
WHERE "URL" = ? OR "标题" = ?
LIMIT 5
若命中同一来源 URL 或明显相同的标题,停止创建并告知用户已有页面的位置。
-
如果没有任何合理的已有分类,向用户说明建议的新分类名称和理由,等待确认后才创建新的分类数据库;未经确认不可新建。
3. 转存图片(确保可显示)
对收集到的正文图片,按以下顺序处理,只处理能稳定显示的图片:
- 优先上传转存:对每张图片尝试用
notion-create-attachment 的 source_url 上传。要求:公开 HTTPS 直链、不重定向、不需要 cookie/headers、≤5 MiB、能在 1 分钟内下载完成。
- 上传成功后,工具返回
markdown_source(形如 file-upload://...),用它替换正文中的原图片 URL。
- 上传失败的图片跳过下一步处理。
- 回退外链:上传失败的图片,保留原 URL 用 Notion 外链图片语法嵌入
,并在图片下方加一行斜体说明:(外链图片,可能失效)。
- 跳过无效图片:明显是 tracking pixel、1x1 透明图、或 data URI 的图片直接丢弃。
- 分批上传:把待转存图片按 2–3 张一批调用
notion-create-attachment,批与批之间 sleep 3 秒。实测 10 张一次性并发会触发接口限流、返回错误并被迫重试。不要先抽样 curl 测试图片可达性,直接上传,失败按回退外链规则处理。
4. 生成标签
- 自动生成 3–6 个简洁标签,覆盖文章的具体主题、关键技术/实体和内容类型(例如
RAG、向量数据库、教程)。
- 标签必须:
- 优先从该分类数据库 schema 中 multi_select 的已有选项里复用同义标签,避免近义重复;
- 没有合适的已有选项时再新增;
- 不重复已选分类名;
- 不使用“文章”“剪藏”“阅读”等无信息量的通用词;
- 不编造正文未出现或无法合理推断的事实。
- 标签写入该行的
标签 属性(multi_select)。
5. 创建文章页面
-
fetch 选中分类数据库的 data source(若本次剪藏尚未 fetch 过其 schema),确认字段名和类型。
-
在该分类数据库下创建一行(一个页面)。properties 按实际 schema 映射:标题、URL/来源、标签、作者、发布日期、摘要。正文放入 content,不要塞进 rich_text 属性(正文较长时 rich_text 会截断)。
-
content 使用下列结构(Notion 不支持的格式用其最接近的块类型表达):
## 摘要
{用 2–4 句忠实概括文章核心观点、结论和适用范围;不得补充原文未支持的结论。}
## 正文
{清理后的文章正文,保留标题层级、列表、代码、表格、图片(已转存的用 file-upload:// 引用,外链的用原 URL)和必要链接。}
不要在 content 顶部重复写文章标题(标题已作为页面 title 属性存在)。
-
设置 allow_async: true,让创建操作异步执行,工具快速返回任务 ID。
-
不要擅自改变数据库 schema。若发现必需字段缺失,向用户说明并等待确认后才用 notion-update-data-source 增加字段。
6. 完成后反馈
完成创建后,简洁报告:
- 文章标题与来源;
- 选用的既有分类;
- 添加的标签;
- 已移除的噪声类型(例如“侧栏广告、推荐文章和订阅横幅”);
- 图片处理结果:成功转存 N 张、外链保留 M 张、跳过 K 张;
- 新建 Notion 页面的链接或页面 ID(异步创建时给出任务 ID,并提示用户页面正文可能需要几秒到几十秒才在 Notion 中可见)。
若失败,明确说明失败发生在获取、正文识别、图片转存、Notion 分类读取、去重或创建的哪个步骤,并给出下一步所需信息。不要声称已保存,除非插件返回了成功结果。