DeepL、火山、有道、百度翻译API密钥申请与首次调用全流程 上周把一个出海内容站的多语言流水线从人工复制粘贴改成 API 自动跑四家翻译引擎的密钥一口气全申请了下来。DeepL、火山翻译、有道、百度前后折腾了整整两天——不是因为流程有多复杂而是每家控制台的产品逻辑完全不同有的把密钥藏在三级菜单里有的要先建子账号再授权有的签名算法不照着文档老老实实推一遍根本调不通。这篇就把四家翻译引擎 API 密钥从注册、认证、建应用、拿密钥到第一次调用成功的完整路径写清楚包括按钮在哪个位置、表单哪几项不能填错、签名怎么算、第一次请求应该看到什么样的返回。适合三类人看刚接手国际化项目的后端同学、需要批量处理语料的内容运营、以及自己写小工具做译文对照的独立开发者。哪怕你只打算用其中一家把四家的申请逻辑对照着看一遍也能省下不少试错时间因为它们的坑位高度重合——实名认证、权限授权、配额计费三座山每家都有一座。说明一下截图这件事控制台改版频率很高静态截图过两个月就失效了。所以我改用页面路径 字段说明 预期结果的方式记录你照着菜单层级点下去比对着老图找按钮更靠谱。关键页面我会把字段顺序写出来对照着填不会错。1. 先想清楚为什么是 API 而不是网页版1.1 网页版和 API 的分水岭到底在哪很多人第一反应是网页版免费又不用申请为什么要折腾密钥。这个问题我一开始也纠结过直到把一条 12 万字的商品描述语料丢进网页版批量翻译才发现问题不在能不能翻而在翻完之后没法用。网页版输出的是给人看的文本API 输出的是结构化 JSON前者你要再写正则去清洗、去重、对齐原文段落后者直接就是translations[0].text字段稳定、顺序稳定、编码稳定。第二个差别在术语一致性。网页版每次翻译都是独立上下文同一个产品名在 200 条文案里能翻出 5 种写法API 侧可以带术语表DeepL 的 glossary、有道和百度的自定义术语库把品牌词、型号、专有名词锁死。这个能力对电商详情页、SaaS 产品文档这种重复词多、错一次全错的场景是刚需靠人工校对补不回来。第三个差别是可控性。API 能拿到响应时间、字符消耗量、错误码出问题能定位到具体哪一条网页版翻错了你只能猜。做流水线的人都知道不可观测的系统等于不可维护的系统这一条比省钱重要得多。1.2 四家引擎的定位差异决定了你该申请几个我建议至少申请两家理由后面第 7 章会展开讲兜底降级但先要知道它们的性格差异。DeepL 在欧语互译上是目前公认的第一梯队句子重组自然、语感好长句处理明显强于其他家代价是中文相关的方向优势没那么突出而且免费额度按字符算量大了肉疼。火山翻译背靠大模型能力中英互译和网络新词、口语化表达的覆盖比较好适合内容社区、短视频字幕这类语料。有道在中英词典义项、成语俗语上有长期积累做教育类、词典类产品的中英方向很稳。百度翻译的优势是接入门槛最低、文档最全、免费额度对个人开发者最友好做原型验证基本零成本。真实项目里我的组合是主引擎用 DeepL 处理欧洲语种中文相关语种用火山或有道百度作为兜底和压测对象。四家全申请不算浪费因为密钥本身不收费只有调用才计费多备一把钥匙在抽屉里线上出问题的时候能救命。2. 动手前的通用准备这几步四家都躲不掉2.1 账号体系与实名认证最容易卡住的第一关四家平台没有一个能跳过实名。个人开发者一般要身份证实名企业要营业执照火山和百度还会区分个人认证和企业认证两种身份能开通的服务、能拿到的配额不一样。这里有个特别容易踩的点个人认证的账号后面想升级成企业认证往往需要重新走一遍流程甚至部分服务要重新开通。如果你是在公司项目里申请一开始就用企业身份注册别图省事用个人号。第二关是手机号和邮箱。四家都要求手机验证DeepL 还要邮箱验证加支付方式验证。我遇到过的最莫名其妙的问题是邮箱被判定为一次性邮箱域名而拒绝注册换成常用邮箱立刻就过了所以别用临时邮箱图快。第三关是账号归属。密钥是挂在账号下的账号是挂在人身上的。公司项目里密钥申请人离职、账号密码找不回来、绑定的手机号停用这三种情况我都见过最后都是重新申请、重新联调、重新上线。落地的做法是用企业邮箱注册、密码进公司密码库、绑定一个公共手机号、把密钥录入配置中心而不是写死在代码里。2.2 免费额度怎么算什么时候会开始扣钱这是四家差异最大的地方也是新人最容易算错的地方。引擎计费单位免费额度大致情况超限后的典型表现DeepL字符按源文本字符数Free 版每月固定额度需验证支付方式返回 456请求被拒火山翻译字符新开通有一定体验额度返回配额类错误码有道字符新账号有体验金按调用扣减返回错误码提示余额不足百度字符标准版每月有免费字符数QPS 限制严格返回 54003 等频率/额度错误具体数字我不写死因为各家调整过不止一次你注册完在费用中心或用量统计页面能直接看到当月剩余。但有一个概念必须理解清楚绝大多数平台按源文本字符数计费不是按译文长度也不是按词数。这意味着你翻中文到英文按中文字符数扣翻英文到中文按英文字符数扣。中文一个字算一个字符英文一个字母算一个字符所以同样一段内容中文原文消耗的额度通常只有英文原文的三分之一左右。算成本的实操方法是拿一批真实语料跑一遍记下总字符数除以当月实际业务量倍数再对照单价。我自己踩过的坑是拿测试用的小样本估算结果线上真实语料里全是长 SKU 编码、URL、HTML 标签这些也会被算进字符数——翻译前必须做清洗把标签、链接、纯数字编号剔掉这一步能省下来的额度往往超过 20%。3. DeepL从注册到拿到 Auth Key 的完整路径3.1 Free 和 Pro 先分清别注册错了产品线DeepL 有两条产品线容易混一条是给个人用的网页版订阅按月付费、无限翻译、给人用另一条是给程序用的 API按字符计费、给机器用。你要申请的是后者入口在官网导航里的API或Developer区域别点进Pro 订阅里去了那两个是完全独立的账号体系网页版订阅不会给你 API 密钥。API 又分 Free 和 Pro 两档。Free 每月有固定免费字符额度缺点是端点地址不一样、请求要走api-free.deepl.com而且注册时仍然需要填写支付方式信息做身份验证只要不超额就不会扣费但这一步不做完拿不到密钥。Pro 用独立端点api.deepl.com按量后付费适合流量稳定的生产环境。我的建议很直接先申请 Free 做联调和灰度等日调用量稳定超过免费额度再升级 Pro。升级不用重新建应用密钥可以沿用只是端点要改。这点设计得比较友好但很多人不知道白折腾一遍。3.2 注册到拿到 Auth Key页面上到底要点哪几下流程拆开是五步我按点击顺序写进 API 页面选 Free 或 Pro 档位点注册。填邮箱、密码收验证邮件点确认链接。填账号信息姓名、公司名个人可以填自己名字、使用场景有个下拉框问你打算用 API 做什么随便选一个贴近的比如网站本地化。填写支付方式Free 档也要填用于身份验证。进入账号后台左侧菜单找Account或账户页往下滚能看到 Authentication Key for DeepL API 一栏那串字符就是密钥。密钥的形态要认清楚Free 档的密钥结尾带:fx后缀Pro 档没有。这个后缀不是格式装饰它是端点判断的依据之一——很多开源库会根据密钥是否以:fx结尾自动选择api-free还是api端点。我第一次用的时候把后缀截掉了结果一直 403排查了半小时才发现是自己手贱。注意这个密钥在页面上是明文可见的也就是说任何能登录你账号的人都能看到。所以账号安全等级要按生产数据库密码来对待别用弱密码别和别的平台共用密码。3.3 十分钟验证第一次请求长什么样拿到密钥别急着写业务代码先用一段最小脚本确认通。Python 环境一行pip install requests就够import requests AUTH_KEY 你的密钥注意 Free 档结尾的 :fx 不要丢 ENDPOINT https://api-free.deepl.com/v2/translate # Pro 档改成 api.deepl.com resp requests.post( ENDPOINT, headers{Authorization: fDeepL-Auth-Key {AUTH_KEY}}, data{ text: 这个季度的重点是提升复购率, target_lang: EN, # source_lang 不填则自动检测中英混排时建议显式指定 }, timeout10, ) print(resp.status_code) print(resp.json())几个细节值得说清楚。第一认证信息走的是请求头Authorization: DeepL-Auth-Key key不是 query 参数这是个加分设计密钥不会出现在访问日志的 URL 里。第二target_lang必须大写中文是ZH注意不是ZH-CNDeepL 的中文只认ZH写成ZH-CN会被告知目标语言不支持。第三text参数可以传多个做批量翻译时一次传多条能显著降低往返开销但要注意单次请求的字符总量和条数都有上限具体上限以文档为准超了会被直接拒绝。成功时的返回是一个 JSON核心结构是translations数组每个元素里有detected_source_language和text。批量传入时数组顺序和传入顺序一致直接按下标对应即可。看到200加这个结构说明密钥可用可以往下走了。3.4 DeepL 特有的两个坑第一个是456 错误。这个错误码在别的平台见不到含义是额度用尽。它和 429请求过于频繁不一样429 等一会儿能恢复456 要等下个月额度刷新或者充值等不来。所以生产环境里 456 必须当作切换引擎的触发条件而不是重试条件。第二个是 URL 参数和表单参数的混用。DeepL 支持把参数放在 query string 里也支持放在 POST 表单里但两者混用的时候以表单为准容易调试时产生误导。我建议统一走 POST 表单别图省事用 GET 拼 query遇到长文本会直接超长。4. 火山翻译先搞定权限模型密钥才有意义4.1 开通服务和密钥其实是两件事火山翻译是整个流程里层级最深的一家因为它的设计是云平台通用权限模型翻译只是其中一个服务。这意味着你不是申请一个翻译密钥而是拿到一个能调用翻译服务的身份。搞混这两件事的人往往会卡在密钥有了但调用报无权限上。正确顺序是注册账号 → 实名认证 → 在控制台搜索机器翻译进入服务页 → 点击开通服务 → 创建访问密钥Access Key / Secret Key→ 给这个密钥所属的身份授予翻译服务权限。少任何一步调用都会失败而且失败信息不一定告诉你缺哪一步。4.2 AK/SK 的创建位置与最小权限原则访问密钥在控制台的密钥管理或访问控制区域创建。创建后会给你两串东西Access Key ID相当于用户名明文和 Secret Key相当于密码只在创建时显示一次。Secret Key 丢了只能重新创建一对没法找回。所以创建完立刻存进配置中心或者密钥库别放在聊天记录里。关于权限这里有个我认为必须坚持的做法不要用主账号的密钥建一个子身份子账号或角色只授予翻译相关的只读调用权限。原因很实际——火山翻译的请求要做签名签名过程需要明文 SK 参与计算如果你把 SK 写进了代码仓库或者容器环境变量泄露风险会跟着整个云账号走。主账号密钥一旦泄露被调用的可就不只是翻译服务了。子身份 最小权限泄露了最多损失一点翻译额度损失面完全不是一个量级。4.3 签名调用为什么它比另外三家麻烦另外三家都是密钥直接放请求里火山是要每次请求现算一个签名。流程大致是把请求方法、路径、query 参数、请求体哈希、时间戳按规则拼成一个规范字符串用 Secret Key 做 HMAC-SHA256 计算再拼回请求头。这里面任何一个环节出错——时间戳偏差太大、参数排序不对、少了一个必填头、请求体哈希对不上——都会得到一个笼统的签名错误。因为是纯机械计算手写很容易错我的建议是直接用官方 SDK别自己撸签名。SDK 你可以按 Python 装volcengine-python-sdk这个包里面有翻译服务的模块初始化时把 AK/SK 和地域传进去然后调用对应的翻译请求对象就行。包名、模块路径、请求类名这几年有过调整装完看一眼仓库 README 的示例代码是最稳的做法别照抄网上老文章的类名。如果你坚持要自己实现比如用的是 SDK 不支持的语言那核心要盯住三点签名用的时间戳必须是 UTC 且和服务器时间偏差很小本机时间不准是最常见的翻车原因测试机时钟漂移几分钟就全挂参与签名的路径和实际请求路径必须完全一致多一个斜杠都算错请求体要先算 SHA256 哈希再参与签名而不是拿原始字符串拼。这三点我全踩过每一个都花了半小时以上。4.4 验证阶段怎么判断是签名问题还是权限问题这两类错误的提示经常长得像区分方法很土但有效把请求里的业务参数清空故意传一个空的文本内容。如果返回的是参数错误说明签名过了、权限也过了问题在业务参数如果仍然返回签名错误那是签名本身的问题如果返回的是权限类错误那签名是对的去查授权策略。我自己最常用的一招是找官方文档里的在线调试或API Explorer页面那里能直接填参数发请求成功后它会给你生成一份带签名的完整请求示例。拿你的本地代码和它逐字段比对差异一眼就能看出来比盲猜快十倍。5. 有道智云应用 ID 和密钥是一对不能拆开用5.1 创建应用时那几项为什么不能随便勾有道的入口是有道智云控制台流程是注册 → 实名认证 → 创建应用 → 勾选要用的服务文本翻译→ 拿到应用 ID 和应用密钥。看起来简单但有一个非常关键的设计它的计费和权限是绑定在应用上的不是绑定在账号上的。这意味着你在同一个账号下可以建多个应用分别对应不同的业务线用量、账单、密钥全部隔离。这个设计对多项目团队特别友好——A 项目超了额度不会把 B 项目搞挂。反过来说如果你图省事只建一个应用给所有项目共用那一旦某个项目写了个死循环把额度刷光全线停摆。创建应用时要填应用名称、选择接入方式API、选择服务类型。服务类型那一项有的版本会问你文本翻译还是语音翻译选错的话拿到的密钥调用文本接口会直接报服务未开通。应用名称建议带项目前缀和环境标识比如内容站-生产后面排查用量的时候会感谢自己。5.2 v3 签名的推导过程我按步骤拆给你有道的鉴权是四家里规则最手工的每个请求都要带一个签名字段签名由应用ID 截断后的原文 随机盐 时间戳 应用密钥拼接后做 SHA256。这里的截断是最容易被忽略的地方规则是原文长度不超过 20 个字符就原样使用超过 20 个字符取前 10 个字符 原文总长度 后 10 个字符。我一开始觉得这个设计很怪后来想明白了它是为了在保证签名强度的同时避免超长文本拖慢哈希计算而且用长度夹在中间可以防止前后缀相同的不同文本产生碰撞。理解了这个意图就不会记错顺序。import hashlib, time, uuid, requests APP_KEY 你的应用ID APP_SECRET 你的应用密钥 def truncate(q: str) - str: size len(q) if size 20: return q return q[:10] str(size) q[-10:] def make_sign(q: str, salt: str, curtime: str) - str: raw APP_KEY truncate(q) salt curtime APP_SECRET return hashlib.sha256(raw.encode(utf-8)).hexdigest() q 我们的新品在下个月上线 salt str(uuid.uuid4()) curtime str(int(time.time())) sign make_sign(q, salt, curtime) resp requests.post( https://openapi.youdao.com/api, data{ q: q, from: zh-CHS, to: en, appKey: APP_KEY, salt: salt, sign: sign, signType: v3, curtime: curtime, }, timeout10, ) print(resp.json())有几个参数必须注意。signType一定传v3不传默认走老版本签名规则算出来必然对不上。salt官方建议用 UUID作用是一次性防重放别用固定值。curtime是秒级 Unix 时间戳和服务器时间差太大会被拒绝。语言代码用的是zh-CHS简体中文这种带变体的写法和另外三家都不一样这个坑我第一次踩的时候试了ZH、zh、zh-CN全都不对。5.3 返回结构里哪些字段值得看有道的返回里除了translation数组还有几个容易被忽略但对排查有用的字段errorCode是字符串类型的0表示成功不是数字 0。这个细节让很多人写出了if resp[errorCode] 0然后永远进不去成功分支的代码。另外还有query回显原文可以用来校验编码是否正常、l检测到的语言方向形如zh2en、basic词典义项中英方向会返回音标、释义、词性做词典类产品时是白送的能力、web网络释义对网络新词特别有用。做内容站的时候我就靠web字段去校验品牌词翻译得对不对比人眼扫一遍快得多。6. 百度翻译开放平台门槛最低但免费版的限制要认清6.1 开发者认证与应用创建的实际路径百度翻译开放平台的流程是四家里最顺的注册百度账号 → 进入翻译开放平台 → 申请成为开发者要选个人还是企业做实名→ 创建应用 → 选择通用文本翻译服务 → 拿到 APP ID 和密钥。创建应用时的表单项不多但接口服务那一项要选对。默认可能只勾了通用文本翻译如果你后面想用语种识别、词典、语音合成需要在这里一并勾上应用创建后能不能追加服务要看平台当时的规则保险起见一次勾全。应用名称填英文或者拼音更稳某些版本对中文名称的兼容性不好这个不确定是不是普遍现象但我碰到过一次保存失败改成英文就过了。免费版和付费版的差别主要在两处每月免费字符数和QPS每秒请求数。标准版的 QPS 限制很严基本上只能做串行调用或者极低并发的场景做批量任务时会明显卡住。如果你要做的是一万条文案批量翻译标准版的 QPS 会让你跑到怀疑人生这时候要么升高级版要么在客户端加队列和限速。6.2 两种鉴权方式怎么选我建议新手先用简单的百度提供了两种鉴权路径。第一种是直接签名把 APP ID、原文、随机数、密钥拼起来做一次 MD5作为sign参数带上每次请求现算。第二种是先换令牌用 APP ID 和密钥调一个专门的接口换access_token有效期一个月后续请求带上这个令牌就行。新手建议用第一种代码短调试直观出错信息也更容易理解。第二种的好处是令牌可以缓存省掉每次的哈希计算而且令牌可以下发给前端虽然不推荐适合有大量短请求的场景。但令牌有有效期需要处理续期和并发续期的问题多出来的复杂度对新手不划算。import hashlib, random, requests APPID 你的APPID SECRET 你的密钥 q 这个功能下周上线 salt str(random.randint(32768, 65536)) sign hashlib.md5((APPID q salt SECRET).encode(utf-8)).hexdigest() resp requests.post( https://fanyi-api.baidu.com/api/trans/vip/translate, data{ q: q, from: zh, # auto 表示自动检测 to: en, appid: APPID, salt: salt, sign: sign, }, timeout10, ) print(resp.json())签名串的顺序是APPID q salt 密钥顺序错了必然失败而且没有任何提示告诉你顺序错了只会返回签名错误。这个坑我在另外几个平台的签名上也见过规律是顺序以文档为准别凭印象。6.3 返回结构和常见的编码坑成功返回里核心字段是trans_result数组每项有src和dst。有一个特别要注意的地方百度返回的译文里换行符是\n转义后的形式尤其是你传入多行文本时结果里的换行会以字面量\n出现直接打印看着没问题写进文件就变成了一行。处理方式是在落库或写文件前做一次dst.replace(\\n, \n)或者干脆一条文本一次请求不要指望批量里含换行还能规整对齐。另一个坑是from参数。填auto让平台自动检测很方便但自动检测有误差中英混排的技术文档经常被误判成英文导致中文部分被原样返回。生产环境里我建议业务侧明确知道语言的就显式指定只有用户自由输入的场景才用auto。7. 四家横向对比与多引擎兜底的真实做法7.1 关键维度对比选型时对着这张表看维度DeepL火山翻译有道百度鉴权方式请求头带密钥AK/SK 每次签名每次请求现算签名现算签名或换令牌接入难度最低最高中等低密钥形态单串Free 带:fx一对ID Secret一对应用 ID 密钥一对APPID 密钥语种代码风格全大写ZH/EN按服务定义带变体zh-CHS小写zh/en权限模型账号级云平台 IAM需授权应用级隔离应用级强项欧语长句、语感中英、口语与新词中英词典义项文档全、门槛低典型弱点免费额度紧张签名调试成本高语种代码易写错免费版 QPS 紧这张表我建议你截图存一下因为语种代码那一行是跨平台迁移时最容易翻车的地方——四家对同一门语言的写法能给你四种答案代码里共用一个常量池、按引擎做一层映射比到处硬编码强得多。7.2 多引擎降级不要把所有请求押在一家身上单引擎方案在 demo 阶段没问题上线之后就是定时炸弹。我遇到过的情况某家引擎在高峰期响应时间从 200ms 涨到 4s前端超时重试把请求量放大三倍然后触发限流整条链路雪崩。如果有第二家兜底最坏情况是译文质量略降而不是页面挂掉。降级的实现思路不复杂封装一个统一的翻译接口内部维护引擎优先级列表主引擎失败超时、限流、额度告罄就按顺序切到下一个同时打点记录切换次数。切换的触发条件要明确我一般设这几条响应超过 3 秒、HTTP 5xx、额度类错误码、连续失败 N 次。注意额度类错误比如 DeepL 的 456要直接标记该引擎当日不可用避免每次请求都先去撞一次墙。还有一个容易被忽略的设计缓存。翻译结果按引擎 源语言 目标语言 原文哈希做键缓存起来重复内容直接命中。真实业务里重复率比想象中高得多——商品名、导航菜单、按钮文案、免责声明这些东西翻一次就够了。我负责的一个站上线三个月后统计缓存命中率 38%等于白捡了近四成的额度。8. 常见问题排查实录与密钥管理心得8.1 报错速查表先看这张表再翻文档现象大概率原因处理方式401 / 403 认证失败密钥截断、多了空格、Free 后缀丢打印密钥长度和末尾字符核对签名错误各平台表述不同拼接顺序错、时间戳偏差、编码不对用官方在线调试生成样例逐字段比对提示权限不足或无权限未开通服务、子身份未授权回控制台查服务状态与授权策略429 / 请求过于频繁超过 QPS 限制客户端加令牌桶限速指数退避重试额度类错误免费额度用尽或余额不足切备用引擎同时告警目标语言不支持语种代码写错最常见对照该平台文档的代码表返回中文原样不动自动检测误判成中文/英文显式指定 source 语言译文里出现字面\n转义未还原落库前统一替换回真实换行这张表是我这两年攒下来的覆盖了我实际遇到的八成问题。剩下的两成里占比最大的是编码问题——请求头没声明 UTF-8、表单提交时被自动转成 GBK、写文件时用了系统默认编码。统一处理方式是请求侧强制Content-Type: application/x-www-form-urlencoded; charsetutf-8代码文件统一 UTF-8读写文件显式指定encodingutf-8。8.2 密钥管理和成本控制几条用血换来的经验第一条密钥不进代码仓库。这是底线不是建议。哪怕你用了.gitignore也挡不住有人git add -f。我的做法是本地用环境变量线上用配置中心代码里只读环境变量且在所有日志输出前做一次脱敏密钥只打印前 4 位和后 4 位。这条规则救过我一次——某次调试时不小心把整个请求对象打进了日志因为做了脱敏泄露的只是几个星号。第二条给每个环境单独申请密钥。开发、测试、生产各一套。共用的后果是开发环境跑个压测生产额度就没了。多套密钥还带来一个好处出问题的时候可以立刻停用某一套而不影响其他环境排查空间大很多。第三条把用量监控做在申请当天而不是出事之后。简单做法是每天定时拉一次各平台的用量接口或者解析调用日志画一条消耗曲线设阈值告警。我踩过的坑是免费额度在月中被悄悄用光然后线上开始大面积切换引擎而告警配置是月底才加上的——中间那半个月的所有译文都来自备用引擎质量下降没人发现直到用户反馈。第四条翻译前先清洗源文本。前面提过但我认为值得单独强调。HTML 标签、URL、纯数字编号、占位符{name}、%s、${price}全都不该送去翻译它们既烧额度又可能被翻坏导致程序渲染出错。我现在的标准流程是正则剔除标签和链接 → 用占位符替换变量 → 翻译 → 占位符还原 → 校验占位符数量是否一致。最后这一步校验很关键占位符丢了会直接导致线上模板报错。第五条别迷信任何一家的译文质量。四家我都做过同一批语料的对照结论是没有一家在所有场景都赢。技术文档、营销文案、法律条款、口语对话每种体裁的最优选择都不一样。所以我现在的做法是抽样评测——每个季度拿 50 条真实语料四家各跑一遍人工打分然后在路由里按业务类型分配权重。这套机制跑下来整体返工率比只用一家降了一半多。最后再分享一个小技巧四家的免费额度刷新周期不一样有的是自然月有的是滚动周期。如果你的用量刚好处在临界点把非紧急的批量任务安排在月初跑紧急的实时请求留给主力引擎这个调度上的小调整能让免额度用得更充分一些。这些都是我在实际跑量中一点点试出来的文档里不会写但它确实能省下真金白银。