Vibe Coding 实战:不写一行代码,48小时交付完整MVP产品
作者:bugyuan
标签:Vibe CodingAI编程MVPCursorClaude产品开发零代码交付
阅读时长:约 25 分钟
写作背景:一次真实的 48 小时实验,从想法到上线
先说结果
产品名:BriefMate —— 一个帮助用户把长文章/会议录音一键转成结构化简报的 SaaS 工具。
- 用户可上传文档或粘贴文本
- AI 自动提炼摘要、要点、行动项
- 支持导出 PDF / Markdown
- 有用户注册登录、订阅计划、使用额度管理
48 小时内完成,全程没有手写一行代码。
不是玩具,不是截图演示。在文章最后有线上地址。
这篇文章记录的是完整的过程、工具选择、遇到的坑,以及我对"Vibe Coding 到底是什么"这件事最后的判断。
什么是 Vibe Coding?
这个词是 Andrej Karpathy 在 2025 年初造的。原话大意是:
你完全沉浸在项目里,不在乎代码本身,只描述你想要什么,让 AI 生成,你接受它、运行它、报错了就把错误扔回给 AI 继续修。你甚至不读那些代码。
这听起来像在开玩笑,但它描述的其实是一种真实的工作流转变:程序员从"写代码的人"变成"描述需求+审查结果"的人。
Vibe Coding 不等于"不懂技术也能开发",这是最常见的误解。它更像是:技术背景决定了你能描述多精确的需求,决定了你能发现多深层的问题,决定了你能把 AI 推多远。
我的十年技术背景,在这 48 小时里用到了每一处——只是用的方式完全不同。
工具栈选择
在开始之前,花了大约两个小时确定工具组合。选择的标准只有一个:AI 对这套技术栈的理解有多深。
前端:Next.js 14 (App Router) + Tailwind CSS + shadcn/ui
后端:Next.js API Routes(全栈,减少跨服务复杂度)
数据库:Supabase(PostgreSQL + Auth + Storage 一体)
AI:Anthropic Claude API(文档处理核心)
支付:Stripe(订阅 + 额度管理)
部署:Vercel(一键部署,免运维)
AI 编程工具:Cursor(主力)+ Claude.ai(架构设计讨论)
为什么这套组合?
这些技术有一个共同特点:它们都是 2022 年后的主流选型,AI 训练数据里充斥着大量相关代码,LLM 对它们的掌握程度远高于老旧技术栈。用 Spring Boot + Oracle 来做 Vibe Coding 会痛苦得多,不是因为技术差,是因为 AI 对这套组合的"肌肉记忆"更强。
Day 1(0~24小时):从混沌到跑通核心流程
第一步:用 Claude 做架构设计(不是写代码,是对话)
在 Cursor 第一行代码之前,我在 Claude.ai 里花了一个半小时做需求澄清和架构对话。
我的提问方式不是"帮我设计一个 SaaS 系统",而是刻意把约束条件说清楚:
我要在 48 小时内独立交付一个 SaaS MVP,技术栈是
Next.js 14 + Supabase + Stripe + Vercel。
核心功能:
1. 用户上传文档(PDF/txt/md),AI 生成结构化简报
2. 免费计划:每月10次;付费计划:无限次
3. 简报可导出 PDF 和 Markdown
约束:
- 我一个人,48小时
- 不要过度设计,能跑通就行
- 后续可扩展,但现在不设计扩展点
请告诉我:
1. 数据库表结构设计(Supabase)
2. 核心 API 路由设计
3. 哪些功能可以用现成服务替代(不要自己造轮子)
4. 48小时内最可能卡住的地方是哪里
这一步产出了整个项目的骨架。Claude 给出的数据库设计:
-- 用户表(Supabase Auth 自动创建,只需扩展)
create table profiles (
id uuid references auth.users primary key,
email text,
plan text default 'free', -- free / pro
usage_count integer default 0, -- 本月已用次数
usage_reset_at timestamptz, -- 下次重置时间
stripe_customer_id text,
stripe_subscription_id text,
created_at timestamptz default now()
);
-- 简报表
create table briefs (
id uuid default gen_random_uuid() primary key,
user_id uuid references profiles(id),
title text,
source_type text, -- text / file / url
source_content text, -- 原始内容(或文件路径)
summary text, -- AI 生成的摘要
key_points jsonb, -- 要点列表
action_items jsonb, -- 行动项列表
metadata jsonb, -- 字数、处理时间等
created_at timestamptz default now()
);
-- RLS 策略(用户只能访问自己的数据)
alter table briefs enable row level security;
create policy "Users can CRUD own briefs"
on briefs for all using (auth.uid() = user_id);
这个设计我看了五分钟,确认没问题,直接在 Supabase Dashboard 里执行。零修改。
第二步:初始化项目(10分钟)
npx create-next-app@latest briefmate --typescript --tailwind --app
cd briefmate
npx shadcn-ui@latest init
npx shadcn-ui@latest add button card input textarea dialog toast
然后打开 Cursor,把整个项目目录加进来。接下来的所有操作基本在 Cursor 的 Composer 里完成。
第三步:Cursor Composer 的正确打开方式
很多人用 Cursor 的方式是"让它写完整的文件",然后发现效果很一般。我这次用的方式完全不同。
核心原则:每次只做一件事,把上下文控制到最小。
我不会说"帮我写完用户认证模块",而是:
在 app/auth/login/page.tsx 创建登录页面。
要求:
- 使用 shadcn/ui 的 Card、Input、Button 组件
- 表单:邮箱 + 密码,一个登录按钮,一个"注册"链接
- 调用 Supabase Auth 的 signInWithPassword
- 登录成功跳转 /dashboard
- 错误状态显示 Toast 提示
- 样式:居中卡片,简洁
Supabase client 已在 lib/supabase.ts 初始化完毕。
这条 Prompt 产出了一个可以直接运行的登录页。跑起来,手动测试,没问题,提交,下一个。
第四步:核心功能——文档处理 Pipeline
这是整个产品最核心的部分,我花时间最认真地写了这条 Prompt:
在 app/api/brief/generate/route.ts 创建 POST 接口。
功能:接收用户上传的文本内容,调用 Claude API 生成结构化简报。
入参(JSON):
{
"content": "原始文本内容",
"title": "用户给的标题(可选)"
}
处理流程:
1. 验证用户已登录(从 Supabase session 获取 user_id)
2. 检查用户额度(profiles 表的 usage_count,free 计划 <= 10)
3. 调用 Claude API(使用 claude-sonnet-4-6 模型)
4. 将生成结果存入 briefs 表
5. usage_count + 1
6. 返回生成的 brief 对象
Claude Prompt 要求生成:
- summary:200字以内的核心摘要
- key_points:5~8个要点,每条 1 句话
- action_items:可执行的行动项(如果原文有的话)
返回格式:严格 JSON,方便前端解析。
错误处理:
- 401:未登录
- 429:额度不足,提示升级
- 500:AI 调用失败
环境变量:ANTHROPIC_API_KEY 已配置。
Cursor 生成了这个文件,我读了一遍(大约 120 行),发现了两个问题:
- Claude Prompt 写得太宽泛,生成质量不稳定
- 额度检查和扣减之间没有加锁,并发可能超扣
这两个问题,我用口语描述给 Cursor:
问题1:Claude 的 system prompt 需要更严格,要求它只输出 JSON,
不要有任何解释文字,否则 JSON.parse 会失败。
在 prompt 最后加:你必须只返回合法的 JSON 对象,
不要有任何前缀或后缀文字,不要用代码块包裹。
问题2:usage_count 检查和更新之间需要用 Supabase 的
select...for update 加行级锁,防止并发超扣。
两条修复,各用了 30 秒。
第一个 24 小时结束时,完成了什么:
- ✅ 用户注册 / 登录 / 退出
- ✅ 文本输入 + 文档上传(PDF/txt)
- ✅ AI 生成简报(核心功能跑通)
- ✅ 简报列表页 + 详情页
- ✅ 基础的额度检查
Day 2(24~48小时):打磨、支付、上线
Stripe 集成(最容易踩坑的地方)
Stripe 是整个 48 小时里最复杂的部分,不是因为代码难写,是因为有太多细节需要理解:Webhook 签名验证、订阅状态同步、测试卡号、沙盒环境……
我的处理方式:先和 Claude 聊清楚流程,再让 Cursor 写代码。
在 Claude.ai 里:
我要用 Stripe 实现一个简单的订阅系统:
- 免费计划:默认,每月 10 次
- Pro 计划:$9.9/月,无限次
用户点击"升级"按钮 → 跳转 Stripe Checkout →
支付成功 → Webhook 通知后端 → 更新数据库
我用的是 Next.js 14 + Supabase。
请帮我梳理:
1. 需要哪些 Stripe API 调用?
2. Webhook 需要处理哪些事件?
3. 最容易出错的地方是哪里?
Claude 给出的流程图:
用户点击升级
↓
POST /api/stripe/checkout
→ 创建或获取 Stripe Customer
→ 创建 Checkout Session(mode: subscription)
→ 返回 session.url
↓
前端 redirect 到 Stripe 托管页面
↓
用户完成支付
↓
Stripe POST /api/stripe/webhook
处理以下事件:
├── checkout.session.completed
│ → 更新 profiles.plan = 'pro'
│ → 存储 stripe_subscription_id
├── customer.subscription.deleted
│ → 降级回 free
└── invoice.payment_failed
→ 发邮件提醒(这次先跳过)
↓
用户回到 /dashboard?upgrade=success
明确了这个流程,再让 Cursor 写就清晰多了:
创建 app/api/stripe/checkout/route.ts。
流程:
1. 获取当前登录用户
2. 从 profiles 取 stripe_customer_id,
没有则调用 stripe.customers.create 创建并存入数据库
3. 调用 stripe.checkout.sessions.create:
- mode: 'subscription'
- price: process.env.STRIPE_PRO_PRICE_ID
- success_url: /dashboard?upgrade=success
- cancel_url: /pricing
4. 返回 { url: session.url }
使用 stripe npm 包,已安装。
STRIPE_SECRET_KEY 在环境变量中。
Webhook 处理器同理,每个事件单独描述,分批生成,分批测试。
整个 Stripe 集成花了大约 4 小时,其中 1 小时是在 Stripe Dashboard 配置产品和价格,1 小时是测试 Webhook(用 Stripe CLI 本地转发),2 小时是处理各种边界情况。
让我卡了最久的问题
不是技术问题,是 AI 生成的代码有一个隐藏 bug,我花了两小时才定位到。
现象:用户上传 PDF 后,偶尔生成的简报是乱码或截断的。
我把报错扔给 Cursor,它修了几次,问题依然偶发。
最后我决定自己读生成的 PDF 解析代码(这是 48 小时里我唯一一次认真读代码),发现问题所在:
// AI 生成的代码(有 bug)
const text = await pdf(buffer);
return text.text; // ← 这里在 PDF 很大时会截断
// 正确的写法(我告诉 Cursor 怎么修)
const data = await pdf(buffer);
// 按页拼接,保留完整内容
const text = data.Pages.map(page =>
page.Texts.map(t => t.R.map(r => r.T).join('')).join(' ')
).join('\n');
return decodeURIComponent(text);
这就是我说的"技术背景的价值"——我能识别出 AI 的错误在哪里,能告诉它怎么修,而不是在相信"AI 一定是对的"的前提下盲目调试。
UI 打磨
最后几个小时专门用来让产品看起来像一个真正的产品。
这里我换了一种 Vibe Coding 方式:不描述代码,描述感受。
现在的 Dashboard 页面感觉太工程师风格,太朴素。
我希望它看起来像 Linear 或 Vercel 的 Dashboard——
干净、现代、有层次感。
具体改动:
1. 顶部加一个欢迎语("Good morning, {name}"),
字体大,带当前日期
2. 使用情况用一个漂亮的进度条展示(free: 已用x/10次)
3. 简报列表改成卡片网格,每张卡片显示标题、摘要前50字、创建时间
4. 空状态要好看,不要显示空列表,
显示一个大的居中 CTA:"创建你的第一份简报"
这类 Prompt 效果非常好。UI 是 AI 最擅长的领域之一,只要描述清楚感觉,它能实现得比你手写快很多。
上线前的最后 1 小时
# 环境变量检查
# Vercel 项目配置
# 自定义域名绑定
# Supabase 生产环境迁移(把本地 SQL 在生产 DB 执行)
# Stripe Webhook 换成生产地址
这些操作全部是手工在各个控制台里点的,和写代码没关系。
48 小时整,BriefMate 上线。
复盘:Vibe Coding 真正的边界在哪里
做完之后,我认真想了这个问题。
✅ AI 真正擅长的
样板代码(Boilerplate):登录、注册、CRUD、表单验证——这类代码有固定的模式,AI 写得又快又好,准确率接近 100%。手写这些是在浪费生命。
UI 组件:给一个描述,给一个参考(“类似 Linear 的风格”),AI 能快速产出可用的界面代码。
已知方案的标准实现:Stripe 集成、OAuth、文件上传、PDF 解析——这些有明确的官方文档和大量示例,AI 的成功率很高。
调试已知类型的错误:把报错信息和相关代码一起扔给 AI,大部分时候它能定位和修复。
⚠️ AI 容易出问题的
并发和竞态条件:上面的额度超扣 bug 是典型例子。AI 写的单线程逻辑通常没问题,但多用户并发场景下的正确性,它容易忽视。
性能边界:AI 不会主动帮你想"如果用户上传一个 100MB 的 PDF 会怎样",这需要你主动提出。
复杂的业务逻辑:越接近真实业务的特殊规则(“VIP 用户在促销期间的折扣计算”),AI 越容易理解偏差,需要你用非常精确的语言描述,并仔细验证结果。
跨文件的一致性:当项目变大,AI 有时会在不同文件里用不同的错误处理方式、不同的命名规范,你需要主动维护一致性。
❌ AI 做不了的
定义"做什么":功能范围、优先级、哪些 feature 是 MVP 必须的——这些判断 AI 给不了。它能提建议,但最终决策永远是人的。
识别"这个不对劲":上面的 PDF 解析 bug,AI 自己不知道它的输出是错的,需要你运行、测试、感觉不对、深入排查。这个直觉是积累出来的,不是 AI 能替代的。
审美和品味:AI 能实现你描述的 UI,但"这个设计让人想点"这个判断,依然是人的工作。
给想尝试 Vibe Coding 的人
一些真实的建议:
选对工具栈,优先选 AI 熟悉的技术组合。不要在 48 小时内挑战"用 Rust 写后端",那不是 Vibe Coding,那是给自己找麻烦。
每次 Prompt 只做一件事,上下文越小,AI 的准确率越高。"帮我写整个用户模块"是烂 Prompt,"在这个文件里加一个检查邮箱格式的函数"是好 Prompt。
不要跳过测试。每写完一块就手动跑一下,发现问题及时修,不要攒到最后。Vibe Coding 的 bug 如果攒多了,解决起来比传统方式更难,因为你对代码的理解是浅的。
遇到卡点,先想清楚再让 AI 写。越复杂的问题越要先和 Claude 聊清楚逻辑,再让 Cursor 实现。顺序反了会绕很多弯路。
技术背景真的重要。Vibe Coding 不会让不懂技术的人变成工程师,但会让工程师的产出速度提高几倍。门槛没有降低,但杠杆变大了。
最后
48 小时,一个能收钱的产品,全程没有手写代码。
这在两年前是不可能的。现在它是真实发生的事情。
我不觉得这是程序员的终结。我觉得这更像是印刷机的发明——它不消灭了作家,它让作家能写更多、传播更广。只是"能写字"本身,从此不再是稀缺能力。
真正稀缺的永远是:知道该写什么,知道写出来的东西对不对,知道为什么它对或不对。
这些,依然是人的工作。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)