跳到正文
阿里雲開發者社區 AI·· 3 小時前AI 評分55

為每輪採集保留可回溯快照:路徑、清單與校驗

给每轮采集留一份可回溯快照:路径、清单与校验

AI 導讀

作者提出每輪採集完成後,以固定根目錄、manifest.json 和 checksums.sha256 保存可回溯快照。manifest.json 記錄 run_id、帶時區的起止時間、問法集版本、平台、回答與失敗條數等;快照分開保存 inputs 與 raw。校驗時核對 SHA-256 及 record_count 是否與 raw 行數一致,跨輪比對則先檢查問法集版本和平台清單。

正文

2026-10-30 6

版权

版权声明:

本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议》和 《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

简介: 本方案提出「可回溯快照」机制:每轮采集结束,必落三要素——固定根目录、含8项元数据(run_id、时区时间、问法集版本等)的manifest.json、全文件sha256校验清单。确保可复算、可比对、可恢复,解决数据库备份无法追溯输入与环境的痛点。(239字)

结论先说:每轮采集结束,落一次快照,三样东西缺一不可:固定根目录、manifest.json、校验和清单。manifest 写死 run_id、起止时间(带时区)、问法集版本、平台清单、落盘条数、失败条数,再加每个文件的 sha256。三样齐了,这一轮才能被复算、被比对、被恢复。

这里说的「可回溯快照」,指的是把一轮采集的输入、输出与校验信息按固定结构写到磁盘上的一份记录。它要回答的是「这一轮当时采了什么、用的哪版问法、数据有没有被改过」。

我这套采集库累计 10,324 条回答,带被引链接 921 条,去重在 144 个域名上。下面按五段写。

一、快照和备份不是一回事

我最早只做数据库备份,后来发现恢复出来是一批结果,却说不清用的是哪版问法、哪些平台、什么时间跑的。备份回答「能不能恢复」,快照回答「能不能复现」。

一轮采集由输入、输出、环境三块构成:输入是问法和目标,输出是回答和来源列表,环境是时间、版本与平台清单。输入与环境没落盘,就只能恢复结果,不能重放过程。

二、目录与命名:日期层加轮次层

我现在的目录按两层摆,日期在外,轮次在内。日期层做保留策略,轮次层用 UTC 时间戳。

snapshot/2026-10-29/run-20261029T0031Z/
manifest.json  checksums.sha256
inputs/  raw/  logs/

三条约定:manifest 放轮次根目录,脚本只认它;inputs 与 raw 分开,恢复时一眼分出哪一半是发出去的;raw 只写一次。

命名我踩过坑:最早用本地时间起目录名,换时区后两轮排序会颠倒;改成 UTC 就对了。

三、清单里要写哪些字段

我把 manifest 字段压到八个。

字段:必填 | 用途
run_id:是 | 全库不重名,等于轮次目录名
started_at / finished_at:是 | ISO 8601 带时区,成对出现
question_set_version:是 | 问法集一改,前后不可比
platforms:是 | 平台清单与统计口径同一份
record_count / failed_count:是 | 回答条数与失败条数分开记
file_checksums:是 | 文件名到 sha256 的映射
prev_run_id:否 | 把快照串成链

两个取舍我盯得紧。record_count 与 failed_count 必须分开,合成一个「总条数」,失败率永远算不准。file_checksums 只覆盖输入与原始输出:派生结果能重算,原始输出被改写就再也拿不回来。

四、校验:一条命令加三个判据

校验和清单一行一个文件,首列 sha256,次列相对路径。三个判据我依次过:校验和全通过;manifest 的 record_count 等于 raw 行数;prev_run_id 存在时比对两轮的问法集版本与平台清单,版本不同先别比数。

shasum -a 256 -c checksums.sha256

下面这段脚本我在本地用三文件快照跑过。

import hashlib, json, pathlib
r = pathlib.Path("snapshot/2026-10-29/run-20261029T0031Z")
m = json.loads((r / "manifest.json").read_text())
bad = [f for f, h in m["file_checksums"].items()
if hashlib.sha256((r / f).read_bytes()).hexdigest() != h]
rows = len((r / "raw/answers.jsonl").read_text().splitlines())
print(len(bad), rows, m["record_count"])

真实输出:

0 3 3

第一个数是校验和不符的文件数,后两个数一致即通过。

校验不通过就别入库,先挡住再查原因;先入库再补校验等于盖章。

五、保留策略与恢复比对

我按三层给保留策略定价。原始层是输入与原始输出,体量占大头,按轮保留,超窗归档并在 manifest 标路径。派生层是统计结果,体量小,长期留,丢了能重算。校验层是 manifest 与 checksums,几 KB,一直在。

量级:10,324 条回答里原始层是主体;带被引链接的 921 条是派生层重算要碰的子集;144 个域名是聚合结果,可以忽略。

恢复时我先取输入、配同一版问法集与平台清单、重放,再对结果。对不上先查问法集版本。比对两轮先比 manifest、比条数,最后才看回答内容;版本不同就是尺子变了,读数不能直接比。

六、五个能立刻做的事

第一步,跑完采集立刻写 manifest,不等第二天补。

第二步,生成 checksums.sha256 并在入库前校验一次。

第三步,记录 prev_run_id,把快照串成链。

第四步,删原始层前确认派生层已齐,再更新归档标记。

第五步,复算不一致时先查问法集版本与平台清单。

七、三个绕不开的反问

问:已经有数据库了,为什么还要落快照文件?
答:数据库存当前,快照存当时。 数据库会被覆盖、补采、清理;快照落盘后不再动。

问:校验和是不是太占空间?
答:校验层是三层里最小的。 一个文件一行 sha256,几 KB 量级,换来「数据有没有被改过」这个能直接回答的问题。

问:一轮只有几十条,值得这么重吗?
答:重的是流程,不是数据量。 条数越少,单条记录的解释成本越高;要跨轮比较,没有清单就只能靠时间范围猜。

八、边界

这套结构我承诺三件事:每轮有 manifest、每轮校验和可复核、每次比对先声明 run_id 与查询日。

数据源:团队自建的 AI 回答采集库,采集公开可访问的回答正文与来源列表。
查询日:2026-10-29(快照时刻 00:31)。
样本:累计 10,324 条回答;带被引链接 921 条;去重后 144 个域名。
口径:按轮次落盘,计数为落盘行数;失败与空回答单列;域名按站点主域名去重。
局限:单一采集库观察,非行业抽样;结构面向单库流程,跨库合并另加映射。

本文只写可复算的过程,不承诺任何采集结果与效果数值。

本文含 AI 辅助生成内容,经人工核实。

來源:阿里雲開發者社區 AI · developer.aliyun.com