☰
Vibe-coding实战:AI辅助构建任务看板的全流程复盘
2026/10/19 4:41:30 网站建设 项目流程

最近刚把 Vibe-coding 系列任务里的 Task5 做完了。作为收官之战,这个任务本身不算复杂——限时三天,交付一个能跑起来的完整应用,题材自选。但正因为是最后一道题,它要求把前面几轮练过的提示词设计、代码审查、问题排查、上下文管理全部串起来用一次。我最后做的是一个轻量级任务看板应用,项目代号叫 TaskPilot,从需求描述到第一版能打开页面,再到数据真正落到数据库里,每一步都依靠 AI 辅助生成代码,我自己主要负责拆解需求、审核代码和最终联调。这篇文章把整个流程、关键提示词、踩过的坑和最终交付物完整记录下来,给正在用 AI 编程写项目的人一个真实参考。

1. 收官之战到底在考什么:Task5 的任务拆解

1.1 为什么说这是“收官之战”

Vibe-coding 系列任务一般会分成多个阶段推进。前面的 Task1 到 Task4,分别对应了提示词基础、单点功能实现、接口对接、UI 调试,每一轮都是在某个局部环节里做专项练习。到了 Task5,题目不再给具体功能点,而是要求你自主提出一个“足够完整”的项目,并在限定时间内交付。这个“完整”意味着它不能只是一个函数、一个组件或者一个静态页面,而是要有真实项目的基本要素:数据模型、前后端交互、状态流转、异常处理,以及一份能让人看懂的交付说明。

我理解它真正想考的核心能力,不是“会不会让 AI 生成代码”,而是“能不能在 AI 生成的代码基础上做判断”。AI 可以在几十秒内生成几百行代码,但哪些代码是对的、哪些是假的?哪些需求没说清导致 AI 自以为是?怎么把一个模糊的想法变成 AI 能理解的高质量指令?这才是 Vibe-coding 和工作流里的关键分水岭。Task5 把这些问题全部摆到桌面上,逼你一次性面对。

1.2 我给自己定的产出目标

为了避免题材太大收不了尾,我给自己定了一个边界清楚但又不失完整性的目标:做一个任务看板应用。项目代号 TaskPilot,核心功能有三块:

  1. 支持创建任务,填写标题、描述、优先级、截止日期。
  2. 任务在不同状态列之间流转,比如“待处理 / 进行中 / 已完成”。
  3. 数据需要持久化,重启应用后任务记录不丢失。

这个范围看起来不大,但它天然覆盖了 Vibe-coding 的关键场景:需要有数据模型设计、需要前后端接口约定、需要状态管理,也需要一个能交互的界面。同时它又是很多人熟悉的业务形态,需求容易描述,AI 也更容易生成合理的代码结构。

技术栈我选的是很常见的组合:前端用 React 加一个轻量组件库,后端用 Node.js 加 Express,数据库用 SQLite。选这一套不是因为它们最花哨,而是因为生态成熟、相关语料多,AI 生成时出错的概率相对低。对于 AI 编程来说,选一个“AI 训练语料里出现频率高”的技术栈,比选一个再先进但冷门的技术栈要省心得多。

1.3 为什么选这个方向

我见过不少同学在收官任务里选择做很炫酷的 AI 聊天应用或者复杂的可视化大屏,结果往往卡在“功能发散”上。AI 生成代码很快,但需求越发散,AI 越容易自作主张加功能,最后的代码会变成一个难以维护的黑盒。任务看板这种形态,边界非常清晰:看板是什么、任务怎么流转、状态怎么保存,所有人都能达成共识。这种“共识清晰”的项目,最适合用来验证 Vibe-coding 的工作流,而不是去挑战 AI 的极限。

另外,任务看板还有一个好处:它的数据关系简单,不需要搞用户体系、权限模型这些容易让 AI 生成依赖混乱的东西。一个最小可用版本就可以完整跑通“前端-后端-数据库”这条链路。做完之后如果想扩展,还可以逐步加标签、加评论、加多用户,每一个增量都独立清晰。这就是我最后选它的核心原因——收官任务更重要的是把链路跑通,而不是把规模做大。

2. 用 AI 写代码之前,先写好“需求剧本”

2.1 Vibe-coding 真正考验的是表达能力

很多人第一次用 AI 编程,都会有一个直观感受:AI 写出来的代码“看起来很对”,但一运行就报错。再追问几次,AI 还会振振有词地给出一个同样不对的答案。问题通常不在 AI,而在输入给 AI 的需求描述不够精确。

Vibe-coding 这个说法容易让人误解,以为是靠“感觉”和“氛围”驱动编码。实际上,自然语言就是你和 AI 之间的接口,它同样是严格的编程语言,只是语法变成了句子。你能把“要什么、不要什么、边界在哪里、技术栈是什么”表达得越清楚,AI 的产出质量就越高。

我在 Task5 里用过一个很直观的类比:把 Vibe-coding 想象成带一个理解能力很强但完全没有行业常识的新实习生。你把需求说得含糊,他也会做,但做出来的东西大概率不符合预期;你把验收标准、技术约束、错误处理方式都写在纸上,他就能把活干得七七八八。后面“审查”的工作量会小很多。

2.2 一份可直接套用的任务提示词模板

项目开始前,我没有直接让 AI“生成一个任务看板”,而是先写了一份结构化的需求剧本。这份剧本分成六块:角色定义、项目目标、技术栈、数据模型、接口定义、交付标准。下面是我实际使用过并改过几轮的一个模板,可以直接抄去用:

你是一个熟悉全栈开发的高级工程师。请基于以下需求生成一个最小可用的任务看板应用。 【项目目标】 - 用户可以在页面上创建任务,编辑任务信息。 - 任务分为三个状态列:待处理、进行中、已完成。 - 任务可以在列之间拖动或通过按钮改变状态。 - 所有任务数据需要持久化存储,重启应用后数据不丢失。 【技术栈】 - 前端:React + 组件库 - 后端:Node.js + Express - 数据库:SQLite 【数据模型】 - 任务表 Task:id(自增主键)、title(字符串)、description(字符串)、priority(字符串:low/medium/high)、status(字符串:todo/doing/done)、created_at(时间戳)、updated_at(时间戳)。 【接口定义】 - GET /api/tasks 获取全部任务列表 - POST /api/tasks 新建任务 - PUT /api/tasks/:id 更新任务信息,包括状态字段 - DELETE /api/tasks/:id 删除任务 【约束条件】 - 不要引入用户登录和权限系统。 - 不要生成测试用例,只需要主体功能代码。 - 数据库文件放在后端目录下的 task.db。 - 每一步只输出一个模块的代码,并简要说明改动点。 【交付标准】 - 前端能调用后端接口完成增删改查。 - 刷新页面后任务仍然存在。 - 使用说明文档单独输出。

这份模板看起来很啰嗦,但它解决的问题非常实际。数据模型写清楚了,AI 就不会在字段命名上反复横跳;接口定义写清楚了,前后端联调时就不会出现前端用task.title、后端返回name的错位;约束条件写清楚了,AI 就不会擅自加一个登录模块,让你花大量时间去删代码。

2.3 避免“AI 失忆”的三个习惯

用 AI 写大项目时,最常见的问题就是上下文漂移。对话一开始 AI 还记得你要用 SQLite,聊到二十分钟后,它可能就会在生成的代码里随手 import 一个 MongoDB 的驱动。这是因为它没有真正的记忆,注意力集中在最近的对话内容上,早先的约定会被慢慢稀释。

我的做法有三个。第一,重要约束反复说,不要怕重复。技术栈、数据模型、接口名这些关键信息,在我每次要求生成新模块时都会重新写一遍。第二,阶段性让 AI 输出“当前项目结构总结”,核对它理解的方案是否仍然一致。第三,把已经确认的关键信息抄进一个单独的 project_spec.md 文件里,每次对话开始时直接粘贴进去。这三个习惯帮我避免了很多后续对齐成本。

3. Task5 全流程实操记录

3.1 环境准备与项目骨架

项目启动前的环境准备工作,值得提前做好。我先建了一个项目根目录,然后分别创建了client和server两个子目录,分别放置前端和后端代码。这样的目录分离从第一天就确定好,后面不会因为前后端文件混在一起而让 AI 生成出奇怪的引用路径。

前端我用的是 Vite 加 React 的初始化命令,执行之后项目骨架会自动生成。后端的生成就更简单,直接手写一个 package.json 加上 Express 和 SQLite 相关依赖,然后交给 AI 补齐入口文件。这里要提醒一句:AI 编程工具对初始化脚手架的支持差异很大,最好还是自己动手执行初始化命令,不要把“创建项目”这件事交给 AI。因为脚手架版本在快速变化,AI 的记忆很可能滞后,它给出的初始化命令往往不是过时就是需要额外交互确认,步骤多了反而更容易卡住。

mkdir taskpilot cd taskpilot # 前端 npm create vite@latest client -- --template react # 后端 mkdir server cd server npm init -y npm install express better-sqlite3 cors

依赖安装完成后,我没有急着开始写功能,而是先让 AI 根据项目需求脚本生成后端入口文件。这一步的预期是得到一个能启动的 Express 服务,先跑通GET /api/health这个健康检查接口,确认环境本身没有问题,再进入真正的业务功能。

3.2 后端模块生成:数据表与 API

后端模块我拆成了三小块,分三次让 AI 生成:数据库初始化、任务列表查询、任务增删改接口。每一次只让它输出一个文件,并且要求它在代码开头写清楚这个文件的作用。这样做的原因是,如果一次让 AI 生成整个后端的十几个文件,它很容易在文件之间的引用关系上产生幻觉,出现“看起来已经连接、实际根本没有导出”的假象。

数据库初始化代码,我选择用 better-sqlite3 这个库,因为它简单、同步操作,不需要额外部署数据库服务。AI 生成的初始化代码一般长这样,但顺序可能会乱,所以我拿到后第一件事是检查表结构:

const Database = require('better-sqlite3'); const path = require('path'); const db = new Database(path.join(__dirname, 'task.db')); db.exec(` CREATE TABLE IF NOT EXISTS tasks ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, description TEXT DEFAULT '', priority TEXT DEFAULT 'medium', status TEXT DEFAULT 'todo', created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP ) `); module.exports = db;

这里有一个很容易踩的坑:AI 经常会把CURRENT_TIMESTAMP写成datetime('now')或者其他方言语法。对于 SQLite 来说,这个写法本身没问题,但如果你后端代码里用了别的 SQL 函数,就要注意一致性。我在审查时会把所有数据库相关代码集中看一遍,确保没有混用两套时间格式。

接口生成的环节,我给的提示词会具体到“每个函数要返回 JSON 格式的{ code: 0, data: ... },错误时返回{ code: 500, message: ... }”。这样前端拿到响应后,不需要临时解析各种不同的返回结构,这类约定会极大减少联调时的摩擦。

3.3 前端看板生成:组件拆分与状态对接

前端部分我同样拆成模块来生成。第一步是生成一个任务列表组件,第二步是生成一个任务表单组件,第三步是生成看板的三列布局。这样的拆分让 AI 每次只需要集中解决一个小问题,生成的代码质量明显高于让它一口气输出整个页面。

任务列表组件生成后,我会把后端 API 的返回结构直接贴给它,然后要求它“根据这个接口响应格式,编写前端请求和渲染逻辑”。这个动作尤其重要。如果你不给 AI 看接口的真实返回,它就会自己猜测字段名,大概率猜得和实际代码不一致。我在实际操作中会把接口定义和响应示例当成“上下文饲料”,每次涉及请求时都会喂给 AI。

import { useEffect, useState } from 'react'; import { getTasks, updateTaskStatus, deleteTask } from '../api'; export default function Board({ tasks, setTasks }) { const columns = ['todo', 'doing', 'done']; async function loadTasks() { const res = await getTasks(); setTasks(res.data); } async function moveTask(id, nextStatus) { await updateTaskStatus(id, nextStatus); loadTasks(); } async function removeTask(id) { if (!confirm('确定删除这个任务吗?')) return; await deleteTask(id); loadTasks(); } return ( <div style={{ display: 'flex', gap: 16 }}> {columns.map((col) => ( <div key={col} style={{ flex: 1, border: '1px solid #ddd', borderRadius: 8, padding: 12 }}> <h3>{col}</h3> {tasks.filter((t) => t.status === col).map((task) => ( <div key={task.id} style={{ marginBottom: 12 }}> <p><strong>{task.title}</strong></p> <p>{task.description}</p> <button onClick={() => moveTask(task.id, col === 'todo' ? 'doing' : 'done')}> 推进 </button> <button onClick={() => removeTask(task.id)}>删除</button> </div> ))} </div> ))} </div> ); }

这个组件本身并不复杂,但它是整个前端的主干。让我比较满意的是,AI 生成的组件结构基本符合预期,没有过度抽象。不过它生成的样式是内联的,这在原型阶段完全够用,但如果要做成正式产品,后期还是要替换成样式文件。这也是 Vibe-coding 产出的一个常见特征:先保证功能逻辑能跑通,美化可以放到下一轮迭代。

3.4 联调与前后的“对表”

前后端都生成了之后,开始联调。所谓联调,在我的操作流程里就是“让前后端对表”。我先把后端服务启动,再让前端启动,然后打开浏览器点击了几个按钮。第一次点击“新建任务”时,前端控制台就报了一个 400 错误。查看后端日志发现,请求体里的created_at字段是前端自动填的,但后端表结构里这个字段的定义是自动生成,不需要前端传入。

这个问题很小,但很有代表性:AI 在前端代码里擅自给请求体加了一个后端不需要的字段。解决方案也很简单,我回到 AI 对话里,把后端接收创建数据的逻辑贴给它,然后要求它“修改前端请求体,去掉创建时不需要的字段”。AI 很快给出了修正。我后来复盘发现,如果我在前端生成的提示词里最开始就说明“创建任务时只需要传 title、description、priority、status,其他字段由后端生成”,这一步就不会发生了。所以说到底,很多联调问题本质上都是提示词没有把边界说清。

4. 我踩过的坑与排查速查

4.1 依赖冲突与版本漂移

Task5 期间遇到的第一类坑是依赖冲突。因为是分阶段生成的代码,AI 在前端生成的某个组件里使用了某个组件的旧版本 API,但我在初始化脚手架时安装的是新版本,最终导致运行时直接白屏。排查过程其实是老一套:先看浏览器控制台报错,再链路反查是哪个模块抛出的,最后去改那个模块的引用方式。

这个问题的根源,是 AI 的训练数据里包含大量不同版本的代码。它在生成代码时,不会主动核对当前项目里的具体版本号,只会按照它认为最合理的写法输出。解决办法是安装依赖时尽量锁定版本,并且在给 AI 的提示词里写上“所有依赖的版本以当前项目的 package.json 为准”。这句话成本很低,但能减少很多无效来回。

4.2 接口字段前后对不上

在联调过程中,我遇到过一个比较隐蔽的字段错位:后端的返回字段是id、title、status,前端组件的状态里却一直使用task._id。AI 自始至终没有告诉我它改了字段名,直到删除任务操作一直失效,我逐行检查才发现。这类问题不能指望 AI 自己发现,因为它生成的每一段代码都是“局部自洽”的,但连到一起就不一致。

我的排查策略是让 AI 先输出“当前后端所有接口的响应字段清单”,再输入给前端代码生成时的提示词里。相当于把后端的真实数据契约作为前端的输入约束,而不是各写各的。这个做法后来一直沿用,非常好用。

4.3 AI 自信地“创造”不存在的工具函数

另一个典型问题,是 AI 在生成代码时引用了一个工具函数,但那个函数根本不存在于任何文件里。比如它在一个接口文件里写了formatTime(),但整个项目里都没有这个函数的定义。这类问题在单次生成里很容易被忽略,因为代码没有明显报错符号,运行时却会直接抛异常。

解决这个问题有两个层面的操作。第一层,让 AI 搜索项目里是否已定义该函数,并把它找到的函数定义或替代方案贴出来。第二层,更重要的是建立“代码审查清单”,把外部引用、未定义标识符作为必查项。虽然逐个翻代码很累,但 AI 生成的项目如果跳过这一步,后面修 bug 的成本只会更高。

4.4 安全相关的事,不能全交给 AI

这一点我在 Task5 之后印象特别深。AI 确实可以不厌其烦地帮你写接口,但它的安全知识只会体现在“常见模式”里,不会针对你的具体场景做风险分析。比如它生成的新建任务接口,默认情况下没有对输入长度做限制,也没有校验 title 是否为空。如果直接上线,一个超长字符串就能打乱整个看板布局。

我不是说 AI 完全不能处理安全问题,而是说审查的人要具备基本的安全意识。你可以让 AI“添加输入校验”,它确实能执行;但在它没有接到指令之前,不会主动帮你做。所以我把“输入长度限制、必填字段校验、数据库参数化查询”这些安全基线都放进初始需求模板里,让 AI 从一开始就按这个标准生成。

4.5 常见问题速查表

常见现象可能原因解决思路
前端白屏,控制台报 undefined组件引用了不存在的函数或变量根据报错堆栈反查引用,让 AI 补全或改用安全实现
接口返回 400请求体字段和预期不符把后端期望的参数清单贴给前端,统一字段
删除不生效,但刷新后又恢复前端调用删除接口后没刷新列表修改调用逻辑,删除成功后重新拉取列表
数据库文件越来越大AI 重复创建表或写入冗余数据检查初始化逻辑,加入CREATE TABLE IF NOT EXISTS
任务状态点击后没有变化状态字段值不匹配,比如前端用done,后端默认completed统一枚举值,并在提示词里写明 status 可取值
AI 开始“遗忘”需求上下文过长导致旧约束丢失定期重贴关键约束,或用外部文档承接

这个速查表是后期复盘时整理的。中间有不少问题是反复出现过的,把它整理成表格之后,后续再做类似项目时速度会快很多。这也是 Vibe-coding 的一个好处:你的试错经验可以沉淀成自己的排查文档,下次直接用。

5. 交付复盘与 Vibe-coding 使用边界

5.1 最终交付物长什么样

Task5 最后的交付物结构比我预想的要干净。目录分成了前端、后端、说明文档三块,其中后端包含数据库逻辑、API 路由;前端包含页面组件、请求模块;顶层有一个 README 说明了启动方式和功能清单。中途虽然出现过多轮修改,但最终代码保持在一个相对稳定的状态。

我在这里学到了一个经验,就是在快结束时,让 AI“根据当前代码结构生成一份 README”。大多数 AI 在你要求写文档时,会先用一段“项目介绍”糊弄过去,但如果你要求它“列出启动命令、接口地址、数据模型和已知限制”,产出就会实用很多。TaskPilot 的 README 就是在最后二十多分钟里生成的,反而成了交付物里最亮眼的一部分。

另外,我把收敛到最终状态的代码提交到本地仓库,每个功能模块单独提交了一次。这样做的好处是,每次出 bug 时可以快速回退到上一个稳定版本。AI 编程项目有个特点:改动频率很高,但版本控制习惯很容易被忽略。如果你不用仓库管理,中间某次 AI 生成了一段坏代码,可能就找不回来之前的正确版本了。

5.2 Vibe-coding 适合做什么、不适合做什么

做完 Task5,我对 Vibe-coding 的边界有了更实际的认识。它特别适合快速生成原型、内部工具、教学演示、小型自动化脚本,以及结构清晰的全栈 demo。这类项目的特点是需求明确、边界稳定、技术栈主流,即使 AI 生成了一些不完美的代码,人工也能快速修正。

但在一些要求苛刻的领域,直接全量依赖 AI 生成代码风险很大。比如涉及高并发、强一致性的交易系统,或者作为公共依赖的底层库,这些场景里单个函数的行为偏差都可能酿成大事故。不是说 AI 不能用,而是需要极严格的测试、评审和约束。另一个不适合的场景是“你自己都不知道要什么”的项目。如果你对最终效果完全没有轮廓,AI 生成的代码只会让你更迷糊,因为它最擅长做的就是把模糊的需求变成一段看起来像样的代码。

适合场景不适合场景
内部工具和自动化脚本高并发交易系统
教学演示和快速原型底层公共库
小型全栈应用安全敏感核心模块
数据探索和报表需求完全未知的探索性项目
算法题的思路验证强审计合规要求的系统

这个分红线和绿线不是绝对的,但可以帮助我做精力分配:AI 负责生成骨架,我负责关键路径上的审查和测试。想让 AI 生成一整个生产级系统且不加人工审查,至少在目前的实操里是不现实的。

5.3 给后来者的三条建议

第一,把“需求剧本”当成一等公民。不要上来就让 AI 写代码,先花半小时把项目目标、数据模型、接口定义、技术栈、验收标准写成文字。这份文字不仅喂给 AI,也用来约束你的项目范围。Task5 我能顺利收尾,很大程度上靠的是最初那份需求文档,而不是 AI 本身有多强。

第二,每一次让 AI 改代码,都要要求它给“变更说明”。我在提示词末尾通常加上一句:“请在代码后列出本次改动点和影响范围。”这句话能让 AI 强制回顾自己改了什么。虽然有时候它列得比较泛,但至少你会知道它动过哪些文件,这能帮你快速定位问题。

第三,重要节点手动接管。所谓手动接管,不是自己重写所有代码,而是在几个关键控制点把关:数据库表结构、数据接口的入参和返回值、关键按钮的事件判断、输入校验规则。这些地方如果跑偏,后期返工成本极高。我一般在第一版生成后,会直接把这几个关键文件从头到尾读一遍,不理解的地方就问 AI“为什么要这样写”,能说服我的就留下,说不清楚就让它简化。

把 Task5 做完之后,我最大的感受是:Vibe-coding 没有把程序员变成“代码审核员”,恰恰相反,它把程序员从大量机械写法里解放出来,让人把精力放到更需要判断力的地方。AI 解决了“代码怎么落地”的大部分问题,但“方向对不对、边界清不清楚、交付靠不靠谱”这些事,还是靠人来拍板。后面如果还有类似任务,我一定会把需求文档写得更细再开工,哪怕多花一晚上,也值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询