关于 fhir-ig-translation
fhir-ig-translation 是用于翻译基于 IG Publisher 的 FHIR 实施指南的实验性技能。它从指南配置读取语言方向,并指导创建和验证资源补充、页面、菜单及页面标题目录。
主要功能
- 01从配置读取源语言和目标语言
- 02创建资源翻译补充文件
- 03翻译叙述页面和菜单
- 04生成 IG 页面标题目录
- 05验证翻译文件并标记待审内容
适用场景
- 01将 FHIR 指南本地化为已配置语言
- 02采用现有渲染版本中的译文
- 03检查翻译文件路径和完整性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forschungsgruppe-digital-health/ agent-skills --skill fhir-ig-translation安装后在 Claude Code 中输入/fhir-ig-translation确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/harvest-config.yamltranslate-spec.mdtriggers.mdscripts/ig-translate.sh详细介绍
翻译 FHIR 实施指南
实验性。 自上次更改以来,此技能尚未在真实任务中验证。请先验证其输出,再依赖它。
生成基于 IG-Publisher 的指南的翻译补充文件,并将其准确放置在发布器查找的位置。指南自身的配置决定哪种语言是源语言,哪些语言是译文——此技能会读取该配置,而不是自行假定。
前提条件
-
定位指南。 在工作目录中,查找
input/pagecontent/,以及sushi-config.yaml或ig.ini。scripts/ig-translate.sh会自行检查这一点;如果目录不是 IG 项目,就会显示消息并以状态码 2 退出——它会刻意避免报告“无需翻译”,因为这会导致这里出现无声失败。 -
推导语言对——切勿假定。 读取指南自身的
sushi-config.yaml:parameters: i18n-default-lang: en # the SOURCE language i18n-lang: - de # the TARGET language(s) translation-sources: - input/translations/dei18n-default-lang是源语言:input/pagecontent/使用的语言,也是权威文本。- 每个
i18n-lang条目都是一个目标语言:会在/<lang>/下生成呈现内容的语言。 - 如果未设置
i18n-default-lang,则使用发布器的默认设置,且未声明源语言。请说明这一点并询问,不要猜测——猜错会导致每个文件都放错位置。 - 如果未配置
i18n-lang,就尚无目标语言。添加目标语言属于指南配置变更,应由维护者决定,而非此技能决定。
绝不可跳过这一步。 MII 曾将默认语言从德语改为英语;如果技能硬编码了旧方向,就会把每个文件都放错位置,却仍报告成功。
-
先构建。 资源补充文件需要生成的资源:发布器会写入
fsh-generated/resources/,并在每次构建时为每个资源生成补充模板。在构建成功前进行翻译,就意味着凭空编造msgid值,这是捏造内容。 -
检查问题出在指南还是模板。 语言支持通常由 IG 和用于呈现它的模板包共同负责;这种划分关乎职责,而非路径:
- 此技能负责指南自身的内容:补充文件,以及
input/translations/<lang>/下的翻译页面。 - 模板包负责语言的机制和策略——与语言无关的页眉、页脚和 CSS、继承的 UI 字符串目录,以及默认语言的选择。
对于 MII KDS 模块模板,相应的模板包是 https://github.com/medizininformatik-initiative/ig-template-mii-kds,它有自己的技能来处理这些职责。如果任务是“让模板的覆盖项与语言无关”,那是模板的问题,不属于此技能。
- 此技能负责指南自身的内容:补充文件,以及
操作流程
输出语言:前提条件 2 中推导出的目标语言。 这些说明使用英语;此技能生成的是目标语言的文本。两者并无必然关系,因此特此说明。以下示例使用 de 作为目标语言,因为这是此处的常见情况;请替换为实际推导出的语言。
先确定脚本路径。 以下命令中,工具路径是相对于此技能自身的目录,而非相对于工作目录——工作目录是你正在操作的项目。将
SKILL_DIR设为包含此SKILL.md的目录(你刚刚读过它,因此知道其位置),并在每次调用时使用它:SKILL_DIR=<the directory containing this SKILL.md> # e.g. .claude/skills/fhir-ig-translation在项目根目录运行未加路径的
scripts/...,不只是会失败——如果项目恰好有自己的scripts/目录,且其中有同名文件,它就会悄悄运行那个文件。
-
扫描以获取每个页面和资源的目标路径:
bash "$SKILL_DIR/scripts/ig-translate.sh" --scan <lang> # cwd = the guide's root bash "$SKILL_DIR/scripts/ig-translate.sh" --scan <lang> path/to/ig # or point at it语言参数是必需的——脚本拒绝使用默认值,因此不会在无人选择语言的情况下悄悄翻译。
-
资源补充文件。 每个 StructureDefinition、CodeSystem 或 Questionnaire 对应一个文件,路径为
input/translations/<lang>/<Type>-<id>.po,其中msgid是fsh-generated/resources/<Type>-<id>.json中的确切源文本,msgstr是译文。复制发布器生成的 模板,不要手动编写msgid。 -
叙述页面。 每个页面对应一个译文,路径为
input/translations/<lang>/pagecontent/<same-filename>.md——文件名相同、结构相同、链接相同,FHIR 标识符保持不变。绝不要在input/pagecontent/中创建<name>-<lang>.md同级文件:工具链会将其渲染为单独的页面,而非译文。 -
菜单,如果指南中有菜单:
input/translations/<lang>/includes/menu.xml,与input/includes/menu.xml保持一致。sushi-config.yaml中的menu:属性会生成一个不可翻译的 菜单,并与此冲突——不得同时使用。 -
IG 级目录
input/translations/<lang>/ImplementationGuide-<ig-id>.po。它不是 资源补充文件,也不是可选项:缺少它时,pages:树中的页面标题会保留默认语言,因此/<lang>/会在默认语言的面包屑下渲染本地化的页面正文。<ig-id>是fsh-generated/resources/ImplementationGuide-<id>.json中的id;使用该文件的definition.page树构建单元集合——这是权威页面集合;仅将input/includes/menu.xml用作措辞参考,并为每个未翻译的标题设置空的msgstr和审阅标记。同级的
mii-ig-migration技能包含专门用于生成此文件的生成器。这是一个 前置条件,而非假设:使用者可能只安装了此技能,此时同级路径并不存在。先检查;若路径不存在,则使用下面固定版本的命令安装,或手动编写单元——绝不要在路径无法解析时继续操作。通过已解析的$SKILL_DIR调用它,绝不要直接使用scripts/…,因为项目自身的scripts/会覆盖它:GEN="$SKILL_DIR/../mii-ig-migration/scripts/gen-page-title-po.py" if [ -f "$GEN" ]; then python3 "$GEN" --help; else echo "gen-page-title-po.py not installed — install the sibling skill, or write the units by hand:" echo 'npx skills add "https://github.com/forschungsgruppe-digital-health/agent-skills/tree/v0.14.0" --skill mii-ig-migration --agent claude-code codex --yes' fi/tree/<ref>形式才会固定版本;owner/repo@<ref>不会——在该 CLI 中,@表示技能名称,该命令会悄悄从默认分支安装。重新生成现有目录之前,请先阅读该脚本的文件头:同一个文件还包含手动添加的单元(指南的
title、每个制品的名称),这些单元不归生成器管理;文件头会说明生成器如何处理它们。 -
先验证,再构建:
bash "$SKILL_DIR/scripts/ig-translate.sh" --validate <lang>有发现项(
[WARN])时会以状态码 1 退出;如果没有找到任何可验证内容,则会明确说明并以状态码 0 退出——添加--strict也会让空翻译集验证失败,这才是 CI 的正确配置。 -
在信任译文渲染结果之前,必须进行双语人工审阅。 所有机器翻译都应标记为
TODO:REVIEW,直到人工确认无误。
收集模式——采用现有渲染结果
如果目标语言的渲染结果已存在于某处,请收集现有内容,而不要重新翻译:
- 填写
references/harvest-config.yaml:目标语言文本的来源(叙述内容使用平行渲染的指南;资源文本使用 FSHtranslation扩展或designation),以及页面/制品映射。 - 资源: 将现有的 designation 或 translation 扩展移入
input/translations/<lang>/<Type>-<id>.po。现有渲染结果的页面标题可作为 IG 级目录(步骤 5)的翻译参考,但不能替代该目录。 - 叙述内容: 将页面内容复制到
input/translations/<lang>/pagecontent/<name>.md,并注明每个页面的来源路径。不要臆造内容;不明确之处标记为TODO:REVIEW。 - 按上述说明进行验证、构建和审阅。
工具链实际呈现的内容
除非行中另有说明,均使用 IG Publisher 2.2.11 和 fhir2.base.template 0.1.0(2026-07)进行验证——其中一行依据 HL7 的参考 IG,其在线构建由 2.0.13 版 publisher 生成;另有一行明确标注为未经验证。每行都会说明各自的依据;请勿认为标题适用于所有行。这是 publisher 的行为,适用于任何语言对。
| 内容 | 是否可翻译? | 机制 |
|---|---|---|
叙述性页面(input/pagecontent/<name>.md) | 可以,会渲染 | input/translations/<lang>/pagecontent/<same-filename> — 整个页面会在 /<lang>/ 下渲染。没有对应文件 → 回退到默认语言的源文件。 |
StructureDefinition、CodeSystem、Questionnaire 的资源文本(description、designations、元素 definition) | 可以,会渲染 | 补充文件 input/translations/<lang>/<Type>-<id>.{po|xliff|json} |
菜单(input/includes/menu.xml) | 可以 | input/translations/<lang>/includes/menu.xml |
ImplementationGuide 自身的 title,以及每个制品的 definition.resource.name | 可以,会渲染——但已在 2.0.13 参考构建中观察到,本项目固定使用的版本中未观察到 | input/translations/<lang>/ImplementationGuide-<ig-id>.po。这不是资源补充文件——发布器在加载时导入 IG 的翻译(PublisherIGLoader → importFromTranslations,从源文件读取),因此不受 TRANSLATION_SUPPLEMENT_RESOURCE_TYPES 限制。单元以 #: 注释中的 FHIRPath 为键。HL7 参考构建中可见 es 标题以及 es/artifacts.html 制品名称 |
ImplementationGuide 的 description、publisher、name,以及每个制品的 .description | 未经验证 | 参考目录中存在这些单元,且应放在同一文件中;但在两个构建中均未观察到渲染效果。name 是 FHIR 的计算机友好名称,不是显示文本——不要期待它会渲染。应添加这些内容,但不要声称它们有效 |
面包屑和 pages: 树页面的标题(包括根标签在内的面包屑、目录页面正文、浏览器 <title>) | 可以,会渲染 | 同一 IG 级别 .po 文件中的 ImplementationGuide.definition.page.title 单元;发布器会将其传入各语言的 titlelang / breadcrumblang 映射。已在 2.2.11 的一个迁移后 MII KDS 模块中验证,该模块删除了面包屑覆盖(23 个单元;temp/pages/_data/pages.json 中全部 23 项的 titlelang 均与 en/de 不同,此前为零)。未检查左侧导航菜单——不对此作任何声明。 从生成的 ImplementationGuide-<id>.json 的 pages: 树生成这些单元(这是权威集合),以菜单作为措辞参考;对于仍未翻译的标题,输出空 msgstr 并添加审核标记。HL7 的 FHIR/multi-lang-test-ig 附带此类文件,并据此渲染 es / nl 面包屑;两个 MII 模板仓库的 dev 分支也已附带此类文件。这取代了面包屑覆盖(fragment-pagebegin.html + input/includes/breadcrumb-titles-de.txt);该覆盖仅随一个版本发布,即模板 v0.5.0——从未出现在 v0.4.0 或更早版本中,也从未出现在 dev 上。由 v0.5.0 生成的模块应添加此 .po 并移除覆盖。切勿通过同级页面或菜单技巧绕过 |
ValueSet,concept.display / concept.definition | 部分支持 / 不支持——尚无定论 | 在此工具链中,不会从普通 .po 补充文件应用。此处刻意保留冲突,尚未解决:references/translate-spec.md § 1 将 concept.display / concept.definition 列为受支持的 CodeSystem 补充文件会翻译的字段。两种说法都没有构建验证;下次运行涉及 CodeSystem 补充文件时必须测试,并替换这两种说法 |
在 i18n-lang 中存在、但未出现在 translation-sources 中的语言 | 不支持——且不提示 | 其 .po 文件会被忽略,不报错也不警告,并渲染默认语言。判断某种机制不受支持之前,请先检查这两项配置是否配对 |
请将此表视为事实依据,并在固定使用的 IG Publisher 或基础模板版本变更时重新验证。请从指南自身的构建工作流中读取版本固定信息,不要从本文件读取。
已过时的说法,记录于此以免再次引入:
- 此技能的早期版本使用
<name>-<lang>.md同级文件存放页面,并称叙述页面“尚不可”渲染。这两点都不正确。正确机制是翻译源文件夹,正如 HL7 自己的FHIR/multi-lang-test-ig所示。 - 此技能声称
ImplementationGuide-<id>.po会“被 Publisher 忽略”,IG 标题“没有补充机制”,而pages:树中页面的默认语言面包屑是“工具链限制,而非缺陷”,需要使用 MII 模板的breadcrumb-titles-de.txt作为变通方案。这些说法都不正确:它把TRANSLATION_SUPPLEMENT_RESOURCE_TYPES(确实会限制资源补充文件)泛化到了 IG 资源,而 IG 资源是通过单独的加载时导入来翻译的。页面标题机制已在我们的固定版本 2.2.11 上,通过一个删除了模板面包屑覆盖项的 MII KDS 模块进行了验证;HL7 的参考 IG 包含此类.po文件,其由 2.0.13 生成的线上构建会据此渲染es/nl面包屑。这并不能说明 Publisher 从何时起支持此功能:我们并未声称有最低支持版本,也不应根据这两个版本号推断。导致“翻译未生效”的真正原因,通常是上表中的translation-sources易错点。
验证
bash "$SKILL_DIR/scripts/ig-translate.sh" --validate <lang> # --strict: empty set fails too
- 在 IG 外部运行,或缺少语言参数时,以退出码 2 退出并显示清晰的消息——此项用于防止静默扫描出空结果。
--validate会为每个补充文件和每个页面报告[OK],且不出现[WARN];任何[WARN]都会导致退出码为 1,摘要行会说明实际检查了多少个补充文件和页面。“Checked: 0”且退出码为 0 表示明确没有内容可验证,绝不代表翻译有效(--strict会将其视为失败)。- 当
<lang>不在指南的i18n-lang目标列表中,或未声明i18n-default-lang时,脚本会发出 WARN——这是对前置条件 2 的尽力提醒,并不能替代该条件。 - 每个
.po文件名都采用<Type>-<id>格式,并且与实际存在的fsh-generated/resources/<Type>-<id>.json匹配——包括ImplementationGuide-<ig-id>.po,它是合法文件,并非命名错误。 - 不支持的类型没有补充文件,也不存在
menu.po——Publisher 会忽略这两者。 - 每个
i18n-lang条目都有对应的translation-sources条目;否则,该语言的.po文件会被静默忽略。 - 每个翻译页面在
input/pagecontent/下都有一个同名源页面。 - 构建后,
/<lang>/下的产物页面会显示已翻译的元素文本,且/<lang>/下的叙述页面会以目标语言渲染。 - 使用 IG 级别的
.po文件构建后,/<lang>/下的面包屑、TOC 页面正文和浏览器<title>都会使用目标语言,并且对于pages:树中的每个页面,temp/pages/_data/pages.json中的titlelang都与默认语言标题不同。若某个页面的titlelang仍与源标题相同,则说明该单元没有内容,或msgstr为空,或该语言缺少对应的translation-sources条目。 - 默认语言的
input/pagecontent/和 FSH 源文件保持不变——对它们运行git diff不会有任何输出。
Guardrails
- 默认语言源内容始终优先且具有约束力。 翻译仅用于辅助理解,绝非规范性文本。默认语言由
i18n-default-lang指定,而非由本文件指定。 - 绝不更改源内容。 翻译只能作为补充内容添加到
input/translations/<lang>/下。 - FHIR 标识符不翻译——
name、id、代码和规范 URL 不属于语言文本。 - 不得自行编造。 所有机器翻译都必须标记为
TODO:REVIEW;双语人工审校是强制要求。 - 仅在确认后执行。 默认只进行试运行扫描。
- 提出更改,不要合并。 以拉取请求提交更改,并根据仓库自身惯例确定目标分支——不要想当然地假定。此技能的早期版本将
dev硬编码为目标分支;这是某个仓库的惯例,在其他仓库中并不适用。
范围与界定
涵盖制作并放置指南的翻译补充内容,包括两个溯源方向:翻译默认语言源内容,或收集现有译文。
明确不涵盖:
- 测量或比较指南——参见
fhir-ig-analysis。 - 将指南迁移到 MII KDS 模块模板——参见
mii-ig-migration;该技能将翻译作为迁移步骤之一,然后移交给本技能。 - 模板包的语言机制和政策——这是另一个仓库需要关注的事项;参见前提条件 4。
- 选择指南的语言。 添加
i18n-lang条目会更改指南的配置,这由其维护者决定。 - 评判译文质量。 这属于强制性人工审校,而非本技能的职责。
如果本目录和本地同时提供同名技能,则以本地版本为准。
参考资料
references/translate-spec.md— 完整的操作细节、文件惯例和格式。references/harvest-config.yaml— 收集模式的配置架构。references/triggers.md— Gate 3 提示词集。scripts/ig-translate.sh— 扫描和验证;按设计仅进行试运行,不会写入任何内容。它会扫描资源补充内容旁的 IG 级目录清单,并在--validate中接受该清单;真正不受支持的类型仍会发出 WARN。验证发现问题时退出码为 1;--strict还会在翻译集为空时失败。
溯源
源自 medizininformatik-initiative/mii-kds-module-template 中的 skills/ig-translate,提交为 b5beedb17a66a4397d597429668c7b6d54202c62;后者改编自 forschungsgruppe-digital-health/mii-kds-sample-ig-inoffiziell 的 ig-translate 技能(CC-BY-4.0),并将其重新聚焦于模块侧。这条传承链的两个步骤都经过了明确记录。
于 2026-07-31 为本目录重新调整。除了符合目录规范之外,还做了四项实质性更改:
- 现在辅助脚本与技能一同提供。此前它位于源仓库的
scripts/中,并通过向上遍历父目录来引用。 scripts/ig-translate.sh现在以当前工作目录为操作对象,并检测该目录是否为 IG 项目。此前它会执行cd "$(dirname "$0")/..",假定脚本位于<module-repo>/scripts/;安装为技能的一部分后,cd会进入技能目录,扫描结果会将每个页面都报告为缺失。- 已从说明和护栏中移除
dev分支作为目标的设定,改为发现仓库自身的惯例。 - 语言对由配置推导,而非预先假定。 继承的技能只针对一个方向(
en→de)编写,并且专用于 MII KDS 模块,因此在其名称中使用fhir-前缀言过其实。现在,它会从正在处理的指南中读取i18n-default-lang和i18n-lang;脚本要求显式指定语言参数,不再默认使用de;操作细节也适用于任意语言对。这正是该技能使用此前缀的依据。 于 2026-08-01 修订:在该技能首次真实任务演练(针对kerndatensatz-dokument的试运行)后,--validate发现的问题现在会以状态码 1 退出;如果翻译集为空,脚本会明确报告(并在--strict下失败),而不再无条件以状态码 0 退出;脚本会尽力将<lang>与指南的 i18n 参数交叉核对,并在有问题时发出警告;采集配置中的page_map示例现在涵盖非英语源页面名称;allowed-tools授权现在涵盖执行随附的 bash 脚本。试运行发现的问题位于mii-kds-dokument-ig-inoffiziell沙盒下的docs/reports/dry-run-2026-07-31/。
于 2026-08-05 修订,以撤回一项有记录的错误说法:即发布器无法本地化 pages: 树中页面的标题,且 ImplementationGuide-<id>.po 会被忽略。以下是证据,仅限于此:
- 我们在自己的固定版本(IG Publisher 2.2.11)上进行的构建——迁移后的 MII KDS Dokument 指南,删除了模板的面包屑覆盖,并提供了 23 个
page.title单元:/de/面包屑为德语,包括根标签“Inhaltsverzeichnis”;TOC 页面正文为德语;浏览器的<title>为德语;temp/pages/_data/pages.json中全部 23 个页面的titlelang在 en/de 之间各不相同(此前为零)。构建健康状况不变(sushi 0 个错误,QA err=7,与既定基线一致)。在 2.2.11 上未观察到左侧导航、IG.description、IG.publisher、IG.name和构件名称,因此不对此版本作相关声明。 - HL7 的参考 IG
FHIR/multi-lang-test-ig,由发布器 2.0.13 生成的线上构建——本地化的es/nl面包屑、/es/页眉中翻译后的 IG 标题、/es/artifacts.html上翻译后的构件名称,以及fr(存在于i18n-lang,但不在translation-sources中)作为受控负例。其发布器版本与我们的不同;在表格中单独列出。 - **我们组织内的先例:**两个 MII 模板仓库的
dev分支都已有正确的目录,且ig-template-mii-kds在 MII 自己的kerndatensatz-basis模块中记录了同一机制,标注为“已于 2026-07-30 验证”。
由此带来的调整:渲染表中的每一行都标明支持该功能的构建,并将未观察到的字段标记为未经验证;记录面包屑覆盖仅随一个版本,即模板 v0.5.0 发布(从未在 v0.4.0 或更早版本中发布,也从未在 dev 上发布),并将其标记为现正撤回的误判;新增了一个用于 IG 级目录的 Procedure 步骤,指向 mii-ig-migration 随附的生成器;将此文件与 references/translate-spec.md 之间关于 CodeSystem concept.display/definition 的冲突标记为尚未解决,而非默默作出定论;并且 scripts/ig-translate.sh 不再针对 ImplementationGuide-<id>.po 发出 WARN,也不会因该文件失败——该文件正是此 Procedure 现在要求使用的文件;但对确实不受支持的类型仍会发出警告并失败。
原始许可:CC-BY-4.0,由两个源仓库声明。scripts/ 使用 Apache-2.0,与本仓库的代码许可一致。