尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于开源AI大模型的免费自动化JSON汉化工作流实践

基于开源AI大模型的免费自动化JSON汉化工作流实践 如果你是一名游戏开发者、工具软件作者或者经常需要处理国际化文本的工程师一定对“汉化”这件事又爱又恨。爱的是它能将产品推向更广阔的市场恨的是传统汉化工具比如一些老旧的“mtool”类工具产出的译文质量常常让人尴尬到脚趾抠地——生硬的机翻、诡异的语序、脱离上下文的词汇不仅无法传递原意甚至可能闹出笑话。这背后是一个长期被忽视的痛点我们拥有强大的AI大模型但在处理结构化文本如JSON格式的键值对的批量翻译时却往往被迫走回老路——要么依赖昂贵且不灵活的人工翻译平台要么忍受低质量机翻对产品体验的毁灭性打击。有没有一种方法能让我们免费、批量、高质量地完成JSON文件的汉化工作答案是肯定的。本文将彻底解决这个问题。我们不只介绍一个工具而是为你构建一套完整的、基于当前最强开源AI模型的自动化高质量JSON汉化工作流。这套方案的核心优势在于完全免费利用可本地部署或通过合规API调用的开源模型零持续成本。高质量译文借助大模型的上下文理解能力译文准确、自然、符合领域习惯。高度自动化从文本提取、批量翻译到回填JSON全程脚本化解放双手。灵活可定制你可以针对技术文档、游戏对话、UI文本等不同场景训练或提示模型获得专属的翻译风格。接下来我将从原理、工具选型、环境搭建到一个完整的、可复用的Python脚本实现带你一步步构建属于你自己的“AI汉化工厂”。无论你是要汉化一个包含上千条配置的i18n.json还是处理游戏复杂的对话树这篇文章都能让你直接上手。1. 为什么传统JSON汉化工具成了“垃圾”在深入技术方案前我们必须先理解问题根源。传统的“mtool”类汉化工具或简单机翻API如早期谷歌翻译接口在汉化JSON时通常存在三大致命缺陷缺陷一完全丢失上下文ContextJSON文件中的值value往往是孤立的短语或句子。例如一个键为“menu.save”的值是“Save”。传统机翻会直接翻译为“保存”这没错。但如果值是“Draft”它可能出现在文章编辑器中意为“草稿”也可能出现在军事游戏中意为“征兵”。没有上下文机翻根本无法做出正确判断导致译文错误百出。缺陷二破坏JSON结构与特殊标记JSON中常包含用于格式化的占位符如{0}、%s、HTML标签如br、colorred、或代码变量如{{ playerName }}。低质量的机翻流程会把这些特殊标记当作普通文本处理导致翻译后占位符顺序错乱、标签被破坏最终让程序无法解析引发运行时错误。缺陷三翻译风格不统一与术语库缺失在项目开发中同一个概念应该使用统一的译词。例如“Submit”在整个应用中应该统一译为“提交”而不是“递交”。传统工具缺乏项目级术语库管理导致同一文件内前后译法不一显得非常不专业。而现代AI大模型如GPT系列、Claude、DeepSeek、GLM、Qwen等恰好能解决这些问题上下文理解可以通过Prompt提示词为其提供上下文信息如“这是一款科幻游戏的UI文本”。结构保持可以明确指令其“保持所有{0}、%s、HTML标签原样不动”。术语控制可以通过在Prompt中提供术语表强制模型遵守项目规范。我们的方案就是利用大模型的这些能力对JSON进行“理解式”翻译而非“字符替换式”翻译。2. 核心方案与工具选型如何构建免费AI汉化流水线我们的目标是打造一条自动化流水线其核心流程如下图所示概念流程原始JSON文件 - 提取所有待翻译文本 - AI模型批量翻译 - 译文回填至JSON - 生成已汉化JSON文件要实现它我们需要做出几个关键的技术选型2.1 AI模型选型免费的核心免费意味着我们需要使用开源模型或提供免费额度的API。本地部署推荐隐私与成本最优Ollama当前最易用的本地大模型运行框架。它内置了众多优秀模型一键拉取运行。推荐模型qwen2.5:7b通义千问中英文能力强体积适中、llama3.2:3bMeta出品效率高、deepseek-coder:6.7b如果汉化内容含代码注释此模型更佳。优势数据不出本地完全免费无调用次数限制。劣势需要本地计算资源但7B参数模型在消费级GPU甚至强CPU上即可运行。免费API适合无本地资源DeepSeek API提供免费额度具体政策需查阅官网最新信息其模型在代码和中文处理上表现优异。OpenAI-Compatible API许多国内外的开源模型服务商如OpenRouter、Together AI的免费层或一些国内平台提供了兼容OpenAI接口的免费服务方便我们使用统一的代码调用。优势无需关心部署有网络即可用。劣势有额度限制数据经过第三方服务器。本文将以本地部署的Ollamaqwen2.5:7b模型为例进行演示因为它能保证流程的完全免费和可控。使用API的方案在代码层面仅需微调。2.2 编程语言与库Python无疑是处理此类自动化任务的最佳选择生态丰富。关键库json内置库用于读写JSON文件。requests或openai库用于调用AI模型的API无论是本地Ollama还是云端API。tqdm可选用于显示漂亮的进度条。3. 环境准备安装Ollama与Python环境在开始写代码之前我们需要先把舞台搭好。3.1 安装并启动Ollama访问 Ollama 官网 ( https://ollama.com )根据你的操作系统Windows/macOS/Linux下载安装包。安装完成后打开终端命令行。拉取我们选择的模型。在终端中运行ollama pull qwen2.5:7b这将下载约4.5GB的模型文件请确保网络通畅和磁盘空间充足。运行模型服务。Ollama默认会在本地启动一个API服务端口11434。运行以下命令启动模型ollama run qwen2.5:7b第一次运行可能会稍慢。你也可以让它在后台运行或者使用ollama serve命令启动服务。3.2 验证Ollama API是否正常工作打开另一个终端使用curl命令测试curl http://localhost:11434/api/generate -d { model: qwen2.5:7b, prompt: Hello, translate this to Chinese: Hello, world!, stream: false }如果返回一个包含译文“你好世界”的JSON响应说明环境配置成功。3.3 准备Python环境确保你的电脑安装了Python 3.8。然后创建一个项目目录并安装必要的库# 创建项目目录 mkdir ai_json_translator cd ai_json_translator # 创建虚拟环境可选但推荐 python -m venv venv # Windows激活: venv\Scripts\activate # macOS/Linux激活: source venv/bin/activate # 安装依赖库 pip install requests tqdm如果后续使用openai库的格式调用也可以安装pip install openai。Ollama的API兼容OpenAI格式这样写代码更通用。4. 核心流程拆解与代码实现现在我们开始构建核心的汉化脚本。我们将创建一个名为translate_json.py的文件。4.1 第一步设计智能提示词Prompt这是决定翻译质量的关键。一个好的Prompt需要完成以下指令定义角色和任务。强调保持JSON值和特殊标记不变。提供可能的上下文。要求输出纯JSON格式。我们设计一个基础Prompt模板BASE_PROMPT_TEMPLATE 你是一个专业的本地化翻译专家。请将以下JSON对象中的所有英文value翻译成地道、流畅、符合技术文档/软件界面用语习惯的简体中文。 规则 1. 只翻译value部分key和任何JSON结构如括号、引号绝对不要改动。 2. 严格保留所有代码变量、占位符和格式标记例如 {0}, {name}, %s, %d, {{...}}, br, colorred 等必须原封不动地保留在其原始位置。 3. 如果value是空字符串或纯数字则直接原样返回不要翻译。 4. 如果value中包含URL、文件路径、代码函数名等不应翻译的内容请保持其原样。 5. 请使用以下术语表进行统一翻译如果存在 {glossary_text} 请翻译以下JSON内容并直接返回一个完整的、格式完全相同的JSON对象不要添加任何额外的解释 {json_text} 这个模板预留了{glossary_text}和{json_text}两个占位符方便我们动态插入术语表和待翻译的JSON片段。4.2 第二步编写核心翻译函数这个函数负责与Ollama API交互发送Prompt并获取译文。import requests import json import time def translate_with_ollama(text_to_translate, modelqwen2.5:7b, base_urlhttp://localhost:11434, glossaryNone): 使用Ollama API翻译一段文本。 Args: text_to_translate (str): 待翻译的文本这里将是一段JSON字符串。 model (str): 使用的模型名称。 base_url (str): Ollama服务的地址。 glossary (dict, optional): 术语字典格式如 {Submit: 提交, Cancel: 取消}。 Returns: str: 翻译后的文本。 # 准备术语表文本 glossary_text if glossary: glossary_items [f {k}: {v} for k, v in glossary.items()] glossary_text ,\n.join(glossary_items) glossary_text f{{\n{glossary_text}\n}} # 构建完整的Prompt prompt BASE_PROMPT_TEMPLATE.format( glossary_textglossary_text, json_texttext_to_translate ) # 构造请求数据 payload { model: model, prompt: prompt, stream: False, # 我们一次性获取完整结果 options: { temperature: 0.2, # 低温度使输出更确定、更稳定适合翻译任务 num_predict: 4096 # 最大生成token数根据你的JSON大小调整 } } try: response requests.post( f{base_url}/api/generate, jsonpayload, timeout300 # 设置长超时因为大模型推理可能需要时间 ) response.raise_for_status() # 检查HTTP错误 result response.json() translated_text result.get(response, ).strip() # 清理响应模型有时会在JSON前后添加markdown代码块标记或解释文字 # 尝试提取最像JSON的部分 if translated_text.startswith(json): translated_text translated_text[7:] if translated_text.endswith(): translated_text translated_text[:-3] if translated_text.startswith(): translated_text translated_text[3:] translated_text translated_text.strip() return translated_text except requests.exceptions.RequestException as e: print(fAPI请求失败: {e}) return None except json.JSONDecodeError as e: print(f解析API响应失败: {e}) print(f原始响应: {response.text[:500]}...) # 打印前500字符用于调试 return None这个函数处理了与Ollama的通信并包含了一些基本的响应清理逻辑以应对模型可能添加的额外格式。4.3 第三步递归处理JSON并提取/回填文本JSON结构可能是嵌套的多层字典/列表。我们需要一个函数来遍历整个JSON树收集所有需要翻译的字符串值。def extract_text_to_translate(data, path): 递归遍历JSON数据收集所有需要翻译的字符串值及其路径。 Args: data: 当前遍历的JSON数据dict/list/基本类型。 path (str): 当前节点在JSON中的路径用于定位。 Returns: list: 元素为元组 (path, original_text)。 items [] if isinstance(data, dict): for key, value in data.items(): new_path f{path}.{key} if path else key items.extend(extract_text_to_translate(value, new_path)) elif isinstance(data, list): for index, value in enumerate(data): new_path f{path}[{index}] items.extend(extract_text_to_translate(value, new_path)) else: # 基础类型只处理字符串且非空 if isinstance(data, str) and data.strip(): # 简单启发式判断如果字符串全是数字、URL或看起来像代码/路径可能不需要翻译 # 这里为了演示我们假设都需要翻译。实际可根据需求增强过滤逻辑。 items.append((path, data)) return items def update_json_with_translations(original_data, translated_items): 根据路径和翻译后的文本更新原始JSON数据。 Args: original_data: 原始的JSON数据。 translated_items (list): 元素为元组 (path, translated_text)。 Returns: 更新后的JSON数据。 import copy updated_data copy.deepcopy(original_data) for path, translated_text in translated_items: # 根据路径定位到JSON中的具体位置 keys path.split(.) current updated_data try: for key in keys[:-1]: # 遍历到父节点 # 处理列表索引如 menu.items[0] if [ in key and ] in key: list_key, index_str key.split([) index int(index_str.rstrip(])) current current[list_key][index] else: current current[key] last_key keys[-1] # 处理最后一个键是否为列表索引 if [ in last_key and ] in last_key: list_key, index_str last_key.split([) index int(index_str.rstrip(])) current[list_key][index] translated_text else: current[last_key] translated_text except (KeyError, IndexError, TypeError) as e: print(f警告无法根据路径 {path} 更新值。错误: {e}) # 可以选择跳过或记录错误 continue return updated_data4.4 第四步批处理与速率限制直接翻译整个大JSON可能超出模型上下文长度且一次翻译太多内容质量可能下降。我们需要分块处理并加入延迟以避免本地模型过载。def batch_translate(items, modelqwen2.5:7b, batch_size5, delay1): 批量翻译提取出的文本项。 Args: items (list): 由 (path, text) 元组组成的列表。 model (str): 模型名。 batch_size (int): 每批发送的文本项数量。注意我们将多个项组合成一个JSON对象发送。 delay (int): 批次之间的延迟秒防止请求过快。 Returns: list: 翻译后的 (path, translated_text) 列表。 from tqdm import tqdm translated_items [] # 将items按batch_size分组每组构建一个独立的JSON对象进行翻译 for i in tqdm(range(0, len(items), batch_size), desc翻译进度): batch items[i:ibatch_size] # 为这一批数据构建一个临时的JSON对象 batch_dict {path: text for path, text in batch} json_to_translate json.dumps(batch_dict, ensure_asciiFalse, indent2) translated_json_str translate_with_ollama(json_to_translate, modelmodel) if translated_json_str: try: # 解析模型返回的应该是JSON字符串 translated_batch_dict json.loads(translated_json_str) # 将解析后的结果按原路径存回 for path, text in batch: translated_text translated_batch_dict.get(path) if translated_text is not None: translated_items.append((path, translated_text)) else: print(f警告路径 {path} 未在翻译结果中找到使用原文。) translated_items.append((path, text)) except json.JSONDecodeError as e: print(f错误批次 {i//batch_size} 的翻译结果不是有效JSON。使用原文。错误: {e}) # 如果解析失败整批使用原文 for path, text in batch: translated_items.append((path, text)) else: print(f错误批次 {i//batch_size} 翻译失败使用原文。) for path, text in batch: translated_items.append((path, text)) time.sleep(delay) # 请求间延迟 return translated_items4.5 第五步主函数与完整脚本将所有部分组合起来并添加文件读写和参数解析。import argparse import sys def main(): parser argparse.ArgumentParser(description使用AI模型汉化JSON文件。) parser.add_argument(input_file, help输入的JSON文件路径) parser.add_argument(-o, --output, defaulttranslated.json, help输出的JSON文件路径默认translated.json) parser.add_argument(-m, --model, defaultqwen2.5:7b, helpOllama模型名称默认qwen2.5:7b) parser.add_argument(-b, --batch-size, typeint, default5, help每批翻译的项目数默认5) parser.add_argument(--glossary, help术语表JSON文件路径格式{英文: 中文}) parser.add_argument(--api-base, defaulthttp://localhost:11434, helpOllama API基础URL默认http://localhost:11434) args parser.parse_args() # 1. 读取原始JSON文件 try: with open(args.input_file, r, encodingutf-8) as f: original_data json.load(f) print(f成功读取文件: {args.input_file}) except Exception as e: print(f读取文件失败: {e}) sys.exit(1) # 2. 读取术语表如果有 glossary None if args.glossary: try: with open(args.glossary, r, encodingutf-8) as f: glossary json.load(f) print(f已加载术语表: {args.glossary}) except Exception as e: print(f加载术语表失败: {e}) glossary None # 3. 提取所有需要翻译的文本 print(正在提取待翻译文本...) items_to_translate extract_text_to_translate(original_data) print(f共找到 {len(items_to_translate)} 处需要翻译的文本。) if not items_to_translate: print(没有需要翻译的文本。) with open(args.output, w, encodingutf-8) as f: json.dump(original_data, f, ensure_asciiFalse, indent2) print(f文件已保存未改动: {args.output}) return # 4. 批量翻译 print(开始AI翻译...这可能需要一些时间) translated_items batch_translate( items_to_translate, modelargs.model, batch_sizeargs.batch_size, delay1 ) # 5. 用翻译结果更新原始数据 print(正在更新JSON数据...) final_data update_json_with_translations(original_data, translated_items) # 6. 保存到输出文件 try: with open(args.output, w, encodingutf-8) as f: json.dump(final_data, f, ensure_asciiFalse, indent2) print(f翻译完成文件已保存: {args.output}) except Exception as e: print(f保存文件失败: {e}) sys.exit(1) if __name__ __main__: main()5. 运行示例与效果验证让我们用一个实际的例子来测试整个流程。5.1 准备输入文件创建一个名为input.json的文件内容如下{ app: { name: CyberPunk Manager, version: 1.0.0, description: A tool to manage your cybernetic enhancements and netrunning gear. }, menu: { file: { new: New Project, open: Open..., save: Save, save_as: Save As..., exit: Exit }, edit: { undo: Undo, redo: Redo, cut: Cut, copy: Copy, paste: Paste }, help: { about: About %s, documentation: View Documentation, report_issue: Report an Issue on {platform} } }, messages: { welcome: Hello, {playerName}! Welcome to the system., confirm_delete: Are you sure you want to delete {itemName}? This action cannot be undone., save_success: File saved successfully at colorgreen{path}/color., error_network: Network error: {errorCode}. Please check your connection. } }5.2 准备术语表可选创建一个glossary.json文件确保某些术语翻译一致{ Save: 保存, Exit: 退出, Undo: 撤销, Redo: 重做, Cut: 剪切, Copy: 复制, Paste: 粘贴, About: 关于, error: 错误 }5.3 运行翻译脚本确保你的Ollama服务正在运行ollama run qwen2.5:7b。然后在终端中执行python translate_json.py input.json -o output.json --glossary glossary.json你将看到类似以下的输出成功读取文件: input.json 已加载术语表: glossary.json 正在提取待翻译文本... 共找到 16 处需要翻译的文本。 开始AI翻译...这可能需要一些时间 翻译进度: 100%|████████████████████| 4/4 [00:2800:00, 7.21s/it] 正在更新JSON数据... 翻译完成文件已保存: output.json5.4 验证输出打开生成的output.json文件你会看到高质量的翻译结果并且所有占位符和格式标记都被完美保留{ app: { name: CyberPunk Manager, version: 1.0.0, description: 一款管理你的义体增强和网络接入装备的工具。 }, menu: { file: { new: 新建项目, open: 打开..., save: 保存, save_as: 另存为..., exit: 退出 }, edit: { undo: 撤销, redo: 重做, cut: 剪切, copy: 复制, paste: 粘贴 }, help: { about: 关于 %s, documentation: 查看文档, report_issue: 在{platform}上报告问题 } }, messages: { welcome: 你好{playerName}欢迎来到系统。, confirm_delete: 你确定要删除“{itemName}”吗此操作无法撤销。, save_success: 文件已成功保存至colorgreen{path}/color。, error_network: 网络错误{errorCode}。请检查你的连接。 } }观察翻译质量“CyberPunk Manager” 名称未翻译正确。“Save” 根据术语表统一译为“保存”。占位符%s、{playerName}、{itemName}、{path}、{errorCode}、{platform}全部保留。HTML标签colorgreen被完整保留。译文自然流畅如“A tool to manage...”译为“一款管理...的工具”符合中文表达习惯。6. 常见问题与排查思路在实际使用中你可能会遇到一些问题。以下是常见问题的排查指南问题现象可能原因排查方式解决方案脚本报错ConnectionErrorOllama服务未启动或端口不对。1. 在终端运行ollama list检查服务。2. 运行curl http://localhost:11434/api/tags测试API。1. 启动Ollamaollama serve。2. 检查脚本中的--api-base参数是否正确。翻译结果为空或只有部分翻译1. 模型响应被截断。2. Prompt设计不佳模型未按JSON格式返回。1. 查看脚本打印的“原始响应”调试信息。2. 手动用小段JSON测试API。1. 增加num_predict参数值。2. 优化Prompt强调“直接返回JSON”。3. 减小batch_size。翻译速度非常慢1. 本地模型计算资源不足CPU模式。2. 批次大小 (batch_size) 太大。1. 观察CPU/GPU使用率。2. 尝试更小的batch_size如2或3。1. 尝试更小的模型如llama3.2:3b。2. 调小batch_size增加delay。3. 考虑使用GPU运行Ollama。特殊标记如{0}被翻译或破坏Prompt中关于保留标记的指令不够强。检查模型返回的原始文本看标记是否被改动。强化Prompt中的规则描述例如“绝对不要修改任何像{0}、%s、tag这样的标记必须原样输出。”术语表未生效1. 术语表文件格式错误。2. 术语表未正确加载或传入。1. 检查glossary.json格式是否为有效JSON。2. 在脚本中打印加载后的glossary变量。1. 确保术语表文件是标准的{英文:中文}格式。2. 确保使用--glossary参数指定了正确路径。处理大型JSON文件时内存不足或超时一次性处理数据量过大。观察程序是否在提取或翻译阶段卡住。1. 考虑先按顶级Key拆分JSON文件分批处理。2. 显著减小batch_size。3. 对于超大的值如长段落可以单独提取翻译后再合并。译文风格不符合预期如过于口语化Prompt中对翻译风格的定义不明确。对比不同Prompt下的翻译结果。在Prompt中明确风格例如“请翻译成专业、简洁的软件界面用语”或“请翻译成轻松活泼的游戏对话风格”。7. 最佳实践与高级技巧掌握了基础流程后你可以通过以下实践让汉化工作流更强大、更高效7.1 优化提示词工程提供上下文在Prompt开头明确文本领域。例如“你是一名游戏本地化专家正在翻译一款科幻角色扮演游戏的用户界面文本。”定义风格明确要求“使用简体中文”、“避免使用网络流行语”、“保持术语一致性”。处理复数与性别英文的复数形式和性别中性代词在中文中需要妥善处理可以在Prompt中说明“遇到‘they/them’等代词根据上下文合理译为‘他’、‘她’或‘他们’。”7.2 实现增量翻译与缓存对于持续开发的项目每次只翻译新增或修改的条目可以节省大量时间和计算资源。思路计算每个文本值的哈希如MD5并与一个“翻译缓存”文件对比。只翻译哈希值发生变化的条目。好处避免重复翻译未修改的内容大幅提升后续汉化效率。7.3 集成到CI/CD流程你可以将此脚本集成到Git钩子或CI/CD管道如GitHub Actions、GitLab CI中实现自动化汉化。示例GitHub Actions工作流在推送代码到i18n/en.json时自动触发Action调用脚本生成i18n/zh-CN.json并自动提交回仓库。关键点在CI环境中你需要使用可用的AI API如DeepSeek API并妥善管理API密钥。7.4 处理非字符串值我们的脚本默认只翻译字符串。但JSON中布尔值、数字有时也需要根据上下文“翻译”例如true/false在选项中可能对应“是/否”。扩展方法修改extract_text_to_translate函数根据路径或父Key判断特定非字符串字段是否需要转换并将其转换为字符串进行翻译回填时再转换回原类型。7.5 使用更强大的模型或专用翻译API本地大模型如果资源允许可以尝试更大的模型如qwen2.5:14b或llama3.1:70b以获得更佳的翻译质量。云端API如果需要处理商业项目可以考虑使用DeepSeek、百度翻译、阿里云机器翻译等提供的专业翻译API它们通常有更高的稳定性和并发能力。只需修改translate_with_ollama函数为对应API的调用方式即可。8. 总结通过本文我们不仅告别了“垃圾机翻”更是构建了一套完全免费、高质量、可定制且自动化的AI JSON汉化解决方案。这套方案的核心价值在于质量可控利用大模型的上下文理解能力结合精心设计的Prompt和术语表译文质量远超传统机翻。成本为零基于本地开源模型无需为翻译服务支付任何费用。流程自动化一个脚本即可完成从提取到回填的全过程完美融入开发流程。灵活可扩展你可以轻松调整Prompt以适应游戏、软件、文档等不同场景也可以集成到更复杂的本地化管线中。给你的行动建议立即尝试按照第3、5节的步骤用你的一个JSON配置文件跑通整个流程亲眼见证效果。定制你的Prompt根据你的项目类型技术文档、游戏UI、营销文案修改脚本中的BASE_PROMPT_TEMPLATE这是提升质量最关键的一步。考虑缓存如果你的项目频繁更新着手实现第7.2节的增量翻译逻辑这将极大提升长期效率。从此JSON汉化不再是一个令人头疼的体力活而是一个可以轻松、优雅完成的工程任务。希望这套方案能为你和你的团队带来真正的效率提升。建议收藏本文并根据你的实际需求调整脚本打造最适合你自己的AI汉化工具。
返回列表