OSS PR 选题与 good-first-issue 定位
前三天(Day 171-173)是「读懂主流框架 + 把全局资料过期体检一遍」,结论是 smolagents / DeepEval / Inspect AI 三个 repo 都仍是 2026 活跃主线、未冻结。
阶段: B18 · OSS 收口 + 英文 + 全局 SOTA 复核(Day 171-180) 标签: #oss-contribution #good-first-issue #contributing #repro
今日导引(由浅入深)
前三天(Day 171-173)是「读懂主流框架 + 把全局资料过期体检一遍」,结论是 smolagents / DeepEval / Inspect AI 三个 repo 都仍是 2026 活跃主线、未冻结。
今天把「读」转成「准备贡献」:学找可贡献 issue 的方法论,并在这三个 repo 各筛 1 个 good-first-issue、本地复现其中 1 个。
在 B1→B18 曲线上,这是「从内功外显到真实社区动作」的过渡日——注意诚信底线:merged OSS PR 不算已完成,今天只到「复现 log + 选定 issue 链接」为止。上承 Day 173 的 SOTA 复核(确认 repo 未冻结才值得投入),下接 Day 175 的英文 writeup 体例(把复现写成可对外的 problem→repro→fix→eval 叙事)。
最小可判定产出:1 条复现 log(预期 vs 实际)+ 1 条选定 issue 链接。
一句话锚点:今天练的是「把一个外部 bug 收敛成可判定的复现脚本」,而判定结构(输入→期望→实际断言)和本仓 EvalTask 同构——所以这一天既是 OSS 准备,也是本仓评测能力的对外迁移演练。
1. 机理精读
找可贡献 issue 的方法论:先读 CONTRIBUTING,再按标签筛。 顺序不能反——
- 先读
CONTRIBUTING.md:确认贡献门槛——是否要求 DCO(Developer Certificate of Origin,commit 签Signed-off-by)或 CLA、测试要求(改动必须配测试)、commit 规范(如 Conventional Commits)。这一步决定「这个 PR 提上去会不会因流程不合规被退」。 - 再按标签筛:
good-first-issue/documentation/help-wanted。这三类是新贡献者的入口标签。
依据:smolagents / DeepEval / Inspect AI 各自 CONTRIBUTING (2026)。
CONTRIBUTING 里要逐项对答案的 checklist。 读 CONTRIBUTING 不是泛读,是逐项确认四件事,缺一项 PR 都可能被退:
- 签署要求:DCO(
git commit -s加Signed-off-by)还是 CLA(需在网站签)?两者机制不同,漏签直接挡住合入。 - 测试门槛:是否强制新改动配测试、本地跑哪条命令(
pytest/npm test)必须绿。 - commit 规范:是否 Conventional Commits(
fix:/docs:前缀)、是否要求 squash。 - changelog:是否需要在 PR 里同步加一条 changelog 条目(很多项目把它当合入前置)。
把这四项在选 issue 前就核对清楚,等于把「会不会被流程毙掉」前置排除。
为什么这样排序:流程合规是接受率的前置条件。 一个技术正确但没签 DCO、没带测试、commit 不合规的 PR,reviewer 会直接退回——技术对不对都还没轮到看。先读 CONTRIBUTING 等于先把「会不会被流程毙掉」排掉,再谈技术。
低风险高接受率的 issue 类型。 文档修复、错误信息(error message)改进、边界 bug——这三类改动面小、影响可控、易于 reviewer 快速判断对错,因此接受率高。
反面是大重构、API 变更、有争议的设计——新贡献者碰这些容易陷入长 review 拉锯。选题即风险管理:第一个 PR 求「小而被接受」,不求「大而惊艳」。
复现优先于改:先证明 bug 存在。 选定 issue 后第一步不是写 fix,而是本地复现——clone + 跑最小复现脚本,记录「预期 vs 实际」。
复现成功才证明你真懂这个 bug;很多 good-first-issue 在新版本里已被修或无法复现,复现这一步先把这种情况筛掉。
PR 尺寸即接受率:diff 越小、review 越快。 这是一条经验铁律——reviewer 的注意力有限,一个 +20/-5 行、改一处、带一个测试的 PR,几分钟就能判断对错并合入;一个跨多文件、夹带格式化 noise 的 PR,会卡在「这堆改动到底哪些是必要的」上。
因此选 issue 时要顺带评估「这个 fix 的最小 diff 有多大」:能 10 行内解决的文档/错误信息/边界 bug 优先;需要动核心抽象的,留到熟悉 repo 之后。这条尺寸纪律和本仓「小步可测提交」的工程习惯一致。
边界:外部动作不等于已完成。 本仓诚信底线——good-first-issue 是别人的 repo,issue 会被他人抢先、PR 会被 review 卡。今天的产出止于「复现 log + issue 链接」,不声称 PR 已 merged(真实提 PR 在 Day 177-178)。
2. 推导 / 手算 / 代码走读
今天是外部 repo 复现 + 本仓可迁移性对照日。复现 log 的结构对照本仓 src/agent/eval/tasks.ts 的任务结构(已用 Read 打开),确认「外部 bug 复现」与「本仓任务定义」在结构上可迁移:
- 本仓任务的标准三元组
EvalTask(agentEval.tsline 20):{ id, prompt, reference?, codeCheck? }——id(可定位)、prompt(输入)、reference(期望行为)、codeCheck(确定性断言)。一个 OSS bug 复现脚本本质同构:输入 → 期望 → 实际断言。 tasks.ts的codeCheck即「可判定断言」:例如aml-ctr-threshold(line 154)的codeCheck: has(/10[,.]?000|\$10k|10k/i)——给定输出,正则判定 pass/fail。复现一个 OSS bug 时,「预期 vs 实际」的判定就是同一形态的断言:期望输出匹配某 pattern,实际不匹配 = bug 复现成功。reference字段 = 期望行为说明(如aml-sar-deadlineline 162 的 reference「30 calendar days...」):对应 OSS issue 里「应该怎样」的描述。复现 log 里「预期」一栏直接对标 reference。- 多面校验也可迁移:
aml-sar-5w1h(line 169)的 codeCheck 用 6 个正则数命中数hits >= 5 && out.length > 120——这是「多条件部分通过」的断言形态,对应 OSS bug 里「修复需同时满足多个验收点」的复现脚本。 - 可迁移性结论:本仓的「任务 = prompt + 期望 + 可判定 check」结构能直接套到「OSS bug 复现 = 输入 + 期望 + 实际断言」,因此复现 log 与
tasks.ts结构对照成立——这条对照本身就是 Day 175 英文 writeup 的素材。
本仓自有可贡献素材(对外 writeup 案例): src/aml/groundTruthEval.ts 的 prediction-source-agnostic 设计(binaryEval 接受 {label, predicted} 对,两者都可来自外部源),是一个干净的、可对外讲的「如何去掉评测循环依赖」案例——它本身就是一篇 writeup 级的素材,不依赖任何外部 repo。
3. 今日实战
按 seed 落地:
- 在 smolagents、DeepEval、Inspect AI 三个 repo 各筛 1 个 good-first-issue(先读各自
CONTRIBUTING.md,确认 DCO/CLA、测试要求、commit 规范)。 - 本地复现其中 1 个:clone + 跑最小复现脚本,记录预期 vs 实际。
- 复现 log 与本仓
src/agent/eval/tasks.ts的任务结构对照(见上,确认可迁移性)。 - 产出复现 log + 选定 issue 链接 1 条。
4. 今日实测 / 产出
- 外部动作(merged OSS PR 不算已完成)→ 将产出复现 log + 选定 issue 链接 1 条。
- 本仓自有可贡献素材:
groundTruthEval.ts的 prediction-source-agnostic 设计可作为对外 writeup 案例。 - 不把「选定 issue」升级成「已 merge」;外部动作如实标外部动作。
复现 log 的最小模板(写进今日产出):
repo: <owner/name> issue: #<id> commit: <sha>
环境: <py/node 版本 + 安装命令>
复现步骤:
1. <最小脚本/命令>
预期: <issue 描述的应有行为 / 对标本仓 reference 字段>
实际: <观察到的现象 / 对标本仓 codeCheck 不通过>
结论: 复现成功 / 无法复现(新版本已修)
这张模板和本仓 EvalTask 的 {prompt, reference, codeCheck} 一一对应——「预期」对 reference、「实际 + 结论」对 codeCheck 的 pass/fail。把它做成固定格式,是为了让 Day 175 的英文 writeup 的 repro 段可以直接搬。
5. 常见误区 / 陷阱
- 跳过 CONTRIBUTING 直接写代码:漏签 DCO / 没带测试 / commit 不合规会被直接退,技术再对也白搭。
- 选有争议/大改的 issue 当第一单:第一个 PR 应「小而被接受」,碰大重构容易陷 review 拉锯。
- 不复现就动手:很多 good-first-issue 在新版本已被修或无法复现;先复现再 fix。
- 抢已被认领的 issue:good-first-issue 会被他人抢先,issue 列表当周需重刷,确认无人认领 + 非 stale。
- 复现 log 不记环境:不写 py/node 版本与 commit sha,reviewer 无法判断你复现的是不是当前分支——复现等于无效。
6. 学习资源(每条带 YYYY-MM)
- smolagents, CONTRIBUTING.md(DCO/测试/commit 规范)— 2026
- DeepEval, CONTRIBUTING.md— 2026
- Inspect AI, CONTRIBUTING.md— 2026
- GitHub Docs, good-first-issue / help-wanted 标签约定— 2026
- 本仓
src/agent/eval/tasks.ts(任务结构,对照复现 log)— 2026
SOTA检查 (2026-06 更新)
- 当前主流:smolagents / DeepEval / Inspect AI 三个目标 repo 均为 2026 活跃项目,good-first-issue 是新贡献者标准入口。
- 是否仍 SOTA:是。但 issue 列表当周需重刷——good-first-issue 会被他人抢先,stale/锁定的旧 issue 不可选。
- 过时黑名单:避免选已 stale / 锁定的旧 issue;避免在维护模式项目(AutoGen/SK)上投精力。
- 下次复查点:选 issue 当周重刷三 repo 的 good-first-issue 列表 + 确认认领状态;提 PR 前(Day 177-178)再确认分支未冻结。
衔接
- 昨天:Day 173 — claude-cookbooks + 全局 SOTA 复核(确认三 repo 仍活跃、未冻结)
- 今天:学 good-first-issue 选题方法论,三 repo 各筛 1 个、本地复现 1 个,产出复现 log + issue 链接
- 明天:Day 175 — 英文 writeup 体例(把复现/去循环案例写成 problem→repro→fix→eval 的对外英文叙事)