
在电脑里翻出一个叫 working 的文件夹是我干这行以来最崩溃的时刻。那个文件夹里堆着 PDF、docx、研报截图、聊天记录导出还有三份都标着“终版”的论文稿。真正压垮我的瞬间是一篇 60 页综述里有一张配图的原始数据脚本消失得无影无踪我不得不花两天时间把图表重新画一遍。作为一个常年维护开源项目的开发者这种返工让我意识到研究过程本身可能比研究内容更欠一次工程化改造。所以 OpenResearch 并不是某家公司推出的商业产品也不是要花钱才能上的平台。它是我给自己搭的一套开源研究工作区模板把选题、文献卡、实验记录、草稿、参考文献和发布页全部收进同一个 git 仓库用 Markdown 写内容、BibTeX 管引用、MkDocs 生成网站再把整套流水线公开出来。它的核心价值在于无论研究做到哪一步材料都在过程可追溯结果可复现任何接手的人都能在半小时内理出头绪。这套思路适合正在写论文的研究生、需要长期维护文档的开源贡献者以及想在一个小团队里建立协作秩序的人。下面写的没有玄乎理论全是我自己反复删改之后沉淀下来、并且还在每天使用的做法。1. 为什么要把研究过程“开源”OpenResearch 的设计起点1.1 传统研究流程里最折磨人的两个堵点第一个堵点是过程黑箱。大多数研究会经历三轮、四轮甚至更多次改稿但真正被记录下来的往往只有最后一版。别人问“你这个样本筛选逻辑为什么从 50 条变成了 23 条”你只能去微信聊天记录里翻半天审稿意见回来要求补充某个实验参数你打开那个命名成“最终版2”的文档发现里面根本没有参数说明。这些情况不是少数瞬间而是每天都在发生。第二个堵点是结果碎片化。一篇论文的正文和配图分开存放实验脚本、数据集分别散落在不同网盘里参考文献又是另一个软件里的私有格式。两周之后你回看自己做的图表会发现链接已经失效PDF 原件不知道去了哪里脚本跑出来的结果和稿子里写的数值对不上。这都不是态度问题是工作流结构本身出了问题。我在开源项目里反复验证过一件事让过程可见并不需要什么天才方法。把源代码放到仓库里、把每次修改记录成一次 commit、把构建脚本写清楚别人拿起来就能复现。这套逻辑完全可以平移给研究写作。1.2 我把开放研究落成三条底层原则搭建 OpenResearch 的时候我给自己定了三条原则后续所有选择都围着它们转。第一条内容必须是纯文本。Markdown 是我所有文件的主格式参考文献用 BibTeX数据用 CSV代码脚本当然也是纯文本。纯文本的好处是永远不用担心软件升级后打不开文件git diff 能精确显示每一处改动而且几乎所有工具都认它。第二条每次变化都必须被 git 记录。即使只有我一个人写我也会把一次修改拆成几次有意义的提交例如“补充实验组样本量说明”“修正第三章引用格式”“更新数据集清洗脚本”。这样做的好处是任何时刻回退都只需要一条命令而不是靠翻目录里的历史副本。第三条发布必须自动化。每次 push 到主分支后网站自动构建、自动发布PDF 也由脚本从同一批源文件生成。出版物的来源只有一份绝不在那里手工调格式。这三点里前两条解决回溯问题第三条解决复现问题。一个研究项目如果连构建都可以一键完成那协作的门槛就已经降到了最低。1.3 为什么我把技术底座选成“纯文本 Git 静态站”有人问我为什么不直接用 Notion、飞书那一类在线文档或者用知名的云笔记。我的回答很简单那些工具在内容和程序之间的隔层太厚。你看不到记录背后的改动历史导出格式受限更无法让自动化脚本去碰里面的内容。而 Git 是无敌的版本容器。每次改动都留下可读的差异记录分支机制让我们可以同时推进“文献综述”“实验记录”“正文修改”三条线而互不干扰GitHub、GitLab 这类托管平台则顺手解决了协作和权限问题。发布端我用的是 MkDocs配 Material 主题。原因也很朴素它在本地构建快能生成静态页面放到任何托管平台都能跑还内置全文搜索代码块和高亮体验都不错。如果你偏爱数字花园的展示风格Quartz 或 Hugo 也可以核心思路一样只是生成器不同。2. 一个能跑起来的 OpenResearch 仓库应该怎么组织2.1 用“输入、过程、输出”三层结构隔离不同性质的文件我第一次搭仓库的时候把目录建得很“大而全”结果十天之后我自己都找不到东西。后来我换成了一套特别朴素却好用的结构模拟了生产线思维。openresearch/ ├─ .github/ │ └─ workflows/ │ └─ publish.yml ├─ src/ │ ├─ bibliography.bib │ ├─ data/ │ │ ├─ raw/ │ │ └─ processed/ │ ├─ notes/ │ │ ├─ 2024-05-01-chen-2024-transformer.md │ │ └─ 2025-11-12-framework-comparison.md │ ├─ draft/ │ │ ├─ manuscript.md │ │ └─ figures/ │ │ └─ pipeline.pdf │ └─ assets/ │ └─ pdf/ ├─ output/ ├─ Makefile ├─ mkdocs.yml ├─ README.md └─ requirements.txtsrc 是整个仓库的心脏它内部又分成四块。data 里只放数据和清洗脚本raw 目录里面的文件一律禁止手工修改任何需要修正的地方都要通过脚本生成到 processed 目录。notes 是文献卡、灵感卡、实验记录的存放区一篇笔记对应一个独立文件互不干扰。draft 放论文正文和配图源码。assets 则用来保存那些不能重新下载的原始 PDF、访谈录音或扫描件。output 目录不放源代码它只是每次构建的产物区里面生成的 PDF 和静态网站都不进 git或者只保留压缩后的发布包。这样设计最大的好处是隔离不同性质的文件不互相污染你永远不会在实验数据目录里找正文也不会在参考文献里翻配图。2.2 用一套命名规则让文件自己会说话目录建好了命名如果混乱一样会前功尽弃。我给自己定了几条硬规矩。第一日期开头的文件一律用 ISO 格式也就是 YYYY-MM-DD。这是因为按名称排序时日期自然形成时间线比“最终版”“真的最终版”“完稿2”这种命名可靠太多。第二每个文献卡文件的命名用“日期-作者-年份-主题”的结构例如 2024-05-01-chen-2024-transformer.md。一眼就知道读的是谁在什么时间写的哪类文章。第三状态不写在文件名上而是写进 YAML front matter。因为文件名的职责是提供简洁的定位信息状态是会变的——你没法通过改文件名来跟踪一项研究从 idea 变成 draft 再变成 archived 的过程。我在 front matter 里用 status 字段维护状态取值只允许 idea、reading、draft、final、archived避免“待整理2”这种无限变种。--- title: Attention Is All You Need 笔记 author: chen year: 2024 status: reading tags: [transformer, attention] ---这套规范几乎不需要学习成本但极大减少了“我明明整理过文件却找不到”的挫败感。2.3 参考文献管理让 BibTeX 成为唯一的事实来源参考文献是整个研究仓库里最容易被搞乱的部分。我见过太多人一边用 Word 的文献管理插件一边在 Excel 里维护参考文献最后报告里引用的条目和真实来源根本对不上。在 OpenResearch 里所有文献统一放在 src/bibliography.bib作为唯一事实来源。BibTeX 是一个纯文本的文献数据库格式每一篇文献由一条 key 和若干字段组成。我平时用 Zotero 收集网页上的引文信息导出为 BibTeX 后丢进仓库遇到 DOI 的文章也可以直接在命令行里用工具拿到对应的 BibTeX 条目。写正文的时候我使用类似“chen2024transformer”的引用语法比如在 Markdown 中这样写注意力机制的提出改变了序列建模的路径[vaswani2017attention]。构建时由 Pandoc 读取 bibliography.bib按照指定的 CSL 样式自动替换成 [1]并生成参考文献表。这样做的好处是正文里永远不出现编好号的“文献 [12]”引用增删时编号自动跟着变不会出现“这段话对应的文献怎么跑偏了”的问题。3. 从零搭建 OpenResearch初始化、写作流和自动发布3.1 第一步初始化仓库和本地写作环境我想尽量说得具体因为很多人看了结构图还是会卡在第一步。假设你用的是 macOS 或 Linux本机已经装好 Python 3.10 和 Git。打开终端从空目录开始mkdir openresearch cd openresearch git init python -m venv .venv source .venv/bin/activate接着安装 MkDocs 和 Material 主题。我建议把依赖写进 requirements.txt方便后续环境重建pip install mkdocs-material pip freeze requirements.txt然后创建前面那张目录树里的子目录并把项目说明写进 README。README 不只是给访客看的更是给自己三个月后看的。我会写上这个仓库解决什么问题、目录怎么划分、如何安装并构建、引用格式是什么。以后你半年没碰这个仓库再回来时就不会对着结构发愣。3.2 第二步定义一套可以重复执行的写作与发布流水线人工步骤越多出错概率越大。所以我把每一步都固化成 Makefile 里的目标让命令去指挥工具而不是靠记忆。My Makefile 长这样简化版.PHONY: serve build pdf clean serve: mkdocs serve build: mkdocs build --strict pdf: pandoc src/draft/manuscript.md \ --citeproc \ --cslsrc/assets/ieee.csl \ --bibliographysrc/bibliography.bib \ -o output/manuscript.pdf clean: rm -rf site output/*你需要确保 Pandoc 已安装sudo apt install pandoc # Debian/Ubuntu brew install pandoc # macOS之后我养成了一个习惯写完一段研究内容至少跑一次make build如果引用了新文献就再跑一次make pdf确认引用能在最终文档里正确落位。这个频率很低但能让你在发布之前发现大部分潜在错误而不是等网站上线再修复。3.3 第三步用 GitHub Actions 把研究笔记变成公开网站研究仓库的最终价值在于公开。我使用 GitHub Actions 实现每次提交后自动构建并发布。工作流文件放在.github/workflows/publish.ymlname: publish on: push: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-pythonv5 with: python-version: 3.11 - run: pip install -r requirements.txt - run: mkdocs build --strict - uses: peaceiris/actions-gh-pagesv4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./site第1步把代码拉下来第2、3步配置 Python 环境并安装依赖第4步构建整站第5步把生成的 site 目录发布到 GitHub Pages。push 一触发网站就更新。由于每个环节都写进了仓库任何人拿到源码都能重建整个发布流程而不是依赖某个人的本地环境。如果你不想公开整个仓库只是自己用也可以把仓库设为私有只让 Pages 公开静态页面同样能达到对外展示而不泄露过程笔记的效果。3.4 许可证选择开放不等于可以随便拿把仓库放上 GitHub 之后第一件事不是写代码而是选许可证。很多人忽略这一点导致想参与协作的人不确定自己能不能合法使用内容、提交 PR。我的建议是分开处理对研究笔记和论文正文用 CC BY 4.0允许他人在注明出处的前提下自由使用对代码和数据文件用 MIT 或 CC0降低后续接手的法律摩擦。如果你希望别人引用但不允许商用可以选择 CC BY-NC但要注意这会让一些非盈利研究团队也望而却步。文本、代码、数据分开声明版权比一刀切更有利于“开放研究”真正被使用起来。4. 开放研究入坑半年遇到的 5 个坑以及我的避坑清单4.1 链接失效数字资料湮灭比想象中快我在整理第三篇综述的时候发现自己引用的一个研究数据集链接已经打不开了。网页快照只保留了首页数据文件早已被清理。最麻烦的是我之前只把 URL 写进了论文引用PDF 原件根本没有下载。后来我立了一条铁律凡是被写进研究的原始材料必须有一次本地化副本。PDF 放进 src/assets/pdf数据文件放进 src/data/raw同时用 README 里的来源说明记录抓取时间和原始链接。宁可多占几百兆空间也不能让研究成果建立在一根随时会断的网线上。4.2 多人协作时合并冲突多到想砸电脑我把 OpenResearch 给团队用之后第一个月最大的噩梦是 git 合并冲突。两个人同时改了 manuscript.md 的不同段落Git 却无法自动合并因为段落之间靠得太近双方的行号变化范围重叠了。解决方式不是学十种魔法命令而是从写作习惯上绕过去。我要求每人负责的草稿必须拆成独立文件例如 intro.md、method.md、conclusion.md 分开存放一次 PR 只改一个主题每次提交前先跑一次 build。当改动被切得足够小冲突自然就少了。如果有需要多人协同的段落就约定谁当前是 owner其他人只提意见不改原稿。4.3 发布前忘了清理隐私信息有一次我差点把一份含个人信息的 CSV 推进公开仓库。那个文件原先是本地实验表不小心被拖到了 src/data/processed 目录而我在提交时又使用了git add .这个危险命令。还好在 push 之前做了一次自查否则隐私会以永久历史记录的形式留在仓库里。从此我要求 .gitignore 至少写上这些*.xlsx *.key *.env *.pem .pytest_cache/ site/ .DS_Store同时我彻底戒掉了git add .每次提交前先git status和git diff保证我加的每一个文件都是真需要提交的。如果真的误提交了敏感信息不要寄希望于删文件就行历史里还会留有记录需要用 git filter-repo 重写历史并强制推送这是一件很麻烦的事所以一开始就要sensitive地挡在门外。4.4 网站发布成功但内容空白多半是路径配置问题我遇到过几次第一版部署之后页面 404 的情况。原因很简单MkDocs 的 site_url 没有配置或者部署的子路径和仓库名不匹配。GitHub Pages 的页面路径是“用户名.github.io/仓库名/”如果你在本地用相对路径没问题部署上去就可能找不到 CSS 和 JS。mkdocs.yml 里三个字段必须提前对齐site_name: OpenResearch site_url: https://用户名.github.io/openresearch/ site_dir: site构建时使用固定的 base 路径部署才不会出岔子。检查完这几个字段再在本地跑一遍make build打开 site/index.html 确认资源都能加载再谈发布。5. 几个我还在用的追加技巧与真实感受最后分享几个不算系统但特别实用的小习惯。第一每次只进仓库做三件事找一篇新文献写两张文献卡跑一次 build。如果 build 失败就只修 build不顺手开新任务。这个保守的频率听起来很慢却让我在三个月后回看时积累下了一套完整可追踪的材料链比当初单次熬夜赶工高效太多。第二不要害怕在 notes 里写“不成熟”的想法。开放研究展示的最终版只是冰山一角真正让协作发生的是过程笔记。我经常把半成品思路直接写成卡片配上“这个问题还没解决”的标题反而吸引来不少同样卡在这里的人真正的进展常常发生在对话里而不是在“完美的终稿”里。第三把 git log 当成自己的研究日志。我每次提交的 message 都会带上这条改动的原因例如“增加访谈对象筛选标准避免同质样本偏差”“删除过时图表改用 2024 年限数据集”。这些文字不是为了给谁看而是为了让我自己半年后回到源代码面前时还能明白当初按下 Enter 的瞬间脑子里想的是什么。OpenResearch 不是一个很难搭建的系统难的是把“研究过程需要被记录”当成一种日常习惯。从最笨的单文件、单目录开始也可以只要先把过程放进版本控制里数据、文字、引用都留在自己能控制的地方后续的调整就有了基础。希望这套被我反复打磨过的模板能成为你开始管理自己研究过程的第一块垫脚石。