每四个 PR 就有一个是 AI slop:怎么正确读 Linux Foundation 这份新调研

·阅读约12分钟·Evergreen Tools Team

2026 年 10 月 20 日,Linux Foundation 发布了一份研究报告,落点在一个维护者早就怀疑的数字上:25% 的入站 PR 被估计为低质量 AI slop,在大型项目里这个比例是 31%。同一份报告里还有另外半句:生成式 AI 让代码编写时间少了 52%,71% 的维护者同意它降低了参与门槛。这两件事同时成立,而真正有意思的正是这个并存。下面不是新闻稿的复述,而是逐个数字讲清它测的是什么、测量本身哪里脆弱,以及一个项目周一早上能拿它做什么。

每四个 PR 就有一个是 AI slop:怎么正确读 Linux Foundat

每四个 PR 就有一个是 AI slop:怎么正确读 Lin

一、这份调研到底测了什么

报告标题是《Navigating Open Source Software Development in the Generative AI Era》,由 LF Research 发布、Red Hat 赞助,Futurewei、OpenSSF 与 LF AI & Data 支持,2026 年 10 月 19-20 日在罗利的 All Things Open 上做了发布。样本口径比标题更重要:受访者是开源贡献者和维护者,描述的是自己的行为和自己的项目,不是对 GitHub 活动做的抓取统计。所以这里每个数字都是「带分母的主观判断」,不是对代码的实测。这个区别决定了你该怎么用那 25%:它是维护者对「入站工作里有多少是低质量」的自报估计——正好是应该拿来驱动分诊策略的那个数字,而不是可以当成客观缺陷率去引用的数字。

# Triage filter: which incoming PRs cannot show their own evidence?
# Requires: gh (authenticated), jq. Run against the queue, not the whole repo.
gh pr list --state open --limit 100 \
  --json number,title,additions,deletions,changedFiles,body,files \
  > /tmp/prs.json

jq -r '.[] |
  (.files | map(.path) | map(select(test("(^|/)(test|tests|spec|__tests__)/|\\.(test|spec)\\."))) | length) as $tests |
  (.body // "" | length) as $blen |
  [ .number, .additions, $tests, $blen,
    (if $tests == 0 and .additions > 50 then "NO-TEST-EVIDENCE" else "ok" end)
  ] | @tsv' /tmp/prs.json \
  | awk -F'\t' '$5=="NO-TEST-EVIDENCE" {print}' | sort -k2 -nr | head -20

# A pull request that changes behavior and touches no test is not necessarily
# slop. But it is the cheapest first pass, and it never needs a judgement call.

二、25% 这个数字,以及它会变高的地方

具体数字是:59% 的维护者表示生成式 AI 普及后贡献量在上升,大型项目里升到 69%;同时 25% 的入站 PR 被估计为低质量,大型项目是 31%。注意这个形状,因为痛苦并不是均匀分布的。大型项目同时吃到更大的量和更高的垃圾占比——如果最省事的做法是把 Agent 指向某个分类里最大、最显眼的仓库,结果本就该是这样。实际后果是:对大型项目来说,卡住流程的是分诊能力,而不是评审质量。一个一周能处理 30 个 PR 的评审者处理不了 90 个,再仔细读也修不好这道算术题。

<!-- Put this in .github/pull_request_template.md, above the description box. -->
## What this changes


## Evidence
- [ ] I ran the affected tests locally: `________`
- [ ] This PR includes a test that fails before the change and passes after
- [ ] If no test was added, here is why: `________`

## If AI assistance was used
- [ ] Disclosed below (tool + how much of the change it produced)
- [ ] I read every line and can explain it
- Tool and scope: `________`

<!-- Maintainers: a blank section is a valid reason to close, not a reason to ask again. -->

三、生产力数字,包括那些倒退的部分

受访者对六类开源开发活动都给出了平均时间缩减估计,而这个分布才是真正有用的细节:代码编写降 52%,方案与设计讨论降 19%,报告把整体收益表述为最高 50%。但同时有 21% 的受访者说,高复杂度任务用了生成式 AI 反而更久。这不是舍入误差,这是你五分之一的资深贡献者。凡是见过 Agent 自信满满地重构一个它根本没看懂的模块的人,都能认出这个数字。结论不是「AI 在难题上更慢」,而是:在搬砖活上省下的时间,有一部分要在「一个错误假设就换来一天调试」的任务上还回去。这是分流的论据,不是弃用的论据。

# Measure review LOAD, not review virtue. Weekly, from the API.
python3 - <<'PY'
import json, subprocess, datetime as dt

raw = subprocess.run(
    ["gh", "pr", "list", "--state", "all", "--limit", "300",
     "--json", "number,createdAt,mergedAt,closedAt,additions,author"],
    capture_output=True, text=True, check=True).stdout

prs = json.loads(raw)
now = dt.datetime.now(dt.timezone.utc)

open_days, merged_days, vols = [], [], 0
for p in prs:
    c = dt.datetime.fromisoformat(p["createdAt"].replace("Z", "+00:00"))
    end = p["mergedAt"] or p["closedAt"]
    e = dt.datetime.fromisoformat(end.replace("Z", "+00:00")) if end else now
    (merged_days if p["mergedAt"] else open_days).append((e - c).days)
    vols += p["additions"]

def pct(xs, q):
    xs = sorted(xs)
    return xs[min(len(xs) - 1, int(len(xs) * q))] if xs else 0

print(f"sample={len(prs)}  median_time_to_merge={pct(merged_days, .5)}d")
print(f"median_age_of_open={pct(open_days, .5)}d  total_additions={vols}")
# When median age of open PRs climbs while merges stay flat, the queue is
# growing faster than you can triage. That is a capacity number, not a mood.
PY

四、信任缺口其实是政策缺口

71% 的维护者同意生成式 AI 降低了参与开源的门槛,同时有 53% 的维护者不认为它提升了社区对贡献的信任。这两句话合起来,比任何口号都更准确描述了真实问题:能参与的人变多了,而相信到手东西的维护者变少了。接下来是这份报告里最该让你警觉的数字——只有 35% 的项目有允许使用生成式 AI 的正式政策,32% 的项目既没有政策也没有制定计划。贡献者一侧,61% 说自己在提交前对 AI 生成代码做了详细审查和完整功能测试,但「是否使用 AI」的披露并不一致。也就是说,大多数人做了对的事却没说,三分之一的项目选择了「不做决定」。

# CI gate: behavior change without a test delta fails the build.
# This is the single rule that makes "AI slop" cheap to reject.
name: change-evidence
on: pull_request

jobs:
  evidence:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - name: Require test delta for source changes
        run: |
          git fetch origin ${{ github.base_ref }} --depth=1
          SRC=$(git diff --name-only origin/${{ github.base_ref }}...HEAD \
                | grep -E '^(src|lib|app)/' | grep -vE '(test|spec)' | wc -l)
          TST=$(git diff --name-only origin/${{ github.base_ref }}...HEAD \
                | grep -E '(test|spec)' | wc -l)
          echo "source_files=$SRC test_files=$TST"
          if [ "$SRC" -gt 0 ] && [ "$TST" -eq 0 ]; then
            echo "::error::Source changed with no test delta. Add a test or explain in the PR body."
            exit 1
          fi

五、项目这周能做的四件事

第一,把政策写下来。报告自己的建议很明确:为 AI 辅助贡献设清晰的书面政策、标准化的归属标注,并要求贡献者在提交前测试并记录 AI 辅助的改动。第二,让贡献变便宜可分诊:要求 PR 里带上测试变更、可复现步骤或明确的失败模式——垃圾贡献通常给不出这些。第三,量「评审负荷」而不是「评审质量」,因为瓶颈是产能。第四,把政策放在贡献者真的会看的地方,也就是 CONTRIBUTING.md 和 PR 模板,而不是没人打开的 wiki 页。下面几段代码是这四个动作里最小但真能跑的版本。

# Disclosure check: read the trailer, do not guess from style.
# Standardize on a git trailer so it survives rebases and squash merges.
python3 - <<'PY'
import subprocess, sys

TRAILER = "AI-Assisted:"

def commits(base="origin/main"):
    out = subprocess.run(
        ["git", "log", f"{base}..HEAD", "--format=%H%x1f%B%x1e"],
        capture_output=True, text=True, check=True).stdout
    for chunk in out.split("\x1e"):
        if not chunk.strip():
            continue
        sha, body = chunk.split("\x1f", 1)
        yield sha.strip(), body

missing, disclosed = [], 0
for sha, body in commits():
    lines = [l.strip() for l in body.splitlines() if l.strip()]
    hit = next((l for l in lines if l.startswith(TRAILER)), None)
    if hit:
        disclosed += 1
        print(f"{sha[:8]} {hit}")
    else:
        missing.append(sha[:8])

print(f"disclosed={disclosed} no_trailer={len(missing)}")
# Fail soft by default: report, do not block. A gate that misfires on
# honest contributors teaches them to write the trailer without meaning it.
PY

六、省下来的时间去哪了

有一条发现被低估了:66% 的受访者说会把生成式 AI 省下的时间投到技术债,63% 投到新功能,58% 投到学习与技能提升。这才是整件事的论据。一个项目如果把 AI 红利花在「更多 PR」上,它会被评审淹死;如果把红利花在背了三年的技术债上,那么造出这条队列的工具,同时也买回了清空它的产能。导师数据指向同一个方向:46% 的维护者说生成式 AI 增加了指导新贡献者的需求,认为减少的是 32%。写代码变快,并不会降低「需要一个知道这代码为什么存在的人」的需求。

每四个 PR 就有一个是 AI slop:怎么正确读 Linux Foundat

每四个 PR 就有一个是 AI slop:怎么正确读 Lin

每四个 PR 就有一个是 AI slop:怎么正确读 Linux Foundat

每四个 PR 就有一个是 AI slop:怎么正确读 Lin

📌 常见问题 FAQ

25% 和 31% 这两个数字是怎么来的?

它们来自 2026 年 10 月 20 日发布的 LF Research 调研,是维护者的自报估计,不是实测缺陷率。25% 的入站 PR 被估计为低质量 AI slop,大型项目升至 31%。用它来争取分诊人力,不要当成某个具体仓库的客观事实。

生成式 AI 到底省了多少时间?

受访者估计代码编写时间降 52%、方案与设计讨论降 19%,报告把六类被测活动的整体收益表述为最高 50%。另外有 21% 的受访者表示在高复杂度任务上使用生成式 AI 反而更久。

贡献量上升是真的,还是只是感觉?

59% 的维护者表示生成式 AI 普及后贡献量在上升,大型项目为 69%。调研测的是「有明确分母的主观感受」,所以应把它当作负荷信号,而不是全 GitHub 的统计计数。

有多少项目有正式的生成式 AI 政策?

只有 35% 的项目有允许使用生成式 AI 的正式政策;32% 既没有政策也没有制定计划。贡献者一侧的 AI 使用披露被认为不一致,尽管 61% 表示提交前做了详细审查与完整功能测试。

维护者最该先做哪一件事?

写下政策,并在 PR 模板里要求测试变更。它把一个关于 AI 的模糊争论变成可核对的要求,也给了你队列给不了的东西:一个不必读完全部内容就能快速关掉 PR 的理由。