拿到一个项目就焦虑进度,代码写了一半不知道该问什么,改完一个功能又崩了另一边——这是我最初一个人尝试做全栈项目时的真实状态。后来我慢慢摸索出一套“原子化 AI 编程”的打法,简单说就是把全栈项目拆成一个个巴掌大的任务,再交给 AI 辅助编程工具去生成、解释、改错,而我只需保证每一小块做完之后能被验证、被记录。这篇个人学习记录,就是把这套打法从思路到落地完整复盘一遍,希望能给同样想“一人成军”的小白一点可以直接抄作业的参考。
1. 先把“一人成军”这件事拆成可执行的最小单位
1.1 为什么一个人做全栈项目,要先拆而不是先学
一说到全栈,很多人第一反应是“要学的东西太多了”。前端要学框架、后端要学接口、数据库要学 SQL、部署要学服务器,还有版本管理、鉴权、缓存、日志……如果按照“学完再做的顺序”推进,大概率在第三周就放弃了,因为反馈周期太长,你根本不知道学那些东西到底用在哪里。
我自己踩过的坑是:一开始啃了半个月的教程,觉得什么都会了一点,结果打开编辑器写项目时依然是一片空白。真正改变进度的,不是“学得更多”,而是“把一个项目第一次跑通”。只要有一个极小的页面能从浏览器发请求到后端,再拿到数据渲染出来,那一刻你对全栈的理解会超过之前所有教程的总和。
所以我的建议是:从第一天就开始做项目,而且是做一个小到不能再小的项目。学习只是这个项目过程中的附属品,需要什么查什么。这个听起来像鸡汤,但配合 AI 编程工具之后,它真的能从口号变成可执行的流程。
1.2 原子化:让 AI 能真正帮上忙的任务切分方式
“原子化”是我从接手一个巨型项目拆模块的经历里学到的思路。我当时的困惑是:让 AI 写一个“完整的登录功能”,它可能直接扔给你几十个文件的代码,你说不清楚哪里对哪里错,出了问题也不知道怎么改。后来我把登录拆成下面这些巴掌大的任务:
- 写一个后端接口,接收用户名和密码,返回一个固定的 JSON。
- 写一个函数,检查密码长度是否大于 6。
- 在前端页面做一个表单,点击按钮后把数据发送到这个接口。
- 在浏览器控制台验证返回结果。
每一个任务都符合三个条件:一句话能说清楚、能独立运行、能立刻判断对错。这就是我理解的原子化:不是把事情切得很碎,而是切到“人能验收、AI能生成”的最小粒度。
这个切法之所以对小白友好,是因为它绕开了最大的认知负担。当你不用同时考虑“前端组件怎么写、路由怎么配、后端怎么起、数据库怎么连”的时候,每个原子任务的上下文就变得很短,AI 生成的代码不容易跑偏,你检查起来也不用看懂所有代码,只要看结果对不对就行。
2. 技术栈与架构设计:怎么选才不会被细节拖死
2.1 耗时最短、反馈最快的技术组合
一个人做项目,最怕的不是技术太差,而是被环境配置消磨掉耐心。我建议第一次做全栈项目时,只管用“身边人用得多、文档资料全、出问题一搜就有答案”的组合,不要追新。我的选择思路如下:
| 层次 | 可选方案 | 我的选择理由 |
|---|---|---|
| 前端 | 以组件为核心的现代前端框架 | 生态成熟、能快速搭页面 |
| 后端 | 轻量级脚本语言后端框架 | 写起来简单、启动快 |
| 数据库 | 文件型数据库起步,再迁到服务型数据库 | 零配置、适合初学者理解 |
| 部署 | 国内云托管平台或服务器面板 | 能看到真实访问效果 |
这套组合的特点是:几乎不需要手动编译,前端改完保存刷新就能看到效果,后端一个命令就能启动。整个项目从初始化到上线,环境配置的环节最少,而环境配置恰恰是小白最容易卡住的地方。
2.2 架构上只保留三个不变量
我以前总想一步到位,把网上那些高并发架构图塞进自己的小项目里,结果代码量翻倍,项目却更跑不通了。后来我给自己定了一个规矩:项目第一版只保留三个不变量,其他的都不做。
第一个不变量是“前后端分离”。不管项目多小,都把页面和接口分成两块。前端负责发请求、渲染数据;后端负责接收请求、返回数据。这个约定让 AI 生成代码时职责非常清晰,不至于一会儿把数据库代码写进前端,一会儿又在前端文件里处理业务逻辑。
第二个不变量是“接口只做一件事”。比如新增记账、列出记账、删除记账,每个接口单独一个路径,不要设计那种传一个 type 参数就切换功能的万能接口。接口职能单一,AI 生成时不容易乱,后面改需求时也不会误伤其他功能。
第三个不变量是“数据库有独立访问层”。也就是说,所有读写数据库的代码集中到一个文件里,不要在好几个文件里各写各的 SQL。这一点在项目小的时候看不出差别,等某天你要改表结构,或者把文件型数据库换成服务型数据库时,就能体会到这个约束有多救命。
2.3 AI 编程工具在项目里的角色分工
AI 编程工具很强,但如果你把它当成“你负责想,它负责全写”,项目很快就会失控。我自己摸索出来的分工是:人负责定义和验收,AI 负责生成和解释。
先说负责定义。每个原子任务要做什么、输入是什么、输出是什么、怎么算成功,这些必须由人来定。比如“写一个接口,接收 JSON,把 title 字段存进数据库,返回带 id 的记录”,这样的描述 AI 几乎能一次生成。反过来如果你说“帮我写个后端”,它给你的东西大概率没法直接用。
再说负责解释。AI 最有价值的地方不是替你写整段代码,而是帮你理解代码。遇到报错时,我会把完整的报错信息丢给它,然后问一句“这个错误是什么意思,怎么修”。它列出的排查步骤通常比我自己瞎猜快很多。
人还要负责验收。AI 生成的代码不是标准答案,必须跑起来看结果。我给自己定了一条铁律:任何一个原子任务,没验证过就不算完成。哪怕只是写了一个加法函数,也要在命令行里跑一遍确认输出正确。这条铁律帮我挡住了不少看似能跑、实际有隐藏问题的代码。
3. 实操:一个最小全栈项目从 0 到 1 的完整过程
3.1 项目定位:做什么、不做什么
理论说了那么多,落到实操才有感觉。我复盘时选了一个例子:做一个个人记账本。当时我给自己定的范围是:能手动添加一笔账、能看所有账单列表、能删除一条账单。就这三个功能,不要再多。
为什么要刻意做这么小?因为“记账本”虽然小,但它覆盖了全栈最核心的链路:前端页面、后端接口、数据库存储、部署上线。跑通一遍之后,你就有了一个可以不断往上加功能的骨架。之后加“编辑功能”“分类统计”“搜索过滤”,都只是在已有链路上加节点,而不是重新搭一张网。
我在记录里写下了这个项目的“不做清单”:不做用户注册登录,不做图表统计,不做多端适配,不做高并发优化。不是这些功能难,而是它们属于另一个复杂度层级。第一次做全栈,目标不是炫技,而是让整条链路闭环。
3.2 把第一版功能写成原子任务清单
项目定了,接下来就是拆任务。我花了一个晚上把“记账本第一版”拆成了下面这张清单,每一个任务都对应一个可以验证的结果。
| 序号 | 原子任务 | 验证方式 |
|---|---|---|
| 1 | 初始化前端项目 | 浏览器打开能看到空白页面 |
| 2 | 初始化后端项目 | 命令行启动后访问根路径返回字符串 |
| 3 | 新增一个 POST 接口 | 用命令行工具请求后返回固定 JSON |
| 4 | 创建数据库表结构 | 表能创建成功,插入一条测试数据能查出来 |
| 5 | 把 POST 接口接上数据库 | 请求后数据出现在数据库中 |
| 6 | 新增一个 GET 列表接口 | 能返回数据库里的所有账单 |
| 7 | 前端做一个添加表单 | 提交后能调用后端接口 |
| 8 | 前端做一个列表展示 | 接口返回的数据能渲染在页面上 |
| 9 | 新增一个 DELETE 接口 | 删除后再次查询列表,数据消失 |
| 10 | 本地全链路联调 | 添加、列表、删除全部通过 |
| 11 | 部署上线 | 外网访问能正常使用 |
这张清单的价值在于:你永远知道下一步该做什么,不会出现“面对空白项目发呆”的情况。每完成一项,就在清单后面打个勾,进度感会非常强烈。这也是我坚持“原子化”的主要原因——它把抽象的“做项目”变成了具体的“完成列表”。
3.3 四步走:后端、数据、前端、部署
有了清单,执行顺序也很有讲究。我的习惯是先做后端和数据库,再做前端,最后部署。因为前端依赖接口,接口依赖数据库,反过来做的话,前端页面会发生不知道请求什么地址的僵局。
第一步,初始化后端项目。我在终端里执行了包管理器初始化命令,然后安装了轻量级 Web 框架和跨域支持库。接着新建入口文件,启动一个最简单的服务,监听某个端口。这时候不要急着写业务代码,先确认服务能起来、浏览器能访问,再往下走。
第二步,设计数据库。我用的是文件型数据库,不需要单独的数据库服务,表结构简单到像一张 Excel 表格:四个字段,分别是自增编号、账单类型、金额、备注。建好表以后,我随手在命令行里插入了一条测试数据,然后查询出来,确认存储这块没问题。
第三步,写接口。新增账单的接口负责接收前端传过来的金额和备注,写入数据库,返回记录编号;列表接口把数据库里的所有记录查出来,按时间倒序返回;删除接口根据编号删掉指定记录。每个接口写完,我立刻用命令行工具模拟请求,确认返回结果符合预期。
第四步,写前端。前端页面只有两个区域:上面是添加表单,下面是账单列表。页面加载时请求列表接口拿到数据渲染;提交表单时把输入内容发送到新增接口,成功后再刷新列表。整个过程不需要复杂的状态管理库,用最简单的页面脚本就能实现。
最后一步,部署。我把前后端分别处理:前端打包后交给云托管平台,后端连同数据库部署到服务器。部署完在浏览器里打开域名,把“添加一笔账→出现在列表→删掉这笔账”重新跑一遍。这一步跑通,整个项目才算真正闭环。
3.4 “人机分工”的提示词示例
很多人用不好 AI 编程工具,是因为提问太模糊。我平时会按照“角色+任务+输入输出+约束”的模板来写提示词。这里分享两个我在记账本项目里用过的提示词:
你是一个熟悉后端编程的助手。请用轻量级 Web 框架写一个处理 POST 请求的接口,路径为 /api/items。 接口接收 JSON 格式的请求体,包含 amount 和 note 两个字段,要求把这两个字段写入数据库的 items 表中。 写入成功时返回一个 JSON 对象,包含新记录的自增 id。请给出完整代码和必要的导入语句。你是一个前端页面开发助手。请写一段页面脚本,实现以下功能:页面加载时自动请求 GET /api/items, 把返回的数组渲染成一个列表,列表项显示金额和备注。请给出可以直接粘贴到 HTML 文件中使用的完整代码。这个模板看起来很简单,但有三个细节很关键:一是明确给出了接口路径和字段名,AI 生成的前端代码能直接对上后端接口;二是要求返回固定结构,方便后端对接;三是要求“可以直接使用”,AI 会补全导入和初始化代码,减少我们自己试错的时间。
4. 常见问题与排查技巧实录
4.1 环境不一致的翻车现场
我做这个项目时遇到过最无语的情况是:AI 给的代码在自己的电脑上能跑,在部署服务器上却一直报错。排查到最后发现,AI 写代码时默认使用了较新的语言版本,而服务器上装的是旧版本,语法不兼容。
后来我给自己加了两道保险。第一,在项目的依赖配置文件里固定版本号,明确写入项目需要的运行环境版本。第二,每次部署前先把本地环境清一遍重新安装依赖,模拟服务器的干净状态。这样部署时遇到的环境问题,能提前在本地暴露一大部分。
AI 生成代码时,我还会在提示词里主动补充一句“请使用当前项目指定的运行环境版本,不要使用最新语法特性”。看似不起眼,但对部署失败率的降低非常明显。
4.2 小改动引起大崩溃的连锁反应
有次我改前端里一个按钮的文案,结果页面上整个列表都不显示了。原因很可笑:按钮所在的组件和列表共用了一段状态管理代码,我顺手把里面一个变量名改掉了,列表读取数据时拿到的是 undefined。
这个坑让我意识到,越小的项目越容易产生“代码耦合”。解决思路不是不再改代码,而是借机养成两个习惯:一是动手前先看清楚改动会影响到哪些变量和函数;二是每改一次,就立刻在浏览器里把核心流程跑一遍。我管这个叫“三分钟回归测试”,虽然听起来粗糙,但对个人项目来说性价比极高。
4.3 卡壳的时候怎么问自己
没有人写代码不卡壳,关键是有没有一套从卡壳里走出来的固定流程。我的流程是:先把报错信息原封不动复制下来,再打开 AI 工具,问“为什么会有这个错误”。很多时候,只要把问题精确描述出来,答案就出来了一半。
如果 AI 给了修复建议还是不行,我会把自己想要的效果和当前代码之间的差距,拆成更小的中间步骤再去问。比如列表渲染不出来,我会依次检查:接口返回的数据结构是否和我预想一样?前端取字段的名字是否拼错?渲染函数是否被正确调用?这样一层层拆下去,问题总能定位到某一个具体的原子任务上。
4.4 原子化开发里的避坑清单
下面这张表是我复盘整个项目后整理的避坑清单,每一条都来自实际翻车记录:
| 现象 | 常见根因 | 排查方向 |
|---|---|---|
| 接口请求跨域报错 | 后端没有允许跨域请求 | 检查后端跨域配置 |
| 页面能打开但数据为空 | 接口返回结构和前端预期不一致 | 分别验证接口数据和前端渲染 |
| 数据库报错表不存在 | 建表代码没执行或表名不一致 | 查看建表日志和连接配置中的表名 |
| 部署后功能失效 | 环境配置与本地不同 | 逐个对比部署环境依赖版本 |
| 修改无效 | 页面缓存了旧代码 | 强制刷新或检查前端是否重新打包 |
这里我最有体会的一条是“接口返回结构和前端预期不一致”。第一次做接口对接时,我以为返回的是数组,结果后端包了一层对象;前端拿到后调用了数组的遍历方法,直接报错。从此我给自己定了一条规矩:前后端每次联调,先在命令行里看一次真实返回结果,再写前端代码。
5. 从记录到迭代:怎么把这次经验变成长久能力
5.1 学习记录模板:不是日记,是证据
“个人学习记录”这个后缀为什么重要?因为做完一个项目后,你学到的不是那几行代码,而是你在这个过程中做过的判断。我每次复盘都会按固定模板写记录,模板只有四栏:原子任务、AI 交互、验证结果、踩坑教训。
比如我记录中的一行是这样的:
- 原子任务:实现新增账单接口。
- AI 交互:让 AI 生成写入数据库的代码,并特别要求返回记录编号。
- 验证结果:用命令行工具请求后,数据库中新增了一条记录,接口返回了编号。
- 踩坑教训:第一次生成的代码没有返回编号,因为我没有在提示词里提出这个要求。结论是提示词里要把“输出长什么样”写清楚。
这个模板的意义在于,它强迫我区分“AI 做了什么”和“我做了什么”。过三个月回看,哪一栏的内容越少,说明我越依赖 AI 直接给结果,而没有真正消化。
5.2 一人成军的三个阶段
我第一次做成记账本项目的时候,以为“一人成军”就是什么都能自己写。后来我发现,它其实是一条从依赖到独立的长路,我把它分成三个阶段。
第一阶段叫“抄写与理解”。这个阶段的我基本复制 AI 给的代码,唯一的任务是逐行读懂它在干嘛。读不懂没关系,用笔记下来,下一次遇到同样的模式时再对照。
第二阶段叫“改写与组合”。这时候我已经能看明白 AI 生成的代码,也能在它基础上改字段名、调逻辑、组合两个函数。这个阶段的目标是“我有需求,AI 出草稿,我来改”。
第三阶段叫“独立设计与复盘”。目前我正处在往这个阶段走的路上。这个阶段更多是动笔设计——自己画数据库表、自己定接口、自己排任务。AI 退回到一个纯粹的编码助手,而不是产品经理。
阶段不同,AI 的角色也不同。第一阶段 AI 是老师,第二阶段 AI 是同事,第三阶段 AI 是打字员。判断自己在哪个阶段的标志很简单:看你还愿不愿意在没有 AI 的情况下,自己写下一个原子任务的核心代码。愿意写、写得慢没关系,这才是能力真正长在自己身上的信号。
最后再分享一个小技巧。原子化任务拆分的时候,我给每一条任务都标了一个预估时间,大部分都在半小时以内。超过半小时还没完成的任务,立刻停止硬啃,拆成更小的步骤再继续。宁可任务列表长一点,也不要让任何一个步骤大到让自己产生畏难情绪。这个习惯帮我撑过了最开始那段最容易放弃的日子,应该也能帮到你。