# Vibe Coding 代码质量保障

> 如何确保 AI 生成的代码质量



你好，我是鱼皮。

很多同学在用 AI 开发时，会有这样的担心：AI 生成的代码靠谱吗？会不会有隐藏的 bug？

这个担心是有道理的。AI 虽然能快速生成代码，但它不能保证代码的质量。作为开发者，你需要建立一套质量保障体系。

本文我就来分享一些实用的方法，帮你确保 AI 生成的代码质量。




## 一、什么是好代码？

在讲如何保障质量之前，我们先要明确什么是好代码。




### 好代码的特征

什么样的代码才算好代码？

这个问题看似简单，但很多人说不清楚。其实，除了能运行之外，好代码最重要的是 **可读性好**：代码清晰易懂、符合团队开发规范，别人（包括未来的你）能快速理解。在此基础上，还要 **可维护性强**，修改和扩展都很容易，不会牵一发而动全身。

当然，这些都要建立在 **功能正确** 的前提下，代码能正确实现需求，没有 Bug。同时，**性能要合理**，在可接受的时间内完成任务，不浪费资源。此外，代码还要 **安全可靠**，没有安全漏洞、能处理异常情况。

![](https://pic.yupi.icu/1/goodcode%E5%A4%A7.jpeg)



### AI 生成代码的常见问题

那么，AI 生成的代码通常会有哪些问题呢？

根据我的经验，最常见的是 **过度复杂**，AI 为了实现功能，经常写很多不必要的代码。另一个常见问题是 **缺少边界处理**，AI 为了让代码能快速运行，可能只考虑正常情况，忽略了空值、错误等特殊情况。

AI 生成的代码还经常出现 **重复代码** 的问题。特别是在前端开发中，如果你让 AI 分别生成多个相似的页面，它不会主动复用代码，而是为每个页面生成独立的代码。

举个例子，假设你要做一个管理后台，有用户列表页、文章列表页、评论列表页。这三个页面的布局和功能都很相似：都是表格展示数据、都有搜索框、都有分页。但如果你分 3 次让 AI 生成，它会给你 3 套几乎一样的代码，只是数据字段不同。更好的做法是先让 AI 生成一个通用的列表组件，然后用不同的配置来复用。这样不仅代码量少，维护起来也容易。

有时候还会存在 **性能问题**，使用了低效的算法或数据结构。了解这些问题，你才能有针对性地检查和改进。




### 建立质量标准

知道了什么是好代码，接下来就要为你的项目建立明确的质量标准。

在代码规范方面，建议使用 ESLint 或 Prettier 统一代码风格，定义清晰的命名规则（比如变量用 camelCase 驼峰式写法，常量用 UPPER_SNAKE_CASE 写法），并规定好文件和文件夹的组织方式。

在功能标准上，要求所有功能都要有测试、要处理边界情况、错误要有友好的提示。

性能方面，可以设定具体的指标，比如页面加载时间不超过 3 秒，API 响应时间不超过 1 秒，数据量大时使用虚拟滚动等。

可以把这些标准写在项目文档里，让 AI 也知道。

💡 不过实际开发中还是要灵活，如果你只是单纯开发个 Demo 类的小项目，干就完了，不用考虑那么多。




## 二、代码审查

代码审查（Code Review）是保障质量的第一道防线。



### 为什么要审查 AI 代码？

有些同学觉得：AI 生成的代码能跑就行了，为什么还要审查？

这个想法其实挺危险的。

首先，AI 不是完美的，它会犯错，会生成有 Bug 的代码。更重要的是，AI 只知道技术，**不了解你的具体业务逻辑**，它生成的代码可能在技术上没问题，但在业务上不合理。

另外，AI 可能只关注当前功能，不考虑未来的扩展性。今天能跑的代码，明天可能就成了技术债。而且，审查代码也是一个学习的机会，能帮你理解代码的工作原理，提升自己的技术水平。所以，审查 AI 代码是必不可少的，尤其是对于有编程基础的同学。

![](https://pic.yupi.icu/1/whyreviewcode%E5%A4%A7.jpeg)




### 审查的重点

那么，审查 AI 生成的代码时，应该重点关注哪些方面呢？




#### 1、功能正确性

最基本的要求是：代码能不能正确实现需求？

这听起来简单，但很容易被忽视。你需要运行代码，**测试所有功能**，尝试各种输入，包括正常的和异常的。

特别要注意边界情况，比如空值、极大值、极小值等，这些往往是 Bug 的高发区。

举个例子：

```typescript
// AI 生成的代码
function divide(a: number, b: number): number {
  return a / b;
}
```

想想看，这段代码有什么问题呢？

答案是：没有处理除数为 0 的情况。

```typescript
// 改进后：
function divide(a: number, b: number): number {
  if (b === 0) {
    throw new Error('除数不能为 0');
  }
  return a / b;
}
```



#### 2、代码可读性

功能正确之后，接下来要看代码是否易读。

记住，代码是给人看的，不只是给机器执行的。

检查时要问自己几个问题：

- 变量名是否清晰？
- 函数名是否表达了功能？
- 逻辑是否容易理解？
- 是否需要添加注释？

如果你看代码时感到困惑，那别人也会困惑。

举个例子：

```typescript
// 不好的命名
function f(x: number): number {
  return x * 2 + 1;
}

// 好的命名
function calculateDiscountedPrice(originalPrice: number): number {
  const discount = 0.2; // 8 折优惠
  return originalPrice * (1 - discount);
}
```



#### 3、错误处理

代码要能优雅地处理错误，不能一出错就崩溃。

你要检查 API 调用有没有错误处理、用户输入有没有验证、异常情况有没有友好的提示。很多 AI 生成的代码只考虑了正常流程，完全忽略了错误处理，这是很危险的。

举个例子：

```typescript
// 不好的错误处理（根本没做）
async function fetchUser(id: string) {
  const response = await fetch(`/api/users/${id}`);
  const user = await response.json();
  return user;
}

// 好的错误处理
async function fetchUser(id: string) {
  try {
    const response = await fetch(`/api/users/${id}`);
    
    if (!response.ok) {
      throw new Error(`获取用户失败: ${response.statusText}`);
    }
    
    const user = await response.json();
    return { data: user, error: null };
  } catch (error) {
    console.error('获取用户出错:', error);
    return { data: null, error: error.message };
  }
}
```



#### 4、性能问题

然后是性能问题。代码要高效，不能浪费资源。

可以看看有没有不必要的循环、有没有重复的计算、数据结构选择是否合理。AI 有时候为了快速实现功能，会选择最简单但不是最高效的方案。

举个例子：

```typescript
// 性能不好
function findUser(users: User[], id: string): User | undefined {
  // 每次都遍历整个数组，O(n)
  return users.find(user => user.id === id);
}

// 性能更好
class UserManager {
  private userMap: Map<string, User>;
  
  constructor(users: User[]) {
    // 用 Map 存储，查找是 O(1)
    this.userMap = new Map(users.map(u => [u.id, u]));
  }
  
  findUser(id: string): User | undefined {
    return this.userMap.get(id);
  }
}
```



#### 5、安全问题

对于商业项目来说，这点至关重要。代码要安全，不能有漏洞。

需要检查有没有 SQL 注入风险、有没有 XSS 攻击风险、敏感信息有没有加密、API Key 有没有暴露。AI 对安全的理解可能不够深入，很容易留下安全隐患。

举个 SQL 注入的例子。SQL 注入是指攻击者通过在输入中插入恶意的 SQL 代码，来执行非预期的数据库操作。

比如下面这段代码是不安全的：

```typescript
// ❌ 不安全：直接拼接用户输入
const query = `SELECT * FROM users WHERE name = '${userName}'`;
```

假设用户在登录时输入用户名 `admin' OR '1'='1`，直接把这个输入拼接到 SQL 语句里，就会变成：

```sql
SELECT * FROM users WHERE name = 'admin' OR '1'='1'
```

这个查询会返回所有用户，因为 `'1'='1'` 永远为真。攻击者就能绕过验证登录任何账户。

正确的做法是使用参数化查询：

```typescript
// ✅ 安全：使用参数化查询
const query = 'SELECT * FROM users WHERE name = ?';
db.execute(query, [userName]);
```

参数化查询会自动转义特殊字符，防止 SQL 注入。

如果你对 Web 安全感兴趣，可以利用鱼皮 [免费的网络安全自学网](https://github.com/liyupi/ceshiya) 来学习这些知识：

![](https://pic.yupi.icu/1/%E6%B5%8B%E8%AF%95%E9%B8%AD%E7%BD%91%E7%AB%99.png)



### 审查流程

可以按照下面的步骤，建立一个系统的审查流程：

1. 自己先看一遍：快速浏览代码，看有没有明显问题

2. 运行测试：测试所有功能，包括边界情况

3. 逐行审查：仔细检查每一行代码，思考是否有问题

4. 记录问题：把发现的问题记下来

5. 要求 AI 改进：把问题反馈给 AI，让它修复

6. 再次审查：确认修复后的代码没有新问题

这个流程可能有点繁琐，但能大大提高代码质量。

对于没有编程基础的朋友，如果自己看不懂代码，可以利用其他的 AI 大模型来帮忙审查。这是一个很实用的技巧：**用多个 AI 交叉验证**。

比如用 Cursor（Claude）生成的代码，可以复制到 ChatGPT 或 Gemini，让它们帮你审查一遍：

```markdown
请审查这段代码，找出潜在的问题，包括 bug、性能问题、安全隐患。
```

不同的 AI 有不同的视角和训练数据，能互相补充，一个 AI 可能忽略的问题，另一个 AI 能发现。

我自己在做重要项目时，经常会让 2 ~ 3 个不同的 AI 审查同一段代码，然后综合它们的建议。这样虽然多花了点时间，但能大大降低出错的风险。特别是对于关键的业务逻辑、安全相关的代码、性能敏感的部分，多一层保障总是好的。



## 三、测试

测试是保障代码质量的关键手段。



### 为什么要写测试？

很多同学觉得写测试浪费时间，但其实恰恰相反。测试能在开发阶段就发现问题，而不是等到上线后用户发现。有了测试，你可以放心地重构代码，不怕改坏。而且，测试代码本身就是很好的文档，展示了如何使用你的函数或组件。

此外，虽然写测试要花时间，但能省下更多调试时间。想想看，如果你每次改代码都要手动测试所有功能，那得花多少时间？有了自动化测试，运行一下就知道有没有问题。

所以，写测试是值得的。

![](https://pic.yupi.icu/1/testpk%E5%A4%A7.jpeg)



### 测试的类型

测试主要有 3 种类型。

- 单元测试：测试单个函数或组件，速度快，容易定位问题，覆盖率要高。
- 集成测试：测试多个模块的协作，确保模块之间的接口正确，覆盖主要流程。
- 端到端测试：模拟用户的完整操作，测试整个系统，覆盖关键场景。

对于 Vibe Coding 项目，我建议 **重点写单元测试和集成测试**。端到端测试虽然也重要，但成本较高，可以只覆盖最关键的场景。



### 让 AI 帮你写测试

如今绝大多数的测试代码已经不需要人工编写了，你可以直接让 AI 帮你生成测试代码。

````markdown
请为这个函数写单元测试，覆盖正常情况和边界情况：
```typescript
function calculateTotal(items: CartItem[]): number {
  return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
```
````

AI 会生成类似这样的测试代码：

```typescript
import { describe, it, expect } from 'vitest';

describe('calculateTotal', () => {
  it('应该正确计算总价', () => {
    const items = [
      { price: 10, quantity: 2 },
      { price: 5, quantity: 3 }
    ];
    expect(calculateTotal(items)).toBe(35);
  });
  
  it('应该处理空数组', () => {
    expect(calculateTotal([])).toBe(0);
  });
  
  it('应该处理数量为 0 的情况', () => {
    const items = [{ price: 10, quantity: 0 }];
    expect(calculateTotal(items)).toBe(0);
  });
  
  it('应该处理小数', () => {
    const items = [{ price: 10.5, quantity: 2 }];
    expect(calculateTotal(items)).toBe(21);
  });
});
```

这段测试代码的作用是：用 `describe` 定义一个测试组（测试 calculateTotal 函数），然后用多个 `it` 定义具体的测试用例。每个测试用例都会调用函数并检查结果是否符合预期。比如第一个测试检查正常情况、第二个测试检查空数组、第三个测试检查数量为 0 的情况、第四个测试检查小数。运行这些测试时，如果所有 `expect` 都通过，说明函数工作正常；如果有任何一个失败，就说明代码有问题。

有了这些测试，你就能确保函数在各种情况下都能正常工作。



### 扩展知识 - 测试驱动开发（TDD）

你可以尝试测试驱动开发（Test-Driven Development，简称 TDD）。这是一种 “先写测试，再写代码” 的开发方式。

听起来很反直觉对吧？一般不都是先写代码，再写测试吗？

但 TDD 的逻辑是：你先定义好函数应该如何工作（写测试），然后让 AI 根据测试来实现功能。这样能确保代码从一开始就是符合需求的、可测试的。

具体流程是：

1. 先写一个会失败的测试（因为功能还没实现）
2. 然后让 AI 实现功能让测试通过，运行测试确保所有测试都通过
3. 最后优化代码但保持测试通过

这样一来，能避免写出 “看起来能用但实际有问题” 的代码。




## 四、调试技巧进阶

即使有了审查和测试，还是难免会遇到 Bug。这时候，你需要掌握调试技巧。



### 1、使用断点调试

很多同学调试代码时只会用 `console.log`，也就是在代码里加一行 `console.log(变量名)` 来打印变量的值，然后在浏览器控制台查看。

这个方法虽然简单，但效率不高，而且调试完还要把这些 log 删掉。

其实断点调试要高效得多。在 VS Code 或 Cursor 中，你只需要在代码行号左边点击设置断点，然后按 F5 开始调试。

![](https://pic.yupi.icu/1/image-20260105092822939.png)

代码会在断点处暂停，这时你可以查看所有变量的值：

![](https://pic.yupi.icu/1/image-20260105092855154.png)

还可以单步执行代码，看看每一步发生了什么。这比到处加 `console.log` 然后再删掉要方便多了。



### 2、浏览器调试工具

前端开发时，浏览器的调试工具是你的好帮手。在浏览器中按 F12 就能打开开发者工具。

里面有几个常用的面板：

- Console（控制台）面板可以查看日志和错误，执行 JavaScript 代码，查看变量值。
- Sources（源代码）面板可以设置断点，单步执行，查看调用栈。
- Network（网络）面板可以查看 API 请求，检查请求和响应，分析加载时间。
- Performance（性能）面板可以分析性能瓶颈，查看渲染时间，找出慢的操作。

![](https://pic.yupi.icu/1/image-20260105093342746.png)

掌握这些工具，你的调试效率会大大提高。



### 3、二分法定位问题

如果你不确定问题在哪里，可以试试二分法。

很好理解，直接把代码分成两半，注释掉其中一半，看问题是否还在。如果还在，说明问题在另一半；如果不在，说明问题在这一半。然后继续把有问题的那一半再分成两半，重复这个过程，直到找到问题。

这个方法虽然简单，但很有效，特别是在处理大段代码时。



### 4、橡皮鸭调试法

这是一个看似玄学呆板，实则有一定科学原理的方法。

当你被 bug 困住时，试着向别人（或者一只橡皮鸭）解释你的代码：阿巴阿巴，这个函数应该做什么…… 它先做了这个…… 然后做了那个…… 咦，这里好像不对……

很神奇的是，在解释的过程中，你往往就会发现问题。因为解释的过程会强迫你重新理清思路，从不同的角度看问题。

哪个程序员没有一只小黄鸭呢？

![](https://pic.yupi.icu/1/smallyellowduck%E4%B8%AD.jpeg)



### 5、让 AI 帮你调试

把错误信息和相关代码给 AI，让它帮你分析：

````markdown
这段代码报错了：
```
TypeError: Cannot read property 'map' of undefined
```

代码是：
```typescript
function UserList({ users }) {
  return (
    <div>
      {users.map(user => <UserCard key={user.id} user={user} />)}
    </div>
  );
}
```

请帮我分析问题并给出解决方案。
````

AI 会告诉你问题可能是 `users` 为 `undefined`，并给出解决方案。

这无疑是最多同学使用的方法，但这招不是 100% 有效的，可以优先尝试，解决不了再人工处理。



## 五、质量检查清单

可以建立一个质量检查清单，每次提交代码前都让 AI + 人工过一遍。

不过现在 AI 大模型的编程能力越来越强了，很多 AI 工具已经内置了代码检查能力，会自动提示一些常见问题。所以这个清单简单了解即可，不用死记硬背。




### 功能检查

- [ ] 所有功能都能正常工作
- [ ] 边界情况都处理了
- [ ] 错误情况有友好提示
- [ ] 用户体验流畅


### 代码检查

- [ ] 代码符合项目规范
- [ ] 变量和函数命名清晰
- [ ] 没有重复代码
- [ ] 复杂逻辑有注释
- [ ] 没有被注释掉的代码


### 性能检查

- [ ] 没有不必要的重复计算
- [ ] 列表渲染使用了 key
- [ ] 大数据量使用了分页或虚拟滚动
- [ ] 图片进行了优化


### 安全检查

- [ ] 用户输入都经过验证
- [ ] 敏感信息没有暴露
- [ ] API Key 使用环境变量
- [ ] 没有 SQL 注入风险


### 测试检查

- [ ] 核心功能有单元测试
- [ ] 测试覆盖率达标
- [ ] 所有测试都通过
- [ ] 手动测试了主要流程


### 文档检查

- [ ] README 是最新的
- [ ] 重要函数有注释
- [ ] API 接口有文档
- [ ] 环境变量有说明



## 六、使用 Linter 和 Formatter

自动化工具能帮你发现很多问题。

💡 这部分内容比较专业，主要适合有编程基础的同学。如果你是完全零基础，可以先跳过，等有需要时再回来看。




### ESLint 代码检查

ESLint 是一个 JavaScript / TypeScript 代码检查工具，能自动发现代码中的问题，比如未使用的变量、可能的 Bug、不符合规范的写法等。就像一个自动化的代码审查员，帮你在运行代码之前就发现问题。

安装和配置（最新的配置方法以 [官方文档](https://eslint.org/docs/latest/use/getting-started) 为准）：

```bash
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
```

创建 `.eslintrc.json` 配置文件，定义检查规则：

```json
{
  "parser": "@typescript-eslint/parser",
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended"
  ],
  "rules": {
    "no-console": "warn",
    "no-unused-vars": "error",
    "@typescript-eslint/no-explicit-any": "error"
  }
}
```

运行检查：

```bash
npm run lint
```

ESLint 会告诉你代码中的问题，比如未使用的变量、潜在的 Bug 等。



### Prettier 代码格式化

Prettier 是一个代码格式化工具，能自动调整代码的格式，比如缩进、换行、引号类型等，让代码看起来更整洁统一。就像 Word 的 “格式刷” 功能，一键就能让所有代码保持相同的风格。

安装（最新的用法以 [官方文档](https://prettier.io/) 为准）：

```bash
npm install -D prettier
```

创建 `.prettierrc` 配置文件，定义格式化规则，比如是否使用分号、使用单引号还是双引号、缩进几个空格等：

```json
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5"
}
```

运行格式化：

```bash
npx prettier --write "src/**/*.{ts,tsx}"
```

Prettier 会自动调整代码格式，让代码看起来更整洁。



### 在编辑器中集成

在 VS Code / Cursor / WebStorm 等其他编程工具中安装 ESLint 和 Prettier 插件，保存文件时自动检查和格式化。

以 VS Code 为例，在 `settings.json` 中配置：

```json
{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}
```

这样每次保存文件，代码就会自动格式化和修复问题。



### 在 Git 中集成

使用 Husky 和 lint-staged 这两个工具，可以在提交代码前自动检查。

Husky 是一个 Git 钩子工具，能在 Git 操作（如 commit、push）时自动执行脚本。lint-staged 则专门用来检查即将提交的文件，而不是整个项目。

执行命令安装这些工具：

```bash
npm install -D husky lint-staged
npx husky init
```

然后在 `package.json` 中配置：

```json
{
  "lint-staged": {
    "*.{ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}
```

这样每次执行 `git commit` 提交代码时，都会自动检查和格式化代码。




## 七、持续改进代码质量

代码质量不是一次性的工作，而是持续改进的过程。要定期花时间重构，简化复杂的函数，提取重复的代码，改进命名、添加注释。建议每周或每完成一个功能，花半小时重构一下，保持代码的整洁。

如果是团队开发，定期开代码审查会议会很有帮助。可以每周选几段代码一起审查，讨论哪里做得好、哪里可以改进、分享最佳实践、统一代码风格。这不仅能提高代码质量，还能促进团队成员之间的学习和交流。

此外，对于程序员来说，多看优秀的开源项目也很重要。React 的源码、Next.js 的源码、知名组件库的代码，都是学习的好材料。看看别人是怎么写的，学习他们的技巧和思路。每次发现 Bug 或遇到问题，记录下来：问题是什么、为什么会出现、如何修复的、如何避免再次出现。这些经验能帮你避免重复犯错，不断提升代码质量。




## 写在最后

代码质量是 Vibe Coding 中最容易被忽视，但又最重要的一环。AI 能帮你快速写代码，但不能保证代码质量。作为开发者，你需要建立一套完整的质量保障体系，或者起码知道什么样的代码是好的、高质量的。

最后总结一下本文的重点：

1. 明确质量标准：知道什么是好代码，建立项目的质量标准。

2. 认真审查代码：不要盲目相信 AI，要仔细审查每一行代码。

3. 写测试：测试是保障质量的关键，不要偷懒。

4. 掌握调试技巧：学会用断点、浏览器工具等高效调试。

5. 使用自动化工具：ESLint、Prettier 等工具能自动发现问题。

6. 持续改进：定期重构，学习优秀代码，记录经验教训。

快速开发很重要，但代码质量更重要。宁可慢一点，也要保证质量。

希望这些方法能帮你建立起完善的代码质量保障体系，让你的 Vibe Coding 项目更加稳定可靠。

加油小伙伴，冲冲冲！👍🏻




## 推荐资源

1）鱼皮 AI 导航网站：[AI 资源大全、最新 AI 资讯、免费 AI 教程](https://ai.codefather.cn)

2）编程导航学习圈：[学习路线、编程教程、实战项目、求职宝典、交流答疑](https://www.codefather.cn)

3）程序员面试八股文：[实习/校招/社招高频考点、企业真题解析](https://www.mianshiya.com)

4）程序员写简历神器：[专业模板、丰富例句、直通面试](https://www.laoyujianli.com)

5）1 对 1 模拟面试：[实习/校招/社招面试拿 Offer 必备](https://ai.mianshiya.com)
