被微信拒审那天,我正坐在沙发上盯着后台那条红色通知,第一反应不是改代码,而是“原来我在用 VibeCoding 的时候,根本没有想过交付物要过审这件事”。我做的这个小程序,前后折腾了三个月,代码量到了3万行左右,素材接近1.8万张,全部是我一个人加几个AI辅助编程工具完成的。这个数字听起来很唬人,但真正让我觉得自己学会VibeCoding的,不是写了多少行,而是被拒审后怎么靠同一个AI把问题定位、修掉、再顺利过审。这篇复盘记录的就是那三个月里的真实过程,包括我是怎么把需求拆给AI、怎么管理这么多素材、又是怎么接住拒审这一脚——给打算用AI做小程序、又担心一个人搞不定的朋友一个参考。
1. 从一次拒审说起:这个项目到底做了什么
1.1 拒审通知背后,是我对交付物的误解
先说一下这个小程序本身。它是一个偏工具属性的产品,核心功能包括自定义卡片生成、每日任务打卡、以及一个带统计的可视化面板。听起来不复杂,但因为我想把“卡片生成”做得足够灵活,把“打卡统计”做得足够顺手,功能越加越多,最后代码量就滚到了3万行。这个量级在传统开发里一个人做大概要小半年,但我当时其实只用了不到两个月就写出了第一个能跑起来的版本。
问题就出在“能跑起来”和“能上线”之间差着一条审核红线。第一次提审,平台返回的拒审理由写得很标准:小程序的用户隐私保护指引中未完整声明涉及的用户信息处理方式,同时部分页面存在内容安全机制不完善的情况。翻译成人话就是:我需要先告诉平台我会收集哪些数据、用来干嘛、怎么保护,但我在用户协议里写得含糊不清;另外我在某些输入框里没有接入内容安全检测,用户如果输入了违规文本,小程序里面是直接展示的。这属于基本功没做好,跟代码写了多少行没有关系。我那时候才意识到,在AI辅助下把功能堆出来只是第一阶段,能不能进入线上环境,考验的是合规层面的完整度。
1.2 什么是 VibeCoding:它不是偷懒,是换了一种控制方式
先说清楚VibeCoding这个词。它指的是开发者通过自然语言描述需求,让AI持续生成、修改代码,开发者更像是在“带氛围”地和工具协作,而不是逐行敲键盘。很多人会误以为这是逃避写代码,或者觉得这就是“AI自动生成一个项目”,但实际用下来,它更像是一种新的控制方式:你告诉AI“我们要做什么、边界在哪、不要碰哪块”,它负责把碎片变成结构。
我在这个过程里最深的体感是:VibeCoding不适合没有编程基础的人直接上手,也不适合完全没有产品思维的人。因为AI生成代码的速度太快了,快到你还没来得及发现问题,它已经写完了。如果你脑子里没有一张方案图,你会完全迷失在它生成的代码里。我做这个小程序的时候,方案图是先手画的,流程是先在纸上拆好模块,再跟AI对话,一句一句让它实现某个具体函数或页面,而不是上来就让它“做一个完整小程序”。这个习惯在后期救了我很多次。
2. 一个人如何扛住3万行代码:架构与流程
2.1 把代码量变可控的第一步,是先把业务模块拆干净
3万行代码如果按单一仓库、平铺方式管理,那不管有没有AI都会失控。所以我在项目启动时就拿到了一个“丑但有用”的方案:把小程序业务拆成四层。
第一层是页面层,也就是用户看得到的底部导航和主页面;第二层是组件层,比如卡片模板、打卡日历、统计图表这些可复用的部分;第三层是工具层,包括请求封装、存储封装、图片压缩这些和业务无关的基础能力;第四层是配置层,把文案、主题色、卡片模板的参数全部集中到一个配置文件里。
拆完之后,AI每次只需要面对一个边界很清晰的子任务。比方说我要做一个“按周视图展示打卡连续天数”的组件,我给AI的描述是“小程序的wxml中,prompt一个函数接收打卡记录数组,输出周视图所需数据,包含连续天数计算,注意跨周逻辑”,它生成的代码往往可以直接用。如果我不拆,直接让它生成整个页面,它会把样式、逻辑、请求全部混在一起,后面改一个功能就要翻半天代码。这个经验挺重要的,因为VibeCoding最忌讳的就是没有边界感——人和机器都需要边界。
2.2 让AI理解“整份项目说明书”,而不是零散指令
一个人带着AI写3万行代码,最大的痛点不是代码,而是“上下文”。AI聊天有窗口限制。如果你每天跟它聊十几次,它早忘记你项目全貌了。我的解决方案是:在项目根目录放一份“项目说明书”,说明书的长度控制在大概两屏,内容包括项目定位、技术栈、目录结构、命名规范、现有模块清单和当前阶段要解决的问题。我每次开新对话,第一件事就是把这份说明书粘进去,然后再提具体需求。
这份说明书不是一次性写完的。我大概每两周更新一次,比如“新增了统计模块,数据字段如下,storage键统一以history_开头”。这样做的好处是AI生成的代码风格会保持一致,不会出现上一段用的是中文变量名,下一段又冒出拼音变量的情况。而且,如果我连续对话太乱导致AI答非所问,我能直接开一个干净的新窗口,重新把说明书的全文贴进去,把当前的bug描述一遍,通常就能回到正轨。
2.3 3万行代码不是一次写出来的:让AI成为“结对评审”
我写这个项目的时候有个习惯:让AI生成代码之后,我会自己读一遍核心逻辑。尤其是涉及数据写入、用户隐私和支付跳转的这些地方,我几乎不会直接拿AI给的代码就用。方式是把AI写好的大文件拆成几百行的小片段,一段段贴回对话里,要求它“以严格代码评审者的身份,找出极端情况下的问题”。
这个过程非常像以前在技术论坛上找人帮忙review代码,但响应速度是秒级的。比如有一次它生成的打卡统计函数在“用户在同一天内修改记录再删除”的情况下会统计错乱,我一共试了三个边界条件才暴露出来。AI评审给出的结论是应该把“删除”动作加一个独立的时间戳判断。这类问题如果是我自己人肉看,大概率要漏掉,但用AI按规则找边界,效率确实不一样。
3. 素材工程:1.8万张素材怎么来、怎么存、怎么加载
3.1 组合式素材生产:1.8万张其实只有50个底图
你看到“1.8万张素材”可能会觉得可怕,但如果我把算法告诉你,你会发现这只是一个数字游戏。我当时做的是一个自定义卡片生成器,用户可以选背景风格、字体样式、插画元素和文案排版。四种维度各有一批选项,理论组合数就超过了1.8万种。
如果按传统的做法,这1.8万张图都要预先做成资源文件,那肯定不可能。我的做法是:只准备了大概50张背景底图,加上30种插画元素和20种文字排版模板,然后写了一个自动化脚本,用canvas在本地把这些元素组合渲染出来,再按配置输出成不同尺寸的透明底图。这一步在技术实现上没有特别难,但需要想清楚“素材的组合规则”和“运行时的加载策略”。
用AI辅助写这个组合脚本的时候,我尝到了VibeCoding的甜头。我给AI的描述是“用Node.js写一个批量脚本,读取config.json里的组合配置,使用canvas库生成PNG,文件名按照category_style_element_variant.png的规则输出”。AI直接把骨架代码生成好,我只需要调整字体路径和画布尺寸。1.8万张素材,单机跑了大概四个小时就全部生成完毕。
3.2 压缩与格式选择:素材多不等于体积大
生成完之后,我立刻发现一个很实际的问题——素材如果不压缩,2MB的小程序代码包根本装不下。1.8万张图如果每张平均50KB,就是900MB,这个量级连云端的下载流量都扛不住。
我的处理分三层。第一层是做同质化合并:很多素材只是颜色差异,我把它们全部转成WebP格式,把透明底图合并到一个雪碧图文件里,通过CSS定位来取图。第二层是尺寸分级:列表页用200px的小图,预览页用600px的中图,只有编辑页才加载原尺寸。第三层是瘦身脚本:我写了一个简单的压缩流水线,把所有生成出来的图用统一质量参数压一遍。大概有两成图片肉眼看起来完全没差别,但体积直接小了一半。
具体脚本我当时已经跑通了,核心代码大概是启动一个本地任务:
node scripts/compress.js --input ./raw --output ./optimized --format webp --quality 80这个脚本遍历原始素材目录,把每一张图都改成WebP格式,质量参数设为80。实测下来,一组原本要2.3MB的背景图,压完之后只有700KB左右,视觉损失基本可以忽略。这个步骤对小程序很重要,因为在微信这类小程序生态里,包体大小直接决定你eCode可不可以带资源文件上线。
3.3 运行时策略:为什么不能把素材全塞进代码包
素材的加载策略是我后期才补的一个模块。我在思考“1.8万张素材”和“小程序包体限制”之间矛盾的时候,才意识到真正的解法不是无限压缩,而是“不要一次性加载所有素材”。
小程序默认包体限制大约在2MB,加上主包和分包,总共也不能无限膨胀。1.8万张素材如果全部打进包里,无论怎么压缩都会超限。我最终的做法是:只把组合规则、配置文件、核心模板放进代码包,所有预测会高频使用的素材也放一小部分,其余素材全部传到云存储上,运行时按需拉取,再加本地缓存。用户第一次打开编辑页的时候会请求一批图片CDN预缓存的清单,后续再访问就直接读缓存。这个方案在前端里很常见,但用在小程序和AI协作开发里,需要想清楚哪些资源必须进代码包、哪些资源可以走运行时加载。
我甚至试过在服务端动态生成缩略图。后来觉得成本太高,还是回到“预生成+CDN”的路线。整个过程并没有用到特别高深的架构,但对一个单人项目来说,提前想清楚资源计划,能省下后面非常大的返工时间。
4. 微信拒审拆解:从平台回执到可落地的整改
4.1 常见拒审类别与对应策略
被拒审之前我对平台审核规则的认知是“把功能做出来就好”,那显然不够。从那次之后,我整理了一份非常实际的小程序审核排查表,在我后来复盘中反复用到。这里列一下比较常见的拒审原因和大多数开发者的对应策略,你可以直接对照看。
| 常见拒审原因 | 表现形态 | 整改方案 |
|---|---|---|
| 类目与实际功能不符 | 选了“工具”类目但有社交内容 | 根据核心功能重新选择最匹配的类目,并补充相关资质 |
| 用户隐私保护指引不完整 | 后台有获取手机号或位置代码,但指引里没声明 | 列出所有在代码里用到的API,逐一对应到隐私声明字段 |
| 强制授权 | 一进入页面就弹窗要求授权头像昵称 | 改为用户主动触发授权,比如点击按钮后再发起 |
| 内容安全能力缺失 | UGC输入框没接入内容检测 | 接入平台提供的内容安全API,对用户输入做识别 |
| 虚拟支付合规问题 | 安卓端存在虚拟物品购买但未走指定渠道 | 梳理所有支付场景,虚拟内容必须走平台规范或换成积分体系 |
| 代码包过大/加载异常 | 小程序长时间白屏或分包加载失败 | 压缩资源,开启按需加载,确保核心页面秒开 |
我当时踩中的是第二条和第四条。隐私声明的问题在于,我在代码里用到了获取用户昵称头像的API,同时启用了位置信息的接口——但我在后台的隐私保护指引里只写了“用于展示信息”,没有明确说明位置信息是用在本地打卡记录上。平台的判定标准很简单:代码里用了什么敏感API,指引里就一定要写清楚。如果你不写,就是不合格。
4.2 隐私保护与用户授权:最容易踩的坑
所有微信小程序在提审时都会有一份用户隐私保护指引,开发者需要在平台后台逐项填写你要收集哪些信息、使用目的和处理方式。我在第一次提审的时候只填了寥寥几句,结果审核员在测试过程中发现我的打卡功能会发起位置授权,但指引里没有对应声明,因此直接判拒。后来我在整改时做了一个很机械但有效的事:把用到的API列表全部打印出来,再和后台的指引选项逐一核对。
具体来说,我全局搜索了整个项目里所有wx.get开头的调用,然后逐一分类。头像昵称填写能力、位置信息、本地缓存读写等,全部添加到指引。除了平台自带的那套勾选,我还在用户协议里新增一段话,用普通用户能看懂的方式说明数据用途。这个动作本来以为很麻烦,结果在AI辅助下只花了半小时就完成。我把搜索出来的API列表粘给AI,让它帮我整理一份“用户协议-数据使用说明”的文案,然后我再做人工校对。改完之后重新提审,隐私这块一次通过。
4.3 内容安全机制:这一步一定要提前接
拒审回执里的另一条是“部分页面存在内容安全机制不完善”。原因其实很直接:我在打卡动态的输入框里允许用户写自定义文字,但没有做任何违规内容识别。平台的要求是,只要你有用户输入的地方,就需要有能力处理违规内容。这个能力不能只靠前端关键字屏蔽,前端只能拦一部分,更稳妥的是调用平台提供的内容安全接口。
整改方式也很直接:在用户输入完文字之后,先本地做一个简单的关键词过滤,同时把输入文本提交到内容安全API做异步检测。检测结果如果是“违规”,就立刻显示提示并禁止发布。这个流程我一开始以为要走很久,但是因为我把功能拆得很细,AI只需要生成一个封装好的“文本检测”函数,然后插入到表单提交的流程里。前后大概花了两个晚上就接完了。需要注意的是,这个接口有频率限制,所以我写了一个节流逻辑:用户停止输入300毫秒后再调用检测,避免每个字符都请求一次。
5. 贴近实战的 VibeCoding 调试方法
5.1 把报错原文“翻译”成指令,是AI协作的核心能力
VibeCoding不是只会提需求,Debug才是决定项目生死的关键。我经历过最崩溃的情况是AI生成了一大段代码,运行时报错直接卡死,而我把报错信息贴回给AI,它给出的修复方案引入了新的问题。后来我总结出一个模式:给AI报错时不要只贴报错信息,还要同时提供它之前生成的代码上下文、我期望的输出结果、以及我尝试过的处理方式。
比如有一次页面白屏,控制台报了一个很隐蔽的错误,大概是某个组件里调用了不存在的属性。单看报错只有一行,但如果我不附上上下文,AI根本不知道它自己生成的那个函数命名和另一个文件里的数据字段不一致。我把相关两个文件的代码节选都贴进去,然后描述:“这段逻辑在打卡记录更新后,应该触发统计面板重绘。现在白屏,帮我在保证现有事件机制不变的前提下,修正数据映射。”AI调整之后,白屏问题马上就消失了。这类经验表明,VibeCoding调试的核心不是“AI聪明不聪明”,而是你给的信息够不够准。
5.2 我常用的AI调试对话模板
到了后期,我几乎把所有调试都固定成一套模板。这套模板不一定适用所有人,但可以当作参考框架。它分四步:先说背景,再说问题,再说约束条件,最后要求AI给出两到三个可选的方案,不要只给一个。
举个例子,我在调打卡连续天数统计的时候,是这样写的:“这是一个微信小程序项目,打卡记录存储在本地storage中。每条记录含打卡日期。我需要计算用户连续打卡天数:如果今天没打卡而且最后一条记录不是昨天,连续天数应该重新归零。请检查我下面这段函数,尤其注意跨月和修改记录的情景。只给修复方案,不要改其他部分。”这个指令结构比“帮我修bug”强太多了。AI能理解边界、知道你的评价标准,还能在约束内工作,而不是自由发挥。
另一个技巧是“让AI提出反例”。我发现生成代码时问AI“这段代码可能被哪些极端输入击穿”,比直接让它写代码更能暴露问题。因为在自然语言对话里,让AI扮演攻击者,它会主动列出边界条件,通常这些边界条件是我根本想不到的。这种“反向提问”的调试方式,大概是VibeCoding最接近真实团队评审的部分。
5.3 人与AI的边界:什么时候必须自己写
AI给我节省了大量编码时间,但有些代码我坚持自己手写。第一类是任何涉及真实支付和用户信息的逻辑,我指的不是不让AI写,而是每一行都要自己再看一遍。第二类是核心算法,比如打卡连续天数的跨周计算,我把AI生成的版本拿去优化了很多次,到最后已经完全能看懂它每一个变量代表什么。第三类是那些层层嵌套的交互状态,比如同时出现弹窗、键盘和授权引导的时候,AI很容易把状态管理写乱。
我给自己定的规则是:AI负责全部“体力劳动”,比如初始化项目、搭页面结构、生成类型定义、批量处理素材;我负责“关键决策”,比如数据结构怎么设计、缓存策略怎么做、哪些函数必须改成纯函数方便测试。这几条边界定下来之后,AI生成代码的可用率明显提高了,因为它知道你想要的不是“能跑”的代码,而是“能维护”的代码。
6. 三个月总结:踩坑清单与独立开发者建议
6.1 我踩过的五个坑
第一个坑是前期没有认真做合规自查,直到拒审才回头补隐私和内容安全,这个代价比想象中大,因为重新提审至少要等一两个工作日。第二坑是素材压缩没有一开始就设计好,前期所有图片用PNG,等到快提审才发现包体超标,不得不用一个晚上重新批量处理。第三个坑是项目说明书没有及时更新,有一段时间AI的代码风格出现明显漂移,后来发现是因为对话窗口重置后,它一直在用旧的项目结构描述生成新代码。第四个坑是依赖性的滥用,在页面里堆了过多的第三方组件库,结果框架更新后部分组件报错,排查起来非常浪费时间。最后一个坑是在AI对话中一次提了太多需求,我以为它能把“页面、逻辑、样式、数据请求”一次性都改了,结果它改到一半就忘记约束条件,反而不如拆成多个小任务。
6.2 给想用VibeCoding做小程序的人的建议
如果现在有人问我,一个人加AI能不能做出一个能上线的小程序?我的答案是可以,但你要接受三个前提。第一,你不能把AI当成外包团队,它是个动作很快但经常需要你纠偏的同事;第二,不管代码怎么生成,你都要具备能读懂核心逻辑的能力,哪怕看不懂每一行,也要能看出“这段代码可能有问题”;第三,合规这件事没有任何捷径,在开工之前就把隐私声明、内容安全、类目选择这些基础打好,比你写了3万行代码再去整改要划算太多。
实操上,我还推荐准备三个独立文件:项目说明书、待办事项列表和测试清单。项目说明书用来维持AI的全局上下文,待办列表用来拆分任务,测试清单用来在提审前做逐项自查。我在拒审之后把这三份文件补上,后续开发效率提高了不少。尤其是测试清单,线上过审前我按清单逐项确认,能明显降低那种“提交后心里没底”的状态。
6.3 最后的一点私人体会
做这个项目之前,我一直觉得软件开发最大的瓶颈是时间不够、人手不够。被微信拒审那天以及之后几天的效率暴涨让我发现,单人开发最大的瓶颈其实是想清楚目标。AI可以帮你把3万行代码写出来,也可以帮你在半天内把手动压缩素材的活全部干完,但它没法替你提前想清楚“平台要求什么、用户会怎么操作、哪些边角条件可能触发异常”。VibeCoding给我最深的改变不是让我变得能写更多代码,而是让我学会把每一个需求拆得更小、更明确。过程中写的3万行代码和1.8万张素材,某种程度上都是副产品,真正的收获是那一套和AI协作的节奏:拆到位、说清楚、多验证、再交出去。如果你也打算一个人做小程序,我建议不要一上来就追求功能多,先把一个核心流程跑通,把合规底子打好,然后让AI帮你把细节滚起来——这个过程会比你想的更顺利,也更有成就感。