没人被裁,只是没人被招了

斯坦福、SignalFire 和 IZA 三组数据在 2026 年指向同一件事:公司没有停止招工程师,只是停止招没经验的工程师。入门级招聘腰斩的账单要三年后才付,被拆掉的是学徒台阶,不是岗位本身。
没人被裁,只是没人被招了
过去一年我听到的关于 AI 和程序员的讨论,几乎都是错的形态。要么说三年内写代码这行没了,要么说这只是又一轮炒作、什么都没变。
两边都能找到数字支持自己,因为两边看的都是总量。总量确实没怎么动。
真正的变化藏在结构里:走人的没变多,进人的变少了。调整发生在招聘这一端,不在裁员那一端。
三组数据指向同一件事
先把结论摆出来:公司没有停止招工程师,公司停止招没经验的工程师。
下面是三组互相独立的证据。
第一组看的是刚入行的人。 斯坦福的一组研究者盯住 22 到 25 岁这个年龄段,拿他们的实际就业人数,跟"假如跟着低 AI 暴露的同龄人一起走"应该有的水平做对比,差了大约 19%。一年前这个缺口是 15%,在扩大。同一批人还查了对照组,那半句才是关键:有经验的从业者身上没有出现这个缺口。
换成更贴地气的口径也一样,22 到 25 岁的软件开发者,就业人数比 2024 年的高点少了约两成,年纪更大的那批人还在增加。
受影响的是"想当程序员的人",不是"已经是程序员的人"。
第二组看的是招聘口。 12 家科技巨头的应届生和入门级招聘量,比 2019 年少了大约三分之二,早期初创公司少了大约四分之三。同一份报告里还藏着一个反着来的数字:这些公司的总招聘量比 2019 年低 25%,工程岗只低 11%,软件工程师在招聘里的占比反而从 46% 升到了 55%。
招的人变少了,招的还是工程师,只是不要新手。
第三组解释了这道门是怎么变窄的。 一份基于几百万条在线招聘信息的研究对比了 ChatGPT 出现前后的变化,初级岗位相对高级岗位少了 14% 到 15%。这个变化只出现在软件类岗位,机械工程完全没有。机制也不绕:岗位名称没改,改的是同一个岗位里要求的年限。原来两年经验能投的,现在要三到五年。
三组数据,三种数据源,指向同一件事。门槛抬高了,招牌没换,进去的人变少了。
门槛是在同一个岗位里抬高的
IZA 那篇论文最有价值的部分不是降幅,是机制。
他们发现,经验要求的上升主要来自雇主在同一个岗位名称下提高年限要求。他们没有创造一批新头衔,也没有把招聘整体挪向高级岗位,而是留着"初级软件开发工程师"这个 title,把门槛往上抬。
这解释了为什么很多人感觉市场对不上账:入口还在,招牌没换,进去的门槛高了。原来两年经验能投的岗位,现在要三到五年。
同一份研究还指出,留下来的初级岗位,要求的能力重心转向了问题解决、沟通和对细节的关注,而不是 AI 专项技能或者提示词工程。市场不是在要求新人会用某个工具,是在要求新人能做工具做不了的那部分。
另一个值得记的细节来自 SignalFire:大科技公司里一个工程经理现在带大约 12 名工程师,2019 年是 10 名;初创公司大约是 15 名。管理幅度在变宽,团队在往"经验密度"这个方向压。
公司内部正在发生什么
Anthropic 在 2026 年 10 月 16 日发了一份关于公司内部就业结构变化的报告,数据来自他们自己,所以得打个折看,但它给出了别处看不到的颗粒度:
初级员工占技术团队的比例从 21% 降到 14%;技术岗招聘中初级占比从 27% 降到 9%,2025 年 12 月之后降得尤其快。
在员工主导的会话里,agent 的工作时长在 2026 年 3 月超过员工时长,到 8 月达到约六比一。
每位工程师的代码提交量在半年里涨了约五倍。
会议时长同比上升约 20%,技术贡献者是 16%。
大约五分之一的受访员工说,自己的工作从"做这件事"变成了"管理做这件事的 agent"。
Anthropic 自己加了一句提醒:一家 AI 公司的数据不代表整体经济。这句话该被认真对待。但他们报告里的那个结构变化,和前面三组数据是同向的:初级岗位变薄,留在场上的人被推向判断、协调和验收。
还有一条反向证据同样该摆出来:有丹麦的研究发现,用 AI 的公司和不用 AI 的公司之间,入门级岗位并没有出现差距。这意味着"AI 直接导致初级岗位消失"这个因果链,目前还没有被单一研究钉死。招聘周期、利率、2021 年那波过度招聘的回吐,都在同一个池子里。
被拆掉的是学徒台阶
我觉得这件事真正的风险不在今年谁的简历被拒,在于一个更长的时间常数。
初级工程师这个岗位从来不只是"便宜的写代码的人"。它同时是培养中级的管道。一个人在初级岗位上写三年样板代码、修三年小 bug、被评审打回几十次,才长成一个能独立扛模块的中级。
现在被 AI 接走的,恰恰是这批最便宜的训练任务。写样板、生成测试脚本、清理 PR、改小 bug,这些正是 GitHub Copilot、Cursor、Claude Code 最擅长的部分。
于是出现了一个时间差:公司省下的是今年的人力成本,欠下的是三到五年后的中级供给。
SignalFire 的报告里提到,每个工程经理带的人变多了,这本身就说明团队在向经验密集的方向压。他们同时提示,入门级招聘塌陷几年之后,行业会遇到中级人才短缺。
IBM 的做法是少数公开的对冲:宣布 2026 年把美国的入门级招聘扩大到三倍,同时重写了初级软件开发岗的职位描述,让新人少写常规代码,多直接对接客户。Stripe 则把新人入职改成围绕评审 AI 生成的代码、写集成测试、结对做系统设计。
这两家做的事情是同一件:保留入口,但把入口里的活换成 AI 做不了的那部分。
缺口什么时候到
我把这个推演写成了一段可以自己调参数的脚本。逻辑不复杂:按每年的入门招聘量做队列,乘以留存率和晋升率,看几年后中级供给相对需求差多少。
需求侧我用了一个简化假设:中级需求保持不变。真实世界里它会波动,但保持不变已经足够说明问题,因为缺口来自供给端。
#!/usr/bin/env python3
"""入门招聘收缩对中级工程师供给的延迟影响推演。
base_hires: 基准年入门招聘量(相对值,2019 = 100)
hire_index: 之后各年入门招聘量指数
retention: 入门工程师年留存率
promotion: 第 N 年晋升为中级的比例
demand: 中级岗位年需求量(相对值)
"""
import json
from statistics import mean
BASE_HIRES = 100.0
RETENTION = 0.82
PROMOTION = {3: 0.45, 4: 0.30, 5: 0.15} # 入职第 N 年晋升中级的比例
def steady_state(base=BASE_HIRES, retention=RETENTION):
"""基准年招聘水平下的稳态中级供给,也就是需求侧的平衡点。"""
return sum(base * (retention ** age) * rate for age, rate in PROMOTION.items())
DEMAND = round(steady_state(), 1)
def cohort_supply(hire_index, base=BASE_HIRES, retention=RETENTION):
"""逐年推演:每年入职队列在若干年后贡献多少中级。
索引为负的年份(基准年之前)沿用首年招聘水平,
这样基准情景从第一年起就处在稳态,缺口为零。
"""
supply = []
for year in range(len(hire_index)):
total = 0.0
for age, rate in PROMOTION.items():
src = year - age
idx = hire_index[src] if src >= 0 else hire_index[0]
total += base * idx / 100.0 * (retention ** age) * rate
supply.append(round(total, 1))
return supply
def gap_report(hire_index, demand=DEMAND):
supply = cohort_supply(hire_index)
rows = []
for i, s in enumerate(supply):
rows.append({
"year": i,
"hire_index": hire_index[i],
"mid_supply": s,
"demand": demand,
"gap": round(s - demand, 1),
"gap_pct": round((s - demand) / demand * 100, 1),
})
return rows
def exposure(tasks, weights):
"""个人任务暴露度:时间占比 x 该任务被 AI 吸收的程度。"""
used = sum(tasks.values())
if abs(used - 1.0) > 0.01:
raise ValueError(f"任务时间占比合计应为 1.0,当前 {used:.2f}")
score = sum(tasks.get(k, 0.0) * weights.get(k, 0.0) for k in tasks)
ranked = sorted(
((k, round(v * weights.get(k, 0.0), 3)) for k, v in tasks.items()),
key=lambda x: -x[1],
)
return round(score, 3), ranked
WEIGHTS = {
"写样板代码": 0.9,
"写单元测试": 0.7,
"改小 bug": 0.6,
"写文档": 0.75,
"数据搬运脚本": 0.8,
"评审别人的代码": 0.25,
"定位线上问题": 0.2,
"需求澄清与拆解": 0.15,
"架构与技术选型": 0.1,
"跨团队协调": 0.1,
"跟客户对口径": 0.1,
}
MY_TASKS = {
"写样板代码": 0.08,
"写单元测试": 0.05,
"改小 bug": 0.07,
"写文档": 0.04,
"数据搬运脚本": 0.03,
"评审别人的代码": 0.22,
"定位线上问题": 0.15,
"需求澄清与拆解": 0.16,
"架构与技术选型": 0.10,
"跨团队协调": 0.06,
"跟客户对口径": 0.04,
}
SCENARIOS = {
"维持 2019 水平": [100] * 8,
"入门招聘腰斩": [100, 62, 45, 38, 35, 35, 35, 35],
"短暂收缩后恢复": [100, 62, 45, 70, 95, 100, 100, 100],
}
if __name__ == "__main__":
print(f"稳态需求基准 {DEMAND}")
for name, idx in SCENARIOS.items():
rows = gap_report(idx)
print(f"\n== {name} ==")
for r in rows[3:]:
flag = "缺" if r["gap"] < 0 else "余"
print(f" 第{r['year']}年 招聘指数{r['hire_index']:>3} "
f"中级供给{r['mid_supply']:>5} 需求{DEMAND} {flag}{abs(r['gap']):>5}"
f" ({r['gap_pct']:+.1f}%)")
score, ranked = exposure(MY_TASKS, WEIGHTS)
print(f"\n个人暴露度 {score:.0%}")
for k, v in ranked[:4]:
print(f" 主要暴露来源 {k} {v:.0%}")跑一遍,三种情景下的结果是:
稳态需求基准 43.9
== 维持 2019 水平 ==
第3年 招聘指数100 中级供给 43.9 需求43.9 余 0.0 (+0.0%)
第4年 招聘指数100 中级供给 43.9 需求43.9 余 0.0 (+0.0%)
第5年 招聘指数100 中级供给 43.9 需求43.9 余 0.0 (+0.0%)
第6年 招聘指数100 中级供给 43.9 需求43.9 余 0.0 (+0.0%)
第7年 招聘指数100 中级供给 43.9 需求43.9 余 0.0 (+0.0%)
== 入门招聘腰斩 ==
第3年 招聘指数 38 中级供给 43.9 需求43.9 余 0.0 (+0.0%)
第4年 招聘指数 35 中级供给 34.5 需求43.9 缺 9.4 (-21.4%)
第5年 招聘指数 35 中级供给 25.1 需求43.9 缺 18.8 (-42.8%)
第6年 招聘指数 35 中级供给 19.0 需求43.9 缺 24.9 (-56.7%)
第7年 招聘指数 35 中级供给 16.3 需求43.9 缺 27.6 (-62.9%)
== 短暂收缩后恢复 ==
第3年 招聘指数 70 中级供给 43.9 需求43.9 余 0.0 (+0.0%)
第4年 招聘指数 95 中级供给 34.5 需求43.9 缺 9.4 (-21.4%)
第5年 招聘指数100 中级供给 25.1 需求43.9 缺 18.8 (-42.8%)
第6年 招聘指数100 中级供给 26.9 需求43.9 缺 17.0 (-38.7%)
第7年 招聘指数100 中级供给 35.6 需求43.9 缺 8.3 (-18.9%)
个人暴露度 33%
主要暴露来源 写样板代码 7%
主要暴露来源 评审别人的代码 6%
主要暴露来源 改小 bug 4%
主要暴露来源 写单元测试 4%这个模型的参数全是我设的:留存率 0.82,第 3 到 5 年分别按 45%、30%、15% 晋升中级,需求取的是基准招聘水平下的稳态值 43.9。它不是预测,是敏感性演示,用来说明两件事。
第一件是延迟。收缩发生在第 1 年,缺口到第 4 年才出现,因为一个 2026 年入职的初级工程师要到 2029 年前后才成为中级。今天的招聘决策,账单在三年后。
第二件是不可逆。"短暂收缩后恢复"那组是最该看的:招聘指数在第 5 年就回到了 100,中级供给在第 7 年仍然差 18.9%。管道断了三年,接上之后流出来的还是三年后的事,中间那批人从来没有入职。持续腰斩的那组更直接,第 7 年缺 62.9%。
把暴露度算给自己看
脚本后半段的暴露度评分,是我用来给自己盘点的工具。权重表是主观的,依据是哪些任务在当前模型能力下最容易被接走:样板代码和文档这类有明确模式可循的活权重高,涉及判断、协调和担责的活权重低。
我按自己一周的实际时间填了一遍,暴露度是 33%。这个数字的意义不在于准不准,在于逼我把时间摊开看清楚。如果你的结果超过四成,说明你的工作里有相当一部分正在变成"AI 先写一遍"的活,那部分的价值会持续走低。
挪的方向也很清楚,就是权重低的那些:评审与验收、线上问题定位、需求澄清、架构取舍、跨团队协调、跟客户对口径。
这几项有个共同点:它们都要求你对结果负责。模型可以起草一版方案,它没法替你在事故会上说"这个决定是我做的"。
还有两个公开数据可以参考。要求 AI 技能的美国职位,平均薪资高出约 28%;AI 工程师是 2026 年美国增长最快的职位,招聘量同比涨 143%,DataCamp 分析 200 万条职位后给出的增幅是 255%。钱和岗位都在往"能判断模型产出"的那一侧移动。
带人的人要改什么
前面讲的是个人视角,带团队的人面对的是同一件事的另一面。
别把入门岗当成本项砍掉。 队列推演里那笔账在三年后付,砍的时候看不出来,付的时候补不回来。IBM 和 Stripe 的选择都不是砍,是改。
训练任务要换,不是取消。 原来交给新人练手的是写样板、生成测试脚本、清 PR。这些活现在 AI 做得更快,但它们承担的培养功能没有替代品。IBM 把初级 JD 改成少写常规代码、多跟客户打交道,Stripe 把新人入职改成评审 AI 产出、写集成测试、结对做系统设计,两家换掉的是任务,留着的是台阶。
产出的合格线要重画。 以前看的是写没写出来,现在该看能不能讲清楚这段改动为什么这么写、AI 给的另一个方案错在哪。前面那套暴露度评分也可以反过来用:给团队每个人盘一次时间去向,暴露度高的那部分活,要么交给工具,要么承认它已经不值钱了。
还有一条反直觉的:现在最该投入的不是让团队学会用 AI,是让团队学会判断 AI 的产出。前者两周就能上手,后者需要的是对系统的理解,而理解只能通过接触真实系统获得。新人接触真实系统的机会,正是被入口收窄拿走的那部分。
对个人,我改了三件事
第一件是停止用代码量衡量自己的产出。上一篇文章里我写过这件事的组织版本,个人版本同样成立:代码行数这个指标已经被 AI 废掉了,它现在衡量的只是你按了多少次 tab。
第二件是主动往验收侧挪。评审、测试策略、上线后的观测,这些活在我这儿的比重从两成提到了三成多。它们累,但它们同时是 AI 做不了的部分,也是将来能解释"为什么需要中级工程师"的部分。
第三件是把"没有初级岗"当成设计约束,而不是抱怨对象。带人的时候,我把原来交给新人练手的任务换成了让他们评审 AI 产出、写集成测试、跟我一起做设计评审。练的东西变了,练的目的没变:还是要长成能独立扛事的人。
这些数据该怎么用
先把事实和判断分开。
事实部分,全部有公开出处:斯坦福数字经济实验室 2026 年 8 月版本的 19% 缺口与资深组无缺口;斯坦福 HAI 2026 AI Index 里 22 到 25 岁开发者较 2024 年峰值下降约 20%;SignalFire 2026 报告里大厂入门招聘较 2019 年下降约 65%、初创约 76%、工程招聘仅下降 11%;IZA 论文中初级相对高级岗位下降 14% 到 15% 且机械工程无此效应;Anthropic 10 月 16 日报告里 27% 到 9% 的技术招聘初级占比;英国 DSIT 2026 年 6 月基于 LinkedIn 数据的分析里软件工程师入门级职位下降 27%。
这些数字的局限同样明确。职位数据不等于就业数据,不同研究的基线年份和"初级"定义各不相同,所以你会在不同报道里看到 20%、27%、65% 这些差得很远的数字,它们量的是不同的东西。英国那份分析明确声明不是因果证据。斯坦福的口径是"相对趋势的缺口",不是绝对人数的减少。丹麦的研究给出了相反的结论。
我自己的判断有三条,没有数据支撑,请当意见看:一是被拆掉的主要是学徒台阶而非岗位本身,长期风险在中级供给;二是招聘收缩的影响有三年左右延迟,且不可逆;三是个人该往验收侧挪,而不是往提示词技巧挪。
还有一件我确定不了的事:这轮收缩里有多少来自 AI,有多少来自利率、周期和 2021 年那波过度招聘的回吐。所有研究都在试图拆开这几股力量,目前没有一份拆得干净。
所以如果你问我冲击有多大,我的答案是:对还在场里的人,冲击不大,甚至多半是好事;对想进场的人,冲击很大,而且大在门口,不在屋子里。