一个会说几十种语言的网站,无需翻译
机器自动翻译自意大利语 · 查看原文
我们如何构建驱动这些页面的翻译系统:按需使用人工智能,始终使用缓存,零感知等待。
传统国际化的问题
多年来,网站的国际化一直是工作流程中的一小段奥德赛:.po文件、人工翻译、遗漏的密钥、由于“仍然缺少德语”而延迟部署。添加一种语言需要时间和金钱;为任何小型公司添加十种语言是不可想象的。
随着最新一代的LLM,机器翻译的质量已经达到了一个足以满足企业网站(而非文学作品)的地步。问题不再是“我们可以自动翻译吗”,而是“我们如何将其集成而不会破坏用户体验”。
架构,简而言之
该网站以意大利语静态提供。当用户选择另一种语言时,一个小型引擎会处理三个MongoDB集合:
i18n_base:源语言文本,采用所选语言(目前为意大利语),每个文本都带有其语言声明、描述其在网站上出现的位置和原因(对于翻译质量至关重要)、语气和字符限制。此描述成为对LLM的提示的一部分,以便LLM知道它是在翻译按钮还是段落。i18n_human:人工润色的翻译,当对于某些页面,我们希望获得编辑质量而非LLM输出时使用。它们优先于自动缓存,并且当源文本更改时会自动“标记”出来。i18n_cache:已生成的翻译,按(字段, 语言)索引。每个条目保留生成时基础文本的timestamp。articoli_i18n:与此文章等较长内容应用相同的逻辑。
首次访问新语言时,系统仅向LLM请求确实缺失的字段,将响应保存到缓存中并返回给浏览器。后续访问相同语言时,速度会立即提升,无需再进行AI调用。
有效的失效机制
缓存是一种有序的谎言:它说“我的真相是这个”,直到有人证明它是错误的。这里的反驳机制很简单:每条缓存的翻译都会存储生成它的基础文本的timestamp。当您修改意大利语文本并更新其updated_at时,该字段在所有语言中的所有翻译都会自动变为陈旧,并在需要时重新生成。无需手动级联,无需清空缓存。
不愿等待的用户
最有趣的部分不是翻译——而是如何显示它。在切换语言时,浏览器会看到一个意大利语页面,每个需要更新的文本块旁边都有一个小小的加载指示器。诱惑是进行一次性调用来一次性翻译所有内容:简单、干净,但会迫使用户等待 LLM 完成所有操作才能看到任何变化。
我们选择了相反的方向。文本按部分(导航栏、正文、页脚)分组,并分成每批包含三个字段的微批次。调用以顺序启动:首先是导航栏中的少数字段,它们会在几秒钟内出现——用户会看到事情正在发生并开始阅读。在阅读时,正文的第一部分到达,然后是第二部分,最后是页脚。
夜间工作
缓存只有一个真正的敌人:第一次访问。第一位德国用户为所有未来的翻译付出代价,而他的体验是留在脑海中的。为了消除(或几乎消除)这个问题,一个后台任务每分钟醒来一次,从尚未完成的语言中选择最期望的语言,获取未翻译的文本,并将其传递给 LLM。下一分钟,下一个。几天之内,最常用的语言就已经准备就绪。
夜间任务还做第二件事:自动审查质量可疑的翻译,并使用不同的 AI 模型重新尝试。当语言之间的对齐很重要时,平庸的翻译不会保持平庸。
如果你是当天第一位德国用户,并且在系统仍在完成缓存时到达,仍然有渐进式加载让你忙碌。如果你是第二位,你甚至不会注意到。
收获
一个无需翻译人员、无需管理文件、无需部署即可添加语言的多语言网站。用户输入一个代码——ja、ca、eu,他们想要的任何代码——页面就会被翻译。第二次翻译是即时的。到第三次,我们很可能已经提前完成了翻译,在正确的时间由一个永不休眠的任务完成。
如果你正在用德语、西班牙语或韩语阅读这一页,它从未被翻译人员撰写过。它只被一个LLM翻译过一次,此后一直从缓存中提供。唯一手动撰写的内容是你现在正在阅读的意大利语版本。
有兴趣将这种架构带到你的网站上吗?让我们聊聊。
联系我们
有评论吗?请写下
此消息仅发送给您。 如果您的评论有趣,我们可能会在文章末尾发布它,但仅在经过审核后。
您在输入时,浏览器正在解决一个简单的计算问题:这是我们防止自动垃圾邮件的方式,无需使用第三方服务或要求您识别图像验证码。无需任何操作,您的数据不会离开本网站。