Fabric 多语言国际化(i18n)系统完全指南:语言检测、翻译加载与扩展实践
【免费下载链接】FabricFabric is an open-source framework for augmenting humans using AI. It provides a modular system for solving specific problems using a crowdsourced set of AI prompts that can be used anywhere.项目地址: https://gitcode.com/GitHub_Trending/fa/Fabric
Fabric 是面向"用 AI 增强人类"场景的开源框架,其国际化(i18n)系统让 CLI 界面、错误提示与交互文案随环境自动切换语言。本文以 docs/i18n.md 为骨架,结合仓库内 i18n 源码与测试,系统讲解语言检测优先级、locale 规范化、翻译文件加载链路、语言扩展方法及排错手段,读完即可在任意语言环境下熟练使用并二次扩展 Fabric 的多语言能力。
一、语言检测机制:五种来源的优先级
Fabric 遵循 POSIX 标准的 locale 检测规范,并按固定优先级从上到下逐级尝试,一旦命中有效语言即停止:
- 显式语言标志:
--language(短参数-g),优先级最高,强制覆盖一切环境变量 - LC_ALL:完整覆盖所有 locale 类别的环境变量
- LC_MESSAGES:仅针对消息类别的 locale 环境变量
- LANG:通用 locale 环境变量
- 默认回退:以上均未设置或无效时,回退到英文(
en)
该优先级在源码 internal/i18n/locale.go 中体现为detectSystemLocale()按LC_ALL → LC_MESSAGES → LANG顺序遍历环境变量;而getPreferredLocale()(见 internal/i18n/locale.go)则进一步把显式语言参数放在最前,其次才轮到系统环境检测。标志定义位于 internal/cli/flags.go,其官方描述为 "Specify the Language Code for the chat, e.g. -g=en -g=zh"。
实操示例
# 方式一:显式语言标志(最高优先级) fabric --language es --pattern summarize # 方式二:LC_ALL 环境变量 LC_ALL=fr_FR.UTF-8 fabric --pattern summarize # 方式三:LANG 环境变量 LANG=de_DE.UTF-8 fabric --pattern summarize # 方式四:多个环境变量并存(LC_ALL 胜出) LC_ALL=es_ES.UTF-8 LANG=fr_FR.UTF-8 fabric --pattern summarize # 结果使用西班牙语(es_ES),因为 LC_ALL 优先级更高测试套件 internal/i18n/locale_test.go 用八组用例完整覆盖了上述规则:LC_ALL覆盖其它变量、LC_MESSAGES在LC_ALL为空时生效、LANG兜底、全部为空返回空串、C/POSIX视为无效、带修饰符的 locale 被剥离、以及"高优先级变量无效时跳过并采用下一级"的容错行为——例如LC_ALL=invalid_locale时系统会忽略它并采用LC_MESSAGES=fr_CA.UTF-8。
二、Locale 格式规范化:从 POSIX 到 BCP 47
系统在检测到原始 locale 字符串后,会将其规范化为 BCP 47 语言标签(形如语言-地区),这一过程由normalizeLocale()实现(见 internal/i18n/locale.go),处理顺序为:
- 特殊值
C、POSIX、空字符串直接视为无效(返回空串,触发英文回退) - 剥离编码部分(按
.分割,去掉.UTF-8等) - 剥离修饰符(按
@分割,去掉@euro、@traditional等) - 将下划线替换为连字符(
en_US→en-US) - 规范化大小写:语言代码小写、地区代码大写,仅保留
语言-地区两段
规范化效果如下表:
| 原始 locale | 规范化结果 |
|---|---|
en_US.UTF-8 | en-US |
fr_FR@euro | fr-FR |
zh_CN.GB2312 | zh-CN |
de_DE.UTF-8@traditional | de-DE |
pt_BR.UTF-8@currency=BRL | pt-BR |
sr_RS.UTF-8@latin | sr-RS |
C/POSIX | 无效,回退英文 |
internal/i18n/locale_test.go 对上述全部格式以及"已规范化输入(en-US)、纯语言代码(en)、空串"等边界情形做了断言;有效性校验isValidLocale()则交由golang.org/x/text/language包解析,language.Parse()成功即为合法(见 internal/i18n/locale.go)。从测试注释可以推断,该解析器较为宽松——未知地区码(如en-ZZ)与下划线形式也能通过校验。
三、翻译文件的三级来源与加载链路
翻译文件按以下顺序加载(见 internal/i18n/i18n.go 的Init()):
- 内嵌文件(最高优先级):通过
//go:embed locales/*.json指令(internal/i18n/i18n.go)编译进二进制,开箱即用、无需联网下载 - 用户配置目录:按需从远端下载后缓存,路径为
~/.config/fabric/locales/,由userLocaleDir()借助os.UserConfigDir()计算并自动创建(internal/i18n/i18n.go) - 远端仓库:下载源位于仓库的
internal/i18n/locales/目录,downloadLocale()直接发起 HTTP GET 拉取对应<locale>.json(internal/i18n/i18n.go)
Init()的具体流程是:先用getLocaleCandidates()生成候选列表,逐个尝试从内嵌 FS 读取;若内嵌命中则更新 locale 并继续,若全部未命中则回退读取内嵌的en.json;随后检查用户配置目录中的本地文件——文件不存在且非内嵌时才触发下载,下载或加载失败仅向 stderr 打印错误、不中断运行。
候选链与地区变体
getLocaleCandidates()(internal/i18n/i18n.go)为请求的语言生成按优先级排列的候选列表:首先是请求的精确 locale,其次是其基础语言代码,最后是基础语言的默认地区变体。defaultLanguageVariants映射(internal/i18n/i18n.go)目前为pt → pt-BR(兼容旧行为),并为de/en/es/fa/fr/it/ja/zh预留了未来默认变体。变体的完整设计思路见 docs/i18n-variants.md,相关测试在 internal/i18n/i18n_variants_test.go 中验证了pt-PT → ["pt-PT", "pt", "pt-BR"]等候选链及pt回退到巴西葡萄牙语的兼容性。
四、当前支持的语言与仓库现状
仓库 internal/i18n/locales/ 目录实际包含以下语言文件:de.json(德语)、en.json(英语)、es.json(西班牙语)、fa.json(波斯语)、fr.json(法语)、it.json(意大利语)、ja.json(日语)、pl.json(波兰语)、pt-BR.json(巴西葡萄牙语)、pt-PT.json(欧洲葡萄牙语)、tr.json(土耳其语)、zh.json(简体中文)。也就是说,从仓库源码看 Fabric 已内置远超文档列举的语种;其中en.json与zh.json均含约 770 个 message key,覆盖 CLI 帮助、配置向导、YouTube/Spotify 集成、TTS、Azure/Bedrock 等各模块文案。
五、翻译文件格式与新增语言
翻译文件采用 JSON 格式,以message_id为键、本地化文本为值,Init()中通过bundle.RegisterUnmarshalFunc("json", json.Unmarshal)注册 JSON 解析器(internal/i18n/i18n.go):
{ "html_readability_error": "use original input, because can't apply html readability" }西班牙语同键示例:
{ "html_readability_error": "usa la entrada original, porque no se puede aplicar la legibilidad de html" }新增一种语言的步骤:
- 新建文件
internal/i18n/locales/{lang}.json,如internal/i18n/locales/ko.json - 以
en.json为基准逐键翻译,确保 key 完全对齐 - 重新构建 Fabric(
go build),让//go:embed将新文件编译进二进制
若新增的是地区变体(如es-MX),则按 docs/i18n-variants.md 的指引:复制基础文件(cp locales/es.json locales/es-MX.json)→ 调整地区差异(技术术语、常见 UI 词、日期时间格式、货币、称呼方式)→ 视需要在defaultLanguageVariants中登记默认变体 → 补充测试 → 更新文档。变体命名遵循 BCP 47:语言代码小写、地区代码大写、连字符分隔(pt-BR而非pt_BR),不过输入侧两种格式均可接受。
语言标志的其它用途
除 i18n 界面文案外,-g/--language还用于 YouTube 字幕抓取:在 internal/cli/cli.go 中,抓取字幕与视频视觉文本时优先采用flags.Language,未指定时回退到配置中的DefaultLanguage(默认en)。
六、错误处理与健壮性设计
i18n 系统采取"尽力而为"的容错策略,任何单点失败都不阻塞命令执行:
- 下载失败:非致命,自动回退到内嵌翻译,错误写入 stderr
- 无效 locale:跳过该候选,继续尝试下一优先级来源
- 缺失翻译:回退到英文
- 缺失文件:使用内嵌默认值
- 加载本地文件失败:打印
i18n_load_failed对应文案后继续
初始化期间的错误文案由getErrorMessage()负责(internal/i18n/i18n.go):先尝试系统 locale 的内嵌消息,再回退英文,最终兜底硬编码文案。翻译入口函数T()通过sync.Once保证只初始化一次,未显式初始化时会自动以空参数触发系统检测(internal/i18n/i18n.go);这一行为在 internal/i18n/locale_test.go 的集成测试中亦有覆盖。
七、环境变量实操与语言切换测试
常见 Unix locale 设置
# 系统级设置 export LANG=en_US.UTF-8 # 覆盖所有 locale 类别 export LC_ALL=fr_FR.UTF-8 # 仅对当前会话设置消息 locale LC_MESSAGES=es_ES.UTF-8 fabric --pattern summarize # 查看当前 locale 设置 locale不修改系统设置即可测试检测逻辑
# 法语 LC_ALL=fr_FR.UTF-8 fabric --version # 西班牙语(内嵌可用) LC_ALL=es_ES.UTF-8 fabric --version # 德语(未内嵌时会尝试下载,当前仓库已内置则直接使用) LC_ALL=de_DE.UTF-8 fabric --version对地区变体可进一步验证回退链:
# 直接指定 fabric --help -g=pt-BR fabric --help -g=pt-PT # 环境变量方式 LANG=pt_BR.UTF-8 fabric --help # 回退行为:pt 应使用 pt-BR fabric --help -g=pt--version、--help等命令适合作为快速探测,因为它们路径短、输出可读性强,能直观反映当前生效的语言。
八、常见问题排查(Troubleshooting)
"i18n download failed" 报错
请求的语言当前不可用时出现此提示属正常现象。系统会打印下载失败原因并回退到英文继续执行,不影响功能。若你确定仓库已内置该语言,请检查语言代码写法(如应写zh而非zh-CN之外的任意地区形式,除非对应地区文件存在)。
语言未生效
检查环境变量是否为空或格式非法:
echo $LC_ALL echo $LC_MESSAGES echo $LANG确保格式合法,例如en_US.UTF-8或fr_FR;若值为C或POSIX,会被判定为无效而回退英文。
语言不是预期的
回顾优先级:--language标志 >LC_ALL>LC_MESSAGES>LANG。任何高优先级来源只要设置了合法值,就会覆盖低优先级变量——例如同时设置了LC_ALL=fr_FR.UTF-8与LANG=de_DE.UTF-8,生效的是法语。
九、实现要点总结
从源码层面看,internal/i18n/locale.go 负责 locale 检测与规范化,internal/i18n/i18n.go 负责 bundle 初始化、内嵌加载、按需下载与候选链解析,internal/i18n/locale_test.go 与 internal/i18n/i18n_variants_test.go 则对检测优先级、格式规范化、变体回退与初始化集成提供了完整测试保障。整套设计遵循 BCP 47 语言标签标准,实现 POSIX locale 环境变量优先级,并在各种边缘情况下优雅降级——这正是其可以安全地在任何终端环境中作为默认机制开启的原因。
需要深入了解变体扩展时,可继续阅读 docs/i18n-variants.md;若想修改默认语言或参与翻译,直接编辑 internal/i18n/locales/ 下的 JSON 文件并按前述步骤重新构建即可。
【免费下载链接】FabricFabric is an open-source framework for augmenting humans using AI. It provides a modular system for solving specific problems using a crowdsourced set of AI prompts that can be used anywhere.项目地址: https://gitcode.com/GitHub_Trending/fa/Fabric
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考