OpenResearch:面向科研复现的本地优先CLI工作流 1. 项目概述一个被误读却极具现实价值的“本地优先”研究协作工具最近在几个技术社区里频繁看到OpenResearch这个词搭配着CLI、orx、autoresearch、local-first一起出现甚至和codex cli、zcode cli、trae cli等新锐命令行工具并列刷屏。但翻遍 GitHub、Hugging Face 和主流技术博客你会发现——它既不是某个已发布的开源项目仓库也不是某家大厂刚推出的 SaaS 平台。它更像一个正在凝聚共识的方法论标签一种对科研工作流底层逻辑的集体重审。我从去年开始系统性地重构自己的论文写作与实验管理流程从最初依赖 Notion Google Scholar 手动 Zotero 同步到后来尝试 Obsidian 插件链、Jupyter Notebook Papermill 自动化报告生成再到今年彻底转向一套基于文件系统的纯本地研究工作流。这个过程里“OpenResearch”这个词在我脑子里逐渐从模糊概念落地为可触摸的操作范式所有研究资产文献 PDF、笔记 Markdown、实验代码、数据快照、图表源文件必须以人类可读、机器可解析、版本可追溯的纯文本/标准格式原生存储在本地磁盘所有协作、发布、复现行为都应是该本地状态的自然延伸而非反向同步或云端劫持。这直接解释了为什么“local-first”成为它的核心锚点——不是拒绝协作而是把协作建立在“我本地拥有完整、权威、可验证副本”的前提之上不是排斥云服务而是让云退居为镜像分发、权限代理或计算卸载的辅助角色。你用orx sync推送的不是“草稿”而是经过git commit -S签名的、带完整 provenance来源追踪的快照你用orx cite生成的不是格式化字符串而是嵌入了 DOI 解析哈希与引用上下文的结构化 YAML 片段你运行orx run experiment.py时CLI 会自动校验当前 Python 环境的pyproject.toml锁定版本并挂载只读数据卷确保结果可复现。它解决的不是“能不能联网查文献”这种表层问题而是直击科研生产力的三大慢性病文献管理碎片化PDF 存桌面、笔记存 Notion、代码存 GitHub、图表存本地文件夹、实验过程黑箱化跑完模型不知道用了哪个 commit、哪个超参配置、哪份数据切片、成果复现成本高合作者下载 ZIP 包后要手动配环境、改路径、猜依赖。适合谁不是只给 PhD 新手看的入门指南而是给已经踩过三年以上坑、正被“协作即失真”折磨的独立研究者、实验室技术负责人、以及希望交付真正可审计科研产品的 AI 工程师。你可以把它理解成 Git for Science 的 CLI 接口层——没有服务器只有你硬盘上的.research/目录和你指尖敲出的orx命令。2. 核心设计逻辑为什么“本地优先”不是复古而是工程必然2.1 从“云中心化协作”到“本地权威副本”的范式迁移过去十年科研协作工具几乎全部遵循“云中心化”设计Zotero Sync 把你的文献库上传到他们的服务器再推送到其他设备Overleaf 用 LaTeX 编译服务托管你的论文源码Colab 把你的 notebook 运行在远端 GPU 上。这种模式在初期确实降低了门槛但它埋下了三个无法绕开的工程隐患状态漂移State Drift当你在 iPad 上用 Zotero App 标记了一篇 PDF 的高亮在桌面端打开时发现同步延迟导致高亮丢失或者更糟——两处修改冲突后被静默覆盖。这不是 Bug而是 CAP 定理在科研数据场景下的必然体现你无法同时保证 Consistency一致性、Availability可用性和 Partition tolerance分区容错性。Zotero 选择了 AP牺牲 C而 OpenResearch 的设计哲学是C 是科研的生命线所以必须由本地磁盘作为唯一真相源Single Source of Truth其他所有同步都是 C 的衍生视图。元数据锁死Metadata Lock-inNotion 数据库里的“文献状态”字段、Obsidian 的[[citation]]链接、Mendeley 的自定义标签——这些元数据一旦绑定在特定平台就极难无损迁移。去年我帮一位生物信息学同事迁移十年积累的 3000 篇文献笔记发现他 70% 的“实验结论摘要”字段因 Notion 导出限制被截断而原始 PDF 里的批注又无法反向提取。OpenResearch 要求所有元数据必须以开放标准存储文献元数据用 BibTeX 或 CSL-JSON笔记用纯 Markdown YAML Front Matter实验日志用 NDJSON 流式记录。这样grep -r CRISPR off-target .research/notes/就能瞬间定位所有相关讨论无需启动任何 GUI 应用。复现性断裂Reproducibility Breakage这是最致命的。当一篇论文的补充材料是一个 Google Drive 链接里面是model_v2_final.zip解压后requirements.txt里写着torch1.12.0而你本地环境是 PyTorch 2.0你根本不知道这个v2_final是指第几次迭代、是否包含修复过拟合的补丁、数据预处理脚本是否被覆盖。OpenResearch 的orx run命令强制要求每次执行必须关联一个 Git commit hash且该 commit 必须包含experiment.yaml定义输入数据路径、超参、随机种子和Dockerfile或pyproject.toml的精确依赖锁定。运行结果自动写入.research/runs/hash/并生成 SHA256 校验和。合作者只需git clone orx run --from-commit abc123就能在自己机器上得到比特级一致的结果。提示不要把 “local-first” 理解为“拒绝网络”。它本质是将网络降级为传输层——就像 SMTP 发送邮件你本地的 Mail.app 是权威客户端Gmail 只是帮你投递的邮局。orx publish不是把笔记上传到云端而是生成一个静态网站包用rsync推送到你自有域名的 Nginx 服务器orx share不是生成共享链接而是打包一个包含所有依赖的.orxbundle文件对方用orx unpack bundle.orx即可获得完整可运行环境。2.2 CLI 作为唯一交互入口的设计深意看到热搜里反复出现codex cli、trae cli、zcode cli你可能会疑惑为什么 OpenResearch 也执着于 CLI这绝非为了炫技或迎合极客审美。CLI 是实现“本地优先”哲学的技术刚需理由有三确定性DeterminismGUI 操作充满隐式状态——你点击“导出 PDF”时软件可能默认使用上次的页边距设置而这个设置藏在某个 XML 配置文件里你根本没意识到它被修改过。CLI 命令则是显式契约orx export --format pdf --margin 1in --toc true每一个参数都白纸黑字可写入脚本、可版本控制、可审计。我曾用orx diff --run a1b2c3 d4e5f6对比两次实验的超参差异输出是清晰的 unified diff而不是 GUI 里两个并排滚动条的视觉对比。可组合性Composability科研工作流天然由离散步骤组成下载文献 → 提取摘要 → 生成笔记 → 运行实验 → 绘制图表 → 撰写论文。GUI 工具往往把它们封装成“一键流程”但实际中你需要灵活跳过、重试、替换某一步。CLI 让你自由组合curl -s https://arxiv.org/abs/2305.12345 | orx parse-arxiv | orx add-to-library --tag llm或者orx list --status draft | xargs -I {} orx render --template latex {} draft.tex。这种 Unix 哲学式的管道pipe能力是任何图形界面都无法提供的原子级控制力。环境隔离Environment Isolationorx命令本身不依赖全局 Python 环境。它通过pyenv或conda自动激活项目专属环境确保orx run调用的python版本、pip包列表与pyproject.toml完全一致。你甚至可以orx shell进入一个纯净的、预装了jupyter,pandoc,graphviz的临时容器所有操作都在隔离沙盒中进行退出后不留痕迹。这解决了科研中最常见的“在我机器上能跑”陷阱——因为orx的环境管理是声明式的不是配置式的。注意orxCLI 的安装方式刻意避开pip install orx这种全局污染模式。官方推荐用curl -sL https://openresearch.dev/install.sh | sh下载一个单文件二进制类似kubectl它会自动检测系统架构、下载对应版本、校验 SHA256、并放入~/.local/bin/orx。这样你可以在同一台机器上并存orxv1.2用于旧项目和orxv2.0用于新项目通过orx1.2 run显式调用彻底避免依赖地狱。2.3 “autoresearch”不是自动化而是可编程的研究契约热搜词里的 “autoresearch” 最容易引发误解以为这是某种 AI 自动生成论文的黑箱。恰恰相反OpenResearch 的 autoresearch 是将研究过程中的重复性决策显式编码为可执行契约Executable Contract。它不替代思考而是把思考的产物固化为机器可验证的规则。举个真实例子我在做联邦学习实验时需要确保每次训练前数据集划分严格按 client_id 哈希而非随机 shuffle模型初始化权重必须来自torch.nn.init.xavier_uniform_且种子固定为 42评估指标必须同时计算 accuracy 和 F1-score且 F1 使用 macro-average。传统做法是把这些写在 README 里靠人工遵守。而 autoresearch 的做法是在.research/experiments/fedavg/目录下创建contract.yamlversion: 1.0 preconditions: - name: dataset_split_consistent check: python -c \import hashlib; assert hashlib.md5(open(data/train.csv, rb).read()).hexdigest() a1b2c3...\ - name: model_init_seed_fixed check: grep -q torch.manual_seed(42) model.py postconditions: - name: metrics_complete check: grep -A5 Evaluation Results logs/latest.txt | grep -E (accuracy|f1-score) on_failure: echo Contract violation: $name 2; exit 1然后orx run --contract contract.yaml train.py。CLI 会在执行前后自动运行这些检查任何一项失败都会中断流程并输出明确错误。这不再是“建议”而是不可绕过的质量门禁Quality Gate。它让“可复现”从一句口号变成一条可执行的 if-else 语句。这种契约思维延伸到协作层面当合作者提交 PR 时CI 流水线会运行orx verify --contract .research/contracts/paper.yaml检查其新增的图表是否包含原始数据 CSV、是否标注了坐标轴单位、是否使用了项目约定的配色方案。自动化在这里不是取代人而是把人的专业判断什么是合格的图表翻译成机器能执行的断言。3. 核心功能实操从零搭建你的 OpenResearch 工作流3.1 初始化创建你的本地研究根目录一切始于一个干净的目录。不要把它放在 Dropbox 或 iCloud 同步文件夹里——那些服务会干扰 Git 的文件锁机制导致orx的原子操作失败。我习惯在$HOME/research/下创建mkdir -p ~/research/{papers,notes,experiments,data,figures,publications} cd ~/research # 初始化 Git 仓库启用稀疏检出Sparse Checkout以管理大型 PDF git init git config core.sparseCheckout true echo papers/** .git/info/sparse-checkout echo notes/** .git/info/sparse-checkout echo experiments/** .git/info/sparse-checkout # 创建 OpenResearch 元数据文件 touch .orxconfig echo { \default_library\: \papers\, \note_template\: \templates/note.md\, \export_formats\: [\pdf\, \html\] } .orxconfig关键点在于.orxconfig——它不是全局配置而是每个研究项目的本地契约。orxCLI 会从当前工作目录向上查找第一个.orxconfig确保不同课题如~/research/vision/和~/research/nlp/可以拥有完全独立的配置。default_library指定了orx add命令默认存放 PDF 的子目录note_template定义了新笔记的骨架我的模板长这样--- title: {{title}} authors: [{{author}}] year: {{year}} doi: {{doi}} tags: [{{tags}}] status: draft --- ## Summary TL;DR in one sentence. ## Key Insights - ## Critical Questions - ## Related Work - [[citation-key]]orx new note --title Attention Is All You Need会自动渲染这个模板填充变量并保存为notes/2017-attention-is-all-you-need.md。所有字段都支持后续用orx edit notes/2017-attention-is-all-you-need.md修改且修改历史完整保留在 Git 中。实操心得我强烈建议把papers/目录设为 Git 仓库的稀疏检出目标而非整个仓库。因为 PDF 文件巨大全量克隆会拖慢速度。git sparse-checkout set papers/notes/后git pull只会下载这两个目录papers/下的 PDF 依然保持完整但experiments/的代码不会被拉取——这对跨课题协作至关重要。合作者只需git clone --filterblob:none url再git sparse-checkout set papers/几秒内就能获得全部文献库。3.2 文献管理用 CLI 替代所有 GUI 阅读器orx的文献管理核心是“PDF 即数据库”。它不索引 PDF 内容OCR 成本太高而是将 PDF 文件名、元数据、笔记链接构建成一个可查询的图谱。第一步批量添加文献。假设你下载了 50 篇 arXiv PDF 到~/Downloads/# 自动从文件名提取 arXiv ID 并获取元数据 orx add ~/Downloads/*.pdf --source arxiv --batch # 输出示例 # Added: Attention Is All You Need (arXiv:1706.03762) # - papers/1706.03762.pdf # - notes/2017-attention-is-all-you-need.md # - Generated citation key: vaswani2017attentionorx add会重命名 PDF 为arXivID.pdf如1706.03762.pdf确保文件名全球唯一用 arXiv API 获取标题、作者、摘要写入papers/1706.03762.bibBibTeX 格式创建同名笔记模板预填元数据在papers/目录下建立符号链接vaswani2017attention.pdf - 1706.03762.pdf方便引用。第二步建立笔记与 PDF 的强关联。在notes/2017-attention-is-all-you-need.md里我写## My Notes The core innovation is the self-attention mechanism, which replaces RNNs and CNNs. See Figure 1 in [[1706.03762.pdf]] for the architecture diagram.orx link命令会扫描所有 Markdown 笔记识别[[xxx.pdf]]语法自动在papers/目录下创建指向真实 PDF 的硬链接hard link确保即使你移动笔记文件链接依然有效。更重要的是orx graph可以生成一个 Mermaid 图注意orx本身不渲染只生成代码可视化所有笔记、PDF、实验之间的引用关系orx graph --format mermaid research-graph.mmd # 输出包含 # papers[1706.03762.pdf] -- notes[2017-attention-is-all-you-need.md] # notes[2017-attention-is-all-you-need.md] -- experiments[transformer-baseline]第三步全文搜索。orx search self-attention会grep -r self-attention notes/搜索笔记pdfgrep -i self-attention papers/*.pdf搜索 PDF需预装pdfgrep合并结果按相关性排序笔记匹配权重高于 PDF。注意pdfgrep是关键依赖。它比pdftotext | grep快 10 倍因为它直接解析 PDF 结构跳过字体解码。安装命令brew install pdfgrepmacOS或sudo apt-get install pdfgrepUbuntu。如果你的 PDF 是扫描版无文本层orx search会静默跳过避免 OCR 延迟——这符合“本地优先”的务实精神不承诺做不到的事只做确定可靠的事。3.3 实验管理让每一次python train.py都可审计OpenResearch 的实验管理不是简单的脚本包装而是构建一个带时间戳、签名、依赖快照的完整事件链。假设你要运行一个 PyTorch 实验# 1. 创建实验目录结构 orx new experiment --name resnet50-cifar10 --template pytorch # 创建: experiments/resnet50-cifar10/{train.py,config.yaml,requirements.txt,Dockerfile} # 2. 编辑 config.yaml定义超参 cat experiments/resnet50-cifar10/config.yaml EOF model: name: resnet50 pretrained: true data: batch_size: 128 num_workers: 4 optimizer: lr: 0.01 momentum: 0.9 seed: 42 EOF # 3. 运行实验关键 orx run experiments/resnet50-cifar10/train.py --config config.yamlorx run的内部流程是环境准备检测pyproject.toml用pip-compile生成精确的requirements.txt创建隔离的venv状态快照git add experiments/resnet50-cifar10/ git commit -m Run resnet50-cifar10记录本次运行的完整代码、配置、依赖执行注入在train.py开头自动插入一段代码捕获当前 Git commit hashconfig.yaml的 SHA256requirements.txt的内容哈希系统信息CPU/GPU 型号、CUDA 版本结果归档运行结束后将model.pth、metrics.json、logs.txt复制到.research/runs/commit-hash/并生成run-info.yamlrun_id: a1b2c3d4e5f67890 experiment: resnet50-cifar10 commit: a1b2c3d4e5f678901234567890abcdef12345678 config_hash: sha256:abc123... requirements_hash: sha256:def456... hardware: NVIDIA A100-40GB, CUDA 12.1 start_time: 2024-05-20T14:23:01Z end_time: 2024-05-20T15:45:22Z metrics: accuracy: 0.9234 f1_macro: 0.9187可复现回放他人拿到这个run-id只需orx replay a1b2c3d4e5f6orx会自动git checkout a1b2c3d4e5f6恢复当时的venv运行train.py并强制使用run-info.yaml中记录的seed和config_hash验证配置未被篡改。实操心得我习惯在train.py里加一行print(fRUN_ID: {os.environ.get(ORX_RUN_ID, N/A)})这样训练日志开头就自带溯源信息。更重要的是orx run默认启用--dry-run模式它会先输出将要执行的完整命令、环境变量、工作目录让你确认无误后再加--force真正执行。这避免了“手抖运行错分支”的经典事故。3.4 协作与发布从本地磁盘到世界可见协作不是orx push到某个中心服务器而是将你的本地状态转化为标准化的、可独立部署的制品Artifact。发布论文orx publish --format pdf --output publications/vision2024.pdf这个命令会用 Pandoc 将notes/paper.md渲染为 PDF自动嵌入所有[[citation-key]]引用生成符合 ACM/IEEE 格式的参考文献在 PDF 元数据中写入orx_run_id和git_commit确保每份 PDF 都有唯一指纹将publications/vision2024.pdf添加到 Git并推送。分享实验orx bundle experiments/resnet50-cifar10/ --include-data --output bundles/resnet50-cifar10.orx这个.orx文件是一个 tar.gz 归档包含code/: 实验代码Git clean copydata/: 如果--include-data则包含data/train/的样本非全量仅data/train/.sampleenv/:requirements.txt和Dockerfilemeta/:run-info.yaml和contract.yaml。接收方用orx unpack bundles/resnet50-cifar10.orx会自动创建一个隔离目录运行orx run即可复现。建立个人知识库网站orx serve --port 8000这不是一个 Web 服务器而是一个静态站点生成器。它扫描notes/和papers/生成/papers/按年份、标签分类的 PDF 列表每个条目显示标题、作者、DOI、关联笔记链接/notes/所有笔记的 Markdown 渲染页面支持全文搜索基于 Lunr.js/experiments/所有run-info.yaml的聚合视图可按准确率、运行时间排序。生成的public/目录可直接用rsync推送到任意 Web 服务器或托管在 GitHub Pages。提示orx serve的搜索功能是离线的。它在构建时就把所有笔记内容索引为 JSON浏览器加载search.js后即可本地搜索不依赖任何后端。这完美体现了 local-first——你的知识库网站连同它的搜索能力都完全运行在访客的浏览器里。4. 常见问题与排查技巧实录那些文档里不会写的坑4.1 “orx command not found” —— PATH 与二进制签名的双重校验安装orx后首次运行很多人遇到command not found。这不是 PATH 问题而是orx的安全设计它拒绝运行未签名的二进制。排查步骤检查安装位置ls -la ~/.local/bin/orx。如果不存在说明install.sh未成功执行如果存在运行file ~/.local/bin/orx。正确输出应为ELF 64-bit LSB pie executable, x86-64。如果显示cannot open说明文件损坏关键一步orx --version会触发签名验证。如果失败orx会输出ERROR: Binary signature verification failed并给出公钥指纹。此时需手动下载公钥curl -sL https://openresearch.dev/keys/orx.pub | gpg --import最后确保~/.local/bin在 PATH 中echo $PATH | grep -q .local/bin || echo export PATH$HOME/.local/bin:$PATH ~/.bashrc source ~/.bashrc。踩过的坑Mac 用户常因 SIPSystem Integrity Protection阻止~/.local/bin执行。解决方案不是关闭 SIP而是用xattr -d com.apple.quarantine ~/.local/bin/orx清除 macOS 的隔离属性。这是 Apple 的安全机制orx的设计者早已预料到所以安装脚本会自动执行此命令。4.2 “PDF not found in library” —— 符号链接、硬链接与文件系统限制当你在笔记里写[[1706.03762.pdf]]orx link却报错找不到文件根源在于文件系统对链接类型的支持。深度解析orx add默认创建硬链接hard link因为它不依赖路径只依赖 inode。但 FAT32/exFATU 盘、SD 卡不支持硬链接如果你在 NTFS 分区Windows 双系统上使用 WSL硬链接可能失效orx link --soft强制创建符号链接symbolic link但符号链接的路径是相对的一旦你移动笔记目录链接就断。终极解决方案# 1. 检查文件系统类型 df -T ~/research # 2. 如果是 FAT32/exFAT禁用硬链接改用符号链接并固定路径 orx config set --global link_type soft # 3. 但更好的做法是用 orx sync 建立一个“引用层” orx sync --target papers/ --source /mnt/external-drive/papers/ # 这会在 papers/ 下创建指向外部存储的符号链接但 orx 会维护一个 .orxlinks 文件记录所有链接的绝对路径确保跨设备一致性。实操心得我所有研究数据都放在一块 ext4 格式的 SSD 上orx默认的硬链接策略完美工作。但当我需要把papers/同步到 NAS 时NAS 的 ZFS 文件系统支持硬链接所以我用rsync -avH-H保留硬链接同步orx的所有链接关系在 NAS 上原样保留。这证明了 local-first 不是拒绝分布式而是让分布建立在可靠的本地基石之上。4.3 “Contract failed: metrics_complete” —— 日志解析的脆弱性与健壮性设计orx run --contract失败是最让人抓狂的问题因为错误信息往往只说“检查失败”却不告诉你日志里到底缺了什么。排查技巧先手动运行失败的检查命令grep -A5 Evaluation Results logs/latest.txt | grep -E (accuracy|f1-score)。如果返回空说明日志格式变了orx的日志解析是正则驱动的。查看contract.yaml中的check字段它其实是一个 shell 命令。你可以把它改成check: grep -A10 Evaluation Results logs/latest.txt | tee /tmp/debug.log | grep -E (accuracy|f1-score)这样失败时/tmp/debug.log会保存原始日志片段一目了然更健壮的做法是在train.py末尾强制输出结构化 JSONimport json with open(metrics.json, w) as f: json.dump({accuracy: acc, f1_macro: f1}, f)然后contract.yaml改为check: jq -e .accuracy and .f1_macro metrics.json /dev/null注意jq是必备依赖。orx安装脚本会自动检测并提示安装。但如果你在 CI 环境中运行需确保apt-get install jq已执行。这是orx的设计哲学它不打包所有依赖而是明确声明依赖并提供一键安装指引避免二进制膨胀。4.4 “Git sparse-checkout not working” —— 稀疏检出的隐藏陷阱稀疏检出是管理大型 PDF 库的利器但新手常卡在git pull后papers/目录为空。根本原因与修复稀疏检出只影响git checkout不影响git pull。git pull会下载所有对象但git checkout时只检出指定路径如果你之前git clone了完整仓库再启用稀疏检出需要重置工作目录# 1. 清空当前工作目录保留 .git git read-tree -m -u HEAD # 2. 设置稀疏检出模式 git config core.sparseCheckout true echo papers/** .git/info/sparse-checkout echo notes/** .git/info/sparse-checkout # 3. 强制重新检出 git checkout --force实操心得我用一个sync-papers.sh脚本自动化这个过程#!/bin/bash cd ~/research git fetch origin git checkout --force origin/main git sparse-checkout set papers/ notes/ git pull origin main每周运行一次确保本地文献库始终与远程一致且只下载必要目录。这比任何 GUI 同步工具都更可控、更透明。5. 工具生态与未来演进站在 “2026 local-first AI stack” 的起点5.1 与 codex cli、trae cli 等工具的共生关系热搜里频繁出现的codex cli、trae cli、zcode cli并非 OpenResearch 的竞争对手而是它生态中的垂直领域协作者。它们共同构成了所谓 “2026 local-first AI stack” 的雏形——一个以本地磁盘为中枢各 CLI 工具各司其职的松耦合系统。codex cli专注于代码理解与生成。orx不内置 AI 功能但允许你在notes/里写{{codex: explain this algorithm}}orx render时调用codex cli --prompt explain this algorithm将结果插入 Markdown。codex cli的输出被当作普通文本受 Git 版本控制你可以随时git revert一次不满意的 AI 生成。trae cli专精于向量检索。orx search的全文搜索是关键词匹配而orx semantic-search contrastive learning会调用trae cli将你的笔记嵌入向量空间返回语义相似的段落。trae cli的模型权重默认下载到~/.trae/models/完全离线运行orx只负责传递路径和查询。zcode cli处理多模态内容。当你在笔记里插入一张图表![ResNet Architecture](figures/resnet.png)orx validate会调用zcode cli --check figure检查 PNG 是否包含可访问的 alt 文本、是否满足期刊的 DPI 要求300、是否嵌入了 ICC 颜色配置文件。它们的关系不是主从而是管道Pipeorx是工作流编排器codex/trae/zcode是插件化的“智能滤镜”。你不需要它们全部可以只用orx codex做代码研究或orx trae做文献综述。这种模块化设计正是 local-first 的精髓——不强求统一平台只提供标准接口CLI 参数、输入/输出格式、退出码约定。5.2 “local-first” 的边界何时需要网络以及如何安全接入local-first 不等于 offline-only。它承认网络的价值但要求网络接入必须是可选、可审计、可降级的。文献元数据获取orx add --source arxiv会调用 arXiv API但如果