[控场AI]
· 5 分钟阅读· 2,979 字

单人开发8语言游戏站:Python+Docker+免费LLM的实战复盘

单人开发8语言游戏站:Python+Docker+免费LLM的实战复盘

韩国独立开发者用 Python、Docker 和免费 LLM API 为浏览器游戏站实现八语言支持的技术拆解与边界反思。

Yeoul Games 是一位韩国独立开发者运营的浏览器游戏聚合站,最初只有韩语,后扩展至八种语言。技术方案分两条路径:固定界面文案存放在 JSON 翻译表中,通过 HTML 响应过滤器做整句替换;游戏描述则调用 Groq 免费 LLM API 自动翻译,并用 SHA256 指纹校验确保译文与源文本同步。开发中遭遇免费层 tokens-per-minute 限制导致的 413/429 错误,通过减小请求粒度、限制 max_tokens 和 70 秒间隔节流解决,并增加字符集校验丢弃不完整译文。文章还讨论了内容分级翻译策略及其边界:翻译的覆盖范围应与产品实际可用范围对齐。

一位韩国独立开发者用 Python、Docker 和免费 LLM API,让个人浏览器游戏站支持 8 种语言。本文拆解他的技术方案、踩坑记录,以及自动翻译在真实产品中的边界。

单人开发8语言游戏站

从韩语单语到八语言:一个小站的国际化动机

Yeoul Games 是一个无需注册、无需安装即可游玩浏览器游戏的聚合站,由一位韩国独立开发者独自运营。站点最初只是他自己游戏和韩文文字 MUD 的展示页,后来其他韩国独立开发者陆续把作品挂上来。

随着访问来源变杂,他把界面扩展到了韩语、英语、日语、葡萄牙语、西班牙语、越南语、土耳其语和德语八种语言,通过 ?lang=en 这类查询参数切换。整套服务跑在家用群晖 NAS 的 Docker 容器里,后端是 Python 写的 Web 服务器。这个选择的性价比很高:没有云服务账单,也没有复杂的运维链路,代价是资源受限,这一点在后面直接导致了翻译管线的故障。

技术方案拆解:两条翻译路径

固定界面文本:JSON 翻译表 + 响应过滤器

所有界面字符串存放在一个 JSON 表里。每个 HTML 响应都经过一个过滤器,把韩语字符串替换成对应语言的译文。这里有个细节值得注意:当一句话被 HTML 标签切分时,翻译表的键保留完整句子,以保证替换是精确匹配,而不是碎片化替换导致语序错乱。

这是典型的"静态国际化"思路,好处是零运行时成本、结果可预测;局限是只适用于界面文案,无法处理用户生成内容。

响应过滤器与 HTML 标签切分问题

响应过滤器是 Web 框架中的一种中间件机制:在服务器生成 HTML 之后、发送给客户端之前,对响应体做统一处理。用于国际化时,它遍历响应文本,把翻译表中登记的源语言字符串替换为目标语言译文。难点在于,一句自然语言在 HTML 中常被内联标签(如 <strong>、<a>)切成多段,如果按标签切分后的碎片去匹配,翻译表就必须为每种切分组合准备条目,既不可维护也容易漏替换。以完整句子为键、在过滤阶段做整句匹配,可以绕开这个问题,但要求 HTML 结构不破坏句子连续性,且替换顺序需避免嵌套误伤。

游戏描述:免费 LLM API 自动翻译

开发者上传游戏时勾选游戏本身支持的语言,但无论勾选什么,描述文本都会发送到 Groq 的免费 LLM API,翻译成其余七种语言。这样一位巴西访客至少能读懂一款韩语游戏讲的是什么。

为了保证译文不过期,后台线程对源字段做指纹计算。代码里用 hashlib.sha256 对规范化后的 JSON 做哈希,取前 16 位作为 _src 指纹。页面渲染时,只有当存储的指纹与当前文本匹配,译文才会被采用。开发者一旦修改描述,页面先回退显示韩语原文,直到新译文落地。这个设计解决了一个容易被忽视的问题:过期的译文比没有译文更危险,因为它会用错误的信息描述一个已经变化的产品。

Groq 与免费 LLM API 的运作方式

Groq 是一家提供大模型推理服务的云平台,其特点是使用自研的 LPU(语言处理单元)硬件加速推理,主打低延迟生成。开发者可以通过兼容 OpenAI 格式的 API 调用托管在其上的开源模型(如 Llama 系列、Mixtral 等)。所谓“免费 API”,通常指平台提供的免费额度层级:无需绑定付费方式即可在限定速率下调用,但会施加 tokens-per-minute(每分钟令牌数)和 requests-per-minute 等限制。一旦超出,服务端会返回 429(请求过多)等状态码,而非静默降级。对于个人项目而言,这种免费层足以支撑低频、批量的翻译任务,但必须自行设计节流与重试逻辑,不能假设接口随时可用。

踩坑实录:免费额度的真实代价

免费层级的 tokens-per-minute 限制是这次开发中最直接的障碍。作者开始收到 HTTP 413 和 429 错误。他的修复策略分三步:减少单次请求量(一次只处理一个游戏的一个语言组)、限制 max_tokens、请求之间等待 70 秒(空闲时 240 秒)。

即便如此,仍有部分译文返回不完整,比如一句日语结尾混进了韩文字符。他先手工修正,后来加了 auto_ok 校验函数:如果译文里出现了源文本中没有的韩文字符(通过正则 [가-힣]+ 匹配),就丢弃这条译文。这个思路可以推广到任何"源语言字符不应出现在目标语言"的翻译质检场景。

据作者在原文中的描述,这些限制并非一次性解决,而是通过"每轮只处理一个游戏×一个语言组"的轮询节奏,把请求压到免费额度之下。这是一种用时间换成本的典型策略,适合个人项目,但不适合对延迟敏感的产品。

HTTP 413 与 429 的区别

413(Payload Too Large)表示请求体超过服务器允许的大小,在 LLM API 场景中往往与单次请求携带的文本过长或 max_tokens 设置过高有关;429(Too Many Requests)则是速率限制被触发,代表单位时间内请求数或令牌数超出配额。两者成因不同,修复手段也不同:413 需要减小单次请求的输入或输出规模,429 需要拉长请求间隔或降低并发。把两者混为一谈容易导致“只加等待却仍报 413”的无效调试,理解状态码语义是排查这类问题的第一步。

翻译边界:哪些该译,哪些不该译

作者对内容做了分级处理,这个判断值得单独拿出来说:

  • 公告与规则:由作者用韩语撰写,非韩语页面机器翻译,但始终附带韩语原文链接,原文保持权威地位。
  • 其他用户的帖子:完全保持原样,不做翻译。
  • 游戏描述:全量自动翻译。
  • 游戏本体:不翻译。

这种分级反映了一个务实的产品判断:规则类内容需要准确性,所以保留权威原文;用户内容涉及表达权,不宜擅自改写;描述类内容以"能读懂"为目标,机器翻译够用。

非韩语页面还提供了一个"可用我的语言游玩"的筛选器,依据是开发者勾选的语言支持。但由于目前绝大多数游戏只有韩语,这个筛选器实际返回的结果很少。这是一个诚实的现状呈现:功能做了,但供给还没跟上。

现状与开放问题

站上目前有 42 款游戏,几乎全部来自韩国独立开发者,游戏本体仍以韩语为主。翻译只覆盖界面和描述,且译文质量在部分场景仍有瑕疵。

作者本人提出的疑问很有价值:自动翻译的描述究竟是在帮助用户,还是在设定错误的预期?如果一位英语用户读着流畅的英文描述点进去,发现游戏界面全是韩语,这种落差可能比看到韩语描述更令人沮丧。这个问题没有标准答案,但它指向了国际化产品的一个核心矛盾——翻译的边界应该与产品实际可用的边界对齐。

对于其他做浏览器游戏的开发者,这个案例的可复用点在于:静态文案用翻译表、动态内容用 LLM 加指纹校验、免费额度用节流换稳定、质量兜底用字符集校验。这套组合拳的成本接近于零,适合个人项目起步阶段。

站点地址:https://yeoulgame.com/?lang=en

#浏览器游戏站国际化#Python多语言实现#LLM自动翻译#Groq免费API#Docker部署#独立开发者#翻译指纹校验
分享:

相关推荐