mcpField
F
fhir-ig-translation

fhir-ig-translation

github.com/forschungsgruppe-digital-health文档处理0295 次安装9 周前更新
代码仓库

关于 fhir-ig-translation

fhir-ig-translation 是用于翻译基于 IG Publisher 的 FHIR 实施指南的实验性技能。它从指南配置读取语言方向,并指导创建和验证资源补充、页面、菜单及页面标题目录。

主要功能

  1. 01从配置读取源语言和目标语言
  2. 02创建资源翻译补充文件
  3. 03翻译叙述页面和菜单
  4. 04生成 IG 页面标题目录
  5. 05验证翻译文件并标记待审内容

适用场景

  1. 01将 FHIR 指南本地化为已配置语言
  2. 02采用现有渲染版本中的译文
  3. 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.yaml
translate-spec.md
triggers.md
scripts/
ig-translate.sh

详细介绍

翻译 FHIR 实施指南

实验性。 自上次更改以来,此技能尚未在真实任务中验证。请先验证其输出,再依赖它。

生成基于 IG-Publisher 的指南的翻译补充文件,并将其准确放置在发布器查找的位置。指南自身的配置决定哪种语言是源语言,哪些语言是译文——此技能会读取该配置,而不是自行假定。

前提条件

  1. 定位指南。 在工作目录中,查找 input/pagecontent/,以及 sushi-config.yaml 或 ig.ini。scripts/ig-translate.sh 会自行检查这一点;如果目录不是 IG 项目,就会显示消息并以状态码 2 退出——它会刻意避免报告“无需翻译”,因为这会导致这里出现无声失败。

  2. 推导语言对——切勿假定。 读取指南自身的 sushi-config.yaml:

    parameters:
      i18n-default-lang: en        # the SOURCE language
      i18n-lang:
        - de                       # the TARGET language(s)
      translation-sources:
        - input/translations/de
    
    • i18n-default-lang 是源语言:input/pagecontent/ 使用的语言,也是权威文本。
    • 每个 i18n-lang 条目都是一个目标语言:会在 /<lang>/ 下生成呈现内容的语言。
    • 如果未设置 i18n-default-lang,则使用发布器的默认设置,且未声明源语言。请说明这一点并询问,不要猜测——猜错会导致每个文件都放错位置。
    • 如果未配置 i18n-lang,就尚无目标语言。添加目标语言属于指南配置变更,应由维护者决定,而非此技能决定。

    绝不可跳过这一步。 MII 曾将默认语言从德语改为英语;如果技能硬编码了旧方向,就会把每个文件都放错位置,却仍报告成功。

  3. 先构建。 资源补充文件需要生成的资源:发布器会写入 fsh-generated/resources/,并在每次构建时为每个资源生成补充模板。在构建成功前进行翻译,就意味着凭空编造 msgid 值,这是捏造内容。

  4. 检查问题出在指南还是模板。 语言支持通常由 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/ 目录,且其中有同名文件,它就会悄悄运行那个文件。

  1. 扫描以获取每个页面和资源的目标路径:

    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
    

    语言参数是必需的——脚本拒绝使用默认值,因此不会在无人选择语言的情况下悄悄翻译。

  2. 资源补充文件。 每个 StructureDefinition、CodeSystem 或 Questionnaire 对应一个文件,路径为 input/translations/<lang>/<Type>-<id>.po,其中 msgid 是 fsh-generated/resources/<Type>-<id>.json 中的确切源文本,msgstr 是译文。复制发布器生成的 模板,不要手动编写 msgid。

  3. 叙述页面。 每个页面对应一个译文,路径为 input/translations/<lang>/pagecontent/<same-filename>.md——文件名相同、结构相同、链接相同,FHIR 标识符保持不变。绝不要在 input/pagecontent/ 中创建 <name>-<lang>.md 同级文件:工具链会将其渲染为单独的页面,而非译文。

  4. 菜单,如果指南中有菜单:input/translations/<lang>/includes/menu.xml,与 input/includes/menu.xml 保持一致。sushi-config.yaml 中的 menu: 属性会生成一个不可翻译的 菜单,并与此冲突——不得同时使用。

  5. 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、每个制品的名称),这些单元不归生成器管理;文件头会说明生成器如何处理它们。

  6. 先验证,再构建:

    bash "$SKILL_DIR/scripts/ig-translate.sh" --validate <lang>
    

    有发现项([WARN])时会以状态码 1 退出;如果没有找到任何可验证内容,则会明确说明并以状态码 0 退出——添加 --strict 也会让空翻译集验证失败,这才是 CI 的正确配置。

  7. 在信任译文渲染结果之前,必须进行双语人工审阅。 所有机器翻译都应标记为 TODO:REVIEW,直到人工确认无误。

收集模式——采用现有渲染结果

如果目标语言的渲染结果已存在于某处,请收集现有内容,而不要重新翻译:

  1. 填写 references/harvest-config.yaml:目标语言文本的来源(叙述内容使用平行渲染的指南;资源文本使用 FSH translation 扩展或 designation),以及页面/制品映射。
  2. 资源: 将现有的 designation 或 translation 扩展移入 input/translations/<lang>/<Type>-<id>.po。现有渲染结果的页面标题可作为 IG 级目录(步骤 5)的翻译参考,但不能替代该目录。
  3. 叙述内容: 将页面内容复制到 input/translations/<lang>/pagecontent/<name>.md,并注明每个页面的来源路径。不要臆造内容;不明确之处标记为 TODO:REVIEW。
  4. 按上述说明进行验证、构建和审阅。

工具链实际呈现的内容

除非行中另有说明,均使用 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,与本仓库的代码许可一致。

评论

支持 Markdown