三月一日,惊蛰。深圳蛇口,海上世界背后的一处老別墅区。一栋三层白色小楼藏在榕树和九里香丛中,铁门紧闭,窗帘拉得严严实实。別墅是林浩租的,签了半年,对外说是“浩宇游戏平台技术攻坚基地”,实际门口掛了个手写木牌,上面两个字:“氧舱”。
上午九点,別墅一楼客厅。十二个人,十二台电脑,沿著墙壁摆了一圈。窗帘是厚重的墨绿色绒布,隔绝了所有自然光,只有屏幕的冷光和头顶日光灯惨白的光。空气里有新电脑散发的塑料味,有速溶咖啡的焦苦,有熬夜后的汗酸,还有一种紧绷的、近乎实验室的无菌感。
张小龙站在客厅中央的白板前,白板上没写代码,没画架构,只有一行用红笔加粗的字:“老太太也能上来就语音聊天”。字下面画了个简单的流程图:开机→点图標→说话。只有三步。
“从今天起,我们在这里封闭开发一百天。”张小龙开口,声音不高,但很清晰,“目標只有一个:做出一款让老太太都能零门槛使用的语音聊天工具。不是『好用』,是『不用学就会用』。不是『流畅』,是『像呼吸一样自然』。做不到,我们不出这个门。”
十二个人,有从浩宇调来的老员工,有张小龙从广州带来的前foxmail工程师,有刚招的应届生。所有人看著那行字,表情各异。有人皱眉,有人困惑,有人跃跃欲试。
“老大,”一个戴眼镜的年轻工程师举手,叫周明,是浩宇的老员工,之前做游戏客户端的,“语音聊天技术很复杂,要调编解码,要搞网络適配,要处理回声消除。老太太怎么可能懂这些?我们应该先做內测,让核心用户反馈,慢慢优化……”
“没有慢慢。”张小龙打断他,“林浩只给三个月。三个月后,產品公测。我们要面对的,是几亿普通用户,不是极客。他们不会给我们第二次机会。体验不好,一秒就刪。”
他走到白板前,在那行字下面又写了一行:“所有技术问题,必须在產品层解决,不能让用户感知。”
“什么意思?”另一个工程师问,李涛,张小龙从广州带来的,做底层协议出身。
“意思是,网络不好,我们要自动降码率,不能卡。有回声,我们要算法消除,不能有杂音。对方说话声音小,我们要动態增益,不用用户调音量。”张小龙顿了顿,“所有技术实现,必须藏起来。用户看到的,只是一个按钮,点下去,就能说话。就这么简单。”
“这……这做不到吧?”周明嘟囔,“网络波动是物理限制,算法再强也……”
“那就做到物理极限。”张小龙看向他,“林浩给了我们一个算法,『小艺』压缩。语音带宽能降到原来的30%。用这个当基础,我们再优化。网络波动,前向纠错。回声消除,用深度学习模型。这些技术,我们都有。现在要做的,是把它们打磨到极致,然后包装成一个最简单的界面。”
他走到第一台电脑前,打开一个简陋的demo。屏幕上只有一个界面:深灰色背景,中间一个大大的圆形按钮,按钮上是麦克风图標。按钮下方一行小字:“按住说话”。
“这是第一版界面。”张小龙说,“只有这一个按钮。点一下,开始录音。鬆开,发送。收到语音消息,自动播放。没有好友列表,没有群组,没有设置——什么都没有。就这一个按钮。”
客厅里一片寂静。所有人都盯著那个简陋到可笑的界面。这……这也叫產品?
“我们要做的,就是让这个按钮,在任何网络环境下,任何硬体配置上,都能稳定工作。”张小龙说,“分组。周明,你带三个人,攻网络自適应。目標:在56k拨號、1m adsl、区域网三种环境下,语音延迟都低於200毫秒,卡顿率低於1%。李涛,你带三个人,攻音频处理。目標:在菜市场、地铁、办公室三种噪音环境下,语音清晰度达到90%以上。小王,你带两个人,做ui和交互。目標:从点击按钮到开始录音,反应时间低於50毫秒。小刘,你带两个人,做后台服务。目標:支持百万级並发,消息到达率99.99%。我负责整体架构和算法调优。”
分工明確,时间紧迫。没人再质疑。键盘声瞬间响起,密集得像暴雨。
第一天,周明组就卡住了。他们在模擬56k拨號环境下测试,丟包率一旦超过5%,语音就断断续续。“前向纠错要发冗余包,但冗余包占带宽,反而增加延迟。这是个死循环。”
张小龙走过去,看著屏幕上的数据流。“冗余包不用每次发。根据网络实时状况动態调整。网络好,少发。网络差,多发。用机器学习预测丟包率,提前发冗余。”
“可机器学习模型需要训练……”
记住我们101看书网
“林浩给了训练数据,浩宇游戏平台几千万条语音消息,带网络环境標籤。今晚就训。”
第二天,李涛组遇到回声。他们在別墅里测试,两个房间互相语音,回声大得像在山谷里喊话。“现有的回声消除算法,对付不了这种复杂环境。”
张小龙调出“小艺”算法里的深度学习模型。“用这个。输入原始音频和回声参考信號,输出消除后的音频。模型我预训练过了,你们微调。”
“可深度学习计算量大,实时性……”
“优化。模型压缩,定点量化,汇编级加速。我要明天看到结果。”
第三天,小王组的ui出了问题。按钮点击响应时间达標了,但用户反馈“不知道按了没有”。张小龙说:“加一个视觉反馈。按下时按钮顏色变深,周围有涟漪扩散动画。动画要流畅,不能卡。”
“可动画会吃资源……”
“用css3硬体加速。我要的是体验,不是省那点cpu。”
每天,林浩会在下午四点准时出现。不开车,步行过来,背著一个双肩包,里面是当天要看的代码和测试报告。他进来后不说话,只是走到每个人的电脑后面,看屏幕,看日誌,看测试数据。看完了,走到张小龙面前,只说一句话。
第一天:“网络延迟的99分位值太高,降到150毫秒以下。”
第二天:“回声消除在低频段效果不好,重训模型。”
第三天:“按钮动画掉帧,优化到60fps。”
第四天:“启动速度慢了一秒,砍掉所有非必要初始化。”
第五天:“语音消息播放时不能打断,加个进度条。”
第六天:“断网重连逻辑太复杂,简化到三步。”
第七天:“安装包大了0.5m,砍掉一个冗余库。”
永远只有一句话,指出一个最具体的问题。然后转身离开,不多说一个字。像最苛刻的教练,只指出你的弱点,不告诉你怎么练。
压力巨大。但团队在高压下,开始蜕变。周明组把网络自適应算法优化到第七版,56k拨號下的延迟降到180毫秒。李涛组用深度学习模型,在菜市场噪音下也能提取清晰人声。小王组的ui流畅得像德芙巧克力。小刘组的后台服务稳如磐石。
但张小龙不满意。他看著测试数据,总觉得少了什么。
第三十天,凌晨两点。张小龙把所有人叫到客厅,打开电视,接上摄像头。摄像头对著客厅中央的一把椅子。
“现在开始用户测试。”他说,“不测试功能,测试『感觉』。我坐在这里,你们轮流过来,假装是我奶奶,用这个產品给我发语音消息。我要看你们的操作,看你们的表情,听你们第一句话说什么。”
眾人面面相覷。但还是照做。第一个是周明,他坐下,拿起手机(测试机),点开那个唯一的按钮,按住,说:“小龙啊,吃饭了没?”
发送。播放。声音清晰,延迟很低。
“感觉不对。”张小龙摇头,“你太熟练了。我奶奶不会这么自然。她会犹豫,会紧张,会不知道说什么。再来。”
李涛上。他坐下,盯著按钮看了三秒,才小心地按下去,说:“餵?能听见吗?”
“好一点,但还是很像测试。”张小龙说,“想像你真的是老人,第一次用智慧型手机,第一次语音聊天。你会怎么做?”
测试持续到凌晨四点。十二个人,演了十二个“奶奶”。有的小心翼翼,有的大大咧咧,有的说方言,有的嗓子哑。张小龙看著,记著,在白板上写观察:
“犹豫期平均3秒”
“第一次说话习惯说『餵』”
“鬆手时很紧张,怕没发出去”
“听到自己声音会愣一下”
“背景音很重要(电视声、炒菜声)”
第二天,產品改了。启动后,不是直接进聊天界面,而是一段简单的引导动画:一个慈祥的老奶奶头像,配一行字:“按住下面,对孙子说话”。按钮变大,顏色更醒目。按下时,按钮会有温和的脉动,像心跳。鬆开时,有“嗖”的一声轻响,表示发送成功。收到消息自动播放,但第一次播放前,有文字提示:“孙子来信啦”。
林浩下午来看,没说话,自己坐下,用了一次。按住,说:“测试。”鬆开。播放。
然后他说:“引导动画里的老奶奶,不像我奶奶。”
张小龙愣住。
“我奶奶更瘦,头髮更白,眼神更慈祥。”林浩说,“换一个。要让人一看就有亲近感。”
美术组连夜改图,找了上百张老人照片,最终定稿一个:清瘦,白髮梳得整齐,眼睛弯弯的,嘴角有笑纹。像每个人的奶奶。
第四十五天,林浩来,说:“语音播放时,不能操作其他应用。老太太可能会边听边想回话,结果点不了按钮。”
加了一个“语音播放时按钮禁用”的提示,但提示要友好:“先听完孙子说啥,別急”。
第六十天,网络自適应算法终於稳定。在模擬的极端网络环境下(丟包率20%,延迟500毫秒),语音依然连续,只是音质下降,但不会断。张小龙说:“可以了。”
林浩测试后,说:“音质下降时,加个提示:『网络不太好,我慢点说』。用老奶奶的声音说。”
加了个tts语音,温柔,缓慢,带点方言腔。
第七十五天,產品基本成型。启动快,连接稳,语音清,交互顺。团队鬆了口气,觉得终於可以交差了。
林浩来,测试了十分钟,然后说:“不够极致。”
眾人心一沉。
“哪里?”张小龙问。
“情感。”林浩说,“这还是个工具,冷冰冰的工具。我们要做的,是桥樑,是温暖。奶奶给孙子发语音,不是要传达信息,是要传达关心。孙子给奶奶回语音,不是要匯报近况,是要让她安心。这个產品,要能传递情绪。”
“怎么传递?”
“细节。”林浩说,“比如,奶奶说话慢,我们的语音播放速度,可以自动適配——奶奶的语音,用原速。孙子的语音,如果太快,自动放慢一点。比如,深夜收到消息,播放音量自动调低,不吵醒人。比如,长时间没联繫,启动时加一句:『好久没和孙子聊天了吧?』比如,发送成功时,加一个温暖的音效,像拥抱的声音。”
团队沉默了。这些细节,每一个都要改代码,调参数,测体验。时间只剩二十五天了。
“做不做?”张小龙问团队。
没人说话。但眼神说明了一切——做。
最后二十五天,疯狂。周明组重写了音频播放引擎,加了语速自適应。李涛组优化了噪音检测,深夜自动降噪。小王组设计了十几个情感化提示,每一个都测试了上百遍。小刘组在后台加了用户行为分析,用来触发那些温暖的提醒。
第九十九天,凌晨。產品最终测试。十二个人,轮流模擬奶奶和孙子,发了三百条语音消息。每条消息,都在不同网络环境、不同噪音背景、不同时间下测试。数据完美:延迟、卡顿、清晰度、用户满意度,全部达標。
张小龙坐在那把椅子上,最后一次测试。他点开產品,启动,看到那个慈祥的老奶奶头像,看到“按住下面,对孙子说话”。他按住按钮,忽然不知道该说什么。
沉默了三秒,他鬆开。发送了一条空白语音。
然后,他听到產品的提示音,是老奶奶温和的声音:“怎么不说话?想孙子了吧?”
那一刻,张小龙眼眶突然一热。
他知道,成了。
第一百天,三月十日。林浩准时出现。他没测试,只是坐下,让张小龙演示了一遍。从启动,到发送,到接收,到那些温暖的细节。
演示完,林浩沉默了很久。
然后他说:“名字定了。叫『氧气』。o?。让沟通,像呼吸一样自然。”
他站起身,走到门口,回头:
“明天,公测。”
门关上。脚步声远去。
別墅里,十二个人,没人说话。只有屏幕上的o?图標,在黑暗里,静静亮著。
像一颗刚刚点燃的星。
即將照亮,无数人孤独的夜。