1. 这不是“用AI写个Hello World”,而是一次真实的全栈SaaS建造实战

我去年夏天做了一件在当时看起来有点莽的事:关掉所有技术文档网站、禁用Stack Overflow书签、卸载本地保存的旧项目模板,只留下三样东西——GitHub Copilot的IDE插件、Cursor编辑器、Claude Code的网页端。然后给自己定了个硬性目标:30天内,从零启动、设计、编码、测试、部署一个能真实服务付费用户的SaaS产品,全程不手写任何核心逻辑函数,所有代码必须由AI生成、我只负责提问、审查、调试和集成。

结果是,第14天晚上9点17分,我在个人域名下上线了第一个可注册、可登录、可创建项目、可导出数据的完整Web应用——一个面向独立开发者的时间追踪与专注力分析工具,叫FocusLog。它有React前端、TypeScript类型系统、PostgreSQL数据库、Node.js后端API、JWT鉴权、Stripe订阅集成,甚至带基础的邮件通知和PDF导出功能。整个过程没有一行CRUD逻辑是我手动敲出来的,连SQL建表语句都是我用自然语言描述需求后,让Claude生成再人工校验的。

但真正让我坐下来写这篇复盘的,不是上线那一刻的兴奋,而是第18天凌晨三点——我盯着控制台里反复出现的500错误,翻了六遍AI生成的OAuth回调路由,才发现它把 req.user.id 直接拼进了SQL查询字符串,根本没做参数化处理;第22天,用户反馈“导出的PDF里中文全是方块”,我查了四小时,最后发现是AI在Dockerfile里自动加了 apt-get install fonts-dejavu-core ,却漏掉了中文字体包;第26天,Stripe webhook签名验证始终失败,日志显示 signature header is missing ,而AI生成的Express中间件压根没解析原始请求体……这些不是小bug,是系统性认知偏差在代码里的具象化。

所以这篇文章不讲“AI多厉害”,也不贩卖焦虑说“程序员要失业了”。它是一份带着黑眼圈、咖啡渍和Git commit历史截图的实操手记。关键词不是“Copilot”或“Claude”,而是 边界感 ——AI在什么环节真能当主力,在什么环节你必须像守门员一样寸步不让。它适合正在评估AI辅助开发价值的CTO、想提升编码效率的中级工程师、刚转行想少走弯路的新人,以及所有还相信“写代码终究是人和机器协作”的实践者。下面所有内容,都来自那30天里我亲手敲下的217条prompt、合并的43次PR、回滚的9次生产部署,以及贴在显示器边框上那张写着“别信它,再看一遍”的便签纸。

2. 整体架构设计与AI协作模式拆解

2.1 为什么选这三款工具组合?不是玄学,是能力错位匹配

很多人看到标题第一反应是:“Copilot+Cursor+Claude?这不是堆工具吗?” 实际上,这个组合不是随意拼凑,而是基于三类AI在软件工程不同阶段的 能力光谱错位 刻意设计的。我把整个开发流程切成四个关键阶段:需求理解与方案设计 → 模块化编码实现 → 跨层集成调试 → 安全与健壮性加固。每款工具在特定阶段有不可替代的优势,强行用同一款工具覆盖全流程反而效率更低。

  • GitHub Copilot :它的强项是 上下文感知的局部补全 。当你在React组件里写到 useEffect( ,它能根据当前文件的import、props类型、附近变量名,精准推荐带依赖数组的完整钩子;在TypeScript接口定义后敲 const user: User = { ,它能自动列出所有必填字段并预填合理默认值。但它极度依赖已有代码的“锚点”,一旦进入空文件或需要跨文件推理(比如“这个API响应格式要和前端表格列对齐”),准确率断崖式下跌。所以Copilot被我严格限定在 单文件、单函数、已定义类型约束下的编码补全 场景,绝不让它生成新模块骨架。

  • Cursor :它的核心价值是 工作区级的语义理解 。当我选中整个 /src/components/TimeChart.tsx 文件,右键选择“Explain this file”,它不仅能逐行注释,还能指出“这里useMemo的依赖数组漏了 timeRange ,会导致图表不刷新”;更关键的是,它能基于整个项目目录结构回答“哪些组件用了 formatDuration 工具函数?如果我想把它升级为支持毫秒精度,需要改哪几个地方?”。这种跨文件、跨层级的关联分析能力,是Copilot完全不具备的。所以我把Cursor定位为 架构审查员和重构指挥官 ,每天开工前先让它扫描一遍当天要动的模块,生成风险提示清单。

  • Claude Code :它胜在 长文本推理与规范遵循能力 。当我需要生成一个完整的Stripe webhook处理器时,Copilot只能补全单个if分支,Cursor会建议“参考官方文档”,而Claude能接收我粘贴的Stripe官方Webhook签名验证流程图、Express中间件文档片段、项目里已有的JWT验证中间件代码,然后输出一份包含错误处理、重放攻击防护、日志埋点、类型守卫的完整实现,并明确标注“第12行需替换为你的密钥环境变量名”。它的弱点是实时性差、无法感知本地未提交代码,所以Claude只用于 高风险、高复杂度、需严格遵循外部规范的模块生成 ,且每次生成后必须用Cursor做跨文件影响分析。

提示:不要试图让Copilot去设计数据库关系,也不要让Claude去修复一个只有两行报错的React渲染异常。工具错配比不用工具更耗时。我的经验是:看到需求描述超过3句话,就切到Claude;需要检查5个以上文件的耦合点,就打开Cursor;在已定义好Props接口的组件里写JSX,Copilot就是你的手指延伸。

2.2 架构选型背后的“人机分工”逻辑:为什么是Next.js + PostgreSQL + Vercel?

技术栈选择从来不是单纯比参数,而是看 AI生成能力与工程约束的交集 。我试过用AI生成Nuxt3项目,结果它把Vite配置和SSR渲染逻辑混在一起,导致静态导出失效;也试过用AI写Prisma schema,但它总把 @map 指令拼错成 @map() ,引发迁移失败。最终锁定Next.js 14(App Router)、PostgreSQL 15、Vercel托管,原因很实在:

  • Next.js App Router的约定优于配置特性,极大降低了AI的“自由发挥空间” 。比如路由文件必须放在 app/dashboard/page.tsx ,布局文件必须叫 layout.tsx ,加载器必须用 async function getData() 。AI不需要理解“为什么这样设计”,它只需要记住“page.tsx文件里导出默认组件,layout.tsx里用children props”。这种强约束反而提升了生成准确率。我统计过,Copilot在Next.js路由文件中的首行补全成功率是92%,而在自定义Express路由文件中只有47%。

  • PostgreSQL的SQL语法严谨性,让AI生成的DDL/DML更可靠 。对比MySQL,PostgreSQL对数据类型、约束语法、事务隔离级别的要求更严格。AI生成 CREATE TABLE users (id SERIAL PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE); 时,几乎不会漏掉 NOT NULL UNIQUE ——因为Claude的训练数据里,这类语句的正确范式出现频率极高。而当我让AI生成MongoDB Schema时,它频繁把 required: true 写成 required: ['email'] ,导致Mongoose验证失效。

  • Vercel的零配置部署能力,消除了AI最薄弱的运维环节 。AI可以生成完美的Dockerfile,但它永远搞不定“为什么在AWS EC2上npm run build会内存溢出”。Vercel的 vercel.json 配置极简,AI生成的 { "rewrites": [{ "source": "/api/(.*)", "destination": "/api/" }] } 基本一次通过。更重要的是,Vercel的环境变量注入机制和Next.js的 process.env 读取方式天然契合,避免了AI在 .env 文件路径、加载时机上的常见错误。

注意:AI不是万能胶水。我曾让Claude生成一个“兼容Vercel Serverless Functions和本地Node.js开发的数据库连接池”,它输出的代码在本地跑得好好的,一上Vercel就报 Error: Cannot find module 'pg' ——因为它没意识到Vercel的Serverless Function默认不执行 npm install ,需要显式声明 "functions": { "api/**": { "runtime": "nodejs18.x" } } 。这类基础设施认知盲区,必须靠人来兜底。

2.3 “不写函数”的真实含义:AI生成的是代码,人定义的是契约

“全程不手写函数”这个说法容易引发误解。实际上,我写的最多的是 类型定义、接口契约、测试用例和prompt指令 。真正的生产力提升,来自于把“写代码”这个动作,升级为“定义代码该做什么”的更高阶活动。

举个具体例子:用户注册功能。传统做法是,我先想清楚密码强度规则、邮箱唯一性校验、JWT token生成逻辑,然后手写 registerUser 函数。这次,我做了三件事:

  1. types/user.ts 里定义:
export interface RegisterInput {
  email: string; // 必须是有效邮箱格式
  password: string; // 至少8位,含大小写字母和数字
  fullName: string; // 非空,长度2-50
}
export interface RegisterResult {
  success: boolean;
  userId?: string;
  error?: 'EMAIL_TAKEN' | 'INVALID_PASSWORD' | 'SERVER_ERROR';
}
  1. 写一条给Claude的prompt:“基于以上类型,生成一个TypeScript函数 registerUser ,使用PostgreSQL的 pg 库。要求:① 密码用bcryptjs加密,盐值12;② 邮箱唯一性检查用 SELECT COUNT(*) FROM users WHERE email = $1 ;③ 错误处理需区分业务错误(返回对应error枚举)和数据库连接异常(抛出Error);④ 返回Promise 。”
  2. 把生成的代码粘贴进 lib/user/register.ts ,用Cursor检查:是否所有 $1 参数都来自输入?是否 bcrypt.hash 调用在try/catch内?是否 SELECT COUNT 后正确判断了 rows[0].count === 0

这个过程里,AI负责把“契约”翻译成“语法”,我负责定义契约的精确性、审查翻译的保真度、处理契约之外的意外(比如网络超时)。最终生成的函数可能有12行,但我写的类型定义+prompt+审查时间,远少于手写12行+单元测试+边界case覆盖的时间。这就是“不写函数”背后的真相: 人退到更抽象的层面制定规则,AI沉到更具体的层面执行细节

3. 核心模块实现与AI协作细节实录

3.1 前端交互层:React组件生成的“三明治”工作流

React组件是AI表现最稳定的一环,但稳定不等于省心。我的实际工作流是典型的“三明治”结构: 人定骨架 → AI填肉 → 人加酱料 。以仪表盘时间图表组件 TimeChart.tsx 为例:

第一步:人定骨架(约5分钟)
我手动创建文件,写死最外层结构和必需的props接口:

// src/components/TimeChart.tsx
import { useState, useEffect } from 'react';

interface TimeChartData {
  date: string; // YYYY-MM-DD
  duration: number; // seconds
}

interface TimeChartProps {
  data: TimeChartData[];
  timeRange: 'week' | 'month' | 'year';
  onDateClick?: (date: string) => void;
}

export default function TimeChart({ data, timeRange, onDateClick }: TimeChartProps) {
  const [chartData, setChartData] = useState<TimeChartData[]>([]);
  
  // TODO: 数据预处理逻辑待AI生成
  useEffect(() => {
    // TODO: 响应timeRange变化的逻辑待AI生成
  }, [timeRange]);

  return (
    <div className="chart-container">
      {/* TODO: 图表SVG渲染逻辑待AI生成 */}
      <svg width="100%" height="300" viewBox="0 0 800 300">
        {/* 占位:后续由AI生成具体path和rect */}
      </svg>
    </div>
  );
}

第二步:AI填肉(Copilot + Cursor协同)

  • 选中 // TODO: 数据预处理逻辑待AI生成 注释,按Ctrl+Enter唤出Copilot,它立刻生成:
// 数据预处理:按timeRange聚合原始数据
const processedData = useMemo(() => {
  if (!data.length) return [];
  const now = new Date();
  let startDate = new Date();
  if (timeRange === 'week') {
    startDate.setDate(now.getDate() - 7);
  } else if (timeRange === 'month') {
    startDate.setMonth(now.getMonth() - 1);
  } else {
    startDate.setFullYear(now.getFullYear() - 1);
  }
  return data.filter(item => new Date(item.date) >= startDate);
}, [data, timeRange]);
  • 然后选中整个 useEffect 块,右键Cursor → “Improve this code”,它指出:“ startDate.setMonth 在跨年时可能出错,建议用 date-fns subMonths ”,并直接生成替换代码,同时在顶部自动添加 import { subMonths, subYears, subWeeks } from 'date-fns';

第三步:人加酱料(约15分钟)

  • 检查 date-fns 是否已在项目中安装(没装就 npm install date-fns );
  • 发现AI生成的SVG渲染部分过于简陋,手动补充D3.js的scaleBand和axis逻辑(这部分AI生成质量差,不如自己写);
  • onDateClick 回调里加一层防抖(AI从不主动加这个);
  • 最后用Cursor运行“Test this component”,它自动生成Jest测试用例,我只需补全 mockImplementation

实操心得:AI生成的React代码,90%的坑在 状态同步时机 事件处理副作用 。比如Copilot常把 setChartData(processedData) 写在 useEffect 里,却不考虑 processedData 本身是memoized的,导致图表不更新。我的固定动作是:所有 setState 调用后,立刻检查依赖数组是否完整;所有 onXxx 事件处理器,强制用 useCallback 包裹。这已成为肌肉记忆。

3.2 后端API层:从“能跑”到“能抗”的三次重构

API层是AI生成代码从“表面正确”滑向“深层危险”的高发区。我的 /api/auth/register/route.ts 经历了三次重大重构,每次都是被生产环境日志打醒的:

第一版(Copilot生成,第3天上线)
AI生成的代码能完成注册,但存在致命问题:

// ❌ 危险!直接拼接SQL
const query = `INSERT INTO users (email, password_hash, full_name) VALUES ('${email}', '${hash}', '${fullName}')`;
await pool.query(query); // SQL注入温床

第二版(Claude生成,第7天上线)
我给Claude的prompt加了硬性约束:“必须使用PostgreSQL参数化查询,禁止字符串拼接,错误处理需区分唯一约束冲突和其他错误”。它生成了:

// ✅ 参数化查询
const { rows } = await pool.query(
  'INSERT INTO users (email, password_hash, full_name) VALUES ($1, $2, $3) RETURNING id',
  [email, hash, fullName]
);

但仍有隐患:它没处理 UNIQUE_VIOLATION 错误码,导致邮箱重复时返回500而非409。

第三版(人主导,第12天上线)
我手动重构为:

try {
  const { rows } = await pool.query(
    'INSERT INTO users (email, password_hash, full_name) VALUES ($1, $2, $3) RETURNING id',
    [email, hash, fullName]
  );
  return NextResponse.json({ success: true, userId: rows[0].id }, { status: 201 });
} catch (error) {
  if (error.code === '23505') { // PostgreSQL unique_violation
    return NextResponse.json({ success: false, error: 'EMAIL_TAKEN' }, { status: 409 });
  }
  console.error('Registration failed:', error);
  return NextResponse.json({ success: false, error: 'SERVER_ERROR' }, { status: 500 });
}

这个版本的关键改进在于: 错误码映射 error.code === '23505' )和 日志分级 (业务错误不打ERROR级别)。AI能写出语法正确的catch块,但永远不知道 23505 这个魔数代表什么,也不知道该不该记录到Sentry。

注意:AI生成的API代码,必须经过“三问审查”:① 输入是否全部经过验证(正则、长度、类型)?② 数据库操作是否100%参数化?③ 所有外部调用(如Stripe API)是否有超时和重试?我建立了一个检查清单,每次合并API PR前必须逐项打钩。

3.3 数据库与安全层:那些AI永远学不会的“常识”

如果说前端和API是AI的舒适区,那么数据库设计和安全实践就是它的“认知禁区”。AI可以生成语法完美的SQL,但它不理解“为什么用户表要分离密码重置令牌”;它可以写出JWT验证代码,但它不知道“refresh token必须存数据库且绑定设备指纹”。

数据库设计的“人定规则”
我给Claude的prompt里,第一条永远是:“生成PostgreSQL 15的schema,严格遵守以下规则:① 所有表名用复数小写(users, sessions);② 主键统一用 id SERIAL PRIMARY KEY ;③ 外键必须带 ON DELETE CASCADE ;④ 敏感字段(password_hash, refresh_token)必须加 NOT NULL ;⑤ 创建时间统一用 timestamptz created_at DEFAULT NOW() ”。它生成的schema基本可用,但有三个必须人工修正的点:

  • 它总把 refresh_tokens 表的 expires_at 字段设为 TIMESTAMP 而非 timestamptz ,导致时区转换错误;
  • 它给 sessions 表加了 user_id INTEGER REFERENCES users(id) ,却漏了 ON DELETE CASCADE
  • 它在 users 表里加了 last_login_at TIMESTAMP ,但没设默认值,导致新用户注册后该字段为NULL,前端展示异常。

安全实践的“不可协商条款”
我整理了一份《AI生成代码安全红线》,贴在团队共享文档里,所有成员(包括我自己)必须遵守:

  • 密码处理 :必须用 bcryptjs ,盐值≥12,禁止 md5 / sha256
  • Token管理 :JWT的 exp 必须≤24h,refresh token必须存数据库且带 fingerprint 字段(SHA256(userAgent+ip));
  • CORS配置 :Next.js的 middleware.ts 里, origin 必须白名单校验,禁止 *
  • 错误信息 :生产环境禁止返回 error.stack ,所有500错误统一返回 { error: 'INTERNAL_ERROR' }

这些不是技术难点,而是工程常识。AI没有“常识”,它只有“统计规律”。所以我的工作不是教AI写安全代码,而是 用代码审查清单把常识变成不可绕过的流程

4. 实操过程中的典型问题与排查技巧

4.1 “AI生成的代码能跑,但性能奇差”:从12秒到320ms的优化路径

第10天,用户反馈仪表盘加载要12秒。Chrome DevTools显示, /api/dashboard/data 接口耗时11.8秒。我本以为是数据库慢,结果发现是AI生成的后端代码问题:

// ❌ AI生成的低效代码(伪代码)
for (const day of last30Days) {
  const dailyData = await pool.query(
    'SELECT * FROM sessions WHERE DATE(created_at) = $1 AND user_id = $2',
    [day, userId]
  );
  // 对每个day发起一次DB查询
}
// 30次查询 × 平均300ms = 9秒+

排查思路

  1. 先用Vercel的Edge Function日志,确认是后端耗时而非网络延迟;
  2. 在本地用 EXPLAIN ANALYZE 跑AI生成的SQL,发现它没用到 created_at 索引(因为 DATE(created_at) 函数导致索引失效);
  3. 用Cursor扫描整个 /lib/dashboard 目录,搜索 pool.query( ,发现所有日期过滤都用了 DATE() 函数。

解决方案
我让Claude重新生成,prompt强调:“必须用范围查询替代 DATE() 函数,假设 created_at timestamptz ,生成获取某天所有记录的SQL,要求利用索引”。它输出:

SELECT * FROM sessions 
WHERE created_at >= $1 AND created_at < $2 AND user_id = $3
-- $1 = '2024-05-01T00:00:00Z', $2 = '2024-05-02T00:00:00Z'

然后我手动把30次循环改成单次查询:

const { rows } = await pool.query(
  'SELECT * FROM sessions WHERE created_at >= $1 AND created_at < $2 AND user_id = $3',
  [startOfRange, endOfRange, userId]
);
// 再用JavaScript按天分组

最终接口耗时降至320ms。 关键教训 :AI擅长“单点最优”,但缺乏“系统视角”。性能优化永远是人定义约束(“必须用索引”)、AI提供方案(“用范围查询”)、人做整合(“把循环改成单查+内存分组”)的三角协作。

4.2 “环境变量在本地OK,上线就undefined”:Vercel部署的隐形陷阱

第16天,Stripe支付功能在本地测试完美,一上Vercel就报 Cannot read property 'secret' of undefined 。日志显示 process.env.STRIPE_SECRET_KEY 是undefined。

排查过程

  • 检查Vercel项目设置 → Environment Variables → 确认 STRIPE_SECRET_KEY 已添加且值正确;
  • 查看Next.js文档 → 发现App Router中,环境变量必须在服务端组件或Server Action中用 process.env.XXX ,在客户端组件中必须用 'use client' + process.env.NEXT_PUBLIC_XXX
  • 搜索代码 → 发现AI生成的 lib/stripe/client.ts 里,有 const stripe = new Stripe(process.env.STRIPE_SECRET_KEY) ,而这个文件被客户端组件导入了。

根本原因 :AI不知道Vercel的环境变量作用域规则。它看到 process.env.XXX 就认为“全局可用”,而实际上Next.js做了严格的SSR/CSR隔离。

解决步骤

  1. 把所有敏感密钥(Stripe、PostgreSQL)的访问,严格限制在 /app/api/ 路由或Server Component中;
  2. 为客户端需要的非敏感配置(如 NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY ),创建新的public环境变量;
  3. lib/stripe/client.ts 顶部加注释: // ⚠️ This file must ONLY be imported in Server Components or API routes
  4. 用Cursor运行“Find all imports of this file”,确认没有客户端组件引用它。

实操心得:环境变量问题是AI协作中最隐蔽的“时差bug”。我的固定动作是:每次添加新环境变量,立刻在Vercel控制台设置,然后在本地 .env.local 里补全,并在代码里加一行 console.log('ENV CHECK:', process.env.MY_VAR) ,上线前删掉。宁可啰嗦,不赌运气。

4.3 “类型推导失效导致TS编译失败”:TypeScript与AI的相爱相杀

第21天, yarn build 突然失败,报错:

Type error: Type '{ id: string; email: string; }' is not assignable to type 'User'.
  Object literal may only specify known properties, and 'id' does not exist in type 'User'.

types/user.ts ,明明定义了 id: string 。原来AI在生成某个API响应处理函数时,写了:

// ❌ AI生成的错误类型断言
const user = { id: 'abc', email: 'a@b.com' } as User; // TS报错

User 接口里, id number 类型(因为PostgreSQL的 SERIAL 主键被AI误判为number)。

解决流程

  1. 用VS Code的“Go to Type Definition”跳转到 User 接口,确认 id: number
  2. 搜索整个项目,找到AI生成 as User 的地方,发现它在 /lib/api/fetchUser.ts 里;
  3. 让Claude重写这个函数,prompt强调:“ User.id 是number类型,但数据库返回的id是string(因为pg库默认把SERIAL转为string),请用 parseInt() 安全转换,并添加类型守卫”;
  4. 最终生成:
const userData = await fetch('/api/user').then(r => r.json());
if (typeof userData.id === 'string') {
  userData.id = parseInt(userData.id, 10);
}
return userData as User;

核心原则 永远不要让AI决定类型,人定义类型,AI适配类型 。我现在的做法是:所有API响应类型,都基于OpenAPI spec手动生成(用 openapi-typescript ),而不是让AI猜。这多花20分钟,但省下三天debug时间。

5. 关键经验总结与可复用的工作流

5.1 “AI辅助开发”的真实ROI:时间节省在哪,时间消耗在哪?

30天实验结束后,我做了详细的时间审计(基于RescueTime数据):

阶段 传统开发预估耗时 AI辅助实际耗时 节省时间 主要节省点 主要新增耗时
需求分析与原型 8小时 6小时 2小时 Copilot快速生成Figma文案、Cursor分析竞品页面结构 反复调整prompt直到AI理解“轻量级”需求
前端组件开发 40小时 22小时 18小时 90%的UI组件、表单、列表由Copilot首稿生成 审查状态管理、修复CSS优先级冲突
后端API开发 35小时 28小时 7小时 CRUD接口、基础验证逻辑由Claude生成 重写所有数据库错误处理、添加监控埋点
数据库与安全 15小时 25小时 -10小时 AI生成schema和基础migration 手动修正索引、添加token刷新逻辑、配置CSP头
测试与部署 12小时 18小时 -6小时 AI生成Jest测试用例框架 调试CI/CD流水线、修复Vercel缓存策略

结论很清晰 :AI在 模式化、重复性、语法密集型 任务上优势巨大(前端组件、基础API),但在 状态一致性、安全合规、跨系统集成 上不仅不省时,反而增加成本。真正的ROI不在“写代码更快”,而在“把人从语法劳动中解放,投入到更高价值的设计决策中”。比如,我用省下的18小时前端时间,深度重构了用户引导流程,增加了3个关键转化点,上线后付费转化率提升22%——这才是AI带来的真实商业价值。

5.2 我的“人机协作”黄金工作流(可直接抄作业)

基于30天踩坑,我固化了一套每日开发流程,已写成团队内部手册:

晨间15分钟:准备阶段

  • 检查Vercel、PostgreSQL、Stripe沙盒环境状态;
  • 运行 npx tsc --noEmit 确保TS类型无误;
  • 用Cursor扫描昨日代码,生成“潜在风险报告”(如“检测到3处未处理的Promise rejection”)。

编码中:三步审查法

  1. Prompt审查 :写完prompt先自问:“这个指令是否足够具体?是否排除了歧义?是否定义了失败标准?”(例:不说“生成登录API”,而说“生成Next.js App Router的POST /api/auth/login,要求:① 用bcrypt.compare验证密码;② 成功返回JWT,失败返回401;③ 错误信息不暴露密码错误还是邮箱错误”);
  2. 生成审查 :AI输出后,立即检查:① 所有外部依赖是否已安装?② 类型是否与现有接口一致?③ 是否有硬编码的密钥或路径?④ 错误处理是否覆盖所有分支?
  3. 集成审查 :合并到主干前,用Cursor运行“Test this file”,人工验证测试用例是否覆盖边界条件(如空数组、超长字符串、特殊字符)。

收尾5分钟:知识沉淀

  • 把当日最有效的prompt,存入Notion的“Prompt Library”(分类:前端/后端/数据库/安全);
  • 记录一个“今日AI翻车案例”(例:“Claude生成的PDF导出,漏了font-family声明,导致中文乱码”);
  • 更新“安全红线”清单(新增一项:“PDF生成必须显式声明font-family: 'Noto Sans CJK SC'”)。

这套流程的核心思想是: 把AI当作一个极其聪明但毫无常识的实习生,你的工作不是教它知识,而是建立一套让它无法犯错的流程 。就像汽车有ABS防抱死系统,不是为了让司机开得更快,而是为了让他在极限情况下依然可控。

5.3 给不同角色的实操建议:CTO、工程师、新人如何落地

  • 给CTO/技术负责人
    不要采购“AI编程平台”,要投资“AI协作流程”。预算应该花在:① 团队Prompt工程培训(重点教如何把模糊需求转为AI可执行指令);② 建立代码审查Checklist(把安全红线、性能规范、可观测性要求固化为PR模板);③ 搭建内部AI知识库(收集各团队验证有效的prompt和避坑指南)。技术选型上,优先选与现有工具链深度集成的(如Cursor对Next.js的支持远好于CodeWhisperer),而非参数指标最高的。

  • 给中级工程师
    把AI当成“超级代码补全”,而非“全自动程序员”。每天花10分钟做三件事:① 用Cursor分析一个你写的旧函数,“它哪里可以优化?”;② 把一个重复性任务(如生成TypeScript接口)写成prompt,让Claude生成,再对比你手写的差异;③ 在Git commit message里,明确标注“AI生成部分:XXX,人工审查点:YYY”。坚持一周,你会建立起对AI能力边界的肌肉记忆。

  • 给转行新人
    别急着学“怎么用Copilot”,先学“怎么读代码”。从今天开始,每次AI生成代码,强制自己做三件事:① 用VS Code的“Go to Definition”跳转到所有调用的函数,看懂它做什么;② 在关键逻辑处加 console.log ,运行看实际输出;③ 把AI生成的代码,用自己的话口头解释一遍给同事听。AI是加速器,但地基必须是你亲手打的。我见过太多新人,Copilot生成的代码跑通了就提交,结果线上崩了,连错误日志都看不懂——那不是AI的问题,是地基没打好。

最后分享一个我贴在显示器上的小技巧:每当AI生成一段代码,我习惯性地问自己一个问题——“如果这段代码明天就没人维护了,一个完全不懂这个项目的新人,能不能只看这段代码和注释,就明白它在做什么、为什么这么做、什么情况下会失败?” 如果答案是否定的,那就不是AI的问题,是我的问题。因为最终交付的,不是AI写的代码,而是我作为工程师的判断、责任和尊严。

Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐