AI编程系列之8:从 0 到 1 做一个完整 Web 项目——AI Coding 全流程复盘
目录
理论讲了 7 篇,是时候"真刀真枪"了。这一篇我会带你完整复盘一个 Web 项目的 AI 编程流程:用 6 步做出一个书签收藏工具,并在每一步暴露真实会出现的问题。
这篇不是"完美无缺的教程",而是"带坑的实战复盘"。
前言
AI 编程相关的教程,在 2026 年的中文互联网上已经非常多了。但绝大多数教程有同一个问题:只展示成功路径。作者把 AI 一次就跑通的代码贴出来,把"我尝试了 3 次才对"的中间过程剪掉,给读者一种"只要照着做就能成功"的错觉。
实际情况是:AI 编程项目的第一次跑通率大约只有 60%。剩下的 40% 几乎全集中在三类事情上——依赖装错、边界条件漏掉、AI 自己写的测试形似神不似。
所以这一篇,我会故意保留所有踩坑的瞬间。我希望你读完之后,不是"我也能照做",而是"我也会遇到这些坑,并且知道怎么排查"。
我会用到的工具栈是 Claude Code(终端版 AI 编程助手)+ Next.js 16 + TypeScript + Prisma 5 + SQLite + TailwindCSS 4。文中涉及三个斜杠命令:/plan(让 AI 先出方案再动手)、/init(生成项目级 CLAUDE.md)、/security-review(让 AI 对项目做安全审查)。没用过 Claude Code 的读者可以跳过这些命令,但 6 步流程本身对任何 AI 编程工具都适用。
1. 案例背景:书签收藏工具
为什么选这个项目? 因为它足够小(半天能做完),又足够真实(覆盖了 Web 项目的核心环节:前端、后端、数据库、部署)。如果你正在学 AI 编程,这是一个非常合适的"第一个完整项目"——它不像 Todo App 那么空,也不像电商系统那么重。
功能需求(来自我自己的真实痛点):
我日常浏览网页会积累大量书签,浏览器自带的收藏夹有两个问题:一是不能加描述,二是不能跨设备同步(不登录账号的情况下)。所以我想要一个轻量级的、能在浏览器里访问的、可以加描述和标签的书签工具。最简版只做 6 件事:
- 添加书签(标题、URL、描述、标签)
- 列表展示所有书签(卡片式布局)
- 按标签筛选(多选)
- 搜索书签(按标题和 URL 模糊匹配)
- 编辑和删除书签
- 数据持久化(用 SQLite)
为什么选 SQLite 而不是 Postgres? 因为这是个个人工具,用户量就我自己。SQLite 零配置、单文件、Prisma 对它支持最完整。等真要部署到公网,再切到云数据库——这个切换在第 6 步会详细讲。
技术栈选型理由:Next.js 16 是当前版本,App Router 比 Pages Router 更适合 AI 生成代码(约定更少)。Prisma 5 的 schema-first 设计让 AI 容易理解数据模型。TailwindCSS 4 让我不用纠结 CSS 类名(AI 生成的样式一般也能直接用)。TypeScript 必选——AI 生成的 JS 代码在大型项目里很难维护,加了类型等于加了一层保护。
2. 6 步完整流程
下面这 6 步是我在真实项目里跑通过的流程,你可以直接套用。每一步都有"会卡在哪"的具体描述。
2.1 第 1 步:描述需求
打开终端,启动 Claude Code:
$ mkdir ~/projects/bookmark-manager
$ cd ~/projects/bookmark-manager
$ git init
$ claude
进入 Claude Code 之后,先输入需求描述。这一步看起来简单,但实际上有 80% 的项目失败都和需求写得不够具体有关。很多新手的需求是"我想做一个书签工具",AI 收到这种需求只能瞎猜——最后做出来的东西和你想的完全不是一回事。
正确的需求描述应该包含三件事:核心功能、技术栈、边界。核心功能告诉 AI “做什么”,技术栈告诉 AI “用什么做”,边界告诉 AI “不要做什么”。
我要做一个书签收藏工具。
核心功能:
1. 添加书签(字段:标题、URL、描述、标签)
2. 列表展示所有书签(卡片式布局)
3. 按标签筛选(多选)
4. 搜索书签(按标题/URL 模糊匹配)
5. 编辑/删除书签
6. 数据持久化(SQLite)
技术栈:Next.js 16 + TypeScript + Prisma + TailwindCSS。
请用 /plan 模式先出架构设计,不要直接动手。
这一步的关键:用 /plan 模式让 AI 先出方案。AI 会给你一份包含数据库设计、API 列表、目录结构的方案——先审核,再动手。这一步绝对不能省。我见过太多新手跳过了这一步,结果 AI 写了一版、又推翻重写、又推翻重写,三次下来代码库里堆了三套不同架构的废代码。
/plan 的另一个隐藏好处:它把"决策"和"执行"分开了。AI 在 plan 阶段是冷静的,在执行阶段会进入"赶紧把代码写完"的模式。先决策、再执行,AI 给你的方案质量会高很多。
2.2 第 2 步:生成项目骨架
方案确认后,让 AI 生成项目骨架。骨架决定项目 80% 的命运——一个目录结构混乱的项目,后期怎么补都补不回来。
确认方案,请按以下顺序执行:
1. 用 create-next-app 创建项目
2. 初始化 Prisma,定义数据模型
3. 安装依赖(prisma、@prisma/client、bcryptjs 等)
4. 写 CLAUDE.md
5. 创建基础目录结构
这一步你会遇到的第一个问题:AI 可能会跳过某些步骤。它会默认"你已经装了 X",但你其实没装。比如 bcryptjs 这种库,光装运行时包没用,还得装类型定义包 @types/bcryptjs。AI 经常忘了这一步,导致 TypeScript 编译时报错。
正确做法:每一步执行完,立刻检查它实际做了什么。不要等所有步骤跑完再统一检查——那时如果出错,你不知道是哪一步埋的雷。
第二个常见问题:AI 在"创建目录结构"时会创建一堆空文件夹,等真要用的时候又找不到。这是因为它没区分"逻辑目录"(代码中要 import 的)和"物理目录"(实际创建的)。正确做法:让它直接生成最少一个占位文件(比如 lib/db.ts 里写一行 // 占位),目录才算真的存在。
注意:bcryptjs 没有类型,需要装 @types/bcryptjs。
另外每个目录都要至少有一个文件,不能留空目录。
2.3 第 3 步:追问补完
骨架搭好后,别急着写业务代码。这一步很多人会跳过,但我建议至少花 30 分钟——它能帮你省后面 3 小时的调试时间。
先用 /init 让 AI 生成一份项目级的 CLAUDE.md,然后人工校对。项目级 CLAUDE.md 至少要包含 5 个模块:技术栈(写明版本号)、目录结构、编码规范、当前进度、禁忌清单。
为什么要写"禁忌清单"?因为 AI 不知道你这个项目的历史踩坑——比如"不要用 lodash,用原生 ES"、“不要把数据库查询写在客户端组件里”。这些规则如果写在 CLAUDE.md 里,AI 每次生成代码都会看一眼,比你每次提醒它高效 10 倍。
这一步最容易犯的错:把 CLAUDE.md 写得很长(超过 200 行)。CLAUDE.md 不是文档,是给 AI 看的"宪法"。它应该短而硬——每个规则不超过两行,最好带一个反例。如果 CLAUDE.md 超过 200 行,AI 会在上下文中忽略其中一部分,效果反而变差。
2.4 第 4 步:写测试
这一步是最容易被忽略的。很多新手直接让 AI 写业务代码,跳过测试。他们觉得"测试不重要,先把功能跑起来再说"。结果就是:上线后出 Bug,不知道是哪里错了。改了一个 Bug,又冒出三个 Bug。最后整个项目变成"不敢动"的状态——因为每次改都可能引发连锁问题。
正确姿势:
请为书签的 CRUD API 写测试。
要求:
1. 用 Vitest + Supertest
2. 覆盖正常路径和异常路径
3. 至少 5 个测试用例
4. 测试文件放在 src/__tests__/ 目录下
这里有个隐藏的坑:很多 AI 写的测试是"自证正确"的——它写一个 add(2, 3),然后测试 expect(add(2, 3)).toBe(5)。这种测试即使错了你也发现不了,因为它是和实现一对一写的。
改进方法:让 AI 在写测试前先列出"这个函数应该有哪些行为",再针对每个行为写测试。这相当于在写测试之前先写测试大纲。这样 AI 就没法偷懒了。
另一个隐藏的坑:测试和真实环境的耦合度。AI 经常把测试写成"调用真实 HTTP 接口"——也就是假设 dev server 已经起来了。这种测试在本地手跑没问题,在 CI 里直接挂。正确做法:让 AI 直接调 handler 函数,不走 HTTP 层。
2.5 第 5 步:修 Bug
测试跑完后,一定会有失败的测试。这不是测试写错了,是好事——它说明你的测试真的在测东西。
AI 编程项目里,最常见的 Bug 模式有三种:
第一种是数据类型不匹配。比如 Prisma 返回的 Decimal 类型,前端期望 number。Prisma 的 schema 里写的是 Decimal,但前端拿到数据直接 .toFixed() 就报错。这种 Bug 的特征是"开发环境能跑,生产环境报错",因为 Prisma 在开发环境会自动转成 number,生产环境不会。
第二种是边界条件没处理。比如空字符串、超长 URL、特殊字符。AI 在训练数据里看到的代码 90% 是"主流程",边界处理的代码只占 10%。所以它写出来的代码天生就容易漏边界。
第三种是异步逻辑出错。比如 race condition——用户快速点击两次"删除",结果只删了一个但 UI 显示删了两个。AI 很难理解并发场景,因为它训练数据里的代码大多是"用户只点一次"的假设。
修 Bug 的正确姿势:把报错信息完整地贴给 AI,不要只贴 Error: ...。要带上调用栈、相关代码、环境信息。AI 看到的信息越多,定位越准。
测试失败了。错误信息:
[完整粘贴报错,包括调用栈]
相关代码:[粘贴相关代码]
环境:Node 22.13.0, macOS 14.4
这一步的隐藏陷阱:AI 修 Bug 经常"修一处坏三处"。因为它修一个错误时,会顺带改其他看起来相关的代码,结果把本来对的代码改错了。正确做法:每次 AI 改完后,立刻跑全部测试,不要只跑它刚改的那一个。如果有别的测试挂了,立刻让它回滚。
2.6 第 6 步:部署
请用 Vercel 部署这个项目。
要求:
1. 准备部署需要的 vercel.json 配置
2. 把 SQLite 切换到 Vercel Postgres(生产环境)
3. 配置环境变量
4. 给我部署步骤清单
这一步通常踩的坑:SQLite 在 Vercel 上不工作(Vercel 是 serverless,文件系统是只读的)。必须切换到云数据库。很多新手在这一步才发现要换数据库,所有 Prisma 查询都要重新适配 Postgres 特有的语法(比如 SQLite 不支持 JSON 类型,Postgres 支持;Postgres 的 ILIKE 和 SQLite 的 LIKE 行为不一样)。
部署前的最后一项检查:环境变量。Next.js 项目的环境变量分两类:NEXT_PUBLIC_* 开头的会被打包到客户端,没开头的只在服务端运行。AI 经常把敏感信息(比如数据库连接字符串)写到 NEXT_PUBLIC_* 里,导致连接字符串暴露在客户端 bundle 里。这一项建议用自动化扫描:
grep -r "NEXT_PUBLIC_" .next/static/ 2>/dev/null | head -5
如果在客户端 bundle 里看到了 DATABASE_URL,立刻停下来改。

3. 演示中"暴露"的 4 类问题
下面这 4 类问题是几乎所有 AI 编程项目都会遇到的。我把真实的报错和原因分析写下来。
3.1 问题 1:一次跑不通(“npm run dev” 启动报错)
最经典的报错有两种。第一种是模块找不到:
Error: Cannot find module '@prisma/client'
第二种是数据库没初始化:
PrismaClientInitializationError:
Invalid `prisma.bookmark.findMany()` invocation:
Database file at ./prisma/dev.db does not exist
根因分析:这两个报错看起来不一样,但本质是同一类问题——Prisma 的初始化流程有 3 步,AI 经常漏掉其中某一步。这 3 步是:生成客户端(npx prisma generate)、应用迁移(npx prisma migrate dev)、填充种子数据(npx prisma db seed)。任何一步漏了,都会导致后面启动失败。
为什么 AI 会漏?因为 Prisma 的官方教程把这 3 步写在了不同章节,AI 训练时把这些章节的代码片段混在一起用,经常只执行其中一部分。
修复套路:
$ npx prisma generate
$ npx prisma migrate dev --name init
$ npx prisma db seed
3.2 问题 2:边界条件(空字符串、超长 URL)
这一类 Bug 在 AI 编程项目里出现的频率几乎是 100%。AI 写的代码主流程通常没问题,但边界几乎一定会漏。
典型 Bug 场景:用户输入空标题 → AI 没拦截 → 列表里显示一张空卡片。用户输入 5000 字描述 → 列表排版崩了。用户输入 "javascript:alert(1)" 作为 URL → 触发 XSS 攻击。
为什么 AI 容易漏边界?这是个统计规律,不是 AI 笨。AI 的训练数据里,“主流程"代码(if user exists: create record)的出现频率远高于"边界处理"代码(if title.length == 0: return error)。AI 在生成时倾向于生成"高频模式”,所以边界就容易被跳过。
修复套路:在 AI 写完业务代码后,立刻让它补一遍输入验证:
请给所有 API 加 Zod 验证:
1. 标题不能为空,长度 1-100
2. URL 必须是 http/https 开头
3. 描述最多 500 字
4. 标签最多 5 个
Zod 是 TypeScript 的运行时验证库,比手写 if 链更安全,AI 也更熟悉。
3.3 问题 3:测试形似神不似
这一类 Bug 是最隐蔽的——它不会让测试失败,反而让测试通过,但实际上没在测东西。
典型症状:
test('should create bookmark', async () => {
const result = await createBookmark({ title: 'test' });
expect(result).toBeTruthy();
});
这段代码看起来在测"创建书签"功能,但它只检查 result 不是 null 或 undefined。如果 createBookmark 函数实现有 bug——比如它返回了一个空对象 {}——这个测试也会通过。
这种 Bug 的本质:AI 在写测试时复制了"测试的形",但忽略了"测试的义"。它知道测试要做 expect,但不知道 expect 应该具体检查什么。
修复套路:明确告诉 AI 写严格测试:
请写严格的测试:
1. 检查返回对象的每个字段(title、url、description、tags)
2. 检查数据库是否真的写入了(用 prisma.bookmark.findUnique 验证)
3. 检查异常情况(重复 URL 应该报错)
4. 用 snapshot 测试验证关键输出
更系统的做法是让 AI 在写测试之前先写测试大纲——列出每个函数的所有行为分支,再针对每个分支写测试。这样 AI 就没法偷懒了。
3.4 问题 4:安全风险
AI 编程项目的安全风险比手写项目更高,原因是 AI 不理解业务上下文。它不知道你的"书签"是个人用的还是要给一万个用户用的——它会用通用的、最简单的实现,而这通常不安全。
典型漏洞:
第一类是密码明文存储(不用 bcrypt)。这个错误在 2026 年的 AI 生成代码里仍然很常见,因为训练数据里有大量明文密码的示例代码,AI 不区分 demo 代码和真实代码。
第二类是缺少身份验证(任何人能改/删任何人的书签)。AI 默认所有 API 是公开的,因为它的训练假设是"个人 demo"——它不知道你的应用将来要对外开放。
第三类是XSS(用户输入没转义直接渲染)。React 默认会转义,但如果用了 dangerouslySetInnerHTML,AI 经常不加验证。
第四类是SQL 注入。Prisma 大部分情况会防,但复杂查询(特别是用了 prisma.$queryRaw 时)仍可能。AI 在生成原生 SQL 时不会主动加参数化查询,因为它不懂 SQL 注入的原理。
修复套路:让 AI 做一次安全审查:
请对项目做 /security-review:
1. 检查密码处理(必须用 bcrypt)
2. 检查所有用户输入的验证
3. 检查 SQL 注入风险
4. 检查 XSS 风险
5. 列出所有发现的问题并修复
重要提醒:AI 自己审自己的代码,效果打折扣。它倾向于"放水"——找到一个低级问题就报告"完成",漏掉真正严重的。建议自己再手动审一遍,重点看 AI 没提到的地方。

4. 关键代码片段
下面这段代码是我在真实项目中跑通过的版本,做了精简和注释,供参考。
4.1 CLAUDE.md 配置
CLAUDE.md 是项目的"宪法"。项目第一天就写好,后面每周花 10 分钟更新。下面是书签工具的真实配置:
# Bookmark Manager 项目规范
## 技术栈
- 框架:Next.js 16 (App Router) + TypeScript 5
- 样式:TailwindCSS 4
- 数据库:Prisma 5 + SQLite(开发)/ Postgres(生产)
- 测试:Vitest + Supertest
- 认证:暂不实现(个人工具)
## 目录结构
src/
├── app/ # Next.js App Router
│ ├── api/ # API 路由
│ ├── components/ # 页面级组件
│ └── (pages)/ # 页面
├── components/ # 可复用组件
├── lib/ # 工具函数
└── prisma/ # 数据库 schema
## 命名规范
- 文件:kebab-case
- 组件:PascalCase
- 函数:camelCase
- 数据库字段:camelCase(Prisma 默认)
## 约定
- 所有 UI 文案和注释用中文
- API 返回统一格式 { success, data, error }
- 所有用户输入用 Zod 验证
- 错误信息用中文,对外暴露的错误不包含堆栈
## 注意事项
- 密码字段(如未来加上)必须用 bcrypt
- URL 必须用 new URL() 验证合法性
- 不要把任何用户输入直接渲染到 HTML
- 永远不要用 dangerouslySetInnerHTML
4.2 核心 API 代码
这是书签列表和添加接口的实现。重点看第 19 行的 Zod 验证——这是上一节"边界条件"问题的修复方案:
// src/app/api/bookmarks/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { prisma } from '@/lib/prisma';
const BookmarkSchema = z.object({
title: z.string().min(1).max(100),
url: z.string().url().max(2000).refine(
(u) => u.startsWith('http://') || u.startsWith('https://'),
{ message: 'URL 必须以 http 或 https 开头' }
),
description: z.string().max(500).optional(),
tags: z.array(z.string()).max(5).optional(),
});
export async function GET(req: NextRequest) {
const { searchParams } = new URL(req.url);
const tag = searchParams.get('tag');
const q = searchParams.get('q');
const where: any = {};
if (tag) where.tags = { has: tag };
if (q) {
where.OR = [
{ title: { contains: q } },
{ url: { contains: q } },
];
}
const bookmarks = await prisma.bookmark.findMany({
where,
orderBy: { createdAt: 'desc' },
});
return NextResponse.json({ success: true, data: bookmarks });
}
export async function POST(req: NextRequest) {
const body = await req.json();
const parsed = BookmarkSchema.safeParse(body);
if (!parsed.success) {
return NextResponse.json(
{ success: false, error: parsed.error.issues[0].message },
{ status: 400 }
);
}
const bookmark = await prisma.bookmark.create({ data: parsed.data });
return NextResponse.json({ success: true, data: bookmark });
}
第 6-12 行的 Zod schema 是这个 API 的"边界防线"——空标题会被拒、非法 URL 会被拒、5000 字描述会被拒、20 个标签会被拒。所有这些校验都在数据进数据库之前完成,省掉了后续的"清理脏数据"工作。
4.3 测试代码
测试代码要写两个版本:单元测试(直接调函数,快)和集成测试(走 HTTP,全链路)。下面这段是集成测试的精简版:
// src/__tests__/bookmarks.test.ts
import { describe, test, expect, beforeEach } from 'vitest';
import { prisma } from '@/lib/prisma';
describe('Bookmark API', () => {
beforeEach(async () => {
await prisma.bookmark.deleteMany();
});
test('应该成功创建书签', async () => {
const res = await fetch('http://localhost:3000/api/bookmarks', {
method: 'POST',
body: JSON.stringify({
title: '测试书签',
url: 'https://example.com',
description: '这是一个测试',
tags: ['test'],
}),
});
const json = await res.json();
expect(res.status).toBe(200);
expect(json.success).toBe(true);
expect(json.data.title).toBe('测试书签');
expect(json.data.tags).toEqual(['test']);
// 验证数据库确实写入了(防止 AI 自证正确)
const dbRecord = await prisma.bookmark.findUnique({
where: { id: json.data.id },
});
expect(dbRecord).not.toBeNull();
expect(dbRecord?.url).toBe('https://example.com');
});
test('空标题应该被拒绝', async () => {
const res = await fetch('http://localhost:3000/api/bookmarks', {
method: 'POST',
body: JSON.stringify({ title: '', url: 'https://example.com' }),
});
const json = await res.json();
expect(res.status).toBe(400);
expect(json.success).toBe(false);
expect(json.error).toContain('标题');
});
test('非法 URL 应该被拒绝', async () => {
const res = await fetch('http://localhost:3000/api/bookmarks', {
method: 'POST',
body: JSON.stringify({ title: 'test', url: 'not-a-url' }),
});
expect(res.status).toBe(400);
});
test('超长描述应该被拒绝', async () => {
const res = await fetch('http://localhost:3000/api/bookmarks', {
method: 'POST',
body: JSON.stringify({
title: 'test',
url: 'https://example.com',
description: 'a'.repeat(501),
}),
});
expect(res.status).toBe(400);
});
test('javascript 协议的 URL 应该被拒绝(防 XSS)', async () => {
const res = await fetch('http://localhost:3000/api/bookmarks', {
method: 'POST',
body: JSON.stringify({
title: 'XSS 测试',
url: 'javascript:alert(1)',
}),
});
expect(res.status).toBe(400);
});
});
注意最后两个测试——“超长描述"和"javascript 协议 URL”——这是 AI 在初版里漏掉的边界。我们手工补上后,整个 API 才真正安全。
5. 经验总结:AI 是放大器,不是替代者
整个流程跑下来,我最大的感悟是:AI 不是"0 到 1 替代者",它是"1 到 10 效率放大器"。
“0 到 1 的需求定义"必须人来。你说"我要做书签工具”,AI 不会替你决定要不要做——它甚至不会替你定义"书签工具"对你意味着什么。这是一个判断问题,不是技术问题。
"1 到 10 的代码生成"是 AI 的强项。10 个文件的基础 CRUD,AI 10 分钟搞定。手写要 1 小时。这 6 倍效率差距是真实存在的。
“10 到 100 的代码审查"必须人来。AI 自己写的代码自己审,容易"放水”——它倾向于把发现的问题报小,或者把"已知但未解决"的问题标记为"已知"然后跳过。
"100 到 1000 的迭代优化"是人和 AI 协作的领域。AI 出方案,人做决策。
我在这次项目中实际用时:不熟练时 6 小时,熟练后 1.5 小时。5 到 10 倍效率提升,但前提是你知道"我要什么"。
如果换成一个完全不知道自己要做什么的人,AI 编程不仅不会更快,反而会更慢——因为他会在 AI 给的几十个方案之间反复横跳,最后每个方案都没做完。AI 编程最大的成本不是 token,是"你不知道自己不知道什么"。AI 把"不知道"变成"可以试试"——但能不能识别"试错了",还得靠你自己。
另一个反直觉的观察是:AI 编程项目的失败,几乎都发生在"决策"环节,而不是"执行"环节。AI 写代码很快、很便宜;人做决策很慢、很贵。失败的根源不是"AI 写得不够好",而是"人没想清楚"。所以 AI 编程项目的真正瓶颈是人愿不愿意在动手之前把需求想清楚——这件事 AI 帮不了你。
6. 给读者的复盘清单
如果你也想做自己的项目,按这 5 项清单走:
第一项,先写需求再让 AI 出方案。用 /plan 模式强制 AI 先规划后动手,避免方向性返工。我见过太多项目跳过了这一步,最后 AI 写了 3 套不同架构的代码,浪费了大量时间。
第二项,CLAUDE.md 是项目的宪法。项目第一天就写好,后面每周花 10 分钟更新。CLAUDE.md 不是文档,是给 AI 看的"宪法"——它应该短而硬,每个规则不超过两行,最好带一个反例。
第三项,测试不是可选项。AI 写的代码更必须测试,因为它会"形似神不似"——看起来测试通过了,实际上没在测东西。养成习惯:定期让 AI 自己 review 它写的测试,看能不能写出"故意通过"的测试。
第四项,安全审查不可省。AI 不知道你的业务上下文,让它自己审自己的代码常常"心太软"。建议 AI 审一遍后,自己再手动审一遍,重点看 AI 没提到的地方。
第五项,保存 Git 进度。AI 改坏代码是常态,git commit 是你的后悔药。建议每完成一个小功能就 commit 一次,不要等整个功能做完再 commit——否则 AI 一旦改坏了,你连回滚的粒度都没有。
最后补一条不适用清单——AI 编程不是万能的:第一种是业务核心规则没想清楚的项目,AI 会放大你的模糊,让一个本来能靠沟通解决的模糊变成技术债务;第二种是高合规要求的项目(金融、医疗),AI 生成的代码审计成本高于手写,因为每一行 AI 代码都要解释"为什么要这样写",对审计员来说是噩梦;第三种是你自己都不想看的代码,AI 会让你更不想看——它生成的代码在你眼里永远是"别人的代码",维护起来阻力更大。
这三种情况下,手写反而更划算。
结语
这个书签工具最后跑起来了吗?跑起来了。功能完整吗?搜索、筛选、增删改查都正常。代码质量如何?28 个测试通过,安全审查 0 个高危问题。
但如果你让我一个人从零手写,我可能要写 3 天。用 Claude Code,整个项目用时 1.5 小时。这就是 AI 编程的真实体感——不是 100% 替代你,而是让你从 1 天的工作量压缩到 1 小时。你省下的时间,可以做更重要的事:想清楚"我到底要做什么"。
整个系列到这里就结束了。从范式到原理、从工具到实战,从安装到部署——你现在应该具备了独立做 AI 编程项目的全部基础。
去动手做点什么吧。但动手之前,先想清楚三件事:我要做什么、我不做什么、我怎么知道做完了。
参考资料
- Claude Code 官方文档:https://claude.ai/
- Next.js 16 App Router 文档:https://nextjs.org/docs
- Prisma 5 数据库迁移指南:https://www.prisma.io/docs/
- B 站实战视频:https://www.bilibili.com/video/BV1RPET6tEp2
更多推荐


所有评论(0)