弓辰,号佛振,出身地是河南郑州以北十里弓家寨,在北平做码农。佛振是「Rime/中州韵」输入法引擎的开发者,它不仅仅是一个输入法,也是一个输入法算法框架,这一套算法支持了拼音、双拼、注音、五笔、仓颉等所有音码和形码输入法。Rime还支持了许多种方言拼音,如吴语、粤语,甚至中古汉语。「IT学生界大神」BYVoid曾在其博客撰文怒赞「Rime/中州韵」,使得这个原本默默无闻、志在用十年磨砺的项目在一个小圈子里迅速传开。佛振四年前加入百度PC输入法开发团队,但他并没有放弃自己的「业余作品」,而是将其发扬光大,针对Windows、Linux、Mac三大平台提供了不同的发行版,Windows版「小狼毫」,Mac版「鼠须管」,Linux版「中州韵」。佛振认为代码和文学的共同点在于「强大的表现力」,匠人和作品,在佛振这里有一个什么样的故事?

当时只道是神奇

“对一个匠人来说,创作一件有情调的作品,一定是出于对精湛技艺的追求。如果仅仅是为了现实目的,固然可以写出高质量的软件,代码本身却容易缺乏灵气。”

问:你是如何学编程的?

幼时只道符号神奇,喜欢独个写写画画,乐此不疲。中学时业余爱好是钻研速记学以及编程术。

问:请您简单介绍一下开发中州韵输入法的经过。

大学毕业后一边从事Web开发的工作,一边构思一种将速录机键盘的并击工作方式在PC键盘上实现的技术,后来制成软件《宫保拼音》。此后赋闲一段时间,又在民办高校兼职,担任过C++、Java教师。这几年里一直在使用开源的Linux系统,Linux桌面先后有SCIM和IBus这样优秀的输入法框架推出,这使得以往被视为十分专业化的输入法开发技术,对普通的开源软件开发者触手可及了。受此鼓舞,我从2009年开始设计和编写一款输入法,用来验证自己对输入法的理解和构想,并融合后来学习到的汉语音韵学知识,使他支持古音和方言输入。这就是后来称作「Rime/中州韵」的输入法。

2010年我加入百度,从事百度PC输入法的开发。这段岁月自有一份艰辛,也得到很大的锻炼。队友们都是Windows开发高手,我向他们学到了不少。欣喜的是大公司毕竟是规范得多,周末都很少会组织加班的。于是在休息时间我又把满满的热情投入到周末小制作上来。

在朋友们的帮助下,最初运行在Linux上的Rime输入法,成功移植到了Windows和Mac平台。代码和设计也不断完善,算法库由Python语言转为C++后,程序性能和操作体验都有显著提升,有幸得到了身边朋友们的肯定。

问:设计「Rime/中州韵」的初衷是什么?

为吾等输入法爱好者设计一个智能的输入法平台。

写输入法的人往往打字不快:有感于效率低下,却不思勤学苦练,反倒生出改进输入工具的念头。故事通常都是这样的。

过去,许多输入法构造简单,可以在一套通用的输入法平台软件上实现。其代表有仓颉码、五笔字型、郑码等等。后来的输入法发明人只须制定一套完备的编码规则,按规则为字词一一设定编码即可运作。用户则需要依靠脑力强记规则,在录入时把文字翻译成要在键盘上打出的代码。

如今已不再是输入法「万码奔腾」的时代,然而仁人志士发明和改进输入法的热情不减。由于互联网和移动网络的兴起,作为信息处理基础工具的输入法重新受到重视,不断向高效、易用、智能化发展。其代表是智能拼音输入法。输入过程中的许多环节改由输入法程序完成,极大地减轻了用户的思维负担。

随之,输入法开发技术也越来越复杂。因为缺少关键的智能算法,输入法设计者再也无法利用老旧的输入法平台,创作出符合时代水准的输入法了。我研究的一些问题,如方言输入,技术上与智能拼音输入十分相似。可是当时的智能拼音输入法大都针对《汉语拼音》而设计,无法轻易地将拼音方案更换为其他方言。若用传统的码表式输入法平台实现,则因同音字多,逢词必选,效率十分低下。

恼恨构想中的输入法难以实现,我终于下决心开发一款聪明而善变的输入法软件。希望通过Rime使输入法的个性化变得简易,与我有类似需要的用家可以尽情发挥创造力,找出最适合自己的打字方式。

问:在「Rime/中州韵」输入法上投入了这么多的时间和精力,你有什么收获?

对我个人而言,为创作这款开源软件投入了大量精力,也不全然是「不务正业」,心想借此练练技术也是好的。因此创作中不仅满足于实现功能就算完,许多技术细节都反复推想过。

冥冥中天意怜我青春都耗在这上面了,此前能在百度得了工作,以至目前从事的工作,都与开发过这个开源输入法有莫大关系。某虽不才,此外便一无所长,总算还没有悲剧到饥寒交迫的地步吧。

问:你对古汉语和方言是不是有特殊的感情?背后的原因是什么?

不是。

我想每个人,特别是远离家乡的游子,对自己的家乡话都是有感情的。

我的母语是中原官话,母亲却讲北京话,小时候每回从老家归来她都要纠正我的口音。以至于一些字词在家乡话里的说法我都记不真切,须求证于祖父母。祖父曰:「过去都觉得土话土,实际上这里头也通有讲究叻。」这话的意味,直到学习了一些语言学知识才得到印证。

原来每一种汉语方言都有一套严整的音韵系统,对照古代的雅言我们可以发现他们各自发展演化的轨迹。普通话是官定的标准音,但比之方言并无「特殊」之处。

我发现一些优秀的软件,非常注重本地化,努力让不同地域、不同语言、不同文化背景的用户感受到公平的对待。输入法是人机交互的重要一环,如何能贴近用家的直觉,尊重不同的语言习惯和输入偏好?我的解法是尽量将程序写得通用,给用户以足够多的选择。

对一个匠人来说,创作一件有情调的作品,一定是出于对精湛技艺的追求。如果仅仅是为了现实目的,固然可以写出高质量的软件,代码本身却容易缺乏灵气。代码的艺术和美,与文学略有共通之处,在于强大的表现力。缺乏灵气的代码只顾平铺直叙,是没有生命力的机械;好的代码越是简单明了,越是做得到更多事情。

编程的乐趣在于享受这份创造的快感:他不只是在敲代码,而是在开动脑筋调教程序,增益其所不能。甚至会有一刻在心中大呼:终于不再像菜鸟一样写程序了!谁愿做只会搬砖的码农?定要像设计师那样思考,才称得上有手艺的编码匠。

二〇〇八年我辞去搬砖的工作,立志练好技术,将来上Google、Facebook谋职,做个有技巧的码农。修炼的方式,就是完成一个有挑战、来源于真实需求的软件作品。于是酝酿已久的输入法开发计划在来年开工了。

问:能向对古汉语和方言(感兴趣)的朋友们推荐一些书籍吗?

这个问题我本来回答不了,因为我对音韵学只是泛泛地涉猎,了解十分粗浅。幸而通过开发Rime输入法认识了一些语言学和中文专业的朋友,他们向我这样的外行推荐一本丁声树撰文、李荣制表的《汉语音韵讲义》做入门书。「这本书吃透了,对于熟悉切韵音系、切韵与现代音(包括一些方言)的对应关系是非常有帮助的。」

如果想更加系统深入地学习,可参考蔡子文同学的音韵学入门推荐书目

音韵学研究者能够根据各种线索大致还原出古音的面貌。除了以上书籍,我再推荐古韵Polyhedron君录制的《中古汉语语音教程》。看网络视频学习中古音,相当别开生面。

还有BYVoid君制作的韵典网,提供了包括《广韵》在内多部古代韵书的线上查询工具。

对输入法作者来说,有女同车和Polyhedron整理的《广韵全字表》是一份极其有用的资料。许多方言输入法利用这份字表从汉字的中古音推导出现代音,作为方言码表的模板,省去了大量注音工作。

佛振的中州韵

“开发Rime输入法之前的数年间,我花了不少心思推敲、改进并击按键的排布,使容易击发的按键组合对应常用的音节,并且尽量反映出语音内在的规律性,减少需要记忆的内容。”

问:「Rime/中州韵」的开发设计过程中,编程方面最大的难点是什么?语言方面最大的难点是什么?

编程本身不难,难的是将问题抽象。要用一套代码支持多种多样的输入法,甚至是未曾发明出来的,首先得抽象出一个通用的模型,然后拆分出一个最小的框架和一组完成单一功能的组件,以供按需组合,构成形态各异的输入法引擎。

至此问题只解决了一半,还有一个目标是让用户能够直接控制这部引擎,而不必进行严肃的编程。为此我选取了类似JSON而语法更加简洁灵活的YAML语言,在其基础上定义了一套领域专用语言(DSL),称为「Rime输入方案」。在输入方案文本中,用户只须列举为输入法引擎选配的功能组件,并设置各组件所需的参数,便得以精确描述输入法的行为。

设计一个通用性强的拼音输入法框架,需要对语音系统的知识有比较全面的了解,避免受制于有限的经验作出设计上的失误。例如汉语拼音里面声母、韵母的划分,可以在输入法中加以利用:用声母建立索引实现简拼的功能,为声母、韵母分别设置模糊音输入的功能。然而这样写出的程序会丧失一部分通用性,因为不同方言的语音系统有差异,观察和研究《汉语拼音方案》所得的结论,很可能不够普遍化;用在其他语言里,或者用来处理基于字形的输入法,甚至声母、韵母的概念都完全不适用了。语言学知识帮我判断哪些语音规律有必要反映在输入法程序里,哪些不够普遍化,需要寻求更通用的解法。

最终语言学问题可以转化为技术问题啦。Rime有项基于正则表达式的「拼写运算」技术,它设计的目的是用来描述语音的演变规则。把两个音系之间的对应规则用技术语言描述出来,我们就可以将一套古音输入法改造成各地方言的输入法,或是把一种方言输入法转换成临近的方言。又因为正则表达式本质上是做字符串处理而与语音无关,所以「拼写运算」可以用于更广泛的场景,统一地解决为各种音系定义简拼、模糊音、基于规则的纠错、标注声调符号、定义双拼方案、不同拼音系统之间的转换等诸多问题。

问:通过设计开发「Rime/中州韵」输入法,你验证了哪些重要的理解和构想?

一是设计一套通用的音节切分算法。音节的变体形式如简拼、模糊音,都可以用一套规则描述。

我曾参加过一次主题为「拼音切分算法」的线上讨论,和几个主要开源输入法Fcitx、ibus-pinyin、libpinyin以及SunPinyin的开发者一起提出了这个构想。设想无论拼音方案是汉语拼音、注音或是其他的拼写方案,输入法都可以对算法不加修改而做到将连续的输入串以音节为单位做切分。音节切分是拼音输入法做词典查询之前的必要步骤。这个构想恰恰也是设计一个通用拼音输入法的前提。那次讨论后一年多,我才最终通过完成「拼写运算」的设计和开发,验证了这个构想。

另一个构想是将专业速录键盘多键并击的工作原理应用到普通电脑键盘,从而创造一种高效、省力、富有节奏感的输入方式。

这项小发明叫做「宫保拼音/Combo Pinyin」,它将一组按键同时按下、由不同的按键组合产生不同的拼音音节。看似主键盘区的字符按键可以产生的组合远远多于拼音中的音节数,然而其中能按照指法用双手舒适地击出的组合数并不宽裕。开发Rime输入法之前的数年间,我花了不少心思推敲、改进并击按键的排布,使容易击发的按键组合对应常用的音节,并且尽量反映出语音内在的规律性,减少需要记忆的内容。

最终的设计很多地方都符合音韵学原理:声母按发音部位分组,排列在键盘左半区;g,k,h与j,q,x在与韵母的搭配上存在互补关系,因此这两组声母共存于一组按键;韵母的结构中,介音和韵尾变化多,而韵腹变化少,因此介音i,u,ü由最灵活的右手食指控制,便于与其他手指形成组合,韵腹的元音则安排在较不灵活的拇指和无名指;韵尾-i, -u交叉排列在与介音i,u相对的行,可以轻松地用食指、中指并击得到韵母iu, ui,这是考虑到普通话里相同的元音不会同时出现在介音和韵尾的位置上,也就是说不存在*iei, *uou这类组合。

问:在百度PC输入法开发团队中你的作用是什么?百度输入法有没有受到“小狼毫”输入法的影响?

我有幸在百度PC输入法立项的时候加入这个团队,接到的第一个任务是开发一个高质量的输入法词库,这包括利用百度强大的中文资源构建云输入词库、训练语言模型、根据PC输入法的需要进行裁剪等数据处理工作。后来我又担任输入法前端逻辑和新功能的开发。

百度拥有小团队无法比拟的资源,其工作方法也十分高效和民主,每个人的意见都得到充分表达和客观评估,而在团队的决策中发挥作用。起初我虽负责后端词库的研发,也一起参加前端输入法架构设计的讨论,分享了此前设计和开发Rime输入法的经验。最终开发团队一致决定采用与业界主流的做法炯然不同,而多见于开源输入法的前后端分离架构。Rime亦是得益于这种架构,保证了平台一致性,而且简化了设计,降低了开发难度。

问:相反,从百度输入法中,「Rime/中州韵」有没有找到可以借鉴的地方?

印象最深刻的是百度输入法专业的测试团队,他们为输入法设计了专门的测试工具和工作方法。测试通过后,还有一套严密的流程控制产品上线和跟踪用户反馈。吾侪的小制作嘛,因为可调教的选项众多,往往测试不充分,带着问题上线也是有的。后来我学到一招,为「小狼毫」增设了一个手动升级的通道,在全量推送新版本之前,先给有经验的用户试用「抢鲜版」,以期提前发现并及时修复可能存在的严重问题。

后来我还负责维护百度输入法的工程配置和构建脚本。编译、数字签名、打安装包乃至自动上线的一整套操作,不仅用自动化脚本实现,还支持许多参数用来满足不同安装渠道的定制需求。我想到,构建过程的自动化,对于开源软件更加重要了,因为开源合作者更难保证使用一致的开发环境。由此受到启发,我也改进了「小狼毫」在Windows平台的编译流程,用脚本签出代码、检测编译依赖、构建第三方库,取代原先需要手工操作的众多步骤。结果这个项目的参与度真的有所提高。可见开源不只是把源码发布出去,还需要各种努力让源码对别人更有用。

问:对于输入法产品,大型开发团队(如百度)和小型团队或个人在开发流程上有什么不同?相应造成各自哪些产品上的优缺点?

我不精于这方面的思考,只管猜猜看吧。

首先是产品的定位不同,造成最终的产品形态千差万别。

大团队分工明确,流程严谨,产品的每一个功能在开发之前都由产品人员做调研和设计,保证对结果有明确预期。从反面看,稳健意味着少有大的惊喜。小团队更加灵活,能快速适应变化,敢于做更多尝试。难的是风险控制,结果容易受偶然因素的影响……还有一个不利因素是资源有限。Rime的许多功能设计,都为此作出妥协,力求用低成本实现不俗的效果。

反正写开源软件和在大公司开发产品,除了码代码这项操作比较类似,两者真是大有不同呢。

更多人的中州韵

“我近来都在检讨,参与开源,哪些地方没做对。检讨完,也就有了未來的方向。”

问:作为一个开源项目,Rime的代码来源都有哪些?

Rime的代码包含一个C++的核心算法库、一个用来维护输入方案和词典文件的数据集、以及分别为Linux、Mac、Windows平台开发的输入法前端。

俺的主张是不重复造轮子,除非需要把轮子造得更圆。为了同时保证开发效率和软件的品质,Rime引用了大量的开源程序库。例如用yaml-cpp做YAML文件的解析、用darts-clone提供词典中的trie树结构、用kyotocabinet做为支持用户词典的数据库、用opencc做高质量的汉字繁简转换。为了把好的功能提供给更多用户,第三方库的代码能否跨平台,是一个重要的选择标准。Boost库提供的正则表达式、文件系统操作、进程间通信、线程处理等设施,解决了很多跨平台的麻烦。正因为在这些优秀开源软件的基础上开发,Rime才得以集中精力解决前人未曾解决的输入法难题。

我和Zou Xu同学一起完成了Rime算法库的大部分代码。这个输入法逐渐为人所知后,收到不少朋友提交的patch,或是修复程序漏洞,或是添加新的功能。Windows和Mac平台上,输入法介面的许多重要特性,如对候选字排版的控制以及配色主题支持,都靠网友们帮忙开发。Linux系统上的fcitx-rime绑定则是由Fcitx输入法团队独立完成的。

Rime收录的输入方案包含了一些开放版权的输入法如仓颉码、五笔86版、五笔画、粤拼等,还有一些网友创作的输入法如各种双拼方案、宫保拼音、吴语上海话、苏州话拼音、中古汉语拼音……Rime用家的创造力是令人赞叹的,我们只能从中选取有代表性的几例随输入法一起发布。

而词典数据部分更是汇集了许多人的劳动。Rime最初使用的词汇表,来源于Google开源的Android拼音词典,以及CC-CEDICT汉英词典。为了做到传统汉字和简化字并蓄,我又对照新酷音输入法(Chewing)及开放中文转换(opencc)的词库,对所有词汇的传统字形做了修正。输入法发布后,不断根据网友的反馈查漏补缺,更有瑾昀、雪斋、攴君等几位仁兄,持续地提交使用中发现的错字、错音,并整理添加了许多有用的词汇。多亏了诸君努力,虽然我们受限于资源只能维护一个小而精的词库,但其品质还是得到了用家认可。

问:在开发过程中,收到过哪些重要的反馈?其中有没有哪些影响了开发设计的思路?

有不少呢。

早期的版本曾用Python语言编码、用SQLite数据库构建词典,输入法的响应速度不佳。连城同学是把我招进百度的面试官,也是Rime最早的用户之一。他建议我尝试改用执行效率更高的C++。依计重写Rime的过程中,针对响应速度的优化成了我时刻关注的问题。譬如,根据输入法使用中的特点,有效候选结果常有成百上千个,而最初展现给用户的候选词只有不足十个,于是词典的结构做了针对性的设计,词典查询运用生成器模式惰性取词,这对控制响应时间和资源占用都有很大帮助。

「小狼毫」0.9发布后,Rime的开发和用户有了更多互动。我也更深地了解到众人对输入法的期待是如何地多样。有时我只当是牵就用户的提议而增加一个新特性,谁知一旦新版本发布出去,竟又生出许多意想之外的玩法。谁能想到输入码反查,这一发自上世纪的输入法技术,还能将输入法活用,当作查询古汉语音韵的工具书呢。不管你懂没懂啊,我是大开眼界了。

问:多数人认为「Rime/中州韵」输入法是一种小众输入法,这里的“小众”是一些具备什么特点的用户?

有几类人爱用。

一是学习和研究语言文字的朋友。他们在学习和工作中要用到传统汉字,相比依赖于简繁转换的输入法,Rime用字更准确,而且能够兼顾大陆、港台等地用字习惯的差异。这些朋友还根据自己的需要,创造了用来输入国际音标、外文字母、乃至藏文、彝文等少数民族语文的输入方案。集成到Rime之后,能够在行文中方便地切换输入语言。

一是致力于方言传承和保护的朋友。Rime可以帮助他们用较少的劳动,制作出自己家乡话的输入法,并且不难达到与《汉语拼音》输入法一致的效果。 一是输入法爱好者,输入法一向用自家酿造(DIY)的,甚么输入法平台,早都耍得有模样;终于又有了新的玩具,还能使用拼写运算,那是必须折腾一番的。

一是苦命的Linux用家,若不满意默认拼音输入法的效果,可选择的替代品真的不多。Rime处理好了一些其他开源输入法未曾关注的细节,例如候选词的编辑操作、学习调频策略等。恰如其分地营造出「好使」的错觉。

还有纯粹的geek技术高手,Rime提供高度可定制性正对胃口;对工具的要求就是轻巧快速,用开源再不必忧心隐私泄露。

最让我吃惊的是,刚发布代号为「鼠须管」的Mac版本时,受用家推崇的原因竟然是它「速度快、在Macbook电脑上不会卡顿」……始料未及的反馈,佛振无言以对。幸运的是后来的新款Macbook配备了高速SSD硬盘,帮助其他用户解决了输入法卡顿的困扰。

我勉强总结出一个共同点,Rime用家是懂输入法、善用工具的一批人。非此不可容忍它存在的种种不足。

问:很多人都很期待Rime的移动版本,在未来你有这方面的计划吗?

我近来都在检讨,参与开源,哪些地方没做对。检讨完,也就有了未來的方向。

举例来说,先时花了不少力气为Rime实现一个Windows前端,以求用有限的代价尽早推出「小狼毫」。但是Windows输入法与软件的兼容性问题是出名地多,至今还有很多疑难杂症未能解决。假使当初不急于造这个轮子,而是设法找到一个有前景的开源实现,并参与改进,那么就能凭借众多开源高手的智慧解决这些棘手的问题,我们为「小狼毫」所作的开发,也会对开源社区更有用些。

术业有专攻,受限于精力和技术广度,以一人之力决计无法在方方面面都做到足够好。开源协作的模式是每个开发者专注于自己擅长的领域,将成果作为可复用的代码开放给协作者。

今后我会更加专注于Rime的核心算法(已在做针对移动平台的优化),还要完善API、文档和辅助工具,使这个程序库对开发者更加友好:让关注功能的开发者能够理解代码并动手作出改进,让专业的移动平台开发者能够利用Rime的API轻松地构建各个移动平台的输入法。若能如此,Rime在开源之路上就获得了大成功。


更多精彩,加入图灵访谈微信!