mcpField
R
refactor-research-code

refactor-research-code

github.com/shaishavmaisuria开发5790 次安装4 天前更新
代码仓库

关于 refactor-research-code

refactor-research-code 帮助研究者整理研究代码仓库以便发布,同时保持论文结果对应的数值行为不变。静态审计会按风险分类清理项,可能影响行为的修改须经作者确认。

主要功能

  1. 01只读静态发布审计
  2. 02区分安全与高风险修改
  3. 03整理仓库结构与文件
  4. 04检测双盲审稿身份线索
  5. 05生成重构计划和变更记录

适用场景

  1. 01准备公开发布实验代码
  2. 02整理脚本并记录运行入口
  3. 03双盲投稿前检查身份泄露

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/shaishavmaisuria/research-paper-lifecycle-skills --skill refactor-research-code

安装后在 Claude Code 中输入/refactor-research-code确认已加载。

附带文件references/release-refactor-catalog.mdscripts/release_audit.py

详细介绍

重构研究代码

将研究仓库从“在我的机器上能运行”转变为整洁、有文档记录、可重复运行的公开发布版本——且不改变论文报告的任何一个数字。研究代码会逐渐堆积废弃的实验分支、硬编码路径、神秘超参数、没有文档的“先运行这个文件,再运行那个文件”的操作流程,以及暴露身份的蛛丝马迹。本技能会清理这些冗余,让仓库布局更合理,但将保留结果视为首要原则:它会将每项拟议的更改归类为安全(机械性、保持行为不变)或先征求同意(可能导致数字发生变化),未经作者明确同意,绝不会动任何需要先征求同意的项目。

这不是通用重构(不进行性能改写、不“现代化 API”,也不为重构而调整结构)。唯一目标是在行为完全一致的前提下做好发布准备。如果某项“清理”会改变代码的计算结果,正确做法是标记出来并征求同意,而不是为了让仓库更整洁而牺牲论文的结论。

适用场景

  • “清理 / 重构我的研究代码,为发布做准备。” / “代码一团糟——帮我整理到可以发表的程度。”
  • “删除废弃的实验分支和注释掉的代码。”
  • “将配置与代码分开。” / “这些超参数到处都是硬编码的。”
  • “让我的运行具有确定性 / 可以重复运行。” / “为入口点编写文档。”
  • “让仓库布局清晰明了。” / “为了双盲审稿,去掉我的身份信息。”
  • 在使用 test-research-code(添加测试 / 随机种子 / 环境配置)和 prepare-artifacts(打包并托管,以获取徽章)之前——本技能负责首先进行 结构性清理。

本技能不做什么(请转用其他技能)

你的需求……请改用
添加冒烟测试、固定随机种子、记录环境test-research-code
打包 + 归档 DOI/SWHID + 徽章分类 + 附录prepare-artifacts
对论文进行彻底的双盲审查并可逆地去匿名化anonymize-paper
确认生成的数字与论文中的表格一致verify-results
重新组织论文的章节 / 论证refactor-structure

本技能会标记随机种子 / 环境配置方面的缺漏和身份信息泄露问题,并将其交由其他技能处理;结构性清理则由本技能完成。

输入

  1. 研究代码目录(仓库本身,或存放实验脚本的子文件夹)。本技能只读取本地文件,不会克隆仓库。
  2. 审稿采用双盲 / 单盲 / 非盲中的哪种方式(决定身份信息扫描方式),以及需要扫描的任何身份标识词(作者姓名、机构、内部代号)。
  3. 可选的 .paper-memory/profile.yml(贡献类型——如果是 system 或 dataset 论文,对代码质量的要求会更高,更倾向于发布可复用版本)。
  4. 如果清理工作是为了某个目标会议,可选提供其工件评审轨道——不过徽章规则会由 prepare-artifacts 实时获取,本技能不会获取。

首要原则:保留精确的数值行为

此技能采取的每项操作都属于以下三个类别之一。请将它们之间的界限视为不可逾越。

  • SAFE — 可自由应用(需作者认可): 添加 README / LICENSE / .gitignore;将文件移入 src//包布局(随后修正导入);删除纯粹的垃圾文件(__pycache__、*.pyc、.DS_Store、编辑器交换文件);记录现有入口点;仅重新格式化空白字符/注释。这些操作不会改变代码的计算结果。
  • ASK-FIRST — 未经明确确认,绝不触碰: 删除代码路径(备份文件、注释掉的代码块、if False: 分支——它可能是一个切换式实验,也可能会悄悄遮蔽当前生效的版本);将硬编码的超参数或路径提取到配置中(必须原样保留其值);更改任何涉及随机种子、随机数生成器、线程/工作进程数量、数据类型/精度或评估顺序的内容(这些因素定义了数值)。对于每一项,说明发现的问题、拟议的更改以及为什么这可能改变结果,然后等待确认。
  • IDENTITY — 盲审上传前先清理: 电子邮件、用户主目录路径、作者姓名、.git 历史记录。请在此处列出;深入清查交由 anonymize-paper 处理。

如果无法判断某项更改是否安全,默认归为 ASK-FIRST。一个更漂亮但报告出不同数值的仓库不是成功,而是失败。

流程

遵循「计划 → 确认 → 应用安全项 → 询问风险项」的流程,计划应基于外部、可测量的信号——静态审计,而不是模型觉得仓库「看起来很干净」。明确假设,展示不同解读,并让作者掌握主动权。

  1. 先阅读记忆。 阅读 .paper-memory/lessons.md(如果存在,也阅读 profile.yml),以便跳过作者已修复的问题,并优先指出其 recurring 习惯(例如「你经常提交 .git 和硬编码的 /home 路径」)。参见 paper-memory-convention.md。

  2. 确认范围和盲审级别。 询问评审是否为双盲,以及此次发布的用途(公开发布到 GitHub、盲审补充材料,还是 artifact track)。不要对单盲/非盲发布进行匿名化——这会破坏一个完善的仓库。如果是盲审,询问需要扫描哪些标识信息。

  3. 运行静态发布重构审计(确定性)。 不要手动使用 grep:

    python3 scripts/release_audit.py <code-dir> \
        --blind <none|single|double> --names "Jane Doe,Example University"
    # machine-readable:
    python3 scripts/release_audit.py <code-dir> --blind double --json
    

    该审计会遍历仓库(只读、不执行、不联网、不写入),并按类别(死代码、配置、入口点、布局、确定性、身份信息、卫生)标注发现结果;更重要的是,还会按风险标注:SAFE、ASK-FIRST(行为风险)或 IDENTITY。标志:--strict(任何发现都会导致失败)、--max-files N、--max-bytes N(仓库内 blob 阈值)。退出代码:0 表示没有 ask-first/身份信息发现,1 表示存在 ask-first 或身份信息发现,2 表示用法错误。这是制定计划所依据的信号(外部检查,而非自我判断);审计会指出可改进之处——但不能证明仓库可以复现。

  4. 先提交重构计划,获作者批准后再进行任何编辑。 按 SAFE → ASK-FIRST → IDENTITY 的顺序,将发现归入这三个类别。对于每个 ask-first 项,说明更改内容及其结果风险(「删除这个 if False: 代码块,只有在它在所有配置下都不可达时才安全——请确认?」)。作者逐项批准或否决。类别和安全重构方案见 references/release-refactor-catalog.md。

  5. 应用 SAFE 重构(须获得作者同意),按以下顺序进行——每项对应一个审计类别:

    • 布局 — 添加 README(入口点、每项结果对应的精确复现命令、依赖项、目录结构图)、LICENSE、.gitignore;将散落的脚本整理成 src//包结构,并修正导入。
    • 入口点 — 说明(或接入)一个明确的命令,用于端到端运行整个流程(make reproduce / run.sh / python -m pkg)。
    • 整洁 — 从发布副本中移除 __pycache__、*.pyc、.DS_Store、编辑器交换文件;将项目内的大型数据/模型文件移至下载脚本/存档主机(最后一项须先询问——确认运行时不需要该文件)。
  6. 逐项处理 ASK-FIRST 项,绝不批量处理。 每项变更获批后:进行最小限度的修改,然后通过外部检查验证行为未变——重新运行整个流程(或冒烟测试)并比较输出,而不是只凭肉眼检查差异。通过重新运行确认行为保持不变属于 test-research-code / verify-results 的职责范围;此技能负责标记并协调,若变更确有风险,则停下并征求确认。升级处理是此流程的一部分。具体而言:

    • 死代码 — 仅在确认没有任何内容导入或调用该代码后处理。
    • 配置 — 将字面值提取到配置/CLI 中,并保持完全相同的值;这里的拼写错误会悄然改变结果。
    • 确定性 — 与作者协调后设置/记录种子并固定顺序,然后重新运行以再次确认论文中的数值。添加种子会改变未设种子的运行结果——这是风险最高的修改。将种子/env 的机制交由 test-research-code 处理。
  7. 处理盲审中的身份泄露。 标记电子邮件、主目录路径、姓名和 .git 历史;将深度检查(提交历史、笔记本元数据、自我引用措辞、匿名镜像)交由 anonymize-paper 处理。盲审上传时,绝不要通过代码仓库暴露作者身份。

  8. 重新运行审计,直到达到 SAFE-clean,并明确停止条件。 循环执行审计 → 修复 → 审计,直到不再存在 SAFE/布局/整洁问题,且每项 ask-first 问题均已解决或有意识地延期——不能无限期继续。最多约 3 轮;如果审计仍标记同一项 ask-first 问题,应酌情升级处理,而不是继续修改。

  9. 将重构计划和变更日志写入 paper-workspace/submission/refactor-research-code-plan.md,并在 paper-workspace/INDEX.md 中追加一行。先写已完成的内容(安全项),再写 ask-first 决策(已应用/否决/延期,并注明各自对结果的风险),最后写身份信息交接。引用每项对应的审计发现。

输出

  • 一份重构计划(SAFE / ASK-FIRST / IDENTITY 分类,每项发现包含 category + risk + file[:line]),以及一份记录已应用、否决或延期事项的变更日志——写入 paper-workspace/submission/。
  • 已编辑的代码仓库文件(仅限逐项获批的内容):README / LICENSE / .gitignore、src//包结构、已说明的入口点、已清理的杂项,以及作者确认的任何 ask-first 修改。
  • 清晰的交接清单:种子/env/测试 → test-research-code;打包/DOI/ 徽章 → prepare-artifacts;深度匿名化 → anonymize-paper; 数值与论文核对 → verify-results。

适配你的学科

审计读取的是目录,而非学科,因此布局/死代码/身份检查适用于多种场景。对于非 Python 技术栈,确定性和配置模式有所不同(R 的 set.seed、Julia 的 Random.seed!、用于环境的 renv.lock/Manifest.toml)——脚本已支持其中若干种;请在 scripts/release_audit.py 中为你的语言扩展模式表。结果保持不变的约定具有普遍性:清理代码仓库,保留数值。

守则

  • 保留精确的数值行为——这正是全部意义所在。 未经作者明确批准,绝不进行需要先询问的改动(删除代码、提取常量、改动随机种子/线程/数据类型/顺序);并且必须通过重新运行来验证行为是否保留,绝不能通过阅读差异来验证(自我反思会验证自身的错误——验证必须来自外部)。
  • 如果不确定某项改动是否安全,就必须先询问。 仓库看起来更漂亮,却报告不同的数值,这就是失败。
  • 不要运行任何破坏性或不可信的内容。 release_audit.py 是静态、只读且不联网的。重新运行流水线以验证行为由作者决定,且可能需要沙盒/GPU。
  • **注意匿名化:**进行匿名评审时,绝不要通过仓库或 .git 历史泄露身份;将深入检查交给 anonymize-paper。
  • 各司其职。 不要添加测试/随机种子/环境配置(这属于 test-research-code),不要创建 DOI 或打包制品(这属于 prepare-artifacts),也不要声称结果可复现(这属于 verify-results;而且“复现”从来不代表位精确,也不由此技能决定)。
  • **Copilot,而非 Pilot:**它会规划、询问,并在获得批准后编辑;绝不会代作者提交、存档或推送。
  • references/ 文件保持一层目录深度;此文件不得超过 500 行。

记忆

使用共享的 .paper-memory/ 约定(完整规范: paper-memory-convention.md)。

  • **开始时:**阅读 lessons.md,跳过已修复的清理事项,并优先关注反复出现的发布习惯(例如“你每个仓库都会提交硬编码的 /home/<you> 路径”);阅读 profile.yml 以了解贡献类型。
  • **结束时:**针对每个反复出现的习惯,按规范格式追加一条带日期的记录,并通过 reflect-and-improve 的 reflect_log.py 执行:
    python3 ../reflect-and-improve/scripts/reflect_log.py append \
        --memory .paper-memory --skill refactor-research-code --scope recurring \
        --issue "hyperparameters hardcoded across scripts, no config file" \
        --rec "extract to config.yaml/CLI with identical values every release"
    
  • 按需创建 .paper-memory/,并提出将其添加到 .gitignore;仅保存在本地,绝不上传,也绝不复制到此仓库。

评论

支持 Markdown