arXiv ID 格式¶
当前内容契约更新:固定来源 PDF 已恢复为 paper_access 开关下的鉴权字节, 关闭404,qa_、别名、Range、历史原件不能绕过。新内容在独立 qatlas-content 桶的 content/ 命名空间不可变发布:source 绑定确切 PDF SHA,arXiv vN 是语义版本、 S3VersionId 是物理版本、parse revision 是独立不可变身份;三者不可混用。 同 paper/SHA 可复用 source;冻结导入别名不同字节409(overwrite也不替换)。 解析上传必须完整支持的 Middle+Markdown,保留所有成员原名/字节,MD-only拒收; manifest最后核验发布且PG必需,重传新revision,不覆盖历史。旧MD/JSON/images忽略, 只在内容/PDF访问按需冻结旧PDF,不bulk回填、不删除旧桶;没有nightly/boot/入库自动推理。 下文涉及旧三桶覆盖、仅full.md+images、原PDF410/外部直链的段落保留为历史背景, 不作为当前操作规则。当前API/上传/续读统一见论文内容契约 与Upload API;完整read视图不是原Middle JSON。
QuantumAtlas 以 arXiv ID 为论文的主键。文本侧支持两种 ID 格式 + 版本后缀;存 储侧把每条 ID 拆成「年月分片 / 子领域 / 文件 stem」三段做 sharding。本文档讲 完整规则,包括 2026-06 引入的按子领域分目录新布局以及背后的根因。
1. 两种格式¶
时代 |
格式 |
例子 |
|---|---|---|
老式(≤ 2007-03) |
|
|
新式(2007-04 起) |
|
|
注意 老式 ID 的 category 含斜杠,所以会出现在 URL path 里。server 端
splitPapersPath 按"最后一段"匹配 action / arxiv_id 切分能正确处理。
1.1 老式 category 词表¶
支持的 category 形态(按 internal/paperassets::oldStyleCategoryRE 实现的语法):
形态 |
例子 |
说明 |
|---|---|---|
无子分类 |
|
主题字段为 lower-case,可含 |
大写 2 字母子分类 |
|
子字段 |
小写连字符子分类 |
|
子字段 |
A1 之前的正则只覆盖前两种,碰到
physics.atom-ph/0001001v1这类直接 reject。 现在统一收下。
2. 版本后缀 vN¶
任何 arXiv 论文都可以有多个版本(v1、v2、...)。
入口 |
是否要求 |
|---|---|
|
可不带;server 取 arXiv 当前最新版 |
|
必填;对象寻址按 |
|
必填 |
|
可不带;server 优先查本地 catalog 补最新版本,未收录才抓 arxiv.org(多版本时在响应里显式标) |
|
鉴权固定来源PDF字节,source_id或语义version互斥,开关禁用404、Range同样鉴权;不需解析token |
论文详情 GET /api/papers/{id} 与各资产端点还接受 qa_ paper_id(服务端
解析成该论文的 canonical 身份,取最高已收录的 arXiv 版本;DOI-only 论文走 DOI
管线)。
3. 对象寻址映射(post-A1 layout)¶
server 把 ID 拆成 <YYMM-shard>/<可选 category>/<stem>.<ext>:
arxiv_id |
object key(PDF) |
说明 |
|---|---|---|
|
|
新式扁平 |
|
|
新式扁平 |
|
|
老式带子目录 |
|
|
老式带子目录 |
|
|
含子分类的老式 |
md/ / json/ / images/ 子目录采用同样的三段布局(kind + shard + 可选
category + stem)。完整规则在 internal/paperassets/path.go::AssetKeyFor。
<YYMM> 跟 arxiv.org bulk-data 目录约定 一致。
带 category 子目录是 QuantumAtlas 在 A1(2026-06)后引入的额外维度,bulk-data 上游
没有这一层 —— 我们引入它是为了避免下一节描述的跨子领域冲突。
3.1 为什么老式 ID 要保留 category 子目录¶
老式 7-digit number 不是全局唯一的,只在 category 内唯一。同一个 YYMMnnn
在不同 category 下对应完全不同的论文:
arxiv URL |
标题 |
|---|---|
|
Relation between classical communication capacity and entanglement capability for two-qubit unitary operations |
|
Does curvature-dilaton coupling with Kalb Ramond field lead to an accelerating Universe? |
|
A duality proof of Tchakaloff's theorem |
|
Gravitomagnetic effects |
剥掉 category 后写到同一个 bucket key(pdf/0207/0207065v1.pdf)= silent
overwrite。A1 之前确实是这么存的;当前生产之所以没踩,纯粹是因为 OpenAlex
bootstrap 加了 quant-only filter。一旦扩到 hep-th / cond-mat 等任意第二个子领域,
立刻冲突。
A1 的 pdf/<yymm>/<category>/<stem>.<ext> 子目录布局从结构上彻底排除这种冲突。
3.2 新旧布局对照¶
arxiv_id |
A1 之前(legacy) |
A1 之后(new) |
|---|---|---|
|
|
|
|
|
|
|
|
|
新式 ID 的 layout 不变(数字本来就全局唯一)。仅老式有变更。
3.3 Dual-read 过渡期¶
A1 后立刻部署 server 不会 break 已有数据:
读路径 (
paperassets.LocateAsset/LocateAssetByID) 先查新 layout,未命中 时对老式 canonical ID 回退查 legacy bare key写路径 (
AssetKey/AssetKeyFor) 总是写新 layout,不写 legacy
也就是说:
老对象(pre-A1,bare layout)→ 通过 fallback 仍可读
新写入(post-A1)→ 都进 per-category 子目录
migration 把 legacy 对象
mc cp到新位置(manifest-based,三阶段;plan §4 Phase E)→ 同步更新 catalog 主键一个 release 后移除 dual-read fallback 路径
dual-read 命中由 paperassets.LegacyLayoutReads() 计数,运维可观测 migration 进度。
4. kind 后缀¶
每篇论文除了 PDF 还可能有:
kind |
key 模板(新式) |
key 模板(老式 canonical) |
内容 |
|---|---|---|---|
|
|
|
原始 PDF |
|
|
|
MinerU 解析的 markdown |
|
|
|
arXiv 元数据(题目 / 作者 / abstract) |
|
|
|
MinerU 解析出的图片 zip |
qatlas contrib pdf --pdf 把 PDF 字节落到 pdf/。论文元数据(题目 / 作者 /
摘要 / 引用)走 OpenAlex 上游同步进 PostgreSQL paper registry,不再通过 upload 端点写
json/(v0.7.0 起;该前缀仅保留兼容历史对象的读路径)。
5. 规范化与结构化解析¶
internal/paperassets 提供两层 API:
轻量 helpers(保留兼容历史调用方):
NormalizeIdentifier(s)— 去空白 + 剥arXiv:前缀StripVersion(s)— 去掉尾部vNSafeKey(s)— 把/换成__给老式磁盘 fallback 用
结构化解析(新代码优先用):
Parse(s) (ParsedArxivID, error)— 拆成 Category / Stem / StemBase / Version / YYMM 等字段MustParse(s)— 测试常量用,invalid 输入直接 panicAssetKeyFor(kind, p)— 给ParsedArxivID渲染对象 keyLegacyAssetKeyFor(kind, p)— 给 dual-read fallback 用的 pre-A1 keyLocateAsset(ctx, store, kind, p)— 一站式 read 接口:自动新 layout 优先 + legacy fallback
老式 bare ID(9508027v1,无 category)由 Parse 标记 IsBare=true,调用方决
定怎么处理:
upload 入口 (
ValidateUploadID):当前仍兼容接受 bare(issue #4 缓解)storage 入口 (
AssetKeyFor):bare 输入回退到 legacy layoutpdf/<yymm>/<stem>.<ext>未来(plan §H3 / issue #12):catalog migration 完成后
ValidateUploadID拒 bare,由上层 resolver 反查 registry 拿到 category 再调用
6. 常见坑¶
upload 时漏掉 v1
qatlas contrib pdf 2501.00010 --pdf paper.pdf
server 返回 400 arxiv_id must include version suffix。改成 2501.00010v1。
用了 arxiv.org/abs/... 完整 URL
server 只接受 ID 部分。从 URL https://arxiv.org/abs/2501.00010 抽出
2501.00010 就行。
老式带版本是合法的
quant-ph/9508027v1(含斜杠 + 版本)—— 是合法的,正常工作。
老式 bare 形态(9508027v1,无 category)当前仍接受但有歧义
由 issue #4
历史原因,server ValidateUploadID 仍兼容裸形态。但裸 7-digit 号在不同子
领域下指向不同论文(见 §3.1);当前仅靠"catalog 只有 quant-ph"这个事
实保证不冲突。新代码 / 客户端建议永远带 category 前缀调用。
issue #12 跟踪
最终拒绝裸形态的工作。
DOI 入口同一个端点
GET /api/papers/{id_or_doi}/markdown 自动 detect DOI(^10\.\d{4,9}/),
经 OpenAlex 反查成 arxiv_id 后走同一套 handler。详见 REST API · DOI 寻址。