Appearance
无官方 API 数据源的增量镜像:断点续传、resume 去重、删除传播
第二部 · Agent 实践 · 第33章
撰写日期:2026-07-13
结论
把多个数据源(文档库、AI 会话记录、第三方平台)镜像成一个可增量更新的语料库时,真正的坑不在"抓一次",在"持续对账"和"那个没有 API 的源"。
镜像不是一次性快照,是持续对账的活体副本。能 cron 无人值守的源和必须人工点一次的源,要用不同策略——混为一谈,整条管线会卡在最脆弱的那个环节。
1. 可 cron 与不可 cron:先分层
| 源类型 | 例子 | 同步策略 |
|---|---|---|
| 本机数据 | 本地日志、会话文件 | 定时无人值守抓取 |
| 有开放 API | 文档库、代码托管 | 定时增量拉取 |
| 有风控、无官方 API | 带 Cloudflare 校验 + 429 限流的第三方 | 放弃无人值守,改半自动(见 §2) |
硬把不可 cron 的源塞进无人值守管线,只会让它天天失败、拖垮整条流水线的可信度。
2. 无 API 源:书签断点续传 + 落盘后并入
服务端反爬针对的是无人值守的机器流量。绕法不是更凶地抓,是借用户已登录的浏览器会话、以人类节奏慢速拉:
- 用运行在浏览器会话内的书签脚本(bookmarklet)触发导出;
- 抓到的内容写进抗刷新的持久存储——IndexedDB 优于 localStorage(后者约 5MB 配额会先爆);
- 维护一个已完成 id 的跳过集,每次重启只补真正缺失的项,别把额度浪费在已抓项上(并发互抢额度反而更容易触发 429);
- 对 429 做退避;浏览器多文件下载被静默拦截时,用"新标签页首次下载放行"绕过。
产物落到固定目录后,由主管线增量去重并入。把"必须人工点一次"当成显式设计约束,而不是缺陷——承认无 API,就承认了"每周点一次书签 + 落盘后自动接手"才是这个源的可靠形态,硬追全自动是徒劳。
3. 增量镜像的三要素
镜像的正确性,取决于三件容易被忽略的小事:
| 要素 | 不做会怎样 |
|---|---|
| 断点续传 | 风控触发的页面重载会清空内存态,无持久化则每次重载前功尽弃 |
| resume 去重 | 同一逻辑会话多次续写会落多份日志,不去重会让下游统计(如"高频观点")被同一段话重复加权、扭曲结果 |
| 删除传播 | 源端删了镜像不删,会让系统引用到已被本人否定 / 删除的旧内容,破坏可信度 |
镜像层的删除语义是"跟随源头"——源删镜像删,历史留给版本控制。(这与团队记忆层刻意不同:记忆层的删除不自动跟随,见 Team Memory 系统设计 第 4 节。)
4. 镜像不到的,要留显式跳过清单
总有源镜像不了(无开放 API 的笔记类型、根目录不可枚举只能硬编码入口等)。这些不能默默跳过,要维护一份显式的跳过清单:让"这部分没镜像"变成可见的事实,而不是让人误以为语料库已经全了。可观测的缺失,比看不见的缺失安全得多。
我的判断
镜像系统的难点从来不是"抓取",是"对账 + 诚实":对账靠断点续传 / 去重 / 删除传播三要素,诚实靠给不可 cron 的源和镜像不了的源都留下显式的标记。把哪些源能自动、哪些必须人工、哪些干脆没镜像都摆在明处,这套语料库才敢被下游信任。