资讯动态

DeepL + Lokalise:API自动化串联实现多语言翻译流程优化

发布时间:2026/10/2 11:07:07 来源:尧图企业网站定制
最近半年我一直在做产品的多语种上线感触挺深的一件事是很多人一听到“AI翻译”就以为把文本塞给DeepL拿到译文贴回去就完事了。等真到了多语言站点、移动端文案、营销邮件同时铺开的时候才发现字符串散落得到处都是翻译一致性没法保证人力投入大得惊人。后来我逐步搭了一套“DeepL翻译引擎 Lokalise管理平台 API自动化串联”的方案总算把这摊子理顺了。这篇文章就把我实际踩过的坑、验证过的流程、以及我认为最值得参考的集成方式完整写出来希望能给正在做海外市场或打算做多语种改造的团队一些可落地的参考。这篇文章适合几类人看一是刚接手国际化项目、需要把翻译流程从“Word文档 翻译人员”升级成规范化管线的开发或产品同学二是已经在用Lokalise但翻译质量不稳定、想接入DeepL MT服务提升效率的团队三是纯粹对API集成方案感兴趣、想知道两套SaaS服务怎么通过程序串起来的技术人员。下面内容按“选型背景→DeepL接入→Lokalise管理→集成架构→避坑经验”的顺序展开尽量把每个环节的必要性和操作细节都讲透。1. 为什么最后是DeepL Lokalise这套组合选型这件事我在决定之前其实对比过好几套方案。市面上做机器翻译的服务不少Google Translate、Microsoft Translator、Amazon Translate各有优势做本地化管理的工具有Phrase、POEditor、Transifex等等。但综合考虑到翻译质量、工程化友好度、以及团队协作效率我最后把DeepL和Lokalise放在了一起用。先说DeepL。单论翻译质量尤其在欧洲语言和东亚语言之间的转换上DeepL目前的自然度和上下文理解能力确实是我实测下来最稳的。它不是简单的逐句替换而是能根据语境调整用词和语序这对产品文案、营销素材这种对语气和风格要求比较高的场景非常关键。另外DeepL提供了相对简洁的API按字符计费接入成本不高文档结构清晰对开发者友好。我后面会详细讲API怎么调、需要注意哪些细节。再说Lokalise。本地化管理的核心痛点是“字符串散落、版本混乱、翻译和开发节奏脱节”。Lokalise把一套完善的key-value管理、多语言文件格式支持、翻译协作流程、以及API/CLI工具都整合在了一起。它支持直接从代码仓库同步语言文件也能通过API动态读写翻译内容这就能把“翻译流程”嵌进开发和发布流程里而不是等到上线前才临时抱佛脚。选择这套组合还有一个更实际的原因它们两者配合得挺好。Lokalise内置了Google Translate、DeepL等多个机器翻译提供商你可以在项目设置里直接绑定DeepL API让平台内的翻译任务批量调用DeepL。同时Lokalise的API也相当开放你可以自己在外部系统里写脚本调用DeepL翻译再把结果推回Lokalise。这种“平台内一键MT”和“平台外定制化集成”两条路都走得通灵活性对我来说非常重要。如果你只是一个人做个人项目的多语言文案直接在Lokalise里绑定DeepL就能满足需求不一定需要自己写API脚本。但如果你的业务需要批量处理、需要自定义翻译流程、需要把翻译能力嵌进自己的内容生产系统那就必须深入到API层去做定制集成。这也是为什么我在这篇文章里既讲了平台操作也讲了API集成——因为它们是两套互补的能力针对的就是不同阶段和不同复杂度的问题。2. DeepL API接入认证、语言与术语表的正确打开方式DeepL官方提供REST形式的API接口设计得很干净最常用的就是翻译接口。基本流程是注册DeepL API账号拿到auth_key然后按HTTP规范组织请求把源文本POST过去返回JSON格式的翻译结果。看起来极其简单但有几个地方如果一开始没搞对后面会让你浪费时间。2.1 认证方式和坑DeepL的API认证有两种方式。一种是老式的query参数传key也就是在URL里加auth_keyxxx另一种是更推荐的方式直接在Header里带上Authorization: DeepL-Auth-Key xxx。我强烈建议用Header方式因为key不会出现在URL里安全性更好也不容易在日志里泄漏。实际开发中常见的401错误绝大多数都是key配错了、key过期了、或者key是免费版但调用了付费接口。我遇到过一种很隐蔽的情况代码环境变量里key是对的但构建服务器上的环境变量没更新导致线上调用全是401本地却一切正常。这种问题排查起来很难受建议在代码里把key来源统一收口并且加一条启动时的连接自检逻辑一旦401就立刻报警而不是让错误散落到业务日志里。2.2 翻译接口核心参数DeepL翻译接口的请求格式大致是这样的POST https://api-free.deepl.com/v2/translate Content-Type: application/json Authorization: DeepL-Auth-Key xxxxxxxxxxxx请求体示例{ text: [ Hello, welcome to our product., This is a test. ], target_lang: JA, source_lang: EN, glossary_id: 可选参数 }这里有个非常容易搞混的点语言代码用的是BCP 47风格目标是日文就写JA目标是英式英语就写EN-GB中文简体是ZH-HANS中文繁体是ZH-HANT。不要把zh-CN或者zh-Hans这种带横线的写法直接塞进去DeepL的代码规范不太一样。source_lang其实可以省略DeepL会自动检测源语言但如果你知道源语言是什么显式传更稳既能省去检测耗时也能避免某些短文本被误判。text字段是数组这是很多人忽略的细节。你可以一次性传多条文本减少HTTP请求次数。但要注意的是单次请求的字符数是有上限的如果文本特别长建议分批处理。另外split_sentences这个参数也值得关注默认会按句子切分翻译这对于大段文本来说是好的但如果你传的是带标记的文本或URL可能会被拆坏。处理这类内容时建议设置splitting_tags或者调整切分逻辑。2.3 术语表的重要性DeepL有一个很值钱的功能术语表Glossary。它允许你定义一组“源语言词 → 目标语言词”的强制映射翻译时这些词会优先按你的映射走而不是被模型随意发挥。这个功能对产品文案尤其关键。假设你的产品里有一个专有功能叫“Teams”你不希望它在德文里被翻译成“Mannschaften”而是希望保留英文或使用你们内部规定的特殊译法那术语表就能派上大用场。创建术语表的API大致是POST /v2/glossaries { name: ProductTerms, source_lang: EN, target_lang: DE, entries: Teams\tTeams\nDashboard\tAdministration }注意entries格式是制表符分隔的条目列表每一行一组映射。创建之后你会得到一个glossary_id翻译请求时把这个ID传进去DeepL就会自动应用术语表。实际上如果翻译请求里指定了不兼容的术语表比如术语表的目标语言和请求的目标语言不一致API会直接返回400错误。所以设计术语表时我建议按“源语言-目标语言”成对创建比如EN-DE一份、EN-JA一份不要做一个全局的混合表。2.4 字符配额的评估DeepL API按字符计费免费版每月有100万字符的额度注具体额度以官方最新规则为准超过后要么等待额度刷新要么升级为Pro版按量付费。在接入之前最好先估算一下自己的文本规模和增长量避免上线到一半发现配额追不上进度。我实际用下来的感受是产品UI文案的体量一般不大几千条key全量翻译也就在几万到十几万字符之间真正吃字符的是帮助中心文章、营销邮件、通知模板这些内容。如果内容团队更新频繁一不小心一个月消耗几百万字符很正常。所以建议在架构上做一层“翻译缓存”或“增量翻译”只翻译新增或变更过的字符串不要每次都全量请求DeepL。3. Lokalise项目管理与自动化配置要点在Lokalise里核心概念包括“项目Project”“语言Language”“键Key”“翻译Translation”。你可以把它理解成一个结构化的翻译数据库项目里维护着一组key每个key对应一个内容标识比如“button.save”每个key下面挂着不同语言的翻译值。这套模型干净、直观而且几乎匹配所有类型的软件本地化需求。3.1 文件格式与项目参数选择创建项目时最关键的一个选择是“基础文件格式”。Lokalise支持Android的XML资源文件、iOS的strings文件、Web的JSON文件、以及PO、XLIFF等通用格式。千万别随便选一个因为这会直接影响后续文件导入导出的结构和效果。比如你做Web应用选了JSON格式那么项目内key的组织方式、占位符处理规则都会按照JSON的惯例来。还有一个容易忽略的地方是“占位符格式”。很多API返回的信息里带有变量比如Hello, {name}或者您有{n}条新消息。Lokalise允许你配置占位符的解析规则比如{name}、%s、{{name}}。正确的占位符配置不仅方便翻译人员理解也能在机器翻译时避免占位符被篡改。我在项目里每次新建项目都会专门检查这一项因为翻译内容里如果占位符格式不一致最后生成的译文会很灾难。3.2 在Lokalise中绑定DeepL provider进入项目设置找到“Machine Translation”或“Translation Providers”的配置区域选择DeepL作为provider填入你的DeepL API key。配置完成后项目内的翻译任务可以一键执行机器翻译。你可以选择让Lokalise把某个语言的所有未翻译key批量交给DeepL处理也可以让译者手动在单个key的编辑面板里点击“使用MT填充”。这里有两个实操建议批量MT翻译前先确认术语表已在DeepL侧建好并且心得确认不会把专有名词翻错。Lokalise调用DeepL时会使用你在DeepL账户下配置的术语表吗实际上取决于平台这一侧的实现不同版本的Lokalise支持程度不一样。我在实际验证中发现稳妥的做法是在Lokalise的MT provider配置里也检查是否有globally融入术语表的选项如果没有就用外部脚本预翻译再通过API把结果写回Lokalise。这样术语表策略完全由自己掌握。MT翻译完成后建议开启Lokalise的QA check功能。它能检查出占位符缺失、标签不匹配、译文长度超限等问题。机器翻译偶尔会出一些低级的格式错误这一道QA关卡能救回不少上线事故。3.3 翻译记忆库和一致的术语管理Lokalise内置了“翻译记忆库Translation Memory”功能简单说就是当你确认过某段翻译之后平台会记住这个源文本和目标文本的对应关系。后续其他项目或其他key出现相同或相似的源文本时系统会直接建议使用历史译法。这个功能的好处在于一致性尤其是同一句话在多个位置重复出现时你不会一会儿是“Cancel”一会儿又是“Abort”。我遇到过最头疼的情况就是两个开发各自添加了内容相同但key不同的字符串结果翻译人员翻译完后用户看到的是两种完全不一样的措辞。有了翻译记忆库和严格的项目管理规范这类问题基本能根治。术语管理方面Lokalise也提供了“术语表”机制类似DeepL的Glossary但更偏管理侧。你可以在里面维护品牌词、业务专用词的翻译规范并让翻译团队在Lokalise的编辑器里直接看到术语提示。如果你想把这个术语表同步给DeepL就得走API了这也是我下面要讲的集成方案的一部分。4. 用API把两条管线串起来我采用的集成架构如果你只是小规模使用在Lokalise界面里操作就够了。但如果你有多语言内容发布系统、需要对接内部CMS、或者希望有一个完全自动化的“翻译发布”流程那必须自己搭一条集成管线。我实际采用的架构大致是这样一个链路内容源代码文件或CMS导出→ 解析提取key和源文本 → 调用DeepL翻译带上术语表→ 把结果批量推送到Lokalise项目通过Lokalise API → 触发QA检查翻译人员审核 → 审核通过后通过Lokalise的CLI或API拉取各语言文件 → 构建发布。4.1 调用DeepL批量翻译的实现细节我写了一个简单的Python脚本用来批量翻译JSON文件并保留源格式。核心逻辑分三步读取文件遍历所有value对文本进行批量翻译把结果按原结构回写。import requests import json DEEPL_API_KEY your-auth-key DEEPL_API_URL https://api-free.deepl.com/v2/translate def translate_texts(texts, target_lang, source_langNone): headers { Authorization: fDeepL-Auth-Key {DEEPL_API_KEY}, Content-Type: application/json, } payload { text: texts, target_lang: target_lang, } if source_lang: payload[source_lang] source_lang resp requests.post(DEEPL_API_URL, headersheaders, jsonpayload) resp.raise_for_status() data resp.json() return [item[text] for item in data[translations]] def translate_json_file(input_path, output_path, target_lang): with open(input_path, r, encodingutf-8) as f: data json.load(f) # 收集所有需要翻译的value keys [] texts [] for k, v in data.items(): if isinstance(v, str) and v.strip(): keys.append(k) texts.append(v) # 分批翻译每批50条避免单次请求过大 translated {} BATCH_SIZE 50 for i in range(0, len(texts), BATCH_SIZE): batch_texts texts[i:iBATCH_SIZE] batch_keys keys[i:iBATCH_SIZE] results translate_texts(batch_texts, target_lang) for key, result in zip(batch_keys, results): translated[key] result # 回写 output_data {} for k, v in data.items(): if isinstance(v, str) and k in translated: output_data[k] translated[k] else: output_data[k] v with open(output_path, w, encodingutf-8) as f: json.dump(output_data, f, ensure_asciiFalse, indent2) if __name__ __main__: translate_json_file(en.json, de.json, DE)这个脚本的核心是批次控制。DeepL API一次传几十条短文本是没问题的但如果你一把梭哈传几千条不仅容易触达单次请求的字符限制还可能因为网络超时导致整批失败。分批的好处是失败时可以只重试当前批次不至于全盘重来。还有一个细节是翻译结果和key的对应关系是依靠数组顺序来对齐的所以请求和返回的顺序必须一致才能正确映射。DeepL返回的translations数组顺序和请求text数组顺序是对应的这个特性让批处理变得简单可靠。4.2 把结果推送到Lokalise的API方式Lokalise API的认证方式是X-Api-Token请求头不同的操作权限由这个token的级别决定。我常用的是“贡献者”级别的token只能读写某个项目的翻译内容比较安全。把翻译结果批量推送到某个key下的多个语言主要用的是更新翻译的接口PUT /projects/{project_id}/translations/{translation_id}单条更新有些慢好消息是Lokalise也支持批量更新接口。在推送批量结果之前我先会调用“列出所有key”和“列出所有翻译”的接口把Lokalise里的key_id、translation_id、以及语言代码拉下来建立本地索引。然后逐条比对哪些翻译需要更新再批量提交。这样做的好处是可以做到真正的“增量同步”只更新缺失的或变更过的内容避免覆盖掉翻译人员手动润色过的结果。import requests LOKALISE_API_TOKEN your-lokalise-token PROJECT_ID your-project-id headers { X-Api-Token: LOKALISE_API_TOKEN, Content-Type: application/json, } # 获取key列表 keys_resp requests.get( fhttps://api.lokalise.com/api2/projects/{PROJECT_ID}/keys, headersheaders, params{limit: 100, include_translations: 1} ) keys_resp.raise_for_status() keys_data keys_resp.json()[keys] # 构建索引key_name - translations[lang_iso] - translation_id key_translation_map {} for key in keys_data: key_name key[key_name][web] key_translation_map[key_name] {} for translation in key[translations]: lang_iso translation[language_iso] key_translation_map[key_name][lang_iso] { translation_id: translation[translation_id], value: translation[translation], is_untranslated: translation.get(is_untranslated, False), }这段代码做了一件很重要的事把Lokalise里现有Key和翻译的索引在本地建好。有了这个索引你就能判断哪些翻译值为空、哪些已经存在译文、哪些需要更新。实际项目里我一般会在此基础上加一层过滤逻辑只有当某个key在目标语言下为空时才推送MT结果已存在的译文明文保留。这能避免机器翻译覆盖人工翻译的内容。4.3 自动化触发和定时任务最初的集成版本是我手动跑脚本后来事情多了就改成了定时任务。我用的是简单的cron调度每天凌晨把变更过的源文本翻译并推送。更高级的玩法是接Webhook让CMS或代码仓库在文件更新时自动触发翻译管线但那需要前后端配合复杂度明显上升。我自己比较推荐“定时拉取新增增量翻译”的模式。具体做法是定时从代码仓库拉取最新的源语言文件解析出所有key和文本和Lokalise里的已有key做diff找出新增和变化的条目只翻译这部分增量内容推送回Lokalise记录日志供翻译人员后续检查和修正。这种增量模式不仅省DeepL的配额也大幅减少了重复劳动。多语言项目只要跑起来最怕的就是每天全量重翻一遍既浪费钱又容易把人工优化过的译文覆盖掉。5. 实际踩过的坑与排查链路完整的方案讲完了下面专门分享一下我在落地过程中遇到的几个典型问题。这些问题单独看都不复杂但混在一起很考验排查耐心。以一个当时线上环境的HTTP 401报错为例子完整梳理一下我的排查路径。5.1 “401 Unauthorized: Incorrect API Key”的排查链条当时的现象是集成脚本在本地跑得一切正常但部署到测试服务器上就频频报401错误信息就是unexpected status 401 unauthorized: incorrect api key provided。第一反应是环境变量没设置对于是我检查了服务器的.env文件发现配置内容和本地几乎一样但依然报错。于是我打印了服务器上实际读到的key结果发现key末尾多了一个空格。看起来是小问题但极难察觉。原因是部署时正好有人在服务器上手动编辑过环境变量文件不少编辑器会在保存时保留行尾空格导致key变成了一个带不可见字符的错误串。从此我给自己定了一条规矩所有API key统一放入密钥管理服务不再依赖人工编辑文本文件并且在程序启动时对key做一次trim处理。这个案例的启示是401报错虽然最常见的原因是key错了但为什么错了、错在哪一个环节排查起来却不一定直接。你可以从这几个方向依次检查key是否正确从配置中心读取是否存在环境差异key是否带有多余空格、换行符等不可见字符key是否绑定错误环境免费版和Pro版的API endpoint不一样账号是否欠费或冻结如果使用代理或网关是否被中间层篡改了认证头。5.2 上下文不足导致的误译DeepL的API每次翻译是“无上下文”的也就是说它看到的是孤立的字符串。这个限制在UI文案里体现得尤其明显。比如一个英文字符串“Start”单独翻译成德文可能是“Start”或“Beginn”但如果它是一个按钮表示“开始操作”有的语言里可能用“Loslegen”更贴切。没有上下文机器无法判断。我采用的优化手段是“前缀注入法”在批量翻译时针对不同类型的文本自动加一个上下文提示前缀翻译完成后去掉前缀。举个例子对按钮文案加上context: button\nStart翻译后再剥离。这个方法需要写一些额外的脚本处理但实测下来能提升不少术语准确度。如果你的字符串带有key名另一个做法是把key名一起喂给DeepL作为上下文比如button.save Save这样模型能通过key名推断语义场景结果往往比单纯翻译value值更可靠。5.3 语言代码规范不一致DeepL使用BCP-47风格语言代码Lokalise使用自己的语言ISO代码体系这两者不是一一对应的。最典型的就是中文DeepL的简体中文是ZH-HANSLokalise的简体中文是zh_CN英文下面的变化更多DeepL区分EN-GB和EN-US而Lokalise默认可能只有en。如果你在代码里直接写死了语言代码映射表随着支持的语言越来越多容易出乱子。我最后单独维护了一张映射表把DeepL、Lokalise、以及前端locale代码统一对应起来每次新增语言时先检查这张表再动代码。这看起来是个很小的设计但在实际项目中省了我好几次让人头皮发麻的排查。LANG_CODE_MAP { zh_CN: {deepl: ZH-HANS, locale: zh-CN}, zh_TW: {deepl: ZH-HANT, locale: zh-TW}, de_DE: {deepl: DE, locale: de}, en_GB: {deepl: EN-GB, locale: en-GB}, en_US: {deepl: EN-US, locale: en}, }5.4 长文本截断与格式错乱DeepL对单次请求的文本长度有限制如果你传的是一篇几千字的帮助中心文章很容易被截断或者返回时格式标签被破坏。我最初处理大段HTML内容时直接全文塞给DeepL结果翻译后的HTML标签错位页面直接样式崩坏。后来我换了一种方式先把HTML按标签拆分成片段只对文本节点做翻译标签原样保留翻译完再按原结构拼装回去。这个过程要额外写HTML解析逻辑成本不低但效果立竿见影生产环境的稳定性也明显提升。另一个和格式有关的问题是Markdown文档。Markdown里的链接语法[text](url)中的url如果被翻译链接就废了。我在翻译Markdown内容时会先把链接地址、行内代码块替换成占位符比如%%LINK_1%%翻译完成后再还原。这个方法非常笨但非常有效目前我的所有内容翻译都沿用了这个策略。6. 集成方案的效果评估与未来扩展思路从目前产线运行的情况来看这套方案带来的收益非常明确人工翻译工作量下降了大概70%剩余的30%主要集中在润色和品牌语言把控上发版周期从“翻译等两三天”缩短到“当天提交当天拿结果”术语一致性问题也因为术语表和翻译记忆库的引入基本得到解决。最直接的变化是产品和运营团队的工作方式变了。以前大家最怕的就是“上线前发现英文文案改了”因为这意味着一堆语言的翻译都要跟着动而且动完还要重新走校验。现在文案改完触发一下翻译管线几分钟之内各语言文件就更新完毕运营再也不用抱着Excel表格一行行核对。连带着我们后续的新功能发布从“单英语先上”变成了“同步多语种”对海外用户的反馈速度也快了一个量级。当然这套方案还有不少可以继续优化的地方。我目前正在做的几个方向是一是把DeepL的术语表同步做得更自动化。现在术语表的更新依旧需要半人工操作在DeepL后台维护一遍、在Lokalise里还要维护一遍两边不一致的时候容易出错。理想状态是有一个统一术语库以它为准自动同步到DeepL和Lokalise。我已经在调研Lokalise API对术语表管理的支持程度希望近期能打通。二是引入人工复审的轻量流程。MT翻译虽然质量不错但真正要面对C端用户还是有些句子需要人工润色。我计划在Lokalise里设置“MT预翻译→TMS QA检查→还需人工确认的策略”把未审核的翻译标记成“需要复核”直接推送给翻译成员。这样既保留MT的高效又不至于把最终质量完全交给模型。三是探索更多AI能力的接入。DeepL只是解决了文本翻译的问题实际做本地化时还涉及图片文案OCR、配音字幕、以及某些地区性表达习惯的适配。如果你正在做视频内容出海可能还需要字幕的翻译与时间轴校对这部分和纯文本翻译管线是完全不同的一条链路。我在短视频项目上的计划是后续单独搭一套“语音识别 DeepL批量翻译 字幕平台管理”的流程等跑通了再写一篇分享。就写到这吧。这篇本质上是我半年多实践的一次系统复盘最核心的体会是AI翻译和本地化工具的能力边界不在“能不能翻”而在“你能不能把流程和组织方式设计得让它最大化发挥作用”。像我这种独立开发者虽然看不了几千个项目的规模但用完这套整合方案之后的效率提升也是实打实的。如果你也准备做多语种我的建议很简单小规模先直接用Lokalise配DeepL跑出一两条语言线之后再做API自动化别一开始就搞复杂架构等产量和复杂度上来以后再逐步把术语表、增量翻译、QA校验和自动化管线一项项补进去。这样不会步子迈太大扯到蛋每一步的收益也都看得见摸得着团队也好接受。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑