用Claude Code全流程开发宠物管理App:从PRD到联调的实战经验
1. 用Claude Code从零开工之前先把全流程这件事想清楚1.1 为什么我决定让AI从头参与而不是先手写骨架最近我给自己定了一个有点激进的目标不用传统脚手架不做任何手工初始化让Claude Code从头搭建一个完整的宠物生命周期管理App。这个App听起来不复杂但真要细化它牵扯的是宠物档案、体重曲线、疫苗记录、驱虫记录、体检档案、自动提醒、生命周期阶段判断这些跨模块功能恰好适合拿来检验一件事——AI到底能不能从零到一独立撑起一个项目。说实话我一开始是悲观的。过去用大模型写代码最熟练的场景是我搭好了项目结构AI帮我补函数或者我报一个错误AI给我修。这种模式下AI只是高级补全工具项目再怎么折腾都在人设定的框架里。但我这次想反过来先不写任何代码只给Claude Code一个目标让它自己决定项目结构、技术选型、数据建模、接口设计、页面逻辑做完之后我再逐层验收。为什么这么干因为只有真正把手放开一次才能摸清AI开发的边界在哪里这个边界会直接影响以后所有项目的分工方式。真正的转折点出现在第一轮对话结束之后。我让Claude Code先输出一份完整的需求理解和技术方案它给出的东西比我预想中完整得多——不仅列出了六大核心模块还自己补了宠物生命周期阶段自动划分和疫苗临期提醒两个我没有明确提到的功能并且主动给出了数据表的划分草案。那一刻我就意识到AI全流程开发不是噱头关键问题已经从AI行不行变成了人怎么管AI。1.2 技术选型为什么是FastAPI SQLite React技术选型是整个项目里第一个需要人拍板的决策。我刻意没有让Claude Code自由选型而是给了三个硬约束后端用FastAPI、数据库用SQLite、前端用React。之所以这么定不是因为这是最优组合而是因为它们是AI训练语料里最常见的组合之一生成质量最稳定踩坑概率最低。FastAPI的优势在于它自带OpenAPI文档AI生成的接口可以直接通过Swagger UI验证这给我们后续验收提供了极大的便利。SQLite则够轻一个文件搞定存储不需要额外部署服务对从零搭建这类项目来说能减少大量环境噪音。前端用React加Vite组件化清晰AI生成界面的效率高。三个选型都偏向稳妥型我的原则是在全流程AI开发里不要为了炫技去选冷门框架。冷门框架的AI训练数据稀疏生成代码的质量会断崖式下降到时候查起错来等于把AI省的时间又加倍还回去。提示如果你也想复现这个项目建议不要一上来就上微服务、Redis、消息队列这些重型组件。先把单体应用用AI跑通再逐步加复杂度否则AI生成的代码掺杂大量无关依赖排错难度会激增。我给Claude Code的项目描述里明确写了这两句话后端所有数据通过SQLite文件存储路径在项目根目录下data/app.db和前端只允许使用React Vite不允许引入UI组件库组件一律手写。为什么特意加不允许引入UI组件库因为我被坑过太多次——AI特别倾向于在代码里塞各种第三方包有些包版本冲突一出现就是一整晚的折腾。限制它只能用基础能力反而能让生成结果更可控。1.3 项目范围定义宠物生命周期管理App到底在管什么在让AI写任何代码之前我自己先把业务范围想清楚了一遍。整个App的核心是回答三个问题这只宠物现在处于什么阶段它做过哪些健康事项下一个要做的事项是什么时候围绕这三个问题我圈定了六个核心模块。第一个模块是宠物档案包含品种、性别、生日、绝育状态、芯片号这些基础字段。第二个是体重记录模块用来追踪体重曲线。第三个是疫苗接种记录需要记录疫苗名称、接种日期、下一针到期日。第四个是驱虫记录外驱和内驱分开记录。第五个是体检记录包含体检时间、医院、检查结果摘要。第六个是提醒模块根据疫苗和驱虫记录自动生成临期提醒。表面上看这六个模块各管各的但它们在数据上存在强关联——提醒依赖疫苗和驱虫的到期时间生命周期阶段判断依赖宠物档案里的物种和生日。这种关联关系如果拆不清楚后续AI写代码时一定会四处打补丁。所以在项目描述里我专门花了一段让Claude Code梳理模块之间的依赖关系这是我认为全流程AI开发中最值得花的成本之一让AI在动手前先把数据流讲清楚。2. 项目的第一份产物不是代码是CLAUDE.md和PRD2.1 首轮对话把宠物生命周期管理变成可执行的需求很多人用Claude Code犯的第一个错误就是上来就让它帮我写一个宠物管理App。这种开放式指令写出来的东西只能是零散的玩具代码。我这次的第一步是逼它在动手前输出两份东西一份PRD一份项目管理计划。我的第一条指令大致是这么说的我要做一个宠物生命周期管理Web应用目标用户是养猫养狗的普通家庭。请先不要写代码输出完整的PRD内容包括用户故事、功能清单、优先级、数据实体、页面清单。然后再告诉我你打算分哪几个阶段实现每个阶段的验收标准是什么。它输出的PRD本身就是一次极好的需求校准。我原以为体重记录就只是一条数值和一个时间它却补充了体重记录需要带备注用于标记绝育后的体重变化体重曲线图要能按周/月切换粒度。这些细节如果让我自己想可能要等到开发后期才会补上到那时候改造成本就很高了。AI在最前面把这些潜在需求拽出来成本几乎为零。不过也要提醒一句AI输出的PRD不是不能改而是必须人工审。它给我的初版PRD里出现过用户可以通过社交分享宠物成长日记这种完全偏离核心的功能——我没有这个需求就直接划掉了。PRD阶段的意义在于把AI的想象力纳入框架内但不等于全盘接受它的发散要求。2.2 CLAUDE.md的写法约束AI比提示AI更重要Claude Code有一个我非常看重的特性项目根目录下的CLAUDE.md会被自动读取相当于项目的长期记忆库。这是我控制AI行为最重要的抓手比每轮对话里的临时提示词管用得多。我的CLAUDE.md分成了几个区块。第一块是技术栈铁律写死了后端框架、数据库、前端框架、包管理器。第二块是目录结构约定明确告诉它src/backend和src/frontend各自放什么。第三块是代码风格规范包括命名使用snake_case、注释要写中文、不允许在业务代码里夹带未使用的import。第四块是禁止事项比如不允许修改数据库文件结构除非先经过确认、不允许引入未在本文件列出的第三方依赖。这四块内容写下来之后的每一轮对话AI都会自带约束。我实测下来效果很明显没有CLAUDE.md的时候AI生成的代码里import乱七八糟今天用的是requests明天同一个功能它可能就换成httpx有了CLAUDE.md之后这种风格漂移现象基本消失了。还有个细节想分享CLAUDE.md不用写太长重点不是教AI怎么写代码而是告诉它不要做什么。AI的逻辑是无禁止即许可你少写一条约束它就会自作主张地加一个依赖包或者改目录结构。所以你真正要管住的是边界不是能力。2.3 任务拆解与里程碑验证点第一个里程碑是数据层建好SQLite文件、六张数据表全部落库、插入三条测试数据。第二个里程碑是后端API所有CRUD接口跑通Swagger文档可以操作数据库。第三个里程碑是前端页面能完成创建宠物→查看详情→添加记录→看到提醒这一条完整链路。第四个里程碑是逻辑层功能生命周期阶段判断和疫苗临期提醒上线。第五个里程碑是部署写出启动脚本和初始化脚本。重要的是我要求它每完成一个里程碑就停下来让我验收而不是自己一口气冲到底。全流程AI开发最怕的就是AI一路狂写最后丢给你一个看起来完整但其实处处是雷的大型项目。小步验收意味着每一段AI输出都有人工把关出了偏差最多回滚一小段而不是整个项目推倒重来。这些里程碑的验证点也写进了CLAUDE.mdAI每次完成一个阶段都会主动汇报当前处于第几个里程碑测试结果是怎样的。这个汇报机制帮了大忙——它不仅让项目进度透明化还能逼着AI在说完成之前先跑一遍验证命令而不是凭感觉判断代码正确。3. 数据模型设计是整条链路上最不能交给AI自由发挥的一环3.1 六张表支撑整个生命周期AI全流程开发里我最坚持亲自动手设计的就是数据模型。原因很简单代码写错了可以改但表结构一旦定下来后面所有API、页面、逻辑全都建立在它之上改结构的成本是指数级上升的。所以这个环节我不图快先自己把六张表的字段想清楚再让AI去实现建表脚本。宠物表叫pets核心字段是id、name、speciescat/dog、breed、gender、birth_date、neutered_status、chip_no、avatar_url。体重表叫weight_records关联pet_id记录weight_kg、recorded_date、备注remark。疫苗表叫vaccinations关联pet_id记录vaccine_name、vaccinated_date、next_due_date、备注。驱虫表叫dewormings同样关联pet_id要区分类型typeinternal/external记录product_name、administered_date、next_due_date。体检表叫health_checks关联pet_id记录check_date、hospital、summary、next_check_date。提醒表叫reminders这个表的设计比较特殊它不是让用户手动建的而是根据vaccinations和dewormings的next_due_date自动生成的。为什么单独建一张reminders表而不是每次动态计算因为提醒需要支持用户手动处理——比如用户点了已完成或者已忽略这个状态必须有个地方记录下来。动态计算的方案看着精巧但一遇到状态管理就会变得复杂。这个取舍我很早就定了AI后来还想帮我优化成视图方式我直接否掉了。在数据模型上如果不确定哪种方案更合适选结构最简单、字段最透明的那个。3.2 生命周期阶段判断逻辑生命周期阶段是这个App里最有业务灵魂的部分。它要解决的实际问题很简单一只猫到底算幼年、成年还是老年这不是一个一刀切的问题因为猫和狗的年龄换算规则完全不同。我最后采用了一套简化的规则表猫的幼年期是0到12个月成年期是12个月到7岁7岁以上算老年。狗的划分按体型又分了小、中、大三档小型犬7岁以上算老年中型犬6岁大型犬5岁。这个规则完全不追求生物学上的精确它要考虑的是可解释性——用户的宠物被划进哪个阶段理由必须说得清楚。我要求AI把这条规则实现为一个独立函数输入是species、birth_date输出是lifecycle_stage和一段原因说明文字。这个函数的测试用例我亲自写包括猫和狗的边界日期、闰年出生、年龄刚好卡在阈值上的情况。为什么要这么较真因为这种规则类代码是AI最容易做表面功夫的地方——它会把主要分支写对但边界条件常常漏掉。你不亲自钉死边界上线后用户一只刚好满7岁的猫就会得到错误的阶段判断。3.3 AI生成建表脚本与模型的验证方法数据结构定义清楚后我让Claude Code做三件事编写建表SQL、生成SQLite初始化脚本、生成后端ORM模型。这里有个操作技巧我在后面会反复用到——不是直接说去建表而是让它先输出完整的SQL和执行脚本我确认无误后才允许它触碰数据库文件。它给出的建表脚本基本符合预期但有一个地方踩了雷它默认在reminders表里加了user_id字段说考虑到未来可能支持多用户。这就是典型的AI过度设计。我当前就是一个单家庭本地使用的App完全不需要预留多用户。多出来的一列会影响所有关联查询还会让前端表单多一个隐藏字段纯属负资产。我删掉这个字段并在CLAUDE.md里加了一条不允许为未在需求中出现的场景预留字段。验证方法我坚持插入脏数据测试让AI插入一条体重为负数的记录、一条疫苗日期在未来的记录、一条宠物生日在未来日期的记录看系统是否会拦截。这一步很能检验数据库层的约束是否真正生效。AI自己测试时永远给正常数据永远不会发现这些问题所以这种对抗性测试必须由人来设计和驱动。4. 后端接口、前端页面与点着验收的完整过程4.1 让AI写API的正确姿势先定OpenAPI再写实现数据层稳定之后我要求Claude Code做的第一件后端任务是不写任何实现代码先把所有接口的OpenAPI定义列出来。这又是一个先文档后代码的流程看起来多了一步实际省了后面大量返工。接口清单大致如下创建宠物、更新宠物、获取宠物列表、获取宠物详情、添加体重记录、获取体重曲线数据、添加疫苗记录、添加驱虫记录、添加体检记录、获取提醒列表、标记提醒处理状态、计算生命周期阶段。每个接口我都要求它标注清楚路径、方法、请求参数、响应结构、可能的状态码。为什么要先定OpenAPI因为接口定义是前后端协作的契约。如果让AI直接写后端代码它会写出一套接口再让AI写前端它可能凭着想象生成另一套接口调用方式。双方各写各的联调阶段就变成灾难。先固定OpenAPI相当于给前后端各画了一条永远不能偏离的轨道AI在这条轨道上怎么跑都不会出大格。实测下来OpenAPI定义阶段只花了半小时但联调阶段几乎没有出现前端传的字段后端不认这类问题。这让我觉得AI全流程开发里真正值得人工花时间的是定契约而不是写代码。4.2 前端页面生成从零能跑但别急着说完成前端是Claude Code产出最多也最需要警惕的部分。我让它基于React生成了六个页面宠物列表页、宠物档案页、体重记录页、疫苗记录页、体检记录页、提醒管理页。第一次运行起来的效果远超我预期页面能渲染、跳转正常、表单能提交乍一看项目已完成。但能跑和好用之间差了十万八千里。我逐个页面检查后发现三个问题第一表单没有任何校验日期可以填成2023年2月30日第二删除操作没有任何确认弹窗误触一下数据就没了第三宠物列表没有空状态页没有任何宠物时会渲染一个空白页面用户会以为应用坏了。这些问题不是AI不会写而是它默认你会把验收后面的话补上。所以我现在有一个习惯让AI交付页面后我不读代码直接模拟真实用户把每个流程点一遍专门用手滑和填错值这两种方式操作。只有这样才能逼出那些AI自己永远不会发现的体验缺陷。4.3 全流程联调实测中最有收获的一遍手动验收整个项目最有价值的一次测试是我模拟养猫用户团子完成了一整年的使用流程。我新建了一个宠物档案猫生日起始于一年前。然后依次给它添加了三次体重记录、一针猫三联疫苗、一针狂犬疫苗、两次体内外驱虫、一次体检。每添加一条数据我都刷新页面确认数据是否持久化保存。这条流程走下来真的发现了一个隐藏问题我在添加完猫三联疫苗后提醒页面没有生成对应的下一针到期提醒。排查发现AI在疫苗接口的实现里确实写了创建提醒的逻辑但只在next_due_date非空时创建而前端表单里这个字段的输入框默认值被设置成了空。也就是说只要用户添加疫苗时没有手动填到期日提醒就永远不出现。这个问题的价值不在于bug本身而在于它揭示了全流程AI开发的一条铁律AI在两个模块之间的衔接处是最容易出问题的地方。单个模块内AI写得很完整疫苗记录该有的字段都有提醒模块该有的逻辑也都在但它们之间的数据传递约定没有被严格执行。人肉走一遍真实流程才能把这些跨模块的连接点一个个压出问题来。注意以后你让AI开发多模块项目验收时不要盯着单个模块反复看一定要设计一条跨模块的完整操作链路。跨模块的bug往往比模块内的bug隐蔽得多也严重得多。5. 全流程AI开发踩坑实录五个最容易翻车的高频点5.1 过度自信的AI让我学会了先跑用例再看代码最让我头疼的是Claude Code在汇报时常常带着一种莫名其妙的笃定。有一回我让它修一个历史记录排序问题它回答已修复按照recorded_date倒序排列但我打开页面一看顺序还是乱的。再问它它又改口说刚才的修改可能没有生效我重新检查一遍。一开始我很恼火后来想明白了AI说完成的时候很多时候指的是我的代码逻辑上应该是正确的而不是我实际运行过并验证过了。这件事逼我建立了一个强制流程凡涉及改动必须先让它给出改动后可以验证的测试命令让它亲口说出来运行python -m pytest tests/test_weight_record.py可以验证。说不出来就说明它根本没跑过改的代码就当没改看。现在我不再把AI当成一个说完成就完成的合作伙伴而是当成一个提交代码后需要人来跑测试的初级开发者。它的产出质量上限很高但可靠性需要验收流程来兜底。这个认知改变之后整个项目的不确定性一下子就降下来了。5.2 上下文膨胀导致的逻辑漂移项目进行到第五天的时候我注意到一个规律同一轮对话里连续让它改多个文件最开始的几个文件改得很准越到后面越是敷衍。有一次它前脚刚把疫苗模块的接口结构调整完后脚改到提醒模块时调用的却是调整之前的旧接口名。这种现象的根源在于大模型的上下文机制——每轮对话只是有限长度的窗口早期信息会被逐渐稀释。尤其是Claude Code在一个会话里连续执行十几个文件操作后早期做的决策到了后期就变成遥远的记忆它只能靠猜。我的解法是每完成一个里程碑就新开一个会话新会话第一次消息里附带当前项目的目录结构和关键文件摘要让AI重新建立上下文。这个操作看起来增加了重复输入成本但实际上避免了越写越歪。我的经验是把一次会话当成一个小任务单元而不是整个项目从开始到结束的容器这个边界越清晰AI产出质量越稳定。5.3 重复造轮子与类爆炸我让Claude Code处理体重曲线数据时犯过一个低级错误第一次它写了一个WeightRecord模型第二次改需求时它不知道项目里已经存在这个模型直接在另一个文件里又定义了一个结构几乎一样的WeightRecordModel。结果就是代码里有两套体重记录类字段一样但名字不同连数据库查询都出现两套映射关系。这种事在AI开发中出奇地常见因为它没有项目里已经有了什么的全局意识。我的对策是在CLAUDE.md里加了一段已有核心类型清单把项目里的关键模型类和它们所在的文件路径列出来并明确指示新代码必须复用清单中的类型禁止新建功能等价的新类型。此外每次让它新增文件前我都要求它先搜索确认是否存在同功能文件。类爆炸带给我的教训并不是AI有多笨而是任何开发流程都需要一套可搜索的模块地图。传统开发里人脑自带这个地图AI开发时这份地图必须显式地落到文档里。5.4 自己写测试自己验AI测试的盲区我一开始非常信任AI自动生成的测试用例因为它能写出覆盖正常路径的用例跑起来也是一片绿。但有一次我故意改坏了一个边界条件——把猫的成年阈值从12个月改成11个月——然后让Claude Code跑测试。它的测试套件依然是全绿因为它的测试用例恰好全部都使用了安全值要么是刚出生110天的幼猫要么是5岁的成年猫没有一条用例踩在12个月这个边界上。这个发现让我彻底明白AI生成的测试用例只能证明正常流程没坏不能证明边界条件正确。测试用例本身必须有人的参与尤其是指定边界值的用例必须人工设计之后再让AI去实现。我后来把生命周期阶段的边界测试用例全部自己写好再交给AI去跑这个函数从此再也没有回归过。5.5 目录结构失管还有一个我很少在别人的分享里看到、但实际非常头疼的问题如果不加约束AI会把文件乱放。有一次它把后端的一个工具函数直接放进了前端目录下理由是前端也需要格式化日期的函数。乍一听好像有道理但这种跨层引用很快会把项目变成一团乱麻。为此我建立了三层防御。第一层CLAUDE.md里写死目录结构明确前端不能import任何后端模块后端也不能在前端目录创建文件。第二层每次新会话开始时我都要求AI先打印当前目录树确认自己在正确的位置。第三层如果发现跨目录引用苗头立即叫停并要求重构而不是放任它继续叠加。目录整理看起来是小事但AI开发模式下所有东西都是它生成的一旦结构乱了它自己后续定位代码的能力也会跟着崩。6. 后续迭代AI维护阶段怎么让改需求不失控6.1 每次迭代先同步上下文项目主流程跑通后真正的长期工作才开始不断改需求、加功能、修问题。这一阶段我摸索出一套迭代前同步流程核心是让Claude Code在动代码前先完成三件事读取CLAUDE.md、读取当前目录树、读取本次改动涉及的模块入口文件。这三步做完等于把AI的短期工作记忆刷新了一遍。我观察到一个明显变化之前直接说帮我把提醒改成提前三天通知它可能会在完全不同的位置新建一段逻辑同步上下文后说同样的话它就会在老位置找到提醒生成函数并精准修改。看起来多花两分钟实际上省了大量排查时间。你可能会问为什么要读入口文件而不是把所有文件都读一遍我很明确地设了限制——只允许它读与本次改动直接相关的文件。免得它又把几十个文件全部载入上下文结果又一次逻辑漂移。AI的上下文不是越大越好而是越精准越好。6.2 让AI先列改动清单再动手迭代阶段我做的最有价值的一个习惯是任何改动先让它输出一份改动计划要改哪个文件、具体改哪几个函数、影响哪些依赖模块、是否涉及数据库结构变更。这份计划我先过一遍觉得合理才批开始执行。有一次它计划里写了需要修改数据库结构新增一个record_type字段我一看就觉得不对劲。当前的表结构已经能通过关联查询区分记录类型根本不需要冗余字段这很可能又是AI的近视设计。我驳回了这份改动计划让它改用关联查询方案。结果功能照样实现还避免了数据库迁移的一堆麻烦。这种先计划后执行的模式本质上是把AI当成一个需要代码评审的协作者而不是一个值得全权托付的执行者。AI给方案人做决策这个分工越明确项目越稳。6.3 我对AI全流程开发的真实定位整个项目做下来我最想分享的一个经验是AI全流程开发的效率优势远比我预想的大但全流程并不等于无人值守。Claude Code确实能做到从需求到数据库、从接口到页面、从测试到部署脚本的完整覆盖这极大缩短了项目的冷启动时间——以前我要花一周搭框架的事情现在大半天就能看到可运行的全栈雏形。但它带来的新瓶颈也非常清晰验收工作量变大了。每段AI产出的代码都需要被人工检查、实测、追问边界条件。这不是AI的缺点而是你使用它的方式问题。你越早接受AI负责规模、人负责质量这个分工项目就越顺畅。在维护阶段我还发现CLAUDE.md本身也在持续长大。每踩一个坑我就把对应规则补进去不允许预留未需求字段、不允许跨目录引用、不允许不跑测试就报告完成、不允许在无确认时改数据库结构。这些规则累积起来AI的表现会以肉眼可见的速度变好犯过的错几乎不再重复。如果你也打算用Claude Code管理长期项目我强烈建议你把项目的踩坑史写进CLAUDE.md它才是这个项目最值钱的资产。