作者:bugyuan
标签Vibe Coding AI编程 MVP Cursor Claude 产品开发 零代码交付
阅读时长:约 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 行),发现了两个问题:

  1. Claude Prompt 写得太宽泛,生成质量不稳定
  2. 额度检查和扣减之间没有加锁,并发可能超扣

这两个问题,我用口语描述给 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 小时,一个能收钱的产品,全程没有手写代码。

这在两年前是不可能的。现在它是真实发生的事情。

我不觉得这是程序员的终结。我觉得这更像是印刷机的发明——它不消灭了作家,它让作家能写更多、传播更广。只是"能写字"本身,从此不再是稀缺能力。

真正稀缺的永远是:知道该写什么,知道写出来的东西对不对,知道为什么它对或不对。

这些,依然是人的工作。


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐