如果你没用 FHIR 写过医疗系统的 API,你可能很难理解那种”明明觉得自己写对了,结果一看规范发现自己错得离谱”的崩溃感。FHIR(Fast Healthcare Interoperability Resources)是 HL7 推出的医疗数据交换标准,R4 版本光是核心资源类型就有 150 多种,每种都有自己的必填字段、值集、编码系统和校验规则。
把这么大一套规范塞进脑子里,不是靠”熟能生巧”就能搞定的。大多数开发者的实际状态是:开着 FHIR 官网文档,一边查字段定义一边写代码,时不时还会漏掉某个 mandatory 字段,上线后监控告警一片红。
Anthropic 的 Healthcare 市场最近发布了一个叫 FHIR Developer Skill 的东西,做的就是这件事:把 FHIR R4 的核心规范直接注入到 AI 编程助手的上下文里。它不是一个工具,不是一个库,是一个让 AI 在帮你写代码时自动带上 FHIR 规范意识的”领域知识层”。
说真的,这篇文章不讲 FHIR 的理论基础,也不逐条翻译官方文档。我从这个 Skill 的 SKILL.md 结构出发,拆一下它的设计逻辑、覆盖范围、实际用法,以及它在医疗开发工作流里到底能省掉多少查文档的时间。
环境准备
这个 Skill 的安装方式跟所有 Claude Code 插件一样,一行命令搞定。它托管在 Anthropic 的 Healthcare 仓库里,属于一个三件套市场的一部分:
npx skills add https://github.com/anthropics/healthcare --skill fhir-developer-skill
装完之后不需要任何额外配置。SKILL.md 只有 9.7 KB,六个文件,结构很精简,一个主 SKILL.md 文件、一个 references 目录、一个 scripts 目录。没有 Python 依赖,没有环境变量,不依赖外部 API。

前置条件就两条:有个支持 Skill 系统的 AI 编程助手(Claude Code 或兼容客户端),有基本的 FHIR 概念认知。如果你完全不知道 FHIR 是什么,这个 Skill 不会从零教起,它假设你已经知道 Resource、Bundle、OperationOutcome 这些基础概念在说什么。
一个值得注意的点是它并不要求你有任何编码系统的本地副本。下面这些标准术语系统的 URL 和用法都写死在 Skill 里了,你不需要自己去配 ontology server 或术语服务:
-
LOINC(实验室与临床观测指标) -
SNOMED CT(临床术语全集) -
RxNorm(药品标准化命名) -
ICD-10(疾病与死因分类)
操作流程
Skill 加载后,AI 的行为变化很直接:它会在你写 FHIR 相关代码时自动套用 R4 规范来做校验、建议和错误处理。但从 SKILL.md 的实际内容来看,这个 Skill 的价值不只是在”自动纠错”上,它的 Quick Reference 部分本身就是一份精心裁剪过的速查表。
它覆盖了七个 FHIR 资源类型:
-
Patient(患者基本信息) -
Observation(临床观测数据) -
Encounter(就诊记录) -
Condition(疾病与健康状况) -
MedicationRequest(用药处方) -
Medication(药品定义) -
Bundle(批量操作与搜索容器)
前六个是医疗系统里最常用的核心资源,Bundle 是用来做批量操作和搜索返回的容器类型。
每个资源都有一个”必填字段清单”。比如 Observation 要求 status 和 code,缺一个就返回 422;Patient 反而没有任何必填字段,全是可选的。这个细节很关键,很多开发者习惯性地给 Patient 加一堆 mandatory 校验,结果反而跟 FHIR 规范冲突了。
HTTP 状态码这一块的处理尤其到位。FHIR 对 HTTP 语义的要求比普通 REST API 更严格:
-
201 Created 必须带 Location header -
412 Precondition Failed 用于 ETag 版本冲突,不是 400 -
422 Unprocessable Entity 用于业务规则违反和枚举值无效,也不是 400
这三个”不是 400″的情况是新手最容易踩的坑。Skill 里直接用代码示例展示了正确的处理方式:
VALID_OBS_STATUS = {"registered", "preliminary", "final", "amended",
"corrected", "cancelled", "entered-in-error", "unknown"}
@app.post("/Observation", status_code=201)
async def create_observation(data: dict):
if not data.get("status"):
return JSONResponse(status_code=422, content=operation_outcome(
"error", "required", "Observation.status is required"
), media_type="application/fhir+json")
if data["status"] not in VALID_OBS_STATUS:
return JSONResponse(status_code=422, content=operation_outcome(
"error", "value", f"Invalid status '{data['status']}'"
), media_type="application/fhir+json")

另外它还覆盖了编码系统的用法。这块内容的价值在于它不是简单列出 URL,而是把每种编码系统的实际使用场景跟对应的数据类型一起整理清楚了:
-
Coding 和 CodeableConcept 的区别与各自适用场景 -
LOINC 用于生命体征的常用代码:心率 8867-4、血压 8480-6、舒张压 8462-4、体温 8310-5、血氧 2708-6 -
SNOMED CT 用于临床诊断和手术编码 -
ICD-10 用于疾病分类和报销编码
对写 Observation 和 Condition 这两个资源的开发者来说,相当于把最常用的术语查询结果提前备好了。
关键设计
这个 Skill 最聪明的设计决定,是它没有试图覆盖 FHIR R4 的全部 150+ 个资源类型,甚至没有覆盖所有常用的。它选了七个。
从文档结构来看,这个选择不是随机的。Patient 和 Encounter 是基础管理资源,Observation 和 Condition 是临床数据核心,MedicationRequest 和 Medication 是药事管理入口,Bundle 是传输容器。这七个资源覆盖了一个典型医疗系统 80% 以上的 API 交互场景。
另一个设计细节是它对”必填字段”的处理方式。Skill 里专门强调了一条规则:只有 cardinality 以 “1” 开头的字段才是必填的,0…1 和 0…* 都不是。这条规则看似简单,但在实际开发中被违反的频率出奇的高。很多开发者看到 “subject” 就觉得”这肯定得填”,但 Encounter.subject 的实际 cardinality 是 0…1。
它还内置了一个”常见错误清单”。比如用 CodeableConcept 而不是 Coding 来表示 Encounter.class、在 ETag 不匹配时返回 400 而不是 412、创建资源成功时忘了加 Location header。这些错误清单的价值不在于”告诉你什么是对的”,而在于覆盖了最容易犯但最难排查的那几个坑。

值得留意的是它同时提供了 Python(FastAPI + Pydantic v2)和 TypeScript(Express)两种语言的代码示例。这意味着它不是那种”给你一段伪代码自己领悟”的文档,是在两种实际生产环境中都能直接复制使用的参考实现。
使用场景
这个 Skill 最直接的用武之地,是搭建新的 FHIR REST 端点。你在 Claude Code 里说”帮我写一个创建 Observation 的 POST 接口”,AI 会自动加上以下全部规范化处理:
-
status 和 code 必填字段校验 -
枚举值有效性检查 -
201 Created + Location header -
application/fhir+jsonContent-Type -
OperationOutcome 错误体
你不需要在每个环节都反复翻规范。
第二个高频场景是已有代码的合规审查。把现有的 FHIR 接口代码扔给 AI,让它用这个 Skill 做规范检查,它能逐行对比你的实现跟 FHIR R4 要求之间的偏差。下面这些常见的规范违反都会被点出来:
-
HTTP 状态码用错了 -
必填字段遗漏 -
Content-Type header 缺失 -
ETag 版本控制处理不当
它也能覆盖一些更高级的操作,比如 Bundle 的事务处理和批量操作、SMART on FHIR 的 OAuth scope 配置、搜索分页的正确实现方式。这些场景的规范复杂度比单资源 CRUD 高一个数量级,AI 如果没有 Skill 加持,出错的概率相当大。
不过这个 Skill 的边界也很明确。它不处理 FHIR 版本迁移(DSTU2 到 R4 到 R5),不处理特定厂商的扩展实现,不处理实际的数据持久化逻辑。它做的事情就是一件事:在你跟 AI 讨论医疗 API 代码的时候,确保 FHIR R4 的规范始终在场。
洞察与反思
从 SKILL.md 的组织方式来看,它本质上是一个经过高度压缩和结构化处理的”领域知识注入”。9.7 KB 的文件里塞进了五样东西:
-
HTTP 状态码决策表 -
七种资源的必填字段矩阵 -
六套编码系统的 URL 映射 -
Python 和 TypeScript 两种语言的验证代码模板 -
一个常见错误对照表
这种信息密度的背后是一个很实际的考量:AI 上下文窗口是有限的,每多塞一个 token 就要挤掉其他上下文。这个 Skill 的设计者在资源覆盖范围和知识深度之间做了一次相当精准的权衡。
跟直接在 Prompt 里贴 FHIR 文档对比,这个 Skill 的优势是”结构化”。它不是让 AI 从零散文档中自行归纳规则,而是直接把规则整理成”条件→动作”的决策表形式。HTTP 状态码那块尤其典型:每个状态码都对应一个具体的触发条件,AI 不需要推理,只需要匹配。
但我认为这个 Skill 还有一个隐含的价值,它的”常见错误清单”实际上充当了一个反模式知识库。很多 FHIR 文档只会告诉你”应该怎么做”,不会告诉你”最容易做错什么”。而这个清单正好覆盖了后者,这在实际开发中的价值可能比正向规范还要大。
不过 30 个安装量对于一个 Smithery Skill 来说不算高。这可能跟 FHIR 本身的受众规模有关,也可能是因为医疗开发者对 AI 编程助手的接受度还在爬坡期。从社区反馈来看,用过的人对它的评价很正面,最常提到的词是”省掉了反复查文档的时间”。
资源地址
| 资源 | 地址 |
|---|---|
| Smithery 页面 | https://smithery.ai/skills/anthropics/fhir-developer-skill |
| GitHub 仓库(Healthcare Marketplace) | https://github.com/anthropics/healthcare |
| FHIR R4 官方规范 | https://hl7.org/fhir/R4/ |
| 安装命令 | npx skills add https://github.com/anthropics/healthcare --skill fhir-developer-skill |
总结
FHIR Developer Skill 做的事情并不复杂:把 FHIR R4 最核心的那部分规范整理成 AI 可以直接使用的结构化知识,让你在写医疗 API 的时候不用在两个窗口之间来回切换。
它的真正价值不在于替代查文档,而在于减少”以为自己写对了但实际写错了”的次数。那些 400 还是 412 的边界决策、coding 还是 CodeableConcept 的数据类型选择、subject 到底是不是必填,这些是规范里写得明明白白但开发者经常记混的点。
如果你已经在用 AI 编程助手写 FHIR 接口,这个 Skill 值得装。如果你还在手动翻 FHIR 官网写 API,那更值得装。九千字节的上下文开销,换一个时刻在场的 FHIR 规范意识,这笔交易很划算。
