头图
上周我做了一个实验:卸掉 Claude Code,不碰 Codex,回到纯手写代码的状态,坚持一整周。不是为了证明什么,而是因为有一天写代码的时候,我发现自己连一个 Array.reduce 的回调参数顺序都想不起来了——以前闭着眼都能写。这件事吓到我了。

为什么要做这个实验

先交代背景。我从今年初开始用 Claude Code 做主力开发工具,中间还穿插用 OpenAI 的 Codex,到现在差不多半年。

半年里,我的开发效率确实提升了很多。需要一个新组件,在终端里用自然语言描述一下,Claude Code 直接生成整个文件。写单元测试,一句"给这个模块补全测试用例",批量搞定。遇到不熟的 API,不用翻文档,直接问它。甚至重构、调试、写文档,它都能一条龙做完。

但上周三,我在没有联网的高铁上写一个很简单的数据处理函数时:

const total = orders.reduce((  // 我停在这里了

我脑子一片空白。

reduce 的回调第一个参数是累加器还是当前元素来着?第二个参数呢?初始值放在哪?

以前这些东西是肌肉记忆,不需要思考。但那一刻,没有 Claude Code 帮我补全,我居然卡住了。

我不是不会写代码了,但我正在失去"不依赖 AI 也能写代码"的能力。

这让我非常不安。于是我决定关掉所有 AI 编程工具,纯手写一周,看看到底退化到了什么程度。

实验规则

  • 卸载 Claude Code CLI
  • 不用 Codex、Copilot 或任何 AI 编程 Agent
  • 编辑器只保留 VS Code 原生功能(变量补全、import 路径等非 AI 补全)
  • 可以查文档,但不能用 ChatGPT / Claude 问代码问题
  • 时间:完整的一个工作周,周一到周五

当周正好有一个中等复杂度的需求:给后台管理系统加一个数据导出功能,支持 CSV 和 Excel 格式,带筛选条件和分页导出。不算简单,但也不是什么高难度的活。

Day 1:像回到了 2023 年

第一天最大的感受是——

不是慢一点,是那种"我怎么连这个都要想一下"的慢。

写一个 React 表单组件,以前在终端里跟 Claude Code 说一句"帮我写一个带验证的注册表单",30 秒整个文件就出来了。现在我需要:

  1. 手动写 useState 的声明
  2. 手动写 onChange 处理函数
  3. 手动写 onSubmitpreventDefault
  4. 手动写表单验证逻辑

每一步都不难,但合在一起就是慢。以前 Claude Code 半分钟就能生成一整个组件,现在我手写了四十分钟。

更让我焦虑的是,我发现自己频繁地去看之前的代码——不是因为需要理解业务逻辑,而是因为我忘了某个工具函数的参数怎么传。

比如项目里封装的请求函数:

// 我记得大概是这样,但参数顺序记不清了
const res = await request('/api/export', {
  method: 'POST',
  // 第二个参数是 config 还是 data 来着?
  // headers 在哪一层?
});

半年前我是写这个封装的人。半年后我需要翻源码才能确认用法。

Day 1 产出:平时一天能完成的量,只做了大概 60%。

Day 2-3:最痛苦的阶段

第二天和第三天是最难熬的。

不是因为不会写,而是因为大脑在不断做一件事:抵抗"打开 AI"的冲动。

每次遇到一个需要想两秒的地方,我的第一反应不是思考,而是想切到终端敲 claude。这个反应是无意识的,就像你想查东西时手会自动伸向手机一样。

用 Claude Code 和 Codex 这种 Agent 型工具养成的习惯更可怕——因为它不只是帮你"补全一行",而是帮你"做完一整件事"。你甚至不需要想代码结构,直接用自然语言描述需求就行。这意味着一旦离开它,你不只是打字变慢,是连"怎么拆解任务"都要重新适应

我数了一下,Day 2 一天里我有 37 次想打开 AI 的冲动。

其中大概:

  • 15 次是因为忘了某个 API 的用法(可以查文档解决)
  • 12 次是因为懒得写样板代码(以前直接让 Claude Code 整个文件生成)
  • 7 次是遇到了真正需要思考的问题(这些才是有价值的思考)
  • 3 次是想让 AI 帮我写正则表达式(正则确实该用工具)

有意思的发现:37 次冲动里,只有 7 次是真正"需要"AI 帮助的。其他 30 次,本质上是懒和习惯。

到第三天下午,一件事情开始发生——我的手指开始"记起来"了。

useEffect 的时候,不再需要想参数顺序。写 fetch 的时候,then 链自然地流出来。写 CSS Flex 布局的时候,不再纠结 justify-contentalign-items 哪个是横向哪个是纵向。

这些东西并没有丢失,它们只是被 AI 的即时补全"盖住了"——你不需要从记忆里取出它们,所以它们的检索路径变弱了。但它们还在。

Day 2-3 产出:恢复到平时的 70-75%。

Day 4-5:一个意外的发现

到第四天,一件出乎意料的事情发生了。

我写的代码质量变高了。

不是主观感受,是客观指标。我比较了两份代码:

AI 辅助写的导出模块(一个月前的类似需求):

async function exportData(filters, format) {
  const data = await fetchAllData(filters);
  if (format === 'csv') {
    const csv = data.map(row => 
      Object.values(row).join(',')
    ).join('\n');
    downloadFile(csv, 'export.csv', 'text/csv');
  } else if (format === 'excel') {
    const wb = XLSX.utils.json_to_sheet(data);
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, wb, 'Sheet1');
    XLSX.writeFile(workbook, 'export.xlsx');
  }
}

手写的导出模块(这周):

type ExportFormat = 'csv' | 'excel';

interface ExportOptions {
  filters: FilterParams;
  format: ExportFormat;
  pageSize?: number;
  onProgress?: (percent: number) => void;
}

async function exportData({ filters, format, pageSize = 1000, onProgress }: ExportOptions) {
  const totalCount = await fetchCount(filters);
  const pages = Math.ceil(totalCount / pageSize);
  const allData: ExportRow[] = [];

  for (let page = 1; page <= pages; page++) {
    const chunk = await fetchPage(filters, page, pageSize);
    allData.push(...chunk);
    onProgress?.(Math.round((page / pages) * 100));
  }

  const exporter = exporters[format];
  exporter(allData);
}

const exporters: Record<ExportFormat, (data: ExportRow[]) => void> = {
  csv: (data) => {
    const headers = Object.keys(data[0]).join(',');
    const rows = data.map(row => 
      Object.values(row).map(v => `"${String(v).replace(/"/g, '""')}"`).join(',')
    );
    downloadFile([headers, ...rows].join('\n'), 'export.csv', 'text/csv');
  },
  excel: (data) => {
    const ws = XLSX.utils.json_to_sheet(data);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'Data');
    XLSX.writeFile(wb, 'export.xlsx');
  },
};

区别在哪?

  1. 分页导出 + 进度回调:数据量大时不会一次性拉全部数据撑爆内存。AI 生成的版本直接 fetchAllData,一万条数据就卡了。
  2. CSV 值的转义处理:手写版本处理了引号转义(""),AI 版本没有——导出的 CSV 如果数据里有逗号就会错列。
  3. 类型安全:手写版本有完整的 TypeScript 类型约束,AI 版本全是 any
  4. 可扩展性:用 exporters 对象替代 if-else,加新格式只需要加一个 key。

为什么手写反而质量更高?

因为当你手写的时候,你会思考

AI 补全的速度太快了,快到你来不及想"这里需要考虑什么边界条件"。Claude Code 和 Codex 更夸张——你连代码都不用看,说一句"帮我写个导出功能",整个文件就出来了。你扫了一眼,"嗯,能跑",就过了。

但手写的时候,你被迫慢下来。慢下来就会想:数据量大了怎么办?有没有特殊字符?类型安全吗?以后要加新格式怎么扩展?

速度是代码质量的敌人。 AI 让你太快了。

Day 4-5 产出:恢复到平时的 85%,但代码质量明显更高。

我的结论

1. AI 造成的不是"能力退化",而是"能力休眠"

那些 API 参数顺序、语法细节,并没有从你脑子里消失。它们只是因为长期不被调用,检索速度变慢了。关掉 AI 三天后,大部分都回来了。

但如果一个初级开发者从第一天就完全依赖 AI 写代码,他可能根本没有建立过这些记忆。这才是真正危险的情况。

2. AI 补全在"加速编码"的同时,也在"加速跳过思考"

写代码最有价值的部分不是敲键盘,是想清楚要怎么写。AI 把"敲键盘"的时间压缩到了接近零,但副作用是连"思考"的窗口也一起压缩了。

3. 我不会戒掉 AI,但我改变了用法

实验结束后,我重新装回了 Claude Code。但我做了两个调整:

调整一:核心逻辑手写,样板代码用 AI。

涉及业务判断、数据处理、状态管理的代码,我会手写。表单、列表、CRUD 这种重复性高的代码,继续让 Claude Code 或 Codex 生成。

调整二:每周保留半天"无 AI 编程时间"。

就像运动员不能只靠器械训练一样,程序员也需要定期"徒手"写代码,保持基础能力不退化。

最后

我不是劝你关掉 AI。2026 年了,不用 AI 写代码确实会被淘汰。

但我建议你试一下:关掉 AI,纯手写一天代码。

不需要一周,就一天。看看你会不会像我一样,在 reduce 的参数顺序上卡住。

如果卡住了——不用慌,你的能力还在。但这是一个信号,提醒你该偶尔"脱离辅助"练一练了。

你有多久没有不靠 AI 写过完整的代码了?评论区说说。


kyriewen
329 声望55 粉丝

独立开发者 / 前端工程师