这个项目的起点其实特别朴素——我想做个能让自己坚持刷题的小程序。上班通勤、午休、睡前,总有大段零碎时间,但打开传统刷题应用实在没有动力,打开游戏又觉得浪费时间。于是我想,如果把刷题做成对战,AI 负责出题,是不是就能把碎片时间变成一场场带胜负欲的微型竞赛?
结果这个方向做下来,就是标题里看到的:AI 驱动的对战式刷题小程序,上线一周,靠自然裂变涨了 700 多个用户。没有投一分钱广告,没有找大 V 推广,全部增长来自对战本身的分享闭环和用户自发的邀请行为。这篇文章不打算只讲结果,我想把产品定位、技术方案、裂变机制、踩坑记录这四部分完整拆给你看,尤其适合正在做小程序冷启动、想用游戏化思路做学习产品的开发者,或者对 AI 应用落地好奇的产品经理。
1. 为什么偏偏要做成“AI 驱动的对战式刷题”:定位与机会判断
1.1 从“刷题”到“对战”,中间到底改了什么
传统刷题产品的用户路径基本是:选科目 -> 做题 -> 看解析 -> 继续做题。这套路径不是没有用,但它对抗的是人性里最难的“延迟满足”。刷题带来的反馈是滞后的,正确率是什么时候反馈的?这周、这个月、考试出分的时候。而人对即时反馈的渴望是刻在基因里的,游戏之所以让人上瘾,本质上就是即时反馈做得极致。
对战式刷题把反馈周期从“几周后”压缩到了“几十秒后”。你做错一道题,对手立刻领先,倒计时逼着你加速思考,输赢当场出结果。这种实时对抗带来的情绪波动,会让人想要再来一局——跟游戏的“再来一局”心理机制一模一样。我发现这个心理其实比奖励、积分都更持久。
至于 AI 在这里的作用,很多人第一反应是“AI 生成题目”,但这只是最表层。核心价值有两个:一是用 AI 低成本解决题库供给问题,对战模式非常消耗题目,传统人工写题几千道根本不够;二是 AI 可以做动态难度调整,根据两个人的实时正确率匹配下一题难度,让对局始终保持在“能赢也有翻车可能”的状态,这种状态最容易让人投入。
1.2 核心用户场景与目标人群
这款小程序主要瞄准三类人。第一类是考研、考证人群,他们有明确的短期目标,刷题是刚需,但往往坚持困难,对战模式相当于给备考过程加了心跳。第二类是学生群体,他们天然熟悉游戏化应用,同学之间互相邀请对战几乎不需要教育成本。第三类是职场自我提升人群,他们不愿意下载重应用,小程序即用即走,午休时两分钟一局的节奏刚好。
实际数据也验证了这一点。第一周的用户里,学生和备考人群占比超过六成,而且通过好友邀请链带来的留存显著高于自然搜索用户,因为对战本身绑定了社交关系——你输给熟人不会生气,而是想赢回来,这个心态天然驱动次日回访。
1.3 与传统题库产品、娱乐化答题产品的差异点
市面上不是没有刷题应用,也不是没有答题对战应用,但把“严肃学习内容”和“实时对战”结合的产品很少。娱乐化答题应用的問題是题库太轻量,大家当游戏玩,过了新鲜感就流失;传统刷题应用的问题是内容重但反馈轻,用户很难坚持。
我的定位介于两者之间:题库内容保持严肃,覆盖考研、考证、公考、专业课这些硬需求,但对战形式用娱乐化的方式呈现。用户刷得开心,但刷完确实记住了知识点。这种“轻娱乐重学习”的中间态,是这个产品能靠自然裂变跑起来的基础。
2. 技术方案选型:小程序端、后端、AI 如何搭起来更稳
2.1 小程序端与后端的基础选型
小程序端我选了微信原生开发,没用跨端框架。原因很简单:这个产品不是重交互应用,核心页面就是匹配、对战、结果、排行榜几个,原生小程序的性能和调试体验对这类场景足够友好。而且微信原生语法对分包、分享参数、登录态的处理最直接,碰到兼容问题也好排查。如果你以后打算同时上支付宝小程序,再考虑迁移跨端框架也不迟。
后端选了 Node.js(NestJS 框架)。选它不是因为它性能极致,而是因为团队迭代速度快。对战匹配和 AI 出题都以异步任务为主,Node 的事件循环天然适合这种 I/O 密集型场景。数据存储用的 MySQL 存用户、题库、对战记录,Redis 承担匹配队列、在线状态、排行榜缓存、接口限流。这套组合对几千用户量级完全够用,而且后续水平扩展思路清晰。
登录体系直接接微信手机号快捷登录,不做自建账号体系。对小程序创业者来说,不要浪费时间在账号系统上,微信已经解决了信任问题。唯一要注意的是登录态过期和 session_key 刷新,以及匿名换绑之类的边界,提前设计好。
2.2 AI 能力如何落地:题目生成、答案解析、难度自适应
AI 在这个产品里不是花架子,而是管实际出题。整个流程是这样的:用户发起匹配后,后端从 Redis 里取出当前对局参数(科目、难度、双方当前正确率),然后组装请求发往大模型接口,要求模型返回指定数量的题目、四个选项、正确答案、解析,用 JSON 结构输出。
提示词设计是这里的关键,我踩过不少坑。最初的版本只是说“生成一道考研政治多选题”,结果模型经常返回格式不对的文本,没法直接入库。后来我把提示词改成了带强约束的结构化指令,明确指定 JSON 字段、类型、数量,并要求不输出任何多余字符。为了说明这个逻辑,这里给出我当时用的简化版系统提示词:
你是一个专业题库生成助手,需要根据用户提供的科目和难度生成一道高质量选择题。 输出必须为以下 JSON 结构,不要包含任何其他文本: { "subject": "科目名称", "difficulty": 1-5 之间的整数, "question": "题干,50字以内", "options": ["A. 选项内容", "B. 选项内容", "C. 选项内容", "D. 选项内容"], "answer": "A/B/C/D 中的一个,必须是正确答案字母", "explanation": "答案解析,80字以内,需说明得分的理由" } 约束要求:题干必须信息完整且可独立作答,不能有歧义;正确选项和错误选项必须保持相似格式和长度,避免出现明显异常;错误选项必须有迷惑性,不能凭空编造。生成完的 JSON 还要经过一道校验层:检查字段完整性、answer 是否在 options 范围内、字数是否合理,再用规则做内容安全过滤,命中风险词直接丢弃重新生成。因为模型偶尔会抽风,这一层校验必须做,不能省。
对延迟和成本的体验也必须重视。实测一次完整生成大概要 1.5 到 3 秒,放在对局里会明显拖慢节奏,所以我做了三层优化:第一,预生成缓存,每门热门科目提前由后台任务生成几百道题目进题库,对局时先取缓存,没有缓存才实时请求模型;第二,设置 2.5 秒超时熔断,超时直接降级到静态题库,保证用户不等待;第三,模型返回结果后异步记录 token 消耗,对生成失败和发热科目做限流。这套优化做下来,用户的体感已经非常接近本地题库。
2.3 实时对战匹配与消息推送的核心设计
对战匹配是这个产品技术复杂度最高的模块。核心需求是:两个人进入匹配池,服务器撮合两人进入同一个对局,然后实时广播出题和答题状态。匹配池我直接用 Redis 里的按科目+段位组织的队列,用户发起匹配时后端往对应队列推入用户 ID,另一端持续尝试从队列里弹出两个用户,弹到两个就创建对局,弹到一个就等一会儿再试,直到超时。
为了理解这个过程,用伪代码表示核心逻辑:
// 匹配服务伪代码 async function matchmaker() { while (true) { // 从对应学科+段位的队列中尝试弹出两个候选 const userA = await redis.lpop(`match:${subject}:${rank}`); if (!userA) { await sleep(500); continue; } const userB = await redis.lpop(`match:${subject}:${rank}`); if (!userB) { // 没有对手,把 A 放回去等下一轮 await redis.rpush(`match:${subject}:${rank}`, userA); await sleep(500); continue; } // 撮合成功,创建对局房间 const roomId = `room:${Date.now()}_${randomId()}`; await createGameRoom(roomId, userA, userB); } }这里有几个容易踩的坑。一是弹出用户 A 后必须快速尝试弹出 B,不要让 A 在内存里等待太久,否则闲置用户堆积,匹配体验会变差。二是匹配成功后要给两个用户分别推送“已匹配到对手”的通知,客户端收到通知后进入对战页,这里我用的是 WebSocket 长连接,配合小程序端的 wx.connectSocket 实现。三是超时机制非常关键,匹配超过 15 秒必须给用户一个提示,说明当前该科目对手较少,是否愿意扩大段位范围,降低流失率。
对局过程中的消息主要有:开局信号、每题倒计时、双方当前比分、结束结算。这些消息量不大,但实时性要求高,WebSocket 完全够用。断线重连机制一定提前做,我上线后遇到的最大问题之一就是对局中用户切后台导致连接断开,结果双方都以为自己赢了。后来的方案是在断开后保留对局 30 秒,等待重连,同时给对端发送等待提示。
3. 小程序端核心功能拆解与实现细节
3.1 对战流程的状态机设计与答题逻辑
把对战流程设计成状态机,是避免页面逻辑混乱的最好方式。我的状态划分是:空闲(IDLE) -> 匹配中(MATCHING) -> 对局中(PLAYING) -> 结算(SETTLEMENT) -> 回到空闲。每个状态下页面渲染的 UI 完全不同,用户可以执行的操作也完全不同,比如匹配中不能切科目,对局中不能退出房间等。
答题环节的体验决定留存。核心体验节奏是这样的:开局后双方同时收到第一题,每题答题时间 15 秒,倒计时最后 3 秒有催促使感;提交答案后立即看到对方是否答对、双方比分变化;全部 5 题结束后进入结算动画,展示胜负、得分、知识点回顾。每一题答完的即时反馈很重要,不能让用户干等。
在答题交互上,四个选项按钮采用了大点击区域设计,因为这是移动端对局,用户可能在走路、地铁上单手操作,点击区域太小会带来挫败感。提交答案后立刻锁定选项,同时发送到服务端,服务端做判题并广播给对端。前端不要自己判题,因为这个产品本质上是服务端可信的,以后加排行榜、积分都依赖服务端的统一判定。
3.2 积分、段位与排行榜:让对战结果有沉没成本
对战如果没有长期积累,每局就只是孤立的输赢,用户输一次可能就流失了。所以我加了积分和段位体系。胜负积分参考了 ELO 算法的简化版:胜者分数增量取决于双方积分差,低分赢高分加的更多,高分输低分扣的更多,防止刷分。
段位划分我用了类似游戏的框架:黑铁、青铜、白银、黄金、铂金、钻石、王者。初始段位黑铁,连胜有额外加成,跨段位晋级时有全屏特效。这套体系的作用有几个:一是让用户在输了之后产生不甘心,想要把段位打回去;二是让用户产生“我是这个段位的人”的身份认知,愿意在朋友圈分享战绩时携带段位标识;三是为后续的赛季玩法留了扩展空档。
好友排行榜和对战记录也起了很大作用。用户最在意的是熟人的评价,看到好友段位比自己高,会直接激发追赶心态。我把好友榜放在对战结果页的底部,输了的人看到“好友 xxx 正在挑战你”,点击就能直接发起下一局,这比任何运营推送都有效。
3.3 题库管理、内容冷启动与 AI 维护流程
用小程序的开发者都知道,内容类产品的冷启动最怕题库不够。如果用户对战时反复遇到重复题目,新鲜感会很快消失。因此我用了一个三层题库体系:第一层是人工维护的核心题库,按科目章节组织,质量最高,覆盖必考知识点;第二层是 AI 预生成的题库,离线批量生成后经过自动校验和人工抽检入库;第三层是实时生成题目,只在缓存未命中时触发,作为用户对局的动态补充。
题库维护上,AI 不应该是甩手掌柜。预生成的题我用抽检的方式人工审核,发现错误率超过一定阈值就回炉重造提示词,或者限制该科目的模型参数。用户端也加了“反馈错题”按钮,用户举报的题人工复核后决定修改或下架。对战场景对题目正确性要求很高,一道争议题可能直接引发两个用户同时投诉,这个反馈通道是必备的。
标签体系也很关键。每道题都有科目、章节、知识点、难度四个标签。对局开始前用户选择科目和难度偏好,系统就能只从这个标签子集里选题,让题目不超纲。这里要特别提醒,不要相信大模型自己给你的分类标签,入库时要做一次规则对齐,否则用户会发现“考研政治”里冒出高中数学题。
4. 增长裂变机制设计:700+ 自然用户是怎么跑出来的
4.1 对战即邀请:把裂变融入核心玩法,而不是额外任务
很多产品做裂变是“邀请好友得奖励”,把邀请当成与主流程无关的额外任务,转化率往往很低。我采用的思路是“对战本身就是一个邀请场景”。用户创建对局后,可以选择“邀请好友对战”模式,也可以选择随机匹配。邀请好友时,小程序直接把分享卡片发给好友,卡片上带着发起人的段位、当前连胜数、一句挑衅文案,好友点进来不用注册直接进入对局。
这个设计的高明之处在于,用户邀好友不是为了奖励,而是为了“打赢对方”。被邀请的人接受挑战也不是为了领取福利,而是为了“不接受就输了”。整条链路的启动点不是利诱,而是社交情绪。当然,我也给了邀请奖励:邀请好友完成对局,双方各获得一张复活卡,可以在关键时刻多答一题。但这个奖励是轻量级的,它的作用是助推而非驱动,才不会让人产生“又在拉人头”的抵触感。
4.2 分享卡片与分享场景的 A/B 实验
分享卡片是这个产品获客的第一入口,文案和样式的重要性不亚于产品本身。我前后测了四五个版本,总结出来三个关键点。一是卡片上必须展示“可比较的信息”,段位、积分、连胜数都可以,让人一眼看出这场对局和自己有关。二是卡片上不能只写“来对战”,要写清结果性文案,比如“我连胜 5 场,等你来终结”,挑衅比邀请有效得多。三是卡片跳转的小程序页面必须直通对局,不要跳首页让用户再操作,每多一步就多流失一批用户。
分享场景也埋了三个入口:结算页的“晒战绩”按钮、排行榜页的“挑战好友”按钮、对局中断线后“邀请好友继续对战”的引导。战绩卡片里有本次胜负、得分段位变化、错题回顾三个要素,用户分享出去相当于在朋友圈展示了自己真实的学习状态,不像纯游戏战绩那样有刷屏攻击性,接受度更高。一周数据里,由战绩卡片带来的新用户占比接近四成,这个入口是最大的分享来源。
4.3 一周增长数据复盘:每个来源和关键指标拆解
零投放的前提下,一周时间新增 700+ 用户,我不能说这个数字很大,但对一个没有资源的小团队来说,它证明了自然裂变链路是通的。来看一组我记录的真实数据:
| 指标 | 数值 |
|---|---|
| 总新增用户 | 732 |
| 分享次数(含邀请和战绩分享) | 486 |
| 分享带来的新用户 | 398 |
| 邀请对战成功率(好友点击并完成对局) | 38% |
| 随机匹配带来的回流用户占比 | 27% |
| 次日留存率(整体) | 41% |
| 次日留存率(通过邀请进入的用户) | 53% |
从来源去向看,好友挑战卡片带来的新用户最多,其次是战绩晒图,再次是小程序搜索。有一个现象很有意思:通过好友邀请进入的用户次日留存远高于随机匹配用户,这说明对战产品的用户质量高度依赖社交关系链。电商里有个词叫“私域”,放到对战产品里,熟人之间的 PK 本身就是最强的私域。
另一个关键数据是用户分享的时段。我原以为晚上是高峰,实际数据显示午休 12:00-13:00 和晚上 21:00-22:00 是两个分享高峰。午饭后的碎片时间和睡前的空闲时间是最容易发起对战的场景,这两个时段的产品引导和推送也应该配合。
4.4 隐性增长因素:MVP 快速上线带来的窗口期效应
还有一点是很多复盘文章不会提的——上线速度本身就是增长因素。从想法到上线我只用了三周,功能极其克制:对战、段位、AI 出题、邀请分享,就这四个核心功能。正因为功能少,每个功能都能做扎实,用户第一次打开时不会被大量信息淹没,能最快速理解“这是一个可以和朋友玩的学习产品”。
如果一开始就做社区、做课程、做评论,用户进入后的学习成本会被拉高,分享动机也会被稀释。MVP 状态下,用户看到的每一个元素都是服务于“对战”这件事的,这自然提升了分享的纯度。等用户基数再大一些,我会逐步加功能和复杂玩法,但前提是核心对战体验不能受到干扰。
5. 上线一周遇到的问题:从线上故障到数据调优的实战记录
5.1 AI 响应超时与内容质量问题的应急方案
上线第一天就遇到了 AI 出题延迟的问题。当时正值晚上使用高峰,用户排队匹配的时间长,部分科目没有缓存命中,实时生成请求压力大,最严重时一局对战的等待时间超过了 8 秒,用户大量退出匹配。我马上做了一次紧急调优:把实时请求的超时时间从 2.5 秒进一步压缩到 1.8 秒,超时即返回本地题库;同时增加后台预生成任务,对热门科目提前补足缓存;再就是对实时请求做并发限制,同一科目同时最多只能有十个生成任务,超出直接走本地题库。
内容质量上也出过幺蛾子。有一次用户反馈某道题四个选项中“A 和 C 都是对的”,但我设计的答题逻辑只接受一个正确答案。排查后定位到是模型在生成多选题时错误地使用了单选题格式。修复方案是在提示词里增加更强制的“只能有一个正确答案”指令,同时在入库校验里增加“检查其他选项是否与正确选项语义冲突”的规则。这类问题无法完全避免,只能尽量通过规则减少发生概率。
5.2 匹配并发与断线重连的技术坑
并发匹配最大的一个坑是两个人同时被匹配进不同房间。当时的原因是对局创建和释放双方用户不是原子操作,用户 A 在等待 B 的过程中,自己又发起了一次新的匹配请求,导致一条用户连接被分配到两个房间。修复方案是给用户加一个全局的“当前对局状态”字段,任何新的匹配请求过来先检查该字段,非空闲状态直接拒绝。同时把匹配池的取出操作加了一个随机动作,确保同一用户不会被重复取出。
断线重连的实现也折腾了很久。小程序切后台后 WebSocket 会断开,但服务端可能没立刻感知,导致对局处于挂起状态。后来设计了一个心跳机制:客户端每 20 秒发一次心跳,服务端超过 60 秒没有收到心跳则判定掉线,生成一个断线事件;此时对局前端会显示“对方已掉线,等待 30 秒”,如果掉线方 30 秒内重连成功则对局继续,否则判负。同时加上掉线局不计入排位的保护规则,避免用户因为网络波动被扣分。
5.3 分享裂变带来的刷量风险与风控策略
自然裂变跑起来的同时,也会引来刷量人群。我发现有人通过多账号相互邀请对局来刷积分和段位,对排行榜公平性产生严重影响。清零刷分数据和调整算法都很直接,但更关键的还是防刷机制。
我加了风控组合拳:新用户必须累计完成三场有效对局才能解锁段位排名;每个微信号每日对局上限二十场;同设备注册多账号直接识别合并;对局时长短于二十秒且双方答案完全相同的对局自动标记异常。这一套下来有效遏制了刷量,虽然还是有人能绕过,但成本已经超过收益,大多数人就不会再刷了。这里要给后来的开发者提个醒:风控不要等出事了再做,MVP 阶段就要把基础规则放进去。
5.4 审核与合规层面的实际避坑经验
小程序审核是很多独立开发者被卡住的地方,我也没逃过。首次提审就被拒了两次,原因都和分享有关——审核方认为诱导分享的引导语太强。后来调整的策略是先保证核心功能完整,弱化分享引导按钮的存在感,同时把诱导文案改成更中性的表达。另外,涉及支付的功能一定要处理好虚拟支付合规,涉及用户隐私授权要在首次弹窗时提供清晰说明文案。
这类审核问题没有统一解法,但有一条经验值得分享:审核前自己先用“新用户视角”过一遍产品,把所有可能引起误导的文案截图留存,提交审核时附上这些说明材料。审核人员的核心诉求是判断产品是否有严重违规风险,你主动把风险点解释清楚,通过率会高很多。
6. 写在最后:我个人最真实的几点体会
做这个项目最大的感受是,AI 驱动不是让你省掉产品思考,而是把产品思考的边界放大了。没有 AI,我一个人不可能维护对战所需的海量题库;但有了 AI,反而要花更多精力设计提示词、做内容校验、控制生成成本。技术不是魔法,它只是把原来做不到的事情变成了需要精细运营的事情。
裂变增长的核心永远不是机制本身,而是你的产品有没有制造出值得用户主动分享的情绪。对战式刷题赢的人想晒战绩,输的人想复仇,这两种情绪都会自然转化为分享和召回。如果你准备做类似的社交类小程序,我建议你在设计 MVP 时就把分享链路放在核心流程里,而不是等产品做完再补一个“邀请好友”入口。
最后分享一个小技巧:我测试发现,失败的战绩卡片带来的新用户反而比胜利战绩更高。因为失败更容易引起好友的调侃和挑战欲——“你居然输给这种题了?我来试试”。这个发现让我后续所有战绩分享都保留了失败态,效果出乎意料地好。很多产品恨不得永远展示用户的光鲜,但真实且有情绪的内容,才是最有传播力的。