$catMANUAL||~26 min

用 AI Agent 搭项目的真实流程:从选工具到上线,我踩过的坑和总结的方法论

advertisement

用 AI Agent 搭项目的真实流程:从选工具到上线,我踩过的坑和总结的方法论

最近用 AI Agent 从零搭了一个完整的 Web 项目,从需求分析到部署上线全程让 AI 参与。说实话,过程比我想的复杂得多,不是那种"说一句话就自动生成网站"的爽文剧情。但搞完之后回头看,确实比纯手写快了不少,关键是你得知道怎么用。

这篇文章不聊概念,聊实操。我会把整个流程拆开讲,包括怎么选工具、怎么给 AI 描述需求、中间翻车了怎么处理、最后花了多少钱。如果你也在考虑用 AI Agent 搭项目,这篇文章应该能帮你少走一些弯路。

为什么想用 AI Agent 搭项目

起因很简单:我需要搭一个内部用的数据看板,技术栈不复杂(Next.js + SQLite + 简单的图表),但页面比较多,大概有七八个不同的视图。如果纯手写,估计要一周。我想试试看 AI Agent 能不能帮我缩短到两三天。

之前用 Claude Code 写过一些零散的功能,体验还行,但没试过从头到尾用 AI 搭一个完整项目。这次就当做个实验。

工具选择:Claude Code 还是 Codex CLI

先说结论:我最终用的是 Claude Code,但中间也试了 Codex CLI。

选工具这件事其实挺重要的,因为不同的 AI Agent 擅长的事情不一样。我的判断标准:

  • Claude Code:长上下文能力最强,适合需要理解整个代码库的场景。写复杂逻辑、重构代码的时候表现最好。缺点是贵,sonnet-4 模型输入 $3/百万 token,输出 $15/百万 token。
  • Codex CLI:OpenAI 出的,和 ChatGPT 生态整合好。代码能力不差,但我用的时候感觉它对项目整体结构的理解不如 Claude Code。优点是 ChatGPT Plus 用户有额度,不用额外花钱。
  • Cursor:IDE 集成做得最好,适合在编辑器里边写边调。但这次我不想在 IDE 里搞,我更习惯终端。

最后选 Claude Code 的原因:这个项目需要 AI 理解多个文件之间的关系(路由、组件、数据库 schema),Claude Code 的长上下文在这里优势明显。

工具对比的几个维度

既然聊到工具选择,多说几句。我实际用下来,这几个工具在不同维度上的表现差异还挺大的:

上下文理解能力:Claude Code > Cursor > Codex CLI。Claude Code 的 200K context window 不是摆设,它真的能理解你整个项目。Codex CLI 的上下文窗口小一些,遇到大项目会"忘记"前面的文件。

代码生成质量:说实话差距不大。三个工具生成的代码质量差不多,都会有 bug,都需要人审查。但 Claude Code 在复杂逻辑(比如递归、状态管理)上表现稍微好一些。

响应速度:Codex CLI > Claude Code > Cursor。Codex 用的是 GPT-4o-mini 的时候很快,但用 o3 的时候就慢了。Claude Code 的 sonnet-4 速度还行,opus 就比较慢。

价格:Codex CLI(ChatGPT Plus 额度)< Claude Code < Cursor。如果只是偶尔用用,Codex CLI 的 ChatGPT Plus 额度就够了。经常用的话,Claude Code 虽然贵但效率高,算下来可能更划算。

调试能力

这是我觉得最被低估的一个维度。搭项目的过程中,大概有 30-40% 的时间花在调试上。AI 的调试能力直接决定了你的开发效率。

Claude Code 的调试体验最好。它能直接读你的终端输出,你把报错信息贴给它,它能准确定位问题。有一次我遇到一个 Next.js 的 hydration 错误,报错信息很模糊,我自己看了半天没搞懂。贴给 Claude Code 之后,它分析说是服务端和客户端渲染的数据不一致,帮我定位到了一个时间格式化函数的问题。这个问题如果自己查,估计要花半小时。

Codex CLI 也能读终端,但我感觉它分析复杂报错的能力稍弱一些。特别是涉及多个文件联动的错误(比如类型定义和实际使用不匹配),它有时候会改错文件。

Cursor 的调试能力在 IDE 里是最方便的,因为它可以直接看到你的代码上下文。但它是 GUI 工具,不太适合我现在这种终端驱动的工作流。

这几个维度里,我觉得"上下文理解能力"是最重要的。因为搭项目不是写单个函数,你需要 AI 理解多个文件之间的关系。一个文件改了,其他文件要不要跟着改,这种判断需要全局上下文。

第一步:需求描述,这是最关键的一步

很多人觉得用 AI 写代码就是"告诉它你要什么",然后它就给你变出来。实际上,你描述需求的方式直接决定了输出质量。

我试了三种方式:

方式一:直接说"帮我搭一个数据看板"

结果:AI 生成了一堆通用代码,样式丑陋,数据结构不合理,基本没法用。这种方式等于让 AI 自由发挥,它不知道你的具体场景,只能给你一个"看起来对"的模板。

方式二:写一个详细的 PRD(产品需求文档)

我花了一个小时写了一份文档,包括:

  • 每个页面的布局描述
  • 数据表结构
  • API 接口设计
  • 样式要求

结果:好很多,但 AI 生成的代码还是有不少问题。主要是 PRD 里的描述和实际代码实现之间有 gap,AI 会"理解错"一些需求。

方式三:先让 AI 帮我规划,再逐步实现

这是我最终采用的方式,也是效果最好的:

code
1
我:我想搭一个数据看板,技术栈是 Next.js + SQLite。主要功能是展示
2
   几个维度的统计数据,有图表和表格。先帮我规划一下项目结构和需要
3
   的文件,不要写代码,先列个计划。
4
 
5
AI:[列出了项目结构、需要的文件、数据库 schema 设计、页面路由规划]
6
 
7
我:数据库 schema 这样改一下...页面路由再加一个...样式用 Tailwind。
8
   好,开始搭第一个页面。

这种方式的好处是:你可以在 AI 写代码之前就纠正它的理解偏差,避免写了一堆代码之后发现方向不对要推倒重来。

踩坑记录:第一次用方式二的时候,我写了一个很详细的 PRD,然后说"按照这个文档实现"。AI 一口气生成了 2000 多行代码,我一看,数据库 schema 和 API 接口对不上,前端组件的 props 传错了,样式也乱了。后来学乖了,一次只让 AI 做一件事。

第二步:分模块实现,一次只做一件事

这是我认为最重要的一条经验:不要让 AI 一次做太多事情

我发现 AI Agent 在处理小而明确的任务时表现非常好,但一旦任务复杂度上来,出错率就急剧上升。具体来说:

  • 单个组件(比如一个表格组件):成功率 90%+,生成的代码基本能用
  • 一个完整页面(包含多个组件 + API 调用):成功率 60-70%,经常有小 bug
  • 多个页面 + 数据库 + API:成功率不到 30%,几乎一定会出问题

所以我把整个项目拆成了这样的步骤:

  1. 搭项目骨架(npx create-next-app,配置 Tailwind、ESLint)
  2. 设计数据库 schema,写 migration 文件
  3. 写 API 路由(一个一个来)
  4. 写页面组件(一个一个来)
  5. 把组件和 API 连起来
  6. 调样式
  7. 部署

每一步都是一次独立的对话,完成一步再做下一步。这样出了问题容易定位,也不会出现"AI 一口气写了 2000 行代码但全是 bug"的情况。

第三步:处理 AI 犯的错

用 AI Agent 写代码,犯错是常态。关键是你要能识别错误,并且知道怎么让 AI 修正。

我遇到的常见错误类型:

1. 类型错误

TypeScript 项目里,AI 经常会写出类型不匹配的代码。比如把 string | undefined 传给需要 string 的参数。这类错误最好处理,因为 TypeScript 编译器会直接告诉你哪里错了。

code
1
我:[贴上 tsc 的报错信息]
2
AI:[修复]

基本上贴报错信息给 AI 就能修好,一次成功率很高。

2. 逻辑错误

这种比较麻烦。比如我让 AI 写一个"按日期筛选数据"的功能,它生成的代码语法没问题,但筛选逻辑是错的——把 >= 写成了 >,导致当天的数据不会显示。

这类错误 AI 自己发现不了,你得自己测试才能发现。我的做法是:每写完一个功能,手动测试一下关键场景,发现问题就描述给 AI。

3. 依赖/API 用法错误

AI 有时候会用过时的 API 或者不存在的函数。比如它用了 sqlite3 的一个已经废弃的方法,或者 Next.js 的一个已经被移除的配置项。

处理方式:看到报错后,让 AI 查最新的文档。在 Claude Code 里可以这样说:

code
1
这个报错了,查一下 sqlite3 最新的 API 文档,用正确的方式实现。

4. "看起来对但其实不对"

这是最危险的。AI 生成的代码能跑,没有报错,但行为不符合预期。比如我让它实现一个分页功能,它确实实现了,但每页显示的数量是硬编码的 10 条,不管你怎么设置都不变。

这种只能靠自己测试发现。所以我的建议是:不要完全信任 AI 的输出,每一段代码都要测试

第四步:代码审查和重构

写到一半的时候,我发现代码质量开始下降。因为每次 AI 生成的代码风格不完全一致,有的地方用 async/await,有的地方用 .then();有的组件用函数式,有的用 class。

于是我做了一次重构,让 AI 帮我统一代码风格:

code
1
帮我检查一下整个项目的代码风格,把不一致的地方统一。
2
主要关注:
3
1. 异步操作统一用 async/await
4
2. 组件统一用函数式 + hooks
5
3. 错误处理统一用 try/catch
6
4. 数据库操作统一封装到 lib/db.ts

这次重构花了一个多小时,但效果很好。重构之后代码读起来舒服多了,后面的开发也更顺畅。

重构的时候还发现一个有意思的事情:AI 写的代码有一个共同的问题,就是过度抽象。它会给你搞出很多 utility 函数、wrapper 组件、helper 类,有些只被用了一次。这种"以防万一"的抽象在大项目里可能有用,但在我这个小项目里就是过度设计。重构的时候我把那些只用了一次的抽象直接内联回去了,代码反而更清晰。

经验教训:最好在项目一开始就定义好代码规范,让 AI 按照规范来写。可以创建一个 .cursorrules 或者 CLAUDE.md 文件,把规范写进去。这样 AI 生成的代码风格会一致很多。

CLAUDE.md 配置:让 AI 记住你的项目规范

前面提到要在项目一开始就定义好代码规范。具体怎么做?以 Claude Code 为例,你可以在项目根目录创建一个 CLAUDE.md 文件,Claude Code 每次启动都会读取这个文件。

我的项目里的 CLAUDE.md 长这样:

markdown
1
# 项目规范
2
 
3
## 技术栈
4
- Next.js 15 (App Router)
5
- TypeScript strict mode
6
- Tailwind CSS + shadcn/ui
7
- SQLite via @libsql/client (Turso)
8
- SWR for data fetching
9
 
10
## 代码风格
11
- 组件用函数式 + hooks,不用 class
12
- 异步操作统一用 async/await,不用 .then()
13
- 错误处理统一用 try/catch
14
- 变量命名用 camelCase,文件名用 kebab-case
15
- 不要引入新的第三方库,除非我明确说要
16
 
17
## 文件结构
18
- /app/dashboard/ — 看板页面
19
- /app/api/ — API 路由
20
- /components/ — 可复用组件
21
- /lib/ — 工具函数和数据库操作
22
- /lib/db.ts — 数据库操作统一封装在这里
23
 
24
## 注意事项
25
- 所有 SQL 查询必须用参数化查询,禁止字符串拼接
26
- 组件的 props 必须定义 TypeScript 类型
27
- 不要在组件里写内联样式,用 Tailwind class

这个文件的效果很明显。加了之后,AI 生成的代码风格一致性好了很多,不会再突然冒出一个 class component 或者用 .then() 的写法。

Cursor 的话用 .cursorrules 文件,格式和内容基本一样。Codex CLI 可以用 AGENTS.md。不管用哪个工具,这个步骤都强烈建议做。

Prompt 技巧:怎么跟 AI 说话效率最高

用了这么多天 AI Agent,我发现跟 AI 说话是有技巧的。同样一个需求,不同的描述方式,输出质量差距很大。

技巧一:给上下文,不要只说需求

差的描述:

code
1
帮我加一个搜索功能。

好的描述:

code
1
在 /app/dashboard/page.tsx 这个页面的数据表格上方加一个搜索框。
2
搜索逻辑在 /lib/db.ts 的 getRecords 函数里改,
3
用 SQL 的 LIKE 做模糊匹配,搜索字段是 name 和 description。
4
用 debounce 300ms 避免频繁请求。

差别在哪?第一种描述 AI 只能猜你要什么,它可能在错误的文件里写代码,或者用你不想要的方式实现。第二种描述把上下文都给了,AI 基本上能一次写对。

技巧二:分步骤给指令

不要把所有需求一次性说完。分成多步:

code
1
第一步:在数据库里加一个 search_records 函数
2
第二步:在 API 路由里调用这个函数
3
第三步:在前端加搜索框组件

每完成一步,检查一下,再给下一步。这样出了问题能及时发现。

技巧三:给示例

如果你想让 AI 按照某种风格写代码,给它看一个例子:

code
1
按照 /components/data-table.tsx 的风格写一个新的 chart 组件。
2
注意:用 shadcn/ui 的组件,样式用 Tailwind,
3
数据获取用 SWR,错误处理用 try/catch。

AI 会模仿你给的示例的代码风格,生成的代码一致性会好很多。

技巧四:说"不要做什么"

有时候告诉 AI "不要做什么"比"要做什么"更有效:

code
1
写一个文件上传组件。不要用任何第三方上传库,
2
直接用 fetch + FormData。不要用 class component。
3
不要在组件里写 API 密钥。

AI 有时候会过度设计,引入不必要的依赖。提前告诉它不要做什么,能避免这个问题。

技巧五:遇到问题描述现象,不要描述猜测

差的描述:

code
1
我觉得是 state 更新太慢导致的,帮我优化一下。

好的描述:

code
1
点击按钮之后,页面要等 2-3 秒才更新。
2
看了一下 Network 面板,API 响应只要 100ms。
3
所以问题应该在前端渲染。

把现象描述清楚,让 AI 自己分析原因。你猜的原因可能是错的,但现象是客观的。

第五步:部署

部署这一步倒是比较顺利。项目用的是 Vercel,直接 git push 就自动部署了。但有一个小坑:

Vercel 的 SQLite 支持有限制,生产环境不能用文件系统的 SQLite。我本地开发用的是 better-sqlite3,部署到 Vercel 之后直接报错了。

解决方案是换成 Turso(一个 SQLite 兼容的云数据库)。让 AI 帮我把数据库层从 better-sqlite3 迁移到 @libsql/client,大概花了半小时。

code
1
本地用的 better-sqlite3,部署到 Vercel 之后报错了。
2
帮我把数据库层迁移到 Turso (@libsql/client),
3
保持现有的 schema 和查询不变。

AI 迁移得不错,基本一次成功,只改了数据库连接的部分,查询逻辑没变。

AI Agent 还做不好的几件事

虽然整体体验不错,但也有些地方 AI Agent 确实力不从心:

复杂的状态管理

涉及多个组件之间状态同步的场景,AI 容易出错。比如一个表单有多个联动的下拉框,选了 A 之后 B 要更新,C 要清空。这种逻辑 AI 经常搞混,要么状态更新顺序不对,要么漏掉某个联动。

遇到这种情况,我的做法是自己先理清状态流转逻辑,画个简单的流程图,然后把流程图描述给 AI,让它按这个逻辑实现。

性能优化

AI 生成的代码基本上是"能用就行"的水平,不太考虑性能。比如它会给你生成 N+1 查询、不必要的 re-render、没有 memoization 的计算。这些都需要你自己发现和优化。

有一次我让 AI 写一个数据聚合的函数,它生成的代码遍历了三次数组。我让它优化成一次遍历,它改了,但改完之后逻辑又出错了。最后还是我自己重写的。

安全相关

SQL 注入、XSS、CSRF 这些安全问题,AI 有时候会注意,有时候不会。不能指望 AI 自动帮你做安全防护。

我专门检查了一遍项目里的 SQL 查询,发现有几个地方确实有 SQL 注入风险(直接拼接用户输入到 SQL 语句里)。让 AI 修复之后它改用了参数化查询,但这个检查必须自己做。

业务逻辑

AI 不理解你的业务。它能写出语法正确的代码,但不理解"为什么这个字段不能为负数"或者"为什么这个操作需要管理员权限"。业务逻辑的正确性只能靠你自己把关。

真实成本核算

搞完这个项目,我算了一下花多少钱:

  • Claude Code 调用:大约 50 次对话,平均每次 2000 token 输入 + 3000 token 输出。总消耗约 10 万 input token + 15 万 output token。按 sonnet-4 的价格算:$0.3 + $2.25 = $2.55
  • Vercel 部署:免费额度够用
  • Turso 数据库:免费额度够用(500 行数据,查询量很小)
  • 域名:已有,不算额外成本

总成本:不到 $3。如果纯手写,按我大概 20 小时的开发时间算,按时薪 $50 算就是 $1000。当然这个比较不太公平,因为 AI 做的是比较机械的部分,架构设计和需求分析还是我自己做的。

成本控制的几个技巧

既然聊到钱,多说几个省钱的技巧:

用对模型:不是所有任务都需要最强的模型。写简单的 CRUD 代码,用 sonnet-4 就够了,不用上 opus。只有在需要复杂推理(比如架构设计、复杂算法)的时候才用更强的模型。Claude Code 里可以切换模型,简单任务用 haiku,省钱又快。

控制上下文大小:不要把整个项目都塞给 AI。如果你只需要改一个组件,只给 AI 看相关的文件。Claude Code 会自动管理上下文,但你也可以用 /compact 命令手动压缩上下文。

善用 Git:如果 AI 生成的代码不对,不要在上面反复修改。直接 git checkout 回退,重新给 AI 更好的描述再试一次。反复修改一个错误的方向,既浪费 token 又浪费时间。

批量处理:如果有多个类似的修改要做(比如给所有 API 加错误处理),一次性描述清楚让 AI 批量处理,比一个一个来省 token。

这些技巧加起来,大概能省 30-40% 的成本。对于小项目来说可能感知不大,但如果长期使用,积少成多还是很可观的。

但不管怎么算,AI Agent 确实帮我节省了大量时间。估计实际节省了 60-70% 的编码时间。当然这不包括学习怎么用 AI Agent 的时间——如果你是第一次用,前面几天可能会花不少时间摸索怎么跟 AI 有效沟通。但一旦上手了,效率提升是很明显的。

新手用 AI Agent 搭项目常犯的 5 个错误

我自己踩过,也在群里见过别人踩,总结一下:

1. 不写需求就开始干

最常见的错误。上来就说"帮我搭一个 XX",结果 AI 搭出来的东西和你想的完全不一样。然后反复修改,浪费大量时间和 token。

正确做法:花 10-15 分钟写个简单的需求清单,包括要哪些页面、数据结构是什么、用什么技术栈。不用很详细,但要有。

2. 一次让 AI 做太多

"帮我搭一个完整的电商网站,包含用户系统、商品管理、购物车、订单系统、支付集成。"

这种需求扔给 AI,出来的一定是垃圾。拆成小步骤,一步一步来。

3. 不测试就继续

AI 生成了一段代码,看着好像没问题,就直接让它写下一段。结果后面发现前面的代码有 bug,要回头改,牵一发动全身。

正确做法:每写完一个功能,花 2 分钟测试一下。点一点按钮,看看输出对不对。这两分钟能省你后面两小时。

4. 不读 AI 生成的代码

有些人完全不看 AI 写了什么,直接 accept。这很危险。你不一定要逐行审查,但至少要大致看一遍,确认逻辑是对的。

我有一次发现 AI 在一个排序函数里用了不稳定的排序算法,导致相同分数的项目每次刷新顺序都不一样。如果不看代码,可能到上线了才发现。

5. 遇到问题就放弃

AI 第一次生成的代码不对,很正常。给它更多信息,描述清楚问题,让它再试一次。很多人的反应是"AI 不行"然后自己手写,但其实多沟通一轮就能解决。

当然,如果同一个问题 AI 改了三次还是不对,那就自己动手吧。这种时候通常是需求描述有问题,不是 AI 能力不行。

总结:几条核心经验

搞完这个项目,我总结了几条用 AI Agent 搭项目的核心经验:

需求描述比什么都重要。花时间把需求说清楚,比花时间修 AI 犯的错划算得多。最好的方式是先让 AI 出计划,你审核通过了再让它写代码。

一次只做一件事。不要让 AI 一口气搭完整个项目,拆成小步骤,每步完成后再做下一步。出了问题容易定位,也不会出现大面积返工。

不要完全信任 AI 的输出。每一段代码都要测试。AI 生成的代码"看起来对"的概率很高,但"真的对"的概率没有你想的那么高。

尽早定义代码规范。在项目开始的时候就建好 .cursorrulesCLAUDE.md,把代码风格、技术栈、约定写进去。这样后面的代码会一致很多。

善用报错信息。AI 最擅长的事情之一就是根据报错信息修 bug。TypeScript 编译错误、lint 警告、运行时报错,直接贴给 AI 就行,修 bug 的成功率比写新功能高得多。

定期重构。AI 写的代码容易风格不一致,写到一定量之后做一次统一重构,后面的维护成本会低很多。

后面打算试试用多个 AI Agent 并行干活——比如一个 Agent 写前端,一个写后端,用 Git worktree 隔离。听说有人用这种方式把开发速度又提高了一倍,但也有不少坑,比如两个 Agent 改同一个文件会冲突之类的。到时候搞完了再写篇文章聊聊体验。

另外,如果你对 AI Agent 搭项目有什么心得或者踩过的坑,欢迎评论区分享。大家交流一下,互相少走弯路。

advertisement

用 AI Agent 搭项目的真实流程:从选工具到上线,我踩过的坑和总结的方法论 — AI Hub