OpenResearch 是我发起的一个开放研究协作项目。说得直白一点,就是把我做研究的过程——从选题、查资料、跑数据,到写稿、改稿、评审——全部以开源项目的形态管理起来。这里没有“论文出来但数据只能看摘要”的黑箱,研究中的每一条假设、每一次尝试、每一份分析脚本都放在明面上,其他人可以查看、评论、甚至直接改。如果你也受够了论文结果复现不出来,受够了合作时邮件来回传文档,受够了把自己关在小黑屋里憋论文,那 OpenResearch 的工作方式或许能给你一个新的抓手。这套东西不只适合学术圈的人,产品同学做竞品调研、咨询顾问做行业分析、独立开发者做技术选型评估,也完全可以用同一套逻辑把过程沉淀下来。
下面我会拆解这个项目的设计思路、核心规则、实操流程,以及踩过的坑,方便你照着搭一套属于自己的开放研究体系。
1. 项目定位与整体设计思路
1.1 开放研究的核心痛点
我最初想搭 OpenResearch,是因为发现传统研究流程有一个很别扭的地方:所有人都只关注最终交付物,论文也好、报告也罢,过程几乎完全不可见。可偏偏研究里最容易出问题的地方,恰恰是过程——数据是怎么清洗的、缺失值是怎么处理的、回归模型里到底放入了哪几个变量、删掉某条样本之后结论还稳不稳定。这些问题在成稿里只剩一段话,甚至只剩一个脚注,别人拿到手根本没法验证,连你自己三个月后回看都可能一脸茫然。
另一个痛点是协作的低效。两个人合作写一篇东西,最经典的做法是某个共享文件夹里躺着十几版文档,命名从“v1最终版”到“v2最终版修改2”,最后谁也说不清哪一版才是对的。如果再加上外部审稿人、数据提供方、匿名评审,信息流立刻变成一团乱麻。我见过太多合作项目不是死在研究难度上,而是死在了版本管理和沟通成本上。
还有一个常被忽略的痛点:研究产出物的价值被严重低估。有时候一个失败的研究假设、一组没跑出显著性差异的数据,其实非常有价值,能帮后来的人少走很多弯路。但在传统体系里,这些过程产物往往进了垃圾箱。而 OpenResearch 想做的事情,就是把这些“看不见的东西”变成第一等公民,让整个过程可以被翻阅、被讨论、被复用。
1.2 OpenResearch 的设计目标
所以我在设计 OpenResearch 时,定了三条核心目标。
第一,过程可见。所有跟研究相关的产出,从 idea 草图到最终稿,都要有结构化存档,并且默认对团队或公开可见。这不是为了表演“我很透明”,而是为了让任何人随时都能回答三个问题:当前研究了什么、已经做过哪些尝试、下一步打算做什么。
第二,版本可追。每一份文档、每一份数据、每一段分析代码,都应该有清晰的版本历史。改了什么、谁改的、为什么改,全部记录在案。这不仅是防甩锅,更是为了能够随时回溯到某个历史状态,复现某个结果。
第三,协作异步化。研究不应该是必须“同步在线”的会议动物。理想的协作方式是:每个人在各自的时间线上推进,然后把变更推到公共空间,其他人通过 review 和 comment 参与进来。这种协作方式和开源软件开发高度一致,所以我决定直接借鉴开源社区的经验,而不是自己发明一套轮子。
1.3 方案选型:为什么是 Git + Markdown 而不是在线文档
很多人问我,做开放研究,为什么不直接用腾讯文档、飞书或者 Notion?这些工具也很好,但离我想要的“开放”还差得远。
在线文档虽然实时同步很方便,但有几个硬伤。第一,版本历史太弱,虽然能看到历史版本,但很难对两份版本做细粒度的 diff,更别提把代码、数据和文档放在一起管理。第二,权限和可见性控制过于粗糙,一个链接可以访问,但没法做到“某些字段对某些人可见”。第三,文档和数据分离,数据表在另一个平台,分析脚本在第三个平台,要把全链路串起来非常费劲。
Git 已经是开源世界验证了二十年的版本协作系统,天然支持原子化变更、分支、合并、评审。Markdown 则是纯文本格式,不需要特殊软件就能打开、diff、合并,特别适合研究文档这种以文字为主、又需要版本对比的场景。数据文件尽量以 CSV、Parquet 这类开放格式存放,也能用 Git 管理(配合 Git LFS 处理大文件)。这样从 proposal 到 dataset 到 analysis script 到 manuscript,所有东西都在同一个仓库里,一条命令就能拉起来,完全可复现。
我用一张表来对比一下这两类方案的差异:
| 维度 | 在线文档 | Git + Markdown |
|---|---|---|
| 版本追溯 | 弱,只能看历史快照 | 强,可以任意 diff、回滚 |
| 文档与代码结合 | 难 | 天然契合 |
| 权限控制 | 简单但粗放 | 灵活但需要学习 |
| 离线工作 | 一般 | 完全支持 |
| 协作门槛 | 低 | 中偏高 |
| 数据管理 | 不适合 | 可同时管理代码与数据 |
如果你是单人研究,在线文档也许够用;但如果你想做一个真正“开放”的项目,让其他人能审阅、修改、复用,Git 这套系统目前还是最优解。
2. 核心机制拆解
2.1 研究阶段的标准化拆分
OpenResearch 的第一步,是把模糊的研究流程拆成六个可跟踪的阶段。这个拆法借鉴了软件开发的敏捷思路,每个阶段都有明确的产出物和完成标准,阶段之间用 Pull Request 来流转。
阶段一是选题与问题定义。这个阶段的核心产出是一份 proposal.md,里面写清楚你要回答什么问题、为什么这个问题重要、已有的研究基础有哪些、你打算怎么验证。这个文件是整个项目的“北极星”,后续所有工作都应该围绕它展开。
阶段二是文献与资料收集。我会在 docs/ 目录下维护一份 reading-notes.md,把读过的论文、文章、数据源逐个记录下来,并附带一句话总结和链接。这个文件不是摆样子,它能让后来者快速了解这个领域里哪些坑已经被踩过了。
阶段三是数据准备。所有原始数据放在 data/raw/ 下,清洗后的数据放在 data/processed/ 下,清洗脚本放在 scripts/ 下。关键操作用 DVC 或 Git LFS 做版本管理,这样数据文件的每次变动都有记录。
阶段四是分析与复现。分析 Notebook 放在 notebooks/ 目录,每个 Notebook 的命名按“序号-主题-作者”来,例如 01-exploratory-data-analysis.zhang.ipynb。运行结果尽量做缓存,目标是任何人 clone 仓库后,执行一条 make analyze 就能复现所有图表。
阶段五是写作与整合。论文或报告的手稿放在 manuscript/ 目录下,每章一个 Markdown 文件,通过 Mermaid 或者简单的导航文件来组织结构。这一阶段仍然在仓库里进行,允许小步提交,方便大家看到写作的演进过程。
阶段六是评审与发布。把稿件连同数据、代码一起打包进行内部评审,评审意见以 issue 或 review comment 的形式记录。评审通过后再公开发布,同时附上仓库地址,方便别人复现验证。
这个标准化拆分的最大好处是:任何时候你都能一眼看清楚项目进行到了哪一步,卡在哪个环节,下一步的 entry point 在哪里。对于多线程协作来说,这相当于给每个人都发了一张清晰的路线图。
2.2 开放程度与数据脱敏
很多人一听“开放研究”,第一反应是“所有东西都要公开”。实际上这是误解。开放不等于裸奔,而是要有节奏、有边界地透明。
OpenResearch 支持三种可见性级别:
- 公开可见:对所有人开放,适用于最终报告、复现数据、无敏感信息的分析脚本。
- 内部可见:仅项目成员可访问,适用于访谈记录、个人信息、正在撰写中的草稿。
- 延迟公开:在一段时间内保密,到论文发布或项目结束后再开放。
每个文件可以在仓库里通过一个元数据文件声明自己的可见性级别。比如在meta/visibility.yml里:
manuscript/: visibility: public data/raw/interviews/: visibility: internal notebooks/01_exploratory.ipynb: visibility: public这个机制其实是在“开放”和“隐私”之间做了一个可配置的妥协。对于涉及人类被试、商业保密数据的项目,就必须在项目初期设计好脱敏流程:比如把访谈音频转成文字后去掉人名和机构名,地理坐标做模糊化,金额做区间化处理。我在实际项目中遇到过一个案例,一个众包标注数据集里出现了标注者的手写 ID,如果不做脱敏直接公开,就意味着泄露了个人身份。后来我们在发布清单里增加了“匿名化检查”这一步,才算真正把风险堵住。
2.3 角色与权限设计
既然是一个协作平台,就必须定义清楚角色。OpenResearch 里我定义了三种基础角色。
维护者(Maintainer)负责项目方向、合并 PR、处理纠纷。每个项目至少需要一个维护者,否则没人把关质量,项目会失去方向。
贡献者(Contributor)是实际干活的人,负责推进各项任务。贡献者可以提交代码、写文档、跑分析,但不能直接 push 到主分支,所有变更都要走 Pull Request。
审阅者(Reviewer)负责对贡献者的工作提出意见。审阅者不一定是项目成员,可以是外部专家,他们通过 review 环节把专业度带进来,但不需要自己动手写代码。
在实际操作里,我还会额外设置一个“顾问”角色,他们的权限只有评论区发言权,但意见权重很高。顾问一般是有经验的前辈或者领域专家,用来兜底方向性问题。
角色的定义不是为了阶层化,而是为了让协作流程有秩序感。没有角色定位的开放仓库,往往会出现“人人都能改但没人对结果负责”的混乱状态。
3. 从零搭建 OpenResearch 项目
3.1 项目仓库结构与模板
搭建一套 OpenResearch 项目,并不需要从空白开始。我提供一个最小可用的模板结构,你可以直接复制过去改造。
open-research/ ├── README.md ├── LICENSE ├── Makefile ├── pyproject.toml ├── requirements.txt ├── proposal.md ├── docs/ │ ├── reading-notes.md │ └── design-decisions.md ├── data/ │ ├── raw/ │ ├── processed/ │ └── README.md ├── notebooks/ │ └── 00_start_here.ipynb ├── scripts/ │ ├── clean_data.py │ └── analyze.py ├── manuscript/ │ ├── abstract.md │ ├── 01_introduction.md │ ├── 02_methods.md │ ├── 03_results.md │ ├── 04_discussion.md │ └── references.bib └── meta/ ├── visibility.yml └── roles.ymlREADME.md 是整个项目的入口,我建议至少包含五块内容:
- 项目简介:用两三句话说明研究了什么、为什么重要。
- 当前状态:项目处于哪个阶段,用 badge 或者文字标注。
- 快速开始:别人如何 clone、安装依赖、复现结果。
- 如何贡献:贡献者需要知道的规则和步骤。
- 目录说明:各个文件夹放什么东西。
Makefile是自动化流程的关键入口。我常用的几个 target:
setup: pip install -r requirements.txt data: python scripts/clean_data.py analyze: python scripts/analyze.py html: jupyter nbconvert --to html notebooks/*.ipynb check: python -m pytest tests/这个 Makefile 的核心价值是“一键复现”。任何人拿到仓库之后,不需要阅读二十页说明,只要执行make setup && make data && make analyze就能把主要结果跑出来。这比读论文里的“我们使用 Python 3.8 进行了分析”要强太多。
3.2 用 Git 管理研究全过程
研究过程中的 Git 使用方式,和写代码有些区别,但核心逻辑一致。我习惯于把每个阶段当成一个分支来管理。
主分支main保持始终可用的稳定状态,只有通过评审的产物才能合并进来。开发时新建分支,比如dev/03-data-cleaning或者dev/04-analysis-logit-model,在分支上随意折腾,稳定后再开 Pull Request。
提交信息是重点。为了便于追溯,我强制使用 Conventional Commits 风格,但把前缀调整成研究场景:
idea:记录一个研究想法data:数据变更analysis:分析脚本或结果变更manuscript:文本写作变更meta:项目元数据变更fix:修复一个 bug
举例来说:
git commit -m "analysis: 加入对异常值剔除后的敏感性分析" git commit -m "manuscript: 补全方法章节的样本筛选说明"这样的提交历史读起来就像一本流水账,任何时间点都可以知道“当时在做什么,为什么这么做”。
对于大文件,比如几十 MB 的原始数据,我会启用 Git LFS。这个操作很简单:
git lfs track "data/raw/*.csv" git add .gitattributes git lfs install如果不做这一步,仓库会迅速膨胀到难以操作,clone 一次等半小时,最后只能把历史强制改写。
3.3 引入自动化与质量检查
开放研究不能只靠自觉,自动化检查是保证质量下限的重要工具。
我最常用的是 GitHub Actions 或 GitLab CI,在每次推送、每次提 PR 时跑一遍以下检查:
- 代码风格检查(ruff、black)
- 单元测试(pytest,特别是数据清洗函数和统计函数)
- 文档渲染(Markdown 链接检查、拼写检查)
- 数据版本校验(对比数据文件的 hash,确保没被意外修改)
其中一个特别有效的检查是“可复现性检查”。做法是在 CI 里新建一个干净的虚拟环境,从零开始安装依赖,然后执行整个分析流程,如果脚本因为路径写死、依赖缺失或随机种子问题跑不通,CI 就会直接失败。这个检查能逼着你把环境依赖声明清楚,也让后来者更容易复现结果。
另外,我还会在仓库根目录放一个CITATION.cff文件,里面写清楚项目作者、版本号、引用格式。这个小文件的作用是让贡献者的工作可以被引用,这比后期在论文致谢里加名字要规范得多。
3.4 开放评审与发布流程
评审环节在 OpenResearch 里是透明的。任何人都可以以审阅者身份对 PR 提出意见,意见必须是 constructive 的,也就是要给出具体修改建议,而不是只说“这个不行”。
实际操作时,我会把评审流程拆成三轮:
第一轮是“方向性评审”,重点看研究问题是否合理、方法是否匹配、结论是否过度外推。这一轮通常发生在 proposal 阶段。
第二轮是“技术性评审”,重点看代码质量、数据处理是否规范、统计方法是否严谨。例如有没有做多重比较校正,要不要汇报置信区间,缺失数据的插补方式会不会引入偏差。
第三轮是“表达性评审”,重点看文稿是否通顺、图表是否自解释、引用是否完整。很多学术项目的前两轮都做得很扎实,但最后死在表达上,所以这一轮不能省。
评审的产出物也全部留在仓库里,形成一种“研究审稿意见档案”。这样读者不仅能看到最终论文,还能看到隐藏在最终结论背后的拉锯过程。
发布时我会打一个版本标签,比如v1.0.0,同时产生一份对应的 DOI,方便追踪引用。发布清单包括:
- 最终版 manuscript
- 数据文件(公开部分)
- 分析脚本
- 运行环境说明(Dockerfile 或 requirements.txt)
- 评审意见归档
从实际效果看,这套流程能够让一个项目从“自己一个人闷头干”平稳过渡到“多个人并行推进”,并且不用担心有人无意中破坏了已有结果。
4. 常见问题与避坑实录
4.1 隐私与伦理问题怎么处理
这是我遇到最频繁的顾虑。很多人想开放研究,但手上有访谈数据、用户数据或者商业机密,直接公开肯定不行。
我的经验是:在项目立项时就要明确数据分级。凡是涉及个人可识别信息的数据,一律不能用 Git 管理,哪怕仓库是私有的也不行。我会把这类文件放在本地,或者放到符合安全标准的数据存储里,仓库里只放脱敏后的版本。
脱敏也不是简单删掉姓名和邮箱就完了。有一次我们的数据里含有出生年月和所在城市,这两个字段单独看都没问题,但组合起来足够定位到具体的人。后来我在脱敏流程里增加了“k-匿名性”检查,要求任意一组准标识符组合至少对应 k 个人,k 通常设为5,这样能从统计上降低重识别风险。
如果你自己拿不准,建议在 meta/visibility.yml 里把这类数据标为 internal,并写清楚访问需要申请。开放不等于无条件公开,负责任的开放才是可持续的。
4.2 分支混乱与冲突解决
多人协作写文档时,Markdown 文件的冲突几乎不可避免。特别是两个人同时改写同一段方法描述,Git 合并时会出现 conflict。
解决这个问题有几个技巧。第一,鼓励小步提交,每篇文档拆成多个小节,不同人负责不同小节,冲突的概率会显著下降。第二,先把文档切成模块化结构,比如 manuscript/ 下的每个章节都是独立文件,避免所有人都去改同一个paper.md。第三,如果实在需要并发写同一节,约定一个人主笔、其他人 review,而不是同时编辑。
真要遇到 conflict 了,也不要慌。打开冲突文件,搜索<<<<<<<标记,手动整理两边内容。重点是要理解冲突的根源,而不是机械地把两边都保留。如果这两人表述的是同一件事但用了不同措辞,最好合并成一段更精炼的表达;如果两人观点有分歧,这其实是研究中的正常现象,应该拉出来讨论而不是强行合并。
4.3 贡献者动力不足怎么办
开放项目的最大风险是“没人参与”。我见过不少项目开场时风风火火,三个月后只有维护者一个人在更新。
要让贡献者持续参与,我认为有三件事值得重视。
第一,降低贡献门槛。项目里必须有非常清晰的“新手任务列表”,每个任务都写明涉及的代码、文件、依赖,最好附上参考 PR 的链接。不要假设别人会花三个小时研究你的项目结构。
第二,及时响应。贡献者提交第一个 PR 之后,维护者最好在当天回复。哪怕只是说一句“收到,我这两天会看”,也能让贡献者觉得自己没被忽视。如果长期不处理 PR,贡献者大概率不会再来了。
第三,让贡献者获得署名感。在 README 里加一栏 “Contributors”,无论贡献大小都写上名字。CITATION.cff 里注明核心贡献者,发布时附上作者名单,这会让每个人都感受到劳动成果被认可。
4.4 如何把开放研究持续下去
最后聊一下长期维护的问题。开放研究不是一个“做完一个项目就完了”的事情,更好的形态是形成一组持续演进的研究基础设施。
我现在运营 OpenResearch 的节奏是:每周固定留出半天时间处理项目事务,包括合并 PR、回复 issue、更新路线图。所有项目相关讨论都尽量搬到 GitHub issue 或 Discussion 里,避免在微信里聊完就消失了。每次活动、每次发布,都会在项目里留下记录,这样长期下来,项目本身积累的资料库反而比任何单一研究产出都更有价值。
我还做了一个“月度回顾”的文档,月末把本月进展、数据变化、关键决策写下来,作为项目的档案。这个回顾不需要长篇大论,三五条 bullet points 即可,但在未来追溯某个结论的来源时,这些笔记往往能救命。
如果你准备启动一个开放研究项目,我最后的建议是:不要一上来就追求宏大设计,从最小的一个研究问题、一个私有仓库、两个协作伙伴开始,跑通第一轮流程之后再逐步扩大。开放是一种习惯,不是一把开关,它需要慢慢养成,也需要有人在日常里不断维护边界和节奏。
我个人在这套机制上踩过几次坑之后,最大的体会是:真正困难的地方不是工具不会用,而是如何在“开放”和“效率”之间找到自己的平衡点。过度开放会让讨论失焦,封闭过头又会回到老路。OpenResearch 给了我这个平衡点,让我既能享受协作带来的正向反馈,又不至于在过程管理上消耗过多精力。希望你也能找到适合自己的那个平衡点。