Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计提醒

fhir-software飞尔软件

Agent Skill

fhir-software 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

272

周安装

11

GitHub Stars

46

下载量

85
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:fhir-software(飞尔软件)
来源仓库:https://github.com/topologyhealth/claudefhirskill
仓库路径:skills/fhir-software
安装命令:
npx skills add https://github.com/topologyhealth/claudefhirskill --skill fhir-software
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/topologyhealth/claudefhirskill --skill fhir-software

简介

fhir-software 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中快速定位候选结果。

  • 适用于需要根据关键词或任务场景进行信息定位的场景。
  • 通过关键词搜索和来源线索筛选目标信息。
  • 安装命令:npx skills add https://github.com/topologyhealth/claudefhirskill --skill fhir-software。
  • 建议确认权限范围和维护状态后再使用。

SKILL.md

FHIR Software Development Skill

Expert guidance for building robust FHIR (Fast Healthcare Interoperability Resources) software systems with comprehensive package management, spec knowledge, and development workflows.

Core Architecture

1. Package/Specification Management

Local FHIR Package Cache:

  • Use @fhir/package-loader or equivalent for TypeScript/Node.js environments
  • For Python: fhir-package-loader or custom implementation using requests + json
  • Cache strategy: ~/.fhir/packages/ with version-specific directories
  • Support packages: hl7.fhir.r4.core, hl7.fhir.r5.core, Implementation Guides

Package Resolution Pattern:

// Load and cache FHIR packages
async function loadFhirPackage(packageId: string, version?: string) {
  const cacheDir = path.join(os.homedir(), '.fhir', 'packages', packageId, version || 'current');
  if (await fs.pathExists(cacheDir)) return loadFromCache(cacheDir);

  const packageData = await downloadPackage(packageId, version);
  await cachePackage(cacheDir, packageData);
  return packageData;
}

Document Index Structure: Build searchable index from package contents:

  • StructureDefinitions (resources, profiles, extensions)
  • SearchParameters (for API implementation)
  • ValueSets and CodeSystems (terminology)
  • OperationDefinitions (custom operations)
  • CapabilityStatements (server capabilities)
  • Example instances

2. Development Workflows

FHIR Resource Modeling

# Use Pydantic for FHIR resource modeling in Python
from pydantic import BaseModel, Field, field_validator
from typing import Optional, List, Literal
from enum import Enum
import re

class PatientGender(str, Enum):
    MALE = "male"
    FEMALE = "female"
    OTHER = "other"
    UNKNOWN = "unknown"

class Patient(BaseModel):
    resourceType: Literal["Patient"] = "Patient"
    id: Optional[str] = None
    active: Optional[bool] = None
    name: Optional[List[dict]] = None
    gender: Optional[PatientGender] = None
    birthDate: Optional[str] = None

    @field_validator('birthDate')
    @classmethod
    def validate_birthdate(cls, v):
        if v and not re.match(r'^\d{4}-\d{2}-\d{2}$', v):
            raise ValueError('Invalid date format, must be YYYY-MM-DD')
        return v

    class Config:
        extra = "allow"  # Allow additional FHIR elements

FHIR Server Implementation Patterns

FastAPI + Pydantic (Python):

from fastapi import FastAPI, HTTPException
from fhir.resources.patient import Patient

app = FastAPI()

@app.post("/Patient", response_model=Patient)
async def create_patient(patient: Patient):
    # Validate against FHIR spec
    patient.validate()
    # Store in database
    saved_patient = await db.save_patient(patient)
    return saved_patient

@app.get("/Patient/{patient_id}")
async def get_patient(patient_id: str):
    patient = await db.get_patient(patient_id)
    if not patient:
        raise HTTPException(404, "Patient not found")
    return patient

Express + FHIR TypeScript (Node.js):

import express from 'express';
import { Patient, Bundle } from 'fhir/r4';

const app = express();

app.post('/Patient', (req, res) => {
  const patient: Patient = req.body;

  // Validate resource type and required fields
  if (patient.resourceType !== 'Patient') {
    return res.status(400).json({
      resourceType: 'OperationOutcome',
      issue: [{
        severity: 'error',
        code: 'invalid',
        details: { text: 'Invalid resource type' }
      }]
    });
  }

  // Process and store
  const savedPatient = db.savePatient(patient);
  res.status(201).json(savedPatient);
});

3. FHIR Validation and Quality

Profile Validation

from fhir.resources.core.fhirabstractmodel import FHIRAbstractModel
from fhir.resources import get_fhir_model_class
import json

def validate_against_profile(resource_data: dict, profile_url: str) -> bool:
    """Validate FHIR resource against specific profile"""
    try:
        # Load profile from package cache
        profile = load_structure_definition(profile_url)

        # Validate using fhir.resources - dynamically get the resource class
        resource_type = resource_data.get('resourceType')
        resource_class = get_fhir_model_class(resource_type)
        resource = resource_class(**resource_data)

        # Additional profile-specific validation
        return validate_profile_constraints(resource, profile)
    except Exception as e:
        print(f"Validation error: {e}")
        return False

Terminology Validation

def validate_coding(coding: dict, value_set_url: str) -> bool:
    """Validate coding against ValueSet"""
    value_set = load_value_set(value_set_url)

    # Check if code exists in ValueSet expansion
    for concept in value_set.get('expansion', {}).get('contains', []):
        if (concept.get('code') == coding.get('code') and
            concept.get('system') == coding.get('system')):
            return True
    return False

4. FHIR Search Implementation

Search Parameter Processing

from typing import Dict, Any
import re

class FhirSearchProcessor:
    def __init__(self):
        self.search_params = load_search_parameters()

    def parse_search_query(self, resource_type: str, params: Dict[str, str]) -> Dict[str, Any]:
        """Parse FHIR search parameters into database query"""
        query = {}

        for param_name, param_value in params.items():
            search_param = self.get_search_parameter(resource_type, param_name)

            if not search_param:
                continue

            # Handle different search parameter types
            if search_param['type'] == 'string':
                query[param_name] = self.parse_string_search(param_value)
            elif search_param['type'] == 'token':
                query[param_name] = self.parse_token_search(param_value)
            elif search_param['type'] == 'date':
                query[param_name] = self.parse_date_search(param_value)
            elif search_param['type'] == 'reference':
                query[param_name] = self.parse_reference_search(param_value)

        return query

    def parse_token_search(self, value: str) -> Dict[str, str]:
        """Parse token search: [system]|[code]"""
        if '|' in value:
            system, code = value.split('|', 1)
            result = {}
            if system:
                result['system'] = system
            if code:
                result['code'] = code
            return result
        return {'code': value} if value else {}

5. SMART on FHIR Integration

OAuth 2.0 / SMART App Launch

interface SmartConfig {
  authorizeUrl: string;
  tokenUrl: string;
  clientId: string;
  redirectUri: string;
  scopes: string[];
}

class SmartClient {
  constructor(private config: SmartConfig) {}

  async authorize(): Promise<string> {
    const state = generateRandomState();
    const authUrl = new URL(this.config.authorizeUrl);

    authUrl.searchParams.set('response_type', 'code');
    authUrl.searchParams.set('client_id', this.config.clientId);
    authUrl.searchParams.set('redirect_uri', this.config.redirectUri);
    authUrl.searchParams.set('scope', this.config.scopes.join(' '));
    authUrl.searchParams.set('state', state);
    authUrl.searchParams.set('aud', getFhirBaseUrl());

    return authUrl.toString();
  }

  async exchangeCodeForToken(code: string): Promise<TokenResponse> {
    const response = await fetch(this.config.tokenUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        grant_type: 'authorization_code',
        client_id: this.config.clientId,
        code,
        redirect_uri: this.config.redirectUri
      })
    });

    if (!response.ok) {
      throw new Error(`Token exchange failed: ${response.statusText}`);
    }

    return response.json();
  }
}

Implementation Guides and Extensions

Custom Profile Development

{
  "resourceType": "StructureDefinition",
  "id": "my-patient-profile",
  "url": "http://example.org/fhir/StructureDefinition/MyPatient",
  "name": "MyPatientProfile",
  "status": "draft",
  "kind": "resource",
  "abstract": false,
  "type": "Patient",
  "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
  "derivation": "constraint",
  "differential": {
    "element": [
      {
        "id": "Patient.identifier",
        "path": "Patient.identifier",
        "min": 1,
        "mustSupport": true
      },
      {
        "id": "Patient.name",
        "path": "Patient.name",
        "min": 1,
        "max": "1"
      }
    ]
  }
}

Testing and Validation Tools

Unit Testing FHIR Resources

import pytest
from fhir.resources.patient import Patient

def test_patient_creation():
    patient_data = {
        "resourceType": "Patient",
        "id": "example",
        "active": True,
        "name": [{
            "family": "Doe",
            "given": ["John"]
        }],
        "gender": "male"
    }

    patient = Patient(**patient_data)
    assert patient.resourceType == "Patient"
    assert patient.gender == "male"
    assert len(patient.name) == 1
    assert patient.name[0].family == "Doe"

FHIR Server Testing

import httpx
import pytest

@pytest.fixture
async def fhir_client():
    async with httpx.AsyncClient(base_url="http://localhost:8000") as client:
        yield client

async def test_patient_crud(fhir_client):
    # Create patient
    patient_data = {"resourceType": "Patient", "active": True}
    create_response = await fhir_client.post("/Patient", json=patient_data)
    assert create_response.status_code == 201

    patient_id = create_response.json()["id"]

    # Read patient
    read_response = await fhir_client.get(f"/Patient/{patient_id}")
    assert read_response.status_code == 200

    # Update patient
    updated_data = read_response.json()
    updated_data["active"] = False
    update_response = await fhir_client.put(f"/Patient/{patient_id}", json=updated_data)
    assert update_response.status_code == 200

    # Delete patient
    delete_response = await fhir_client.delete(f"/Patient/{patient_id}")
    assert delete_response.status_code == 204

Common Patterns and Best Practices

Resource References and Includes

def resolve_references(resource: dict, include_params: List[str]) -> dict:
    """Resolve _include parameters for FHIR search"""
    included_resources = []

    for include_param in include_params:
        source_type, search_param = include_param.split(':', 1)

        if resource.get('resourceType') == source_type:
            ref_values = extract_reference_values(resource, search_param)

            for ref_value in ref_values:
                referenced_resource = load_resource_by_reference(ref_value)
                if referenced_resource:
                    included_resources.append(referenced_resource)

    return {
        'resourceType': 'Bundle',
        'type': 'searchset',
        'entry': [{'resource': resource}] + [{'resource': r} for r in included_resources]
    }

Batch and Transaction Processing

async def process_bundle(bundle: dict) -> dict:
    """Process FHIR Bundle with batch or transaction semantics"""
    response_entries = []
    transaction_mode = bundle.get('type') == 'transaction'

    try:
        if transaction_mode:
            await db.begin_transaction()

        for entry in bundle.get('entry', []):
            request = entry.get('request', {})
            resource = entry.get('resource')

            response_entry = await process_bundle_entry(request, resource)
            response_entries.append(response_entry)

        if transaction_mode:
            await db.commit_transaction()

    except Exception as e:
        if transaction_mode:
            await db.rollback_transaction()
        raise

    return {
        'resourceType': 'Bundle',
        'type': 'transaction-response' if transaction_mode else 'batch-response',
        'entry': response_entries
    }

Error Handling and OperationOutcome

def create_operation_outcome(severity: str, code: str, details: str) -> dict:
    """Create FHIR OperationOutcome for error reporting"""
    return {
        'resourceType': 'OperationOutcome',
        'issue': [{
            'severity': severity,
            'code': code,
            'details': {'text': details}
        }]
    }

# Usage in API endpoints
try:
    result = validate_fhir_resource(resource_data)
except ValidationError as e:
    return create_operation_outcome('error', 'invalid', str(e)), 400

Quick Reference Commands

Package Management

# Install FHIR packages
npm install @types/fhir @fhir/package-loader
pip install fhir.resources fhir-package-loader

# Load core FHIR packages
fhir-package-loader install hl7.fhir.r4.core 4.0.1
fhir-package-loader install hl7.fhir.us.core 5.0.1

Validation Tools

# FHIR Validator (Java)
java -jar validator_cli.jar resource.json -version 4.0.1

# HAPI FHIR Validator
curl -X POST "http://localhost:8080/fhir/$validate" \
  -H "Content-Type: application/fhir+json" \
  -d @patient.json

Development Server Setup

# Python FastAPI FHIR Server
uvicorn main:app --reload --port 8000

# Node.js Express FHIR Server
npm start

Integration Points

  • EHR Systems: Epic, Cerner, AllScripts FHIR APIs
  • Cloud Platforms: AWS HealthLake, Azure FHIR, Google Healthcare API
  • Terminology Services: UMLS, SNOMED CT, LOINC
  • Security: OAuth 2.0, JWT, SMART on FHIR scopes
  • Interoperability: HL7 v2 to FHIR conversion, CDA to FHIR

For detailed implementation guidance, reference the FHIR specification at https://hl7.org/fhir/ and implementation guides at https://fhir.org/guides/registry/


6. FHIR Shorthand (FSH) & IG Authoring

Toolchain

ToolRoleInstall
SUSHICompiles .fsh files → FHIR JSONnpm install -g fsh-sushi
GoFSHConverts FHIR JSON → FSH sourcenpm install -g gofsh
IG PublisherRenders IG website from SUSHI outputDownloaded via _updatePublisher.sh

SUSHI Commands

sushi init                          # Scaffold new IG project
sushi build                         # Compile FSH → FHIR JSON (from project root)
sushi build . --snapshot            # Include full StructureDefinition snapshot
sushi build . --log-level debug     # Verbose output
sushi build . --preprocessed        # Debug: dump resolved aliases/rulesets
sushi update-dependencies           # Update deps to latest

Output: fsh-generated/resources/{ResourceType}-{id}.json. SUSHI clears this folder on every build — never edit it manually.

GoFSH Commands

gofsh ./fhir-resources                          # Convert JSON artifacts to FSH
gofsh ./definitions -d hl7.fhir.us.core@6.1.0  # With extra dependencies
gofsh ./definitions --style group-by-profile    # Organize output by profile
gofsh ./definitions --indent                    # Use indented rule style
gofsh ./definitions --fshing-trip               # Validate round-trip accuracy

Project Structure

my-ig/
├── sushi-config.yaml              # Required: IG configuration
├── ig.ini                         # Required for IG Publisher
├── _genonce.sh / _genonce.bat     # Run IG Publisher
├── _updatePublisher.sh / .bat     # Download latest IG Publisher jar
├── input/
│   ├── fsh/                       # All FSH source files
│   │   ├── aliases.fsh            # Alias: $LNC = http://loinc.org
│   │   ├── profiles.fsh
│   │   ├── extensions.fsh
│   │   ├── valuesets.fsh
│   │   ├── codesystems.fsh
│   │   ├── instances.fsh
│   │   └── rulesets.fsh
│   ├── pagecontent/               # IG narrative (Markdown)
│   │   ├── index.md               # Home page
│   │   ├── 1_background.md        # Numbered = TOC order
│   │   ├── {resource-id}-intro.md # Content before artifact
│   │   └── {resource-id}-notes.md # Content after artifact
│   ├── images/                    # Images, PDFs, spreadsheets
│   └── ignoreWarnings.txt
└── fsh-generated/                 # SUSHI output (auto-generated, do not edit)

sushi-config.yaml (Minimal Required Fields)

id: hl7.fhir.us.example
canonical: http://hl7.org/fhir/us/example
name: ExampleIG
title: "Example Implementation Guide"
status: draft                     # draft | active | retired | unknown
version: 0.1.0
fhirVersion: 4.0.1
copyrightYear: 2024+
releaseLabel: ci-build
publisher:
  name: My Organization
  url: http://example.org
dependencies:
  hl7.fhir.us.core: 6.1.0
menu:
  Home: index.html
  Artifacts: artifacts.html
parameters:
  show-inherited-invariants: false

FSH Entity Types

Profile

Profile: MyPatientProfile
Parent: Patient
Id: my-patient-profile
Title: "My Patient Profile"
Description: "Constrained Patient for our IG"
* identifier 1..* MS
* name 1..* MS
* birthDate MS
* gender 1..1 MS
* gender from http://hl7.org/fhir/ValueSet/administrative-gender (required)

Extension (Simple)

Extension: PatientReligion
Id: patient-religion
Title: "Patient Religion"
Context: Patient
* value[x] only CodeableConcept
* value[x] from ReligionValueSet (extensible)

Extension (Complex — sub-extensions)

Extension: USCoreEthnicityExtension
Id: us-core-ethnicity
Context: Patient, RelatedPerson, Practitioner
* extension contains
    ombCategory 0..1 MS and
    detailed 0..* and
    text 1..1 MS
* extension[ombCategory].value[x] only Coding
* extension[ombCategory].value[x] from OmbEthnicityCategories (required)
* extension[text].value[x] only string

Instance

Instance: JaneDoe
InstanceOf: MyPatientProfile
Title: "Jane Doe"
Usage: #example            // #example | #definition | #inline
* name[0].family = "Doe"
* name[0].given[0] = "Jane"
* birthDate = 1970-01-01
* gender = #female

ValueSet

ValueSet: MyConditionStatusVS
Id: my-condition-status
Title: "Condition Status Codes"
* include codes from system $SCT where concept is-a #404684003
* $V3#active "Active"
* exclude $SCT#74964007 "Other"

CodeSystem

CodeSystem: MyCustomCodes
Id: my-custom-codes
* #pending "Pending" "Awaiting review"
* #approved "Approved" "Formally approved"
// Hierarchical:
* #body "Body"
  * #head "Head"

Invariant + Obeys

Invariant: my-inv-1
Description: "Value must be present for vital-signs category"
Severity: #error
Expression: "category.coding.code = 'vital-signs' implies value.exists()"

// In a Profile:
* obeys my-inv-1

RuleSet (Reusable / Parameterized)

RuleSet: PublicationMetadata
* ^status = #active
* ^experimental = false
* ^publisher = "My Org"

// Parameterized
RuleSet: SetContext(contextPath)
* ^context[+].type = #element
* ^context[=].expression = "{contextPath}"

// Usage:
* insert PublicationMetadata
* insert SetContext(Patient)

FSH Rules Quick Reference

RuleSyntaxExample
Cardinality* elem min..max* name 1..* MS
Must Support* elem MS* identifier MS
Type constraint* elem only Type* value[x] only Quantity
Binding* elem from VS (strength)* code from MyVS (required)
Fixed value* elem = value* status = #final
Fixed coding* elem = $SYS#code "display"* code = $LNC#29463-7
Quantity* elem = n 'unit'* value = 70 'kg'
Slice (element)* arr contains name card* component contains systolic 1..1
Slice (extension)* extension contains Ext named n card* extension contains $Race named race 0..1
Obeys* obeys inv-id* obeys us-core-6
Caret (metadata)* ^property = val* ^experimental = false
Insert RuleSet* insert RSName* insert PublicationMetadata

Path Grammar Quick Reference

status                              // Simple element
name.family                         // Nested
valueQuantity                       // Choice [x] resolved
name[0]                             // Array index (zero-based)
name[+]                             // Soft index: next slot
name[=]                             // Soft index: same slot
component[respirationScore]         // Slice by name
extension[race]                     // Extension slice
performer[Practitioner]             // Reference target
^experimental                       // StructureDefinition metadata
code ^short                         // ElementDefinition property

Coding / Quantity Syntax

// Alias declaration (top of file)
Alias: $LNC = http://loinc.org
Alias: $SCT = http://snomed.info/sct

// Code (no system)
#active

// Coding
http://loinc.org#29463-7 "Body Weight"
$LNC#29463-7 "Body Weight"

// Quantity (UCUM)
70.5 'kg' "kg"
120 'mm[Hg]' "mmHg"

Naming Conventions

ItemConventionExample
Profile/Extension/RuleSet namesPascalCaseMyPatientProfile
Item IDskebab-case, max 64 charsmy-patient-profile
Slice nameslowerCamelCaserespirationScore
Alias names$PrefixedName$LNC, $SCT

Key Rules

  1. Declare slices before constraining themcontains rule must precede slice-specific rules
  2. Declare extensions before constraining sub-elements — same ordering requirement
  3. fsh-generated/ is owned by SUSHI — never edit it; it is deleted and regenerated on each build
  4. Caret (^) rules are forbidden in Instances — use them only in Profiles, Extensions, ValueSets, CodeSystems

IG Authoring Workflow

# New IG from scratch
mkdir my-ig && cd my-ig
sushi init               # Interactive scaffold
# Edit sushi-config.yaml and write .fsh files
sushi build              # Compile
./_genonce.sh            # Run IG Publisher

# Migrate existing FHIR JSON to FSH
gofsh ./existing-resources -d hl7.fhir.us.core@6.1.0 \
  --style group-by-profile --indent --fshing-trip

# Debug a failing build
sushi build --log-level debug
sushi build --preprocessed   # Inspect resolved aliases/rulesets

Reference Files

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.34%
按下载量换算31

Claude

27.46%
按下载量换算23

Cursor

19.33%
按下载量换算16

Gemini CLI

8.87%
按下载量换算8

安全审计

Gen Agent Trust Hub

通过

Socket

可疑

Snyk

可疑

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills