Esc
<- 所有文章

从功能堆叠到学习闭环:Bonjour 15 的一次产品重构思考

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

Bonjour 15 当前首页

一开始,我只是想解决一个很简单的问题:

不是一天背 100 个单词,不是连续打卡 365 天,也不是打开 App 之后先面对几十个功能入口。

就是每天十几分钟。

学几个词,听几遍发音,看到它们出现在句子里,过几天再遇到一次。

慢慢地,从“看得懂”,变成“想得起来”,最后能够脱口而出。

于是,我做了一个法语学习网站。

它叫 Bonjour 15。

名字也很简单:

但真正开始做以后,我很快发现了一件很有意思的事:

一、最开始,我也掉进了“功能越多越好”的陷阱

独立开发一个产品,很容易产生一种错觉:

今天加一个功能,产品就进步了一点。

于是功能开始不断增加。

  • 账号注册。

  • 邮箱验证。

  • 登录。

  • 学习记录。

  • 学习天数。

  • XP。

  • 单词学习。

  • 法语到中文。

  • 中文到法语。

  • 错题重练。

  • 例句。

  • 单词发音。

  • 例句发音。

  • 句子里的单词还可以单独点击发音。

后来又加入了:

  • 拼写练习。

  • 语音跟读。

  • 常用句。

  • 场景。

  • 微信小程序。

  • 云端学习进度。

  • 音频库。

  • 5000 个法语词汇。

  • 甚至 AI 对话,也已经进入了未来计划。

从功能清单上看,它越来越像一个“完整的学习平台”。

但当我自己真正坐下来学习时,却发现问题开始出现了。

这让我重新思考:

一个学习产品真正重要的,到底是什么?

二、学习产品最核心的,不是功能,而是“下一步”

假设你晚上十点打开一个学习 App。

你今天已经工作了一整天。

你其实没有多少精力。

这时候,如果首页出现:

  • 单词

  • 句子

  • 听力

  • 拼写

  • 跟读

  • 场景

  • 语法

  • AI 对话

  • 排行榜

  • 今日任务

  • 复习计划

你反而可能不知道点什么。

学习的阻力,就是从这里开始的。

后来我慢慢意识到:

每天15分钟法语学习体验

插图二|“每天 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学习阶梯

插图四|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 的过程中,我越来越发现:做产品和学习语言,其实很像。

刚开始的时候,我们总希望快一点。多一点。复杂一点。

一天背更多词。产品加更多功能。

但真正长期有效的方式,往往恰恰相反。

少一点。

稳一点。

持续一点。

每天进步一点。

我还会继续把它慢慢做好。