从功能堆叠到学习闭环:Bonjour 15 的一次产品重构思考
一个法语学习网站的产品重构:从功能堆叠回到每天15分钟的学习闭环。

一开始,我只是想解决一个很简单的问题:
不是一天背 100 个单词,不是连续打卡 365 天,也不是打开 App 之后先面对几十个功能入口。
就是每天十几分钟。
学几个词,听几遍发音,看到它们出现在句子里,过几天再遇到一次。
慢慢地,从“看得懂”,变成“想得起来”,最后能够脱口而出。
于是,我做了一个法语学习网站。
它叫 Bonjour 15。
名字也很简单:
但真正开始做以后,我很快发现了一件很有意思的事:
一、最开始,我也掉进了“功能越多越好”的陷阱
独立开发一个产品,很容易产生一种错觉:
今天加一个功能,产品就进步了一点。
于是功能开始不断增加。
-
账号注册。
-
邮箱验证。
-
登录。
-
学习记录。
-
学习天数。
-
XP。
-
单词学习。
-
法语到中文。
-
中文到法语。
-
错题重练。
-
例句。
-
单词发音。
-
例句发音。
-
句子里的单词还可以单独点击发音。
后来又加入了:
-
拼写练习。
-
语音跟读。
-
常用句。
-
场景。
-
微信小程序。
-
云端学习进度。
-
音频库。
-
5000 个法语词汇。
-
甚至 AI 对话,也已经进入了未来计划。
从功能清单上看,它越来越像一个“完整的学习平台”。
但当我自己真正坐下来学习时,却发现问题开始出现了。
这让我重新思考:
一个学习产品真正重要的,到底是什么?
二、学习产品最核心的,不是功能,而是“下一步”
假设你晚上十点打开一个学习 App。
你今天已经工作了一整天。
你其实没有多少精力。
这时候,如果首页出现:
-
单词
-
句子
-
听力
-
拼写
-
跟读
-
场景
-
语法
-
AI 对话
-
排行榜
-
今日任务
-
复习计划
你反而可能不知道点什么。
学习的阻力,就是从这里开始的。
后来我慢慢意识到:

插图二|“每天 15 分钟”法语学习体验的产品化表达
它应该替用户决定:
打开 Bonjour 15。
点一下:
然后直接开始。
今天应该学新词,系统帮你安排。
应该复习旧词,系统帮你安排。
某个词经常错,就更容易再次出现。
某个词已经很熟,就少出现一点。
某个词适合拼写,就让你拼一次。
某个句子适合跟读,就让你读一次。
用户真正需要做的事情只有一个:
这其实也是我现在对 Bonjour 15 最核心的产品判断。
三、我决定不再做一个“背单词网站”
Bonjour 15 最早的核心,其实还是背单词。
一个词出现:
maison
然后你选择:
房子
或者反过来:
房子 → maison
这种学习方式当然有效。
但它有一个非常明显的问题:
比如法语里的:
prendre
如果只把它记成“拿、取”,其实价值很有限。
真正日常使用中,更重要的是这些:
prendre le bus · 坐公交车
prendre un café · 喝杯咖啡
prendre son temps · 慢慢来
语言并不是由孤立的单词组成的。
它更像一个个“词块”。
所以 Bonjour 15 下一阶段,我不准备继续疯狂扩充词库。
现在已经有 5000 个词。
数量已经够多了。
真正缺少的,是:
四、5000 个词,不如真正学会 1000 个
这也是我最近最大的一个转变。
以前很容易追求一个数字:
1000 词 · 3000 词 · 5000 词 · 10000 词
看起来词库越大,产品越厉害。
但对于一个初学者来说:
真正决定能不能开始使用一门语言的,往往并不是第 4873 个单词。
而是最常见的那几百、几千个词。
比如:
être · avoir · aller · venir · faire · prendre · vouloir · pouvoir · devoir
这些词几乎贯穿整个法语。
所以我准备重新整理 Bonjour 15 的核心词库。
我把它暂时叫作:
大概会分成:
-
A0:约 200 个词
-
A1:约 500 个词
-
A2:约 300 个词
但重点不是分级。
重点是人工重新整理。
每一个高频词,都尽量补充:
-
词性。
-
阴阳性。
-
真正最常见的释义。
-
自然例句。
-
常用搭配。
-
场景。
-
音频。
-
必要时加入词块。
比如不只是教“faim —— 饥饿”,而是直接学习“avoir faim —— 饿了”。
不只是“besoin —— 需要”,而是“avoir besoin de —— 需要……”。
如果最终能够真正掌握这些高频结构,它比单纯认识几千个孤立词汇更有意义。

插图三|从单词、句子到听说拼写的学习闭环示意

插图四|Bonjour Core 1000 与 A0-A2 学习阶梯路线图
五、另一个让我很在意的问题:声音
做语言学习产品,声音几乎绕不过去。
Bonjour 15 现在已经支持:
-
单词发音。
-
例句发音。
-
句子发音。
-
句子里的单词单独点击发音。
-
浏览器法语 TTS 备用发音。
-
服务器生成的法语语音。
这些功能看起来都没问题。
但我后来发现了一个很典型的工程问题:
例如一组有 10 个词。
系统可能会提前加载:10 个单词音频、10 个例句音频,再加上例句里的若干 token 音频。
如果网络比较慢,用户明明已经能看到单词,却还要等音频加载。
这件事情在技术上很合理:“我要先把资源准备好。”
但在产品上却是错的。
所以接下来 Bonjour 15 会改变音频策略。
以后应该是:
-
文字先出现。
-
第一个词立即开始学习。
-
当前词的声音优先加载。
-
下一题声音提前准备。
-
剩余音频放到后台。
-
如果正式音频加载失败,就用浏览器法语 TTS。
-
如果 TTS 也失败,那就先静音学习。
有声音当然最好。
但声音绝不能成为学习的前置条件。
六、我也不准备做复杂的“记忆算法”
做背单词工具,很容易想到一个词:间隔重复。
SM-2。FSRS。遗忘曲线。due_at。interval。ease factor。各种复习调度算法。
这些算法当然很有价值。
但 Bonjour 15 现阶段,我反而决定暂时不做复杂的强制记忆系统。
因为我的目标不是:
而是:
目前 Bonjour 15 大致维持:
但下一步会做一件更简单的事情:给旧词计算一个轻量的“薄弱程度”。
-
经常答错的词,更容易出现。
-
很久没见过的词,更容易出现。
-
只学过一次的词,更容易出现。
-
已经连续答对很多次的词,出现频率下降。
它不会告诉你:“今天有 132 个词必须复习。”
也不会因为你一天没打开,就堆积一大堆“学习债务”。
这是我一直比较抗拒的一种学习体验。
而不是:“你昨天没学,现在欠我 87 个单词。”
七、打卡应该是奖励,而不是压力
很多学习产品非常强调连续学习天数。
连续 7 天。连续 30 天。连续 365 天。
这个设计很聪明,因为它确实能够提高留存。
但它也可能产生另一个问题:
当学习从“我想学习”,慢慢变成“我不敢断掉数字”,它就开始变味了。
所以 Bonjour 15 目前依然会保留打卡。
但我希望它只是:
而不是学习的目的。
-
你完成完整的一组学习:打卡。
-
增加学习记录。
-
看到一点庆祝动画。
-
积累 XP。
但如果今天没有学习,也没关系。第二天继续。
八、句子会真正进入学习流程
Bonjour 15 其实已经有常用句系统。
比如餐厅、酒店、机场、问路、购物、自我介绍。
这些句子已经存在于数据库里。
但现在有一个问题:它们和单词学习还是相对分开的。
下一步,我希望打破这种分割。
以后一次正常学习可能是这样的:
-
第 1 个:新词。
-
第 2 个:旧词复习。
-
第 3 个:新词。
-
第 4 个:一句常用句。
-
第 5 个:旧词。
-
第 6 个:中文 → 法语。
-
第 7 个:听音选择。
-
第 8 个:一句场景表达。
-
第 9 个:拼写一个已经比较熟悉的词。
-
第 10 个:错题重练。
这样整个学习过程就不再是“连续十张单词卡”。
而会慢慢接近真实的语言学习。
用户不需要自己切换模式。系统自然地带着你走完。
九、拼写和跟读,也不会做成两个大入口
我已经做了一部分拼写和语音识别功能。
比如系统可以显示中文“房子”,让你输入“maison”,也可以调用浏览器语音识别,让你读一句法语。
最开始,我也考虑过把它们做成首页入口:“拼写训练”“跟读训练”。
后来我放弃了。
因为这又会回到之前的问题:
我现在更倾向于:让训练形式自然出现在学习过程中。
-
第一次见一个词:先认识。
-
第二次:做法语 → 中文。
-
第三次:做中文 → 法语。
-
再熟一点:偶尔拼写。
-
再熟一点:偶尔听音。
-
适合开口的内容:偶尔跟读。
这样拼写和口语不是两个产品功能。
十、技术上,我也开始刻意“不折腾”
这几年做个人项目,一个特别容易犯的错误就是:过早追求“高级架构”。
Redis。消息队列。微服务。向量数据库。事件驱动。各种复杂的部署架构。
这些东西本身当然没有问题。
但 Bonjour 15 现在只有一个非常现实的目标:
所以目前我决定继续保持一个非常朴素的技术架构:
Next.js · React · TypeScript · PostgreSQL · Docker Compose
数据库够用。应用服务器够用。音频先放服务器。真的需要,再迁移 OSS。AI 真的有用户需求,再接入。真的有大量用户,再讨论拆服务。
现在没有必要为了想象中的十万用户,把一个几十、几百用户阶段的项目设计成互联网大厂架构。
十一、还有一个变化:生产服务器以后尽量“不碰”
这是这次优化里一个看起来很技术、但其实非常重要的决定。
以前个人项目很容易出现一种开发方式:SSH 登录服务器,改一点代码,重启一下,发现有问题,再改。数据库顺便跑一个 SQL,音频再测试一下。
这种方式项目小时非常快。
但随着真实用户出现,它会变得越来越危险。
所以接下来 Bonjour 15 会建立一个独立的 HomeServer 测试环境。
开发流程会变成:
生产环境以后只做几件事情:
-
更新稳定版本。
-
执行已经验证过的数据库迁移。
-
构建。
-
启动。
-
健康检查。
-
如果出现问题,就回滚。
虽然 Bonjour 15 现在还只是一个很小的独立项目,但只要已经有真实用户,这件事情就值得认真对待。

插图五|本地开发、HomeServer 测试到生产发布的安全工作流
十二、我越来越觉得,独立开发最大的敌人不是不会做,而是“什么都想做”
今天看到 AI 对话不错,想加。
明天看到排行榜不错,想加。
后天发现某个 App 有学习地图,也想加。
然后再做会员、成就、社交、语法课、每日任务、AI 老师。
最后功能越来越丰富。
但真正决定一个产品能不能留下来的,往往还是那个最简单的问题:
所以我现在给 Bonjour 15 定了一条很明确的原则:
这意味着未来一段时间,我不会急着做很多新东西。
反而会花更多时间在一些不那么“性感”的地方:
-
页面是不是立即打开。
-
声音是不是立即播放。
-
例句是不是自然。
-
常用词是不是选得好。
-
错词什么时候重新出现。
-
句子是不是值得学。
-
手机上操作是不是舒服。
-
完成一组之后,有没有一点满足感。
-
第二天打开以后,能不能自然继续。
这些事情放在产品发布列表里可能并不起眼。
但它们真正决定了一个学习产品到底好不好用。
十三、Bonjour 15 最终想变成什么?
我现在心里已经越来越清楚。
它不会变成一个庞大的在线教育平台。
也不会变成一个课程商城。
我希望它最终非常简单。
打开首页。
只有一个最明显的按钮:
点进去。
今天的十几分钟开始。
里面自然包含:
-
新词。
-
旧词。
-
句子。
-
听力。
-
拼写。
-
跟读。
-
错题。
-
场景表达。
系统记得你已经学过什么,也知道哪些地方还不熟。
但你不需要研究算法,不需要安排学习计划,也不需要管理几十个功能。
你只需要:
十五分钟以后,关掉页面。去工作。去生活。第二天再回来。
如果一年以后,一个原本完全不会法语的人,可以慢慢看懂菜单、听懂一些简单表达、在咖啡馆说出一句自然的法语。
那 Bonjour 15 对我来说,就已经是一件很有意义的产品。
写在最后
做 Bonjour 15 的过程中,我越来越发现:做产品和学习语言,其实很像。
刚开始的时候,我们总希望快一点。多一点。复杂一点。
一天背更多词。产品加更多功能。
但真正长期有效的方式,往往恰恰相反。
少一点。
稳一点。
持续一点。
每天进步一点。
我还会继续把它慢慢做好。