我大概花了一个周末加两个晚上,用 Claude Code 从零搭完了一个能真正跑起来的宠物生命周期管理 App。动手之前,我原本的预期是:AI 能帮我写掉大部分样板代码,我负责处理复杂逻辑和收尾工作。跑完之后这个预期基本成立,但过程和我预先想象的完全不一样——最花时间的不是写代码,而是搞清楚要让 AI 照着什么标准写。
这个项目本身不算大,但覆盖了一个完整应用的典型全流程:需求拆解、技术选型、数据模型、接口、页面、调试、测试、部署。把它交给 Claude Code 去走一遍,比单独测试"AI 能不能写函数"有价值得多。如果你也想评估 AI 编程工具到底能承担多少真实工作,或者想找一个合适的练手项目来跑通全流程,这篇记录应该能给你一些参考。
1. 为什么偏偏选"宠物生命周期管理",以及这个项目适合验证 AI 全流程的理由
1.1 宠物养护的真实痛点
养宠物的人都有一个共同的麻烦:事太多,时间一长全靠记性。幼年期的疫苗打了几针、下次驱虫是什么时候、上次体检是什么时候、体重是不是悄悄涨了、宠物现在相当于人类多少岁,这些信息分散在疫苗本、体检单、手机相册和聊天记录里。
宠物生命周期管理 App 要解决的,就是把这一堆杂乱信息收拢成几个清晰的东西:宠物档案、健康时间线、疫苗驱虫提醒、体重趋势、生命周期阶段。功能边界很明确,用户痛点也真实存在,做出来不是那种"为了 AI 而 AI"的玩具项目。
从开发角度看,这个项目还有一个很大的优势:它不依赖复杂的第三方业务系统。既不用对接支付,也不用处理社交关系链,核心就是一套围绕"Pet"这个实体的 CRUD,加上日期计算和提醒逻辑。这种项目的信息密度刚好合适——既能让 AI 发挥代码生成能力,又不会因为外部依赖太多导致 AI 频繁"卡壳"。
1.2 为什么说它是一个理想的 AI 全流程试验场
选项目验证 AI 开发能力,最怕的是选了业务规则绕来绕去的场景。比如做电商订单系统,光是状态机和退款流程就能让 AI 生成一堆似是而非的代码。宠物生命周期管理不一样,它的业务规则可以拆得很清楚:
- 宠物档案:基础信息增删改查
- 生命周期阶段:根据物种、生日计算幼年期/成年期/老年期,展示换算的人类年龄
- 疫苗驱虫提醒:根据最近一次记录时间和建议间隔,自动计算下次日期
- 健康记录与体重趋势:时间线展示,体重折线图
每一个模块都能独立描述、独立验收,符合"给 AI 下任务时任务边界要清晰"的原则。我把这个项目完整跑下来之后最大的感受是:AI 全流程开发能不能顺利,前期把业务拆得多清楚,基本就决定了后面 80% 的体验。
1.3 技术选型:让 AI 在一个成熟技术栈里干活
技术栈我定的是 Next.js App Router + Prisma + Tailwind CSS,本地开发用 SQLite,部署到 Linux 服务器后切到 PostgreSQL,进程管理用 PM2,Nginx 做反向代理。
选这个组合,不是因为它最潮,而是因为它最适合 AI 协作:
- Next.js 的 App Router 是文件即路由,每个页面一个目录,AI 生成的代码结构天然清晰,不容易出现找不到文件在哪的问题
- Prisma 用 schema 描述数据模型,改模型然后生成迁移,这种工作流非常适合对话式迭代——改一行 schema,然后让 AI 去同步迁移和代码
- Tailwind 的原子类让 AI 生成的样式不容易破坏整体布局,不需要维护复杂的 CSS 文件
一开始我没有让 AI 参与技术选型,而是直接把这些约束丢给它。原因很简单:让 AI 自由选型,它往往会给你一个看起来合理但不一定符合你部署习惯的方案。选型这件事人拿主意,生成和执行交给 AI,这是全流程里效率最高的分工方式。
2. 从一句话需求到技术方案:Claude Code 完成的第一轮业务拆解
2.1 第一轮对话:不要让它急着写代码
我见过很多人用 AI 编程工具,上来就是"帮我做一个宠物管理 App",然后 AI 刷刷刷生成几百个文件,看起来热闹,实际一半不能用。关键问题是跳过了业务拆解。
我的第一条指令刻意要求它先别写代码,只做方案:
我是一个独立开发者,想做一个宠物生命周期管理 App。 目标用户是养猫养狗的个人用户。 核心功能必须包含:多宠物档案、疫苗驱虫提醒、健康记录、体重趋势、生命周期阶段展示;提醒功能不要用后台定时任务,采用打开应用时按需计算。 技术栈固定为 Next.js App Router + Prisma + Tailwind CSS,本地用 SQLite。 你先不要写代码,帮我输出: 1. 数据模型草案 2. 页面路由结构 3. 每个页面的主要职责 4. 实现里程碑划分Claude Code 第一轮给出的方案大体在点子上,数据模型分成了 Pet、VaccinationRecord、HealthRecord、WeightRecord 四张表,路由结构覆盖了宠物列表、详情、新增、编辑和健康时间线。但它给的里程碑划分太粗,只有"搭建环境、实现 CRUD、补充提醒"三个阶段,粒度不够。
我让它把提醒功能单独拆出来,并要求它明确"提醒看板"这个页面的计算逻辑。它很快补充了细节:提醒看板统一读取所有宠物的疫苗和驱虫记录,用 date-fns 计算下次日期,标记出已到期和未来 7 天内到期的项目。
这一轮跑完,我对 Claude Code 的定位有了一个更准确的判断:它很强的地方在于把模糊需求翻译成结构化方案,但前提是你得给它足够明确的约束。如果我只说"做一个宠物管理 App",它给出的方案大概率会包含一些我用不上的东西,比如用户注册登录、社交分享功能。
2.2 用 CLAUDE.md 固定项目约定
第一轮对话之后,我强烈意识到一个工具非常值得用:CLAUDE.md。这是 Claude Code 的项目记忆文件,放在项目根目录,每次对话它都会自动读取。
我在 CLAUDE.md 里写明了这几件事:
# 项目约定 - 技术栈:Next.js App Router + Prisma + Tailwind CSS - 包管理器:npm - 数据库:本地使用 SQLite,生产使用 PostgreSQL - 代码风格:函数组件 + TypeScript,优先使用 server action 处理数据变更 - 日期处理:统一使用 date-fns,禁止使用 setMonth 直接改日期 - 提交规范:每个里程碑结束后手动 git commit,不要 AI 自动提交 - 提醒设计:不引入定时任务,在页面请求时按需计算下次提醒日期有了这个文件之后,后续对话里 AI 很少再问"用什么技术栈""日期用什么库"这类基础问题,也很少跑偏生成一些和项目约定不符的代码。这就相当于你给 AI 上了一道"项目宪法",它在生成代码时会更贴近你自己的开发习惯。如果你打算长期用 AI 协作开发,CLAUDE.md 是花半小时写清楚、后面能帮你省好几天时间的投资。
3. 代码落地的过程:数据模型、生命周期算法与核心页面逐个实现
3.1 环境准备与项目初始化
Claude Code 的本质是命令行工具,所以所有操作都在终端里完成。环境准备这一步没有太多玄学,先把基础环境准备好:
# 检查 Node 版本,建议 20 以上 node -v # 安装 Claude Code CLI npm install -g @anthropic-ai/claude-code # 在项目目录初始化 npx create-next-app@latest pet-life-app --typescript --tailwind --app初始化完成后,安装 Prisma 并初始化数据库。这里我没有手动敲建表 SQL,而是直接把数据模型需求发给 Claude Code,让它生成 Prisma schema 和迁移文件。
有一个细节值得说:create-next-app生成的项目结构和 Claude Code 自己从零搭的未必完全一致。直接用官方脚手架的好处是,避免 AI 在配置上自由发挥。脚手架定好骨架,AI 在骨架里填充内容,出错概率会低很多。
3.2 数据模型:让 AI 设计,人审查关系约束
Prisma schema 是 AI 生成的核心文件之一。我要它按照之前确认的数据模型草案,一次性生成完整的 schema。它给出的核心模型是这样的:
model Pet { id Int @id @default(autoincrement()) name String species String // cat / dog / rabbit breed String? birthDate DateTime gender String? neutered Boolean @default(false) avatarUrl String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt weights WeightRecord[] healthRecords HealthRecord[] vaccinations VaccinationRecord[] } model VaccinationRecord { id Int @id @default(autoincrement()) petId Int pet Pet @relation(fields: [petId], references: [id], onDelete: Cascade) name String givenAt DateTime expiresAt DateTime? notes String? } model WeightRecord { id Int @id @default(autoincrement()) petId Int pet Pet @relation(fields: [petId], references: [id], onDelete: Cascade) weightKg Float measuredAt DateTime } model HealthRecord { id Int @id @default(autoincrement()) petId Int pet Pet @relation(fields: [petId], references: [id], onDelete: Cascade) title String recordAt DateTime detail String? costCent Int? }Schema 整体没什么问题,但有两个点是我手动审查后才发现的。
第一,Pet 表缺少一个"类型"字段用于区分品种大小。猫和狗的疫苗提醒时间表不同,而狗又分成小型犬、中型犬、大型犬,它们的成年和老年节点不一样。我要求它加上sizeCategory字段,并塞进一组默认配置。
第二,所有子表的时间字段命名不统一,givenAt、measuredAt、recordAt混着用。这对功能没有影响,但后续写排序和展示逻辑时容易搞混。我让 AI 统一改成recordedAt风格,它花了半分钟全局替换,干净利落。
这里是我的一个核心心得:数据模型这种地基类的东西,无论如何都要人亲自看一遍,重点看关系约束、级联删除、字段命名一致性。AI 能建得非常快,但建完之后你把关的责任一点没少。
3.3 生命周期阶段算法:给 AI 出业务规则题
生命周期阶段计算是这个 App 最"有技术含量"的部分。我给 Claude Code 出的题目是:根据物种和出生日期,判断宠物处于幼年期、成年期还是老年期,并估算相当于人类多少岁。
它给出一版可用的实现,核心是一个配置表和两个纯函数:
type Species = 'cat' | 'smallDog' | 'mediumDog' | 'largeDog'; const LIFECYCLE_CONFIG: Record<Species, { adultAgeMonths: number; seniorYears: number; perYearHumanAge: number }> = { cat: { adultAgeMonths: 12, seniorYears: 10, perYearHumanAge: 4 }, smallDog: { adultAgeMonths: 12, seniorYears: 11, perYearHumanAge: 5 }, mediumDog: { adultAgeMonths: 15, seniorYears: 9, perYearHumanAge: 5 }, largeDog: { adultAgeMonths: 18, seniorYears: 8, perYearHumanAge: 6 }, }; export function getLifecycle(species: Species, birthDate: Date, now: Date = new Date()) { const months = (now.getFullYear() - birthDate.getFullYear()) * 12 + (now.getMonth() - birthDate.getMonth()); const years = months / 12; const cfg = LIFECYCLE_CONFIG[species] ?? LIFECYCLE_CONFIG.mediumDog; const stage = months < cfg.adultAgeMonths ? '幼年期' : years >= cfg.seniorYears ? '老年期' : '成年期'; const humanAge = years <= 1 ? Math.round(15 * years) : years <= 2 ? Math.round(15 + 9 * (years - 1)) : Math.round(24 + (years - 2) * cfg.perYearHumanAge); return { stage, humanAge, ageMonths: months }; }这里有两个细节值得展开。
一是now: Date = new Date()这个参数。我特意要求 AI 把"当前时间"作为可选项传入,不是为了花哨,而是为了让函数可测试。测试时固定传入一个时间点,才能断言"2024年6月出生的猫在2025年1月应该是幼年期"。这是我教它绿色工程的产物,AI 其实很擅长做这种调整,只要你明确提出。
二是配置表没有直接写死"几岁算老年",而是给每个物种定义seniorYears。这个抽象让前端可以做一件事:在宠物详情页展示一句阶段文案,比如"你已经进入老年期,建议每年做两次体检"。这算是把业务规则沉淀成了数据配置,后续调整只需改一行配置,不用动逻辑。
3.4 页面实现:从列表到详情,AI 生成代码的节奏控制
数据模型和算法稳定之后,页面开发就顺畅多了。我按照"列表页 → 新增表单 → 详情页 → 提醒看板"的顺序,一次让 AI 只做一个页面。
宠物列表页和新增表单的生成非常快。Claude Code 会直接生成 server component 读取数据库,再用一个 client component 处理表单提交。表单字段与数据模型一一对应,species和sizeCategory自动渲染成下拉框,出生日期用input type="date"。
有一件事它第一次没做对:日期表单控件的值传给后端时是YYYY-MM-DD字符串,但数据模型定义的是DateTime类型,直接new Date('2025-03-01')解析会有时区偏移问题,在东八区会把日期读成 2 月 28 日。它在生成详情页的年龄计算时暴露出这个 bug,我让它统一改用new Date(dateStr + 'T00:00:00')的方式解析,并在 CLAUDE.md 里记下了这个约定。
提醒看板是模块里最复杂的一个页面。它的逻辑是:遍历所有宠物,读取每只宠物的疫苗和驱虫记录,找到最近一次记录的时间,根据间隔算出下次时间,再和今天比较。Claude Code 生成的第一版嵌套了三层 map,可读性很差,我直接要求它把计算逻辑抽成lib/reminders.ts里的纯函数,页面只负责渲染。抽完之后测试和代码审查都轻松了很多。
4. 调试、测试与重构:让 AI 自己发现问题才是全流程的关键
4.1 三个真实 bug 的排查链路
AI 写的代码第一次就能全跑通是不可能的,所以"怎么用 AI 修 bug"比"怎么让 AI 写代码"更重要。这轮开发中遇到了三个典型问题,每一个都验证了同一个方法论:把现场证据原原本本喂给 AI,让它先分析原因,再给修复方案。
第一个是删除宠物时报外键约束错误。我在测试时删掉一只宠物,Prisma 直接抛错,原因是子表的外键没有配级联删除。我把完整的报错堆栈贴给 Claude Code,它很快就定位到 schema 里VaccinationRecord等模型的外键定义缺少onDelete: Cascade,然后自动生成了迁移并应用。修复命令是:
npx prisma migrate dev --name add_cascade_delete第二个是体重趋势图的连线来回乱跳。检查后发现,查询体重记录时没有orderBy: { recordedAt: 'asc' },数据按主键顺序返回,而用户补录历史体重时插入顺序和日期顺序不一致,图表连线自然就乱了。修复方法是三选一:在 Prisma 查询中排序,或者在拿到数组后 sort,或者 SQL 视图处理。Claude Code 选了第一种,因为它最清晰,页面代码不用改。
第三个是提醒日期跨年计算错误。这个最典型。用 JavaScript 原生的setMonth(current.getMonth() + 3)处理日期,如果当前是 11 月 30 日,会得到一个不存在的 2 月 30 日,JS 会把它自动滚动成 3 月 2 日或 3 日,提醒就莫名其妙提前或延后了。这个 bug 让 Claude Code 查了很久,因为它生成的第一次检查逻辑看着没问题,是我把边界场景直接写成测试用例(11月30日加3个月应该等于次年2月28日),它才意识到是setMonth的问题。最终改用date-fns的addMonths,这个库会自动把溢出的日期收敛到月末。这个案例让我确定了一件事:AI 修 bug 时,明确给出边界条件比反复说"这里不对"管用得多。
4.2 让 AI 写测试:从手动验证到自动化守护
项目功能基本成形后,我要求 Claude Code 给生命周期算法和提醒计算补测试。它用 Vitest 写了两个测试文件,其中一个针对生命周期算法:
import { describe, expect, it } from 'vitest'; import { getLifecycle } from '@/lib/lifecycle'; describe('getLifecycle', () => { it('猫在12个月之前属于幼年期', () => { const birthDate = new Date('2024-06-01T00:00:00'); const now = new Date('2025-01-01T00:00:00'); expect(getLifecycle('cat', birthDate, now).stage).toBe('幼年期'); }); it('猫在10岁之后属于老年期', () => { const birthDate = new Date('2014-03-01T00:00:00'); const now = new Date('2025-01-01T00:00:00'); expect(getLifecycle('cat', birthDate, now).stage).toBe('老年期'); }); it('大型犬在2岁前仍属于幼年期', () => { const birthDate = new Date('2022-06-01T00:00:00'); const now = new Date('2024-01-01T00:00:00'); expect(getLifecycle('largeDog', birthDate, now).stage).toBe('幼年期'); }); });这些测试本身不难,但有一个关键是——正是因为之前写算法时强制要求了now参数,测试才能稳定通过。你现在回头看,这算是我在 AI 协作中学到的最重要一课:你给 AI 提的每一个功能要求,都要顺手想一下"这个逻辑能不能被测试"。如果 AI 生成的函数依赖了全局时间、全局状态或者第三方服务的隐式数据,立刻让它改成可注入、可控制的形式。这条原则决定了 AI 生成的代码是"能跑"还是"能长期维护"。
4.3 重构指令:让 AI 在约束条件下整理代码
页面多了之后,重复代码开始出现。详情页和列表页各有一份几乎一样的"宠物基础信息卡片",提醒看板里也有类似的渲染逻辑。我挑了一个最臃肿的页面文件,向 Claude Code 下达了这样一个重构指令:
pages/pets/[id]/page.tsx 现在同时完成了数据获取、阶段计算、提醒判断和页面渲染,单文件超过 260 行。 请在不改变任何视觉效果的前提下: 1. 把数据库查询逻辑抽到 lib/queries.ts 2. 把阶段和提醒的计算逻辑抽到 lib/pet-metrics.ts 3. 给这两个模块补上单元测试 4. 完成后运行 npm run build,确保没有类型错误 5. 不要动页面的 UI 文案这次重构花了大约 20 分钟。Claude Code 会自动读取原来的文件、提取关键逻辑、创建新模块、修改引用,跑测试和构建。我只需要在最后 review 一遍改动,确认它没有把 props 的命名改乱,没有丢失空状态判断。
重构指令有一个规律:约束条件越具体,结果越可靠。尤其"什么不能动"比"要做什么"更重要。如果你只让它"重构一下",它可能会顺手优化文案、改样式、调整组件结构,导致 diff 很大,review 成本反而上去了。给它一条"视觉效果不变、文案不变、不能新增依赖"的边界,它才会规规矩矩干活。
5. 从本地到服务器:构建、数据库迁移与上线部署的坑
5.1 从 SQLite 切换到 PostgreSQL:环境差异是最大变量
本地开发一直用 SQLite,部署到服务器自然要切换到 PostgreSQL。切换过程不复杂,先在服务器上装好 PostgreSQL,建好数据库和用户,然后在.env里改 DATABASE_URL:
DATABASE_URL="postgresql://pet_user:你的密码@127.0.0.1:5432/pet_life_db?schema=public"接着在服务器上执行数据库迁移:
npx prisma migrate deploy这里有一个容易翻车的点:如果本地迁移历史和生产库的实际状态不一致,migrate deploy可能会卡在某个旧的迁移文件上。我的做法是,在本地彻底删除 SQLite 的 dev.db,然后重新prisma migrate dev生成一份干净的迁移历史。这样交到生产环境时,迁移文件从上到下都是可执行状态。
PostgreSQL 和 SQLite 在类型上也有微妙差异。SQLite 对DateTime存储很随意,PostgreSQL 则严格得多。好在 Prisma 抽象掉了大部分差异,我只需要在 schema 里明确@db.Timestamptz这类注解,否则默认时区可能会把时间偏移。构建阶段 AI 没有参与太多,因为环境问题更依赖人的排查经验。
5.2 上传文件的持久化问题:最容易忽略的部署坑
这个 App 有宠物头像上传功能。开发时我把上传文件直接存在public/uploads下,本地一切正常。上线前我例行检查时突然意识到一件事:生产环境执行npm run build和部署流程时,public目录会被项目发布包完整覆盖,新上传的头像在下一次部署后就会全部丢失。
这不是 AI 能替你发现的问题,因为它属于部署架构层。我的解决方法是:上传目录改为应用外的持久路径,比如/var/www/pet-life-uploads,然后在 Nginx 里加一条静态映射:
location /uploads/ { alias /var/www/pet-life-uploads/; }代码层面需要读取上传文件时,URL 直接拼/uploads/xxx.jpg即可。这个改动对于本项目的体量足够,不用引入对象存储服务。
5.3 构建、启动与服务器配置
部署流程在服务器上跑的命令比较标准:
npm ci npx prisma generate npx prisma migrate deploy npm run build pm2 start npm --name pet-life -- startNginx 反向代理配置也很常规,把 80 端口转发到 3000 端口,同时配好client_max_body_size,否则重一点的头像图片会被 Nginx 默认的 1MB 限制拦掉。
上线之后我做的第一件事是检查 PM2 日志,重点看有没有 Prisma 连接报错和时区警告。这个项目面向国内用户,服务器如果默认 UTC 时区,提醒逻辑算出的"今天"就会差 8 小时。记得在服务器和 Node 进程里都显式设置TZ=Asia/Shanghai,否则日期提醒类功能很容易出现"明明到了日期却不提醒"的诡异问题。
6. 全流程复盘:AI 到底帮了多少,以及哪些地方绝对不能放手
6.1 环节耗时对比
这个项目如果按我过去的习惯做,通常需要 5 到 7 天,其中前端页面和调试占了大头。这次配合 Claude Code,实际大约用了两个晚上加一个完整的周末。下面的表是我自己记录的耗时,仅供参考,不同项目差异会很大:
| 环节 | 常规预估 | AI 协作实际耗时 | 我的主要工作 |
|---|---|---|---|
| 需求拆解与技术设计 | 半天 | 约 1 小时 | 明确功能边界,确认提醒方案 |
| 数据模型与接口 | 1-2 天 | 约 3 小时 | 审查外键、级联、字段命名 |
| 前端页面 | 2-3 天 | 约 1 天 | 控制生成粒度,检查表单校验 |
| 调试与测试 | 1 天 | 约半天 | 把报错原样喂回 AI 定位 |
| 部署上线 | 1 天 | 约 2 小时 + 踩坑 | 处理上传目录、时区、Nginx |
整体下来,编码和调试环节大概是常规开发的三到四成时间,但需求设计和代码审查并没有明显缩短。换句话说,AI 压缩的是"把方案变成代码"的时间,而不是"想清楚要做什么"的时间。
6.2 哪些环节 AI 真的靠谱,哪些必须人盯着
跑完这个全流程,我能很明确地把 AI 的能力边界划出来。
AI 很靠谱的环节:样板代码、CRUD、表单页面、Prisma schema 和迁移生成、日志与报错解释、测试用例编写、按约束重构。这些任务的共同特点是信息完整、预期明确,AI 不需要在模糊地带做判断。
AI 不靠谱的环节:需求边界确认(它倾向于把系统做大,你得主动砍)、安全与权限设计(默认完全没有鉴权,需要人来补)、UI 细节一致性(间距、对齐、交互状态)、部署环境的隐性问题(路径、权限、时区、上传目录持久化)。
尤其安全相关的东西,绝不能因为 AI 会生成代码就放松。这个项目里用户数据是私有数据,我确认了一下:所有数据变更接口没有做任何权限校验,也就是说任何能访问到服务的人都可以增删改宠物记录。这显然不行,所以我要求 Claude Code 给所有 data mutation 加了一层最简单的 token 校验,在 server action 里校验请求头中的访问令牌。AI 完全可以做这件事,但提这个需求的人必须是我——因为它自己不会主动想到"你部署的公网服务需要鉴权"。
6.3 如果想复现这个过程,我建议你这样做
给准备用 Claude Code 从零搭项目的人几条实际建议,都是我踩过之后觉得最有价值的部分。
第一,第一次对话就要把约束交代完整。技术栈、数据库、部署目标、不合用后台定时任务,这些在初轮说清楚,比之后反复纠正省钱得多。
第二,把任务拆成一个个"逻辑闭环"。一次让它完成一件事:先数据模型,再查询逻辑,再单个页面,再提醒算法。一次让它做整个系统,结果往往是表面完整、细节全崩。
第三,改完必须让它自己验证。要求 AI 在完成改动后运行 build 或测试,把报错原样贴回来。这样能逼出很多隐藏问题。
第四,代码审查重点盯这几个地方:数据校验、日期边界、级联删除、上传安全、空状态处理。这是 AI 最容易出错也最容易糊弄过去的区域。
第五,每个里程碑完成就手动提交一次代码。不要让 AI 提交,因为 AI 的提交信息可能很模糊,而且自动提交会让回滚变得混乱。
这次全流程跑完之后,我个人的感受是:Claude Code 确实把"从想法到可运行的软件"这条路缩短了一大截,但它没有替代开发者身上的责任,只是把责任从"亲手敲每一行代码"变成了"准确描述需求、严格验收结果"。我现在自己新项目的习惯也变了——先花半小时把需求、技术栈、边界条件写清楚,再把这个上下文完整交给 AI 去执行。最后再分享一个小技巧:如果某个页面反复修不好,别在同一个对话里纠缠,开一个新对话,把页面相关文件路径、报错信息和 CLAUDE.md 约定重新喂一遍,往往会有奇效。