GitHub 最值钱的资产,是被丢掉的代码:观测层之争已经打响了

GitHub's Most Valuable Asset Is the Code It Threw Away

2022 年 3 月 10 日,我写了一篇 Google Analytics 4 简介,从事件跟踪讲到导出 BigQuery,写得挺认真。

那篇文章发表前两个月,奥地利数据保护局裁定 Google Analytics 违反 GDPR;发表前一个月,法国 CNIL 跟上。我当时知道这件事,但没当回事——一个免费工具被欧洲监管盯上,离一个中国工程师的日常太远了。

四年多以后回头看,那两个月恰好是一个分水岭:一个平台用免费换来了整个互联网的行为观测层,然后看着这个观测层被主权一刀一刀切掉。 我今天要写的是另一件事,但它是同一个剧本的第二幕——只不过这一幕的主角换成了代码,而幕布在 2026 年 4 月 24 日已经拉开。

那天 GitHub 改了一个开关的默认值。

GitHub’s Most Valuable Asset Is the Code It Threw Away

一、一个 opt-in 变成了 opt-out

2026 年 3 月 25 日,GitHub 发布公告,提前 30 天通知:从 4 月 24 日起,Copilot Free、Pro、Pro+ 用户与 Copilot 的 交互数据——官方原文列的是 inputs、outputs、code snippets and associated context——将默认用于训练 AI 模型,除非用户主动关闭。

注意两个细节。

第一,采集对象是 交互数据,不是仓库代码。GitHub 明确区分了两者:私有仓库里的静态代码不用于训练,但你主动使用 Copilot 时的实时处理数据可以用,除非你退出。这两句话放在一起读,边界就清楚了——它要的不是你存了什么,是你 用的时候发生了什么

第二,GitHub 首席产品官 Mario Rodriguez 在公告里把动机说得毫不遮掩:

「We believe the future of AI-assisted development depends on real-world interaction data from developers like you.」

我们相信 AI 辅助开发的未来,取决于来自你们这些开发者的真实世界交互数据。

一个 opt-in 变成 opt-out,在产品术语里叫「默认值调整」,在数据资产术语里叫 采集权变更。同一件事,后一种说法更接近它的实际分量。

而 Business 和 Enterprise 客户被排除在外——GitHub 的说法是,与这两类客户的协议本来就禁止把交互数据用于训练,他们遵守承诺。这个排除条款后面会回来,它是全文最关键的一处证据。

二、已提交链只是幸存链

先说清楚 GitHub 到底在看什么。

如果按「数据飞轮」的标准叙事,GitHub 的资产是代码加上协作图谱:谁在写什么、什么项目在增长、issue 和 PR 如何演化、什么代码被 review 和 merge、开源项目之间如何依赖、什么技术栈正在兴起和衰退。这些都很值钱,也确实构成了「最大的代码托管平台」这个护城河。

但这条链有个结构性缺陷:它是已提交链。

已提交链(GitHub 今天就能看到的):
  Idea → Issue → Plan → Code → Test → PR → Review → Deploy → Feedback
              每一环都只记录了「最后留下来的那一版」

未提交链(Copilot 交互数据里才有的):
  prompt → 生成 9 个版本 → 丢掉 8 个 → 人拒绝的理由 → 改法 → 再试
    训练 Agent 最缺的东西全在这儿
# generated by hugo AI

差别在哪?已提交链是 幸存者偏差的产物。commit 记录的是成功的那一版,它告诉你「什么是对的」,但不告诉你「什么被否掉了、为什么否掉」。而训练 Agent 最稀缺的从来不是正样本——GitHub 上有几十亿行成功的代码,多到用不完——稀缺的是 负样本和偏好对:这样做不行、那样做才行。

这个区分不是抽象的。GitHub 自己的数据资产里,价值密度最高的部分恰好就是携带判断的那部分:

数据携带什么单条价值
commit diff行为——最后选了什么低,量最大
PR review comment判断——「别这么写,要这么写」极高,字面上就是一条标注好的偏好对
revert 原因判断——为什么这条路走不通极高
issue 里的取舍讨论判断——在什么约束下选了什么
Copilot 交互数据未提交链——试了什么、丢了什么这是 2026-04-24 新拿到的

reviewer 写一句「这里别用全局状态,测试不好写」,那就是一条人类标注的偏好数据,带理由、带上下文、带权威性。这种数据不能靠爬代码得到,只能靠 在场

所以 Copilot 的战略意义不是「卖一个 Coding Agent」。卖 Agent 的公司很多,模型能力还在快速收敛。Copilot 真正的意义是:它让 GitHub 从「看得到结果」变成「看得到过程」,而且是在 几十亿次真实开发行为的发生现场 看。

三、Agent 对 UX 没有忠诚

这里有一个人类时代不存在的变量。

开发者留在 GitHub 上,靠的是习惯、协作网络、绿格子、组织内的既成事实。这些锁定对人类有效。

但 Agent 不需要这些。一个 Coding Agent 需要的是:一个能 push 的 git remote、一个能读 issue 的 API、一个能跑 CI 的地方。git 协议本身是去中心化的——GitLab、Gitea、自建仓库,对 Agent 完全等价。它不会因为绿格子好看而多留一天。

这意味着:人类时代的锁定靠 UX,Agent 时代的锁定只能靠「默认上下文存储」地位。

如果 Agent 在别处跑、只把最终结果 push 回 GitHub,那么 GitHub 看到的就是已提交链——那个它本来就看得到的东西。未提交链留在了 Agent 跑的那个地方。仓库退化成存储后端,最值钱的数据从指缝里漏走。

这就是为什么 GitHub 必须自己做 runtime(Copilot Workspace、agent mode 这一类东西),而不是只做一个能接 push 的托管服务。不是因为要做 Agent 生意,是因为不做就采不到。

第一节那条 Business/Enterprise 排除条款,现在可以读得更清楚了。我的推断是:GitHub 把采集范围画在个人版上,是因为个人开发者用的 Agent 就跑在它自己的 runtime 里——Copilot 本来就是那个 runtime。企业客户的 Agent 在哪儿跑,GitHub 控制不了,所以那笔生意干脆用合同划出去。这一条是我从政策边界倒推的,不是 GitHub 的说法。

四、反方:观测层会被主权拆掉

写到这儿,最该正面回应的是这个反驳:

「你在描述一个已经被证伪过的剧本。Google Analytics 就是免费基础设施换观测层,然后 GDPR 来了、Apple ATT 来了,观测层被拆了。GitHub 采交互数据,结局一样——企业一旦发现软件生产过程被观测,就会往代码不出域迁移。GitLab 已经在这么卖了。」

这个反驳有事实,而且事实比我预想的更强。

GA 的欧洲时间线是这样的:

时间事件
2020-07Schrems II 判决,欧美数据传输的法律基础被动摇
2021-04Apple ATT 随 iOS 14.5 上线,跨 App 追踪被砍
2022-01-13奥地利 DSB 裁定 GA 违反 GDPR——Schrems II 后第一个
2022-02-10法国 CNIL 跟进
2022-06意大利 Garante 跟进
2022-09丹麦跟进
2023-07-03瑞典 IMY 因使用 GA 罚 Tele2 1200 万瑞典克朗(约 100 万欧元),并对 CDON 罚款——这是首个因 GA 开出的实质罚款
至 2025-01芬兰、挪威等陆续出具类似裁决,累计已有七国(一说五国)

但这里有一处我原本想说、核实之后发现 说反了 的事实,而更正之后论点反而更硬:

Chrome 的第三方 cookie 弃用——那个被叫了六年「cookie apocalypse」的事——Google 自己在 2024 年 7 月放弃了,2025 年 4 月又确认不会引入替代的同意弹窗。第三方 cookie 至今在 Chrome 里默认开启。Safari 和 Firefox 从 2020 年就默认拦截,但 Chrome 没跟。

也就是说:三把刀里,拥有浏览器的那一把被它的主人自己收回去了,主权方的裁决一把都没收回。

这件事的含义比「GA 被拆了」精确得多:能拆掉观测层的从来不是平台的产品决策——那可以反悔;是主权——那不能反悔。 平台自己会算账,算到广告收入够大就撤回隐私改动;监管机构不跟你算这笔账。

而且 GA 案里还有两个细节值得单独记下来。一是 没有 EU 全域禁令,各国监管机构各自裁决、口径不一,GA4 配合 Consent Mode v2 在很多情况下仍可辩护——主权是碎片化推进的,不是一刀切。二是这些裁决打的都不是「你用 GA」,而是「数据跨境到美国、受美国情报机构管辖」。主权争的是数据落在谁的法律辖区里。

法律那一头也没完。Doe v. GitHub 这个集体诉讼 2022 年 11 月由律师 Matthew Butterick 和 Saveri 律所提起,索赔 90 亿美元法定赔偿;诉状里引用了 GitHub 自己的内部研究——Copilot 约 1% 的情况会复现训练数据里的代码。案子在 2024 年 9 月被批准中间上诉,2026 年 2 月 11 日在第九巡回法院旧金山开庭辩论,争的是一个很窄的技术问题:DMCA §1202(b) 的版权管理信息移除责任,是否要求「完全相同的复制」。截至我写这篇文章,还没有裁决。UC Berkeley Samuelson 诊所的 16 位知识产权法学教授提交了支持 GitHub 的法庭之友意见书。

GitLab 那边则已经把这件事做成了营销:官方博客标题直接叫「治理警钟」,正文一句话——GitLab 不在任何层级用客户代码训练模型,并配了一个 AI Transparency Center,把哪个功能用哪个模型、数据怎么处理、保留多久做成可审计的承诺。

所以反方的事实基础是完整的:主权会来、法律未决、对手已经把「我不采」当成卖点。

五、GitHub 的答案:把两批客户拆开

我的回应是——GitHub 已经回答了这个问题,答案就写在那条排除条款里。

Copilot Business 和 Enterprise 客户的交互数据不用于训练,受数据保护协议约束,未经客户授权不得使用。个人版 Free/Pro/Pro+ 则是 opt-out 默认开启。

这不是妥协,这是定位:采集权和主权是两批客户,卖的是两个东西。

个人版企业版
默认值opt-out(默认采)合同禁止采
换来什么更好的模型数据主权承诺
客户在意什么我的 Agent 够不够聪明我的代码会不会漏出去
谁承担成本开发者用数据付费企业用溢价付费

GA 当年被主权追着跑,一个原因是它想把这两批客户装在同一个产品里——免费给所有人,数据也采所有人,然后用「匿名化」和「同意弹窗」打补丁。补丁打到 Consent Mode v2,本质还是同一套采集逻辑加了个开关。

GitHub 的选择是直接拆开。个人开发者用默认值换模型能力,企业用合同换主权承诺,两笔生意互不污染。

这个拆法也解释了为什么反方的迁移论对了一半:企业确实会往主权侧跑,GitLab 也确实接得住这波。但企业跑掉之后,GitHub 损失的不是数据资产——那部分本来就不在采集范围内——损失的只是席位收入。而它用个人版和公开仓库换来的未提交链,规模不受影响。

所以真正的问题不是「飞轮会不会转」,是「飞轮建在哪块地上」。 GitHub 把它建在个人开发者这块地上,同时用合同把企业那块地让出去。这是一个有意识的地权划分,不是防守失误。

六、量涨了,信号会贬值

但这套逻辑里有一个 GitHub 没在公告里说、我认为会越来越疼的问题:Agent 产出的数据,正在稀释它自己要采的信号。

Agent 写的代码越来越多,语料里人类判断的占比越来越低。拿 Agent 的产出去训练下一代 Agent,是近亲繁殖。这和 高质量数据越多,大模型表现越优秀 里讲的数据瓶颈是同一个问题的另一面——那篇讲的是「好数据不够」,这里讲的是 数据量爆炸时单位信息量在掉

我把这个问题量化成一个可以算的指标:判断密度——一条过程链里,带理由的取舍占全部事件的比例。

from __future__ import annotations

from dataclasses import dataclass
from enum import Enum


class EventKind(Enum):
    """过程事件只有两类:产出了一个东西,或做了一次取舍。"""

    ARTIFACT = "artifact"    # commit、文件、PR——产物流水
    DECISION = "decision"    # 否掉了什么、为什么否掉


@dataclass(frozen=True)
class ProcessEvent:
    """未提交链上的一次留痕。"""

    kind: EventKind
    actor: str                 # "human" | "agent"
    rejected: str | None       # 被放弃的选项,DECISION 才有
    reason: str | None         # 放弃理由——训练 Agent 最缺的就是这个字段


@dataclass
class ChainQuality:
    """衡量一条链值不值得采:看判断密度,不看体量。"""

    total: int = 0
    decisions: int = 0
    reasoned: int = 0          # 可复用的判断数

    @property
    def judgment_density(self) -> float:
        """可复用判断 / 全部事件。

        为什么分母是全部事件而不是 decisions:一条链可以有大量
        DECISION 却几乎不可复用,这种否决没有信息量,不该被算成资产。
        """
        if self.total == 0:
            return 0.0
        return self.reasoned / self.total


def score(events: list[ProcessEvent]) -> ChainQuality:
    """为什么 reasoned 要求 rejected 和 reason 同时存在:

    「改一下」这种字符串是非空的,但它没记下被否掉的是什么,
    对下一个 Agent 零信息量。一条可复用的判断必须同时回答
    「否掉了什么」和「为什么」——缺一个都不能拿去训练。
    """
    q = ChainQuality()
    for e in events:
        q.total += 1
        if e.kind is EventKind.DECISION:
            q.decisions += 1
            if e.rejected and e.reason:
                q.reasoned += 1
    return q


if __name__ == "__main__":
    # 链 A:Agent 高产的一天——40 个产物,2 次带理由的取舍
    chain_a = [ProcessEvent(EventKind.ARTIFACT, "agent", None, None)] * 40
    chain_a += [
        ProcessEvent(EventKind.DECISION, "agent", "递归实现", "栈太深会超时"),
        ProcessEvent(EventKind.DECISION, "agent", "同步调用", "下游 P99 撑不住"),
    ]

    # 链 B:一次人类 code review——6 个产物,8 次否决,其中 5 次给了理由
    chain_b = [ProcessEvent(EventKind.ARTIFACT, "human", None, None)] * 6
    chain_b += [
        ProcessEvent(EventKind.DECISION, "human", "全局状态", "测试不好写"),
        ProcessEvent(EventKind.DECISION, "human", "重试 3 次", "幂等键没做,重试会重复扣款"),
        ProcessEvent(EventKind.DECISION, "human", "同步导出", "超过 30s 会超时,改异步"),
        ProcessEvent(EventKind.DECISION, "human", "自定义解析", "标准库够用"),
        ProcessEvent(EventKind.DECISION, "human", "catch Exception", "吞掉错误,排障时看不见"),
        ProcessEvent(EventKind.DECISION, "human", None, "改一下"),
        ProcessEvent(EventKind.DECISION, "human", None, "这样更好"),
        ProcessEvent(EventKind.DECISION, "human", None, None),
    ]

    for name, chain in [("A: agent 高产", chain_a), ("B: 人类 review", chain_b)]:
        q = score(chain)
        print(f"{name}: total={q.total} decisions={q.decisions} "
              f"reasoned={q.reasoned} density={q.judgment_density:.3f}")
# generated by hugo AI

跑出来的结果(两条链都是我构造的示意数据,用来说明这个指标怎么算,不是对真实项目的实测统计):

A: agent 高产: total=42 decisions=2 reasoned=2 density=0.048
B: 人类 review: total=14 decisions=8 reasoned=5 density=0.357
# generated by hugo AI

链 A 的事件量是链 B 的三倍(42 对 14),判断密度却只有它的七分之一多一点(0.048 对 0.357)。如果按体量计价,A 更值钱;按判断密度计价,B 值钱得多。

这段代码里有个设计我想单独说,因为它对应一个很容易犯的错:reasoned 要求 rejectedreason 同时存在。链 B 里有 8 次否决,只有 5 次算数。剩下 3 次是「改一下」「这样更好」和一条什么都没写的——前两条看着像有理由,但 它没记下被否掉的是什么

这个区别很关键:「改一下,这样更好」对下一个 Agent 是零信息量。它既不知道哪个方案被否了,也不知道换个场景该不该照做。一条可复用的判断必须同时回答「否掉了什么」和「为什么」——缺一个都拿不走。对照链 B 里算数的那条:「否掉全局状态,因为测试不好写」,这两半都在,所以下一个 Agent 遇到类似选择能直接用。

还有一个坑在分母:judgment_density 的分母是 全部事件,不是 decisions。如果分母用 decisions,链 B 会算成 0.625——看起来很高,但它把 14 个事件里那 6 个纯产物动作全藏起来了。用全部事件做分母,才能逼出那个真正的问题:你的过程数据里,有多少是 可复用的判断,有多少只是动作留痕。

由此,采集策略的优先级就反过来了:

  • 别抢产物量——产物会越来越便宜,Agent 自己就能生产无限多
  • 抢判断——review 意见、revert 原因、issue 里的取舍、人被 Agent 说服或拒绝说服的那一刻
  • 抢不到判断就别采——没有理由的过程日志只是 audit trail,人人都有,不构成资产

这也回到第二节那张表:GitHub 数据资产里单字节价值最高的,是 PR review comment。原因现在很清楚了——它是 天然长出来的偏好对,带理由、带权威、带上下文,而且不需要额外埋点。

七、把这套逻辑换到组织工作上

前面六节讲的是软件生产。但如果这套逻辑成立,它不该只对软件成立。

对比一下两边的资产结构,会发现一个很有意思的互补:

意图链(未提交)可验证产物
GitHub✗ 只看到 commit,看不到为什么这么改✓ 测试会跑、代码会崩、CI 会红
组织平台(钉钉这类)✓ IM、审批、会议、组织图谱——意图链是原生的✗ 组织工作没有编译器

GitHub 有可验证的产物,但没有意图链:一个 PR 为什么这么写、当时权衡了什么、谁否掉了另一个方案——大部分不在仓库里。

组织平台正好相反。一个需求的来龙去脉、一次审批为什么被驳回、一场会议里哪个方案被否掉、一个项目卡在谁手里——这些 天然就是未提交链,每天都在 IM 和审批流里发生,从来没被结构化过。我在 Agent 进入企业,还差一个工位 里讲的工位五层,本质就是在给这条链配采集条件。

但组织侧缺一样东西:验证器。代码有编译器、有测试、有 CI,错了会红,这是客观裁决。组织工作没有——「这个方案好不好」「这次客户沟通到不到位」没有客观真相,只有立场。

所以两边各缺一半,而缺的那一半恰好决定了过程数据的价值上限:

GitHub:  有产物验证,缺意图链   → 过程数据缺「为什么」
组织平台:有意图链,缺产物验证   → 过程数据缺「对不对」
              Eval 就是组织工作的编译器
# generated by hugo AI

补上验证器,组织侧的过程数据才从 审计留痕 升格成 可训练语料。这也是我在 评测集是一份没人签字的文件数字员工按工作收费,谁来签「干完了」 里反复讲那件事的原因——当时讲的是工程侧飞轮和商业侧结算,现在多出第三个用途:Eval 是过程数据的生产设备。

因为反事实不会自然沉淀。没有人会主动记录「我本来想这么干,后来没这么干,因为……」——除非有一个署名的验收标准逼着他把理由写下来。GitHub 的 PR review 是软件世界里天然长出来的偏好数据;组织侧没有等价物,得靠 Eval 签名机制人造出来

顺带说一句,这和 企业最有价值的 AI 训练数据,不是文档内容,是隐性知识 讲的不是同一件事,虽然容易被混在一起。那篇讲的是 企业自己 该保护什么——你的隐性知识是资产,别让它变成别人的训练语料。这篇讲的是 平台侧 的采集权——平台想拿走的恰好就是那个东西。两篇是同一场博弈的两端:企业在守,平台在采。看清这一点,才知道自己该在合同里争取哪一条。

最后

回到 2026 年 4 月 24 日那个开关。

一个 opt-in 变成 opt-out,表面是隐私政策的措辞调整。实际上是 GitHub 在回答一个问题:当软件生产过程本身变成数据资产,采集权归谁。 它给出的答案分两半——个人版用默认值采,企业版用合同让。而对手立刻把「让」的那一半做成了卖点。

这场博弈不会在代码托管这一层结束。它会在每一个「过程可以被观测」的领域重演一遍:软件生产、组织协同、医疗记录、教学行为。GA 那一幕的教训不是「免费换数据行不通」——它行通了十几年——而是 观测层一定会被主权追问,而且追问的形式是数据落在谁的辖区、由谁签字授权。能提前把这两件事想清楚的平台,才有资格建观测层;想不清楚的,建得越高,被拆得越响。

至于我自己,2022 年写那篇 GA4 教程时漏掉的那一层,现在补上:免费工具的真正价格,写在它的默认值里。

如果换成你的组织——你沉淀的过程数据,是 audit trail 还是 preference data?那些被否掉的方案,理由写下来了吗,还是只留在某个人的脑子里?欢迎留言讨论。


See also