前端开发 · 2026年2月20日

Vibe Coding反思潮:为什么AI写的代码能跑却不能维护

最近HN上有篇文章火了——《After Two Years of Vibecoding, I’m Back to Writing by Hand》,865个upvote。fast.ai也发了一篇《Breaking the Spell of Vibe Coding》,把vibe coding比作赌博成瘾。

作为一个每天都在用AI写代码的前端架构师,看到这些文章的第一反应是:终于有人说了。

但仔细想想,这些文章的结论又过于极端了。问题不在vibe coding本身,在于大多数人根本不知道怎么正确地用AI写代码。

什么是Vibe Coding

Andrej Karpathy今年初造了这个词:你跟AI说想要什么,AI给你代码,你不看代码直接跑,能跑就行。

听起来很爽对吧?问题是这套在prototype阶段确实能跑,但一旦要维护,灾难就来了。

我在Code Review里看到的真实案例

先说一个我团队里的事。上周review一个PR,一个数据获取的功能,代码长这样:

// AI生成的代码
async function fetchUserData(userId: string) {
  try {
    const response = await fetch(`/api/users/${userId}`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      },
      signal: AbortController.prototype.signal
    });
    
    if (!response.ok) {
      if (response.status === 401) {
        localStorage.removeItem('token');
        window.location.href = '/login';
        return null;
      }
      if (response.status === 404) {
        return null;
      }
      if (response.status === 429) {
        await new Promise(resolve => setTimeout(resolve, 1000));
        return fetchUserData(userId);
      }
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    const data = await response.json();
    return data;
  } catch (error) {
    if (error instanceof TypeError) {
      console.error('Network error:', error);
      return null;
    }
    throw error;
  }
}

看起来没毛病对吧?覆盖了各种edge case,错误处理很全面。

问题是——我们项目里有一套完整的数据获取层,基于React Query + 自定义的apiClient封装。认证、重试、错误处理全在里面了。这段代码应该是这样的:

// 项目约定的写法
const { data: user } = useQuery({
  queryKey: ['user', userId],
  queryFn: () => apiClient.get(`/users/${userId}`)
});

三行搞定。而且重试策略、token刷新、错误上报全部走的统一逻辑,不需要每个地方重新实现一遍。

Alex Kondov那篇文章说得好:“我不在乎代码怎么进你的IDE,我在乎你有没有care它。”

AI不知道你项目里有什么约定。它只知道通用最佳实践。这就是vibe coding最大的坑——代码能跑,但跟项目完全脱节。

Dark Flow:为什么Vibe Coding会上瘾

fast.ai那篇文章提出了一个很有意思的概念:Dark Flow(暗流)。

正常写代码时的心流体验(Flow)是:你的能力和挑战匹配,你能清楚感知自己做得好不好。但vibe coding打破了这两个条件:

  • 你不知道AI生成的代码质量到底怎么样(缺少清晰反馈)
  • 挑战和技能的匹配是模糊的(你在指导AI,但你真的在控制它吗?)
  • AI产出的大量代码给你一种”高产出”的错觉,就像老虎机的”Loss Disguised as Win”

Flask创始人Armin Ronacher的自述特别真实:”我花了两个月疯狂prompt,造了一堆工具,结果发现大部分根本没用上,或者根本不像我以为的那样工作。”

这个描述跟赌博成瘾的模式一模一样。你觉得自己在赢(代码在跑),但实际上你在输(技术债在积累)。

正确的姿势:AI辅助 vs Vibe Coding

我自己每天都在用Claude Code和Copilot,但我不vibe code。区别在哪?

Vibe Coding:“帮我做一个用户管理页面”→ 拿到代码 → 跑一下 → 能跑就merge

AI辅助开发:“帮我做一个用户管理页面”→ 拿到代码 → 读每一行 → 改成符合项目规范的 → 补上项目特定的逻辑 → 写测试 → merge

关键区别:你要读代码

我团队的规范是这样的,发给AI的prompt必须包含项目上下文:

## 项目约定
- 数据获取:使用useQuery + apiClient,不要手写fetch
- 状态管理:Zustand,不要用Redux或Context
- 样式:Tailwind CSS,不要用CSS Modules
- 组件:函数组件 + hooks,不要用class
- 错误处理:统一走ErrorBoundary + apiClient拦截器

## 目录结构
src/
  features/
    user/
      components/   # UI组件
      hooks/        # 业务hooks
      services/     # API调用
      types/        # 类型定义

把这些喂给AI之后,生成的代码质量完全不一样。AI需要约束,跟带新人一样——你不告诉他项目规范,他就按自己的理解来。

一个实际项目的对比数据

上个月我们团队做了个实验,同一个功能模块(后台数据Dashboard),分别用三种方式完成:

指标 纯手写 Vibe Coding AI辅助(带约束)
完成时间 16h 4h 8h
代码行数 820行 2400行 900行
Code Review通过率 首次通过 3轮修改 1轮修改
上线后bug数 1个 7个 2个
后续修改成本 极高(几乎重写)

Vibe coding的代码行数是其他方式的3倍——因为AI会重新实现项目里已有的功能。那2400行代码里有一半是重复轮子。最后修改的时候,维护的同事直接说”不如我重写”。

而带约束的AI辅助开发,时间是纯手写的一半,质量接近手写。这才是正确的打开方式。

给前端团队的具体建议

1. 建一份AI Context文档

每个项目根目录放一个CLAUDE.md或COPILOT.md,写清楚项目技术栈、约定、禁忌。Claude Code和Cursor都会自动读取这个文件。

# CLAUDE.md

## Tech Stack
- React 19 + TypeScript 5.7
- Tanstack Query v5 for data fetching
- Zustand for state management
- Tailwind CSS v4

## Conventions
- All API calls go through src/lib/api-client.ts
- Use barrel exports (index.ts) in each feature folder
- Error boundaries at route level, not component level
- No inline styles, no CSS-in-JS
- Prefer composition over prop drilling

## DO NOT
- Do not use fetch() directly
- Do not create new utility files without checking src/utils/ first
- Do not use any as type escape

2. PR模板里加一条

在PR模板里加一个checkbox:”我已检查AI生成的代码是否符合项目约定”。很简单,但能提醒开发者别无脑merge。

3. 限制AI生成代码的scope

让AI做擅长的事:写类型定义、写测试用例、写工具函数、做代码转换(比如Class Component迁移到Hooks)。不要让AI从零搭一个完整模块——那就是在请它造轮子。

4. Code Review时关注”味道”

AI生成的代码有几个明显特征:

  • 过度防御性编程(每个函数都try-catch)
  • 重新实现已有功能(明明有lodash还自己写deepClone)
  • 过长的函数体(因为AI喜欢把所有逻辑放一起)
  • 注释太”正确”了(真人不会写”This function handles the user authentication flow”这种废话注释)

行业趋势

vibe coding反思潮不是偶然。2024年AI coding工具刚爆发的时候,大家都在兴奋期,觉得程序员要被替代了。两年过去,踩够了坑,行业开始回归理性。

Replit CEO说CEO们可以自己vibe code不需要工程师——这话在HN被喷得很惨。因为写代码从来不是瓶颈,维护代码才是。能跑的代码和能维护的代码之间差着十万八千里。

我的判断:AI coding工具会继续进化,但vibe coding作为一种开发方式会逐渐被淘汰。取代它的是更结构化的AI辅助开发——AI理解你的项目上下文、遵守你的编码规范、在你的架构约束下工作。

Claude Code的CLAUDE.md、Cursor的.cursorrules,这些都是在往这个方向走。未来的AI coding不是”你说什么AI做什么”,而是”AI在你定义的框架里帮你加速”。

工具不是问题,用法才是。