CQL Workbench文件
文件目錄
CQL 入門

讀懂健保預檢規則的 CQL

健保預檢規則實作指引把癌症用藥的給付規定寫成一份份 CQL Library。這頁挑一份肺癌免疫治療的規則,從標頭讀到最後的判斷:它引用哪些模組和代碼、從 TWPAS 申請資料取哪些欄位,給付條件又怎麼組成通過或不通過。

這頁是導讀,不是官方文件:內容依 2026-10-28 核對的持續建置版整理。頁面上的程式碼都是為了說明而寫的示意,不是官方原文;規則全文請看官方頁面,給付規定以健保署公告為準。

這份 Library

指引目前收錄 77 個 Library:66 份給付規則,分屬乳癌、大腸直腸癌、肺癌、肝癌和攝護腺癌;每個癌別另有一份代碼集和一份共通模組,再加上做型別轉換的 FHIRHelpers。這頁讀的是肺癌的 LCPembrAtezoRule1。

選它是因為這一份就用到指引裡大部分的寫法:兩種藥共用一份規則,初次使用和續用分開判斷,條件涵蓋診斷、基因檢測、PD-L1、檢驗值、影像報告和治療計畫文件,最後再產生一份文字報告。原文九百多行、一百多個 define;這頁只講結構,逐行內容請對照官方頁面。

Library
LCPembrAtezoRule1
標題
Pembrolizumab、Atezolizumab給付規定(鱗狀、非鱗狀非小細胞肺癌第一線用藥(單用))
版本
1.0.0,狀態 Draft
引用
FHIRHelpers 4.0.1、LCCodeConcept 1.0.0(肺癌代碼集)、LCReusable 1.0.0(肺癌規則共通模組)

規則讀哪些資料

規則讀的是 TWPAS 定義的申請資料。醫院依 TWPAS 把一件事前審查申請包成 Bundle 上傳,裡面有申請書 Claim,以及病人、用藥、檢驗和報告等資源。這份 Library 的資料需求(dataRequirement)列了五種資源,另外透過 context Patient 讀病人本身:

資源讀什麼用在
Patient出生日期申請時是否滿 18 歲
Claim主要診斷(diagnosis 序號 1 的 ICD-10-CM 碼)、簡要病摘(申請理由)的文字、醫令類別、續用註記、用藥線別、給付適應症代碼、補充資訊肺癌診斷、NSCLC 與組織型態、第一線用藥、給付適應症、初次或續用
MedicationRequestintent 為 plan 的是本次申請的藥品,為 order 的是用藥紀錄;療程起訖日本次與前次申請、療程長度、併用藥品
Observation檢驗、基因資訊、病人狀態評估、癌症分期、治療後療效評估基因原生型、PD-L1、肝腎功能、ECOG、NYHA、M 分期、i-RECIST
DiagnosticReport影像報告、分子或病理檢查報告12 週內的影像、有沒有檢查報告
DocumentReferenceClaim 補充資訊引用的治療計畫文件免疫檢查點抑制劑治療計畫

TWPAS 也有 Condition 的 profile,但這份規則的診斷全部從 Claim.diagnosis 讀,沒有查 Condition。讀官方規則時,要看它實際查的是哪個資源的哪個欄位,不要只看條文猜。

我們打開的規則,前幾行都一樣,只有名稱和引用的癌別不同:

示意:Library 名稱是虛構的,結構和官方規則相同
library LCExampleRule version '1.0.0'
名稱和版本。官方的名稱多半是癌別縮寫加藥名,再加 Rule 和編號;縮寫有 BC(乳癌)、CRC(大腸直腸癌)、LC(肺癌)、HCC(肝癌)、PC(攝護腺癌)。
using FHIR version '4.0.1'
資料模型是 FHIR 4.0.1(R4),和 TWPAS 相同。
include FHIRHelpers version '4.0.1' called FHIRHelpers
輔助函式,把 FHIR R4 的資料型別轉成 CQL 的型別,例如日期和數值,才能拿來比較。
include LCCodeConcept version '1.0.0' called CodeConcept
該癌別的代碼集,取名為 CodeConcept。規則裡寫 CodeConcept.EGFR,就是取代碼集裡名為 EGFR 的代碼清單。
include LCReusable version '1.0.0' called Reusable
該癌別的共通模組,取名為 Reusable,放申請類型、用藥線別、年齡、檢驗判斷等共用的 define 和函式,規則裡寫成 Reusable."初次申請" 這樣。
context Patient
之後每個 define 都針對一位病人計算。

除了這份肺癌規則,我們另外打開大腸直腸癌、乳癌、肝癌、攝護腺癌各一份,標頭都是這個結構。標頭裡沒有 parameter:規則需要的值全部從申請資料裡查。

代碼集:規則用到的代碼

LCCodeConcept 沒有 context,也沒有判斷,只放代碼,分成三類:

  • 代碼系統:國際標準的 SNOMED CT、LOINC 和 HL7 的判讀代碼;TWPAS 的健保代碼系統,例如用藥線別、健保藥品、醫令類別、續用註記、治療後疾病狀態評估、補充資訊類別、給付適應症;以及 TW Core 的臺灣版 ICD-10-CM 和 ICD-10-PCS(2014 與 2023 版)。
  • 檢驗與檢查代碼:用 define 列成字串清單,例如 EGFR、ALK、ROS1 和各種 PD-L1 檢測的 LOINC 碼,GOT、GPT、T-bilirubin、Creatinine、eGFR 的 LOINC 碼,以及影像檢查的 ICD-10-PCS 碼。
  • 藥品代碼:清單用 ATC 碼命名,內容是健保藥品代碼。例如 L01FF02 是 pembrolizumab,L01FF05 是 atezolizumab。
示意,不是官方原文
// 代碼集 Library:先宣告代碼系統,再把代碼列成清單
codesystem "LOINC": 'http://loinc.org'
codesystem "NHILOT": 'https://nhicore.nhi.gov.tw/pas/CodeSystem/nhi-line-of-therapy'

define "某基因檢測": { '代碼A', '代碼B' }

整份代碼集沒有用 valueset 宣告,代碼清單直接寫在 Library 裡,執行時不必另外展開 FHIR ValueSet。在規則裡看到 CodeConcept 加上某個名稱,就到代碼集頁面找同名的 define,看它包含哪些代碼。

從申請資料取值

規則用 retrieve(方括號裡寫資源類型,例如 [Observation])取出這位病人的某一種資源,再用 where 篩選。這份規則裡反覆出現四種寫法:

依類別和代碼找檢驗Observation 先看補充資訊類別(檢驗、基因資訊、病人狀態評估),再看 LOINC 碼在不在代碼集的清單裡,最後比數值或文字。
在申請書裡層層往下找續用註記、用藥線別、給付適應症都在 Claim 的申請品項(item)底下。規則用一層層的 exists 往下找,找到一筆符合就算。
找出本次、前次和首次申請在 intent 為 plan 的 MedicationRequest 裡,依療程起始日排序:最後一筆是本次申請,最早一筆是首次申請,本次之前最近的一筆是前次申請。年齡也是算到本次療程的起始日。
比對文字NSCLC、鱗狀或非鱗狀這些條件,是用 Matches(正規表示式)在簡要病摘的文字裡找關鍵字;基因原生型也有一部分是比對檢驗結果的文字。所以申請時寫的文字會直接影響判斷。
示意,不是官方原文
// 第一種寫法:某項檢驗的數值低於門檻
define "某檢驗低於門檻":
  exists (
    [Observation] O
      where Reusable."IsTestObservation"(O)        // 補充資訊類別是「檢驗(查)」
        and exists (
          O.code.coding C
            where C in CodeConcept.LOINC             // 代碼系統是 LOINC
              and C.code in CodeConcept."某檢驗"     // 代碼在清單裡
        )
        and O.value is FHIR.Quantity
        and (O.value as FHIR.Quantity).value < 2.0   // 數值低於門檻
  )

給付條件:一層一層的 define

給付規定的層級直接變成 define 的層級:條件組成規則,規則組成主要規定。官方的 define 名稱把編號和條文內容寫在一起,例如 1規則1-3=成人,對照給付規定原文時很好找。

示意,不是官方原文
// 條件組成規則,規則組成主要規定,用 and、or 串起來
define "1規則1":
  "1規則1-1" and "1規則1-2" and "1規則1-3"

// 同一條規則,依申請的藥品換一組條件
define "1規則3":
  if "申請藥品A" then "藥品A的PD-L1條件"
  else if "申請藥品B" then "藥品B的PD-L1條件"
  else false

define "主要規定一":
  "1規則1" and "1規則2" and "1規則3" and "1規則4"

這份規則有三個主要規定。主要規定一(初次使用)由四條規則組成:

規則檢查什麼讀的資源
1規則1轉移性非小細胞肺癌第一線用藥:主要診斷為 C34、醫令類別為藥品、簡要病摘註明 NSCLC、M 分期不是 0、第一線用藥、有分子或病理檢查報告、給付適應症為 P013;依組織型態確認 EGFR、ALK 為原生型,非鱗狀另加 ROS1;申請時滿 18 歲。Claim、Observation、DiagnosticReport、Patient
1規則2身體狀況與肝腎功能:ECOG ≤ 1、NYHA I 或 II、GOT 與 GPT < 60 U/L、T-bilirubin < 1.5 mg/dL、Creatinine < 1.5 mg/dL 且 eGFR > 60 mL/min/1.73m²。Observation
1規則3PD-L1,依藥品而定:pembrolizumab 看 Dako 22C3 或 Ventana SP263 的 TPS ≥ 50%;atezolizumab 看 Ventana SP142 的 TC ≥ 50% 或 IC ≥ 10%。MedicationRequest、Observation
1規則4本次療程起始日前 12 週內的影像報告,以及免疫檢查點抑制劑治療計畫。DiagnosticReport、Claim、DocumentReference

主要規定二(續用)要求續用註記為 2,並以 i-RECIST 評估有療效反應,或為穩定病況(SD)但本次和前次不是連續兩次 SD;沒有確認的疾病惡化(iCPD)、沒有中重度或危及生命的藥物不良反應、停藥沒有超過 24 週;而且仍符合 1規則2 的身體狀況與肝腎功能,並有 12 週內的影像報告。

主要規定三(藥品使用規則)是四項限制:每位病人每個適應症只給付一種免疫檢查點抑制劑且不得互換、治療期間不得併用指定的標靶藥物、總使用期間不超過 2 年、每次申請以 12 週為限。這四項在報告裡標成「參考資訊」,不影響最後的申請結果。

最後的判斷

規則的最後幾個 define 把前面的結果整理成輸出:

申請類型
共通模組讀 Claim 上的續用註記:1 是初次使用,2 是續用(TWPAS 代碼表寫作「申請再次使用」),兩者都沒有就是無法判斷。
布林結果
名稱以「_布林」結尾。初次使用看主要規定一,續用看主要規定二,無法判斷申請類型就是 false。
文字結果
通過或不通過,加上申請類型。
報告總結
一段文字報告:申請類型、符合的項目、不符合的項目,最後是申請結果。不符合的項目分成「必要資料未填寫」和「條件或代碼不符合」兩組。
示意,不是官方原文
// 依申請類型決定看哪一組規定;判斷不出類型就不通過
define "申請結果_布林":
  case
    when Reusable."初次申請" then "主要規定一"
    when Reusable."續用申請" then "主要規定二"
    else false
  end

報告怎麼分出「沒填」和「填了但不符合」?規則另外寫了一組判斷資料有沒有填的 define,名稱是「…資料存在」,例如 ECOG資料存在。條件本身多半寫成「找得到符合的資料」,缺資料時是 false 而不是 null,所以只看布林結果,缺資料和不符合都是不通過;靠這組 define,報告才能告訴醫院缺的是哪一項。

和工作台的差別

工作台匯出的 CQL 和官方規則處理的是同一類問題,寫法卻不同:

項目官方預檢規則工作台的 CQL
資料從哪來CQL 自己用 retrieve 查 TWPAS 的 FHIR 資源轉接器先查病歷,把每個條件的答案當成參數傳進來
一個條件一個 define,裡面是查詢、代碼和門檻一個 Boolean 參數;define 只負責組合
代碼每個癌別一份代碼集 LibraryCQL 裡沒有代碼;查病歷是轉接器的事
缺資料條件是 false,另用「資料存在」的 define 在報告裡標出來參數是 null,依三值邏輯往上傳,結果是 insufficient-data
輸出布林結果、通過或不通過的文字,以及報告eligible、ineligible 或 insufficient-data

工作台為什麼用參數,見核心概念的 Parameter-based CQL;參數和三值邏輯怎麼運作,見 CQL 入門的參數和三值邏輯;兩邊怎麼搭配,見台灣官方 CQL 指引的和工作台的關係。

對照時,把官方的每個條件 define 當成一個原子條件,例如 1規則1-3=成人 對應「申請時滿 18 歲」這個條件。逐條對下來,就能看出工作台拆出的條件有沒有漏掉或多出來。也要留意官方規則的判斷細節,例如年齡算到本次療程起始日、影像要在 12 週內;工作台拆條件、轉接器填參數時,都要對齊這些細節。

閱讀檢查清單

打開指引裡任何一份規則,都可以照這個順序讀:

  1. 看頁首的中繼資料:正式網址、版本、狀態,以及 Dependency 列出的代碼集和共通模組。
  2. 看標題和開頭的註解,確認是哪個癌別、哪個藥、哪個適應症。給付適應症代碼(例如 P013)可以到 TWPAS 的給付適應症代碼表查。
  3. 看 include。遇到 CodeConcept 加名稱,到該癌別的代碼集頁面找同名 define;遇到 Reusable 加名稱,到共通模組頁面找。
  4. 用註解分隔線找出各個主要規定,再把規則和條件的編號對回給付規定原文。
  5. 逐一看條件 define:讀哪個資源、哪個欄位、用哪些代碼或門檻。特別留意用 Matches 比對文字的條件。
  6. 找判斷資料有沒有填的 define(這份規則的名稱是「…資料存在」),確認什麼情況算缺資料。
  7. 最後看結果:布林結果、文字結果和報告。標成「參考資訊」的項目不影響申請結果。
  8. 記下核對日期。指引還是草案,同一份 Library 下次打開可能已經改了。

版本與狀態

以下是 2026-10-28 核對到的狀態,和台灣官方 CQL 指引頁的說明一致:

  • 指引是持續建置版(CI Build)0.0.1,標示為草案。頁首註明這不是正式出版品,內容會定期變動。
  • 這份 Library 的版本是 1.0.0,狀態是 Draft。
  • 指引宣告的正式網址在健保署的 nhicore.nhi.gov.tw/cql/ 底下,核對當天還沒有上線;目前在 build.fhir.org 閱讀,指引的下載頁也提供整包 package.tgz。
  • 指引的相依套件列的是 TWPAS 1.2.4,健保署目前發布的 TWPAS 是 1.2.7。拿實際申請資料測試前,先確認兩版之間的欄位和代碼異動。

官方原文

完整的 CQL 請看官方頁面。以下連結都在 2026-10-28 核對過。

  1. 臺灣健保預檢規則實作指引
  2. Libraries 列表(依癌別分組)
  3. LCPembrAtezoRule1:本頁導讀的肺癌規則
  4. LCReusable:肺癌規則共通模組
  5. LCCodeConcept:肺癌代碼集
  6. FHIRHelpers
  7. 臺灣健保事前審查實作指引
  8. TWPAS 的申請書 Claim 定義
  9. TWPAS 的給付適應症代碼表