擁有 CDM 才剛是起點。要發揮價值,需要一整套工具:ATLAS(世代 + characterization UI)、DQD(資料品質)、ACHILLES(profiling)。本文教你安裝與營運。
1. OHDSI analytics 技術堆疊

全部都可透過 Broadsea 用 Docker compose 部署。
2. Broadsea — 一鍵部署
git clone https://github.com/OHDSI/Broadsea
cd Broadsea
cp .env.example .env
# 編輯 .env:Postgres 連線、ATLAS port、安全性
docker compose --profile default up -d
# 連線:
# - ATLAS: http://localhost/atlas
# - WebAPI: http://localhost/WebAPI
# - HADES R Studio: http://localhost:8787
Broadsea 內服務:
broadsea-webtools— ATLAS + WebAPIbroadsea-hades— 預先安裝 HADES 的 RStudio Serverbroadsea-content— Atlas content portalohdsi-postgresql— WebAPI 用 DB
3. ATLAS
3.1 主要功能

3.2 建立世代的工作流程
範例:「2026 年新診斷為第二型糖尿病並開始服用 Metformin 的病人」

ATLAS UI 透過點選拖放即可,無需 SQL → 輸出符合 OMOP 標準的 cohort 資料表。
3.3 匯出 Cohort SQL
ATLAS 自動產生符合 OHDSI Circe 規範的 SQL:
-- Generated by Atlas
INSERT INTO cohort (cohort_definition_id, subject_id, cohort_start_date, cohort_end_date)
SELECT 1, person_id, condition_start_date, ...
FROM condition_occurrence co
JOIN concept_ancestor ca ON co.condition_concept_id = ca.descendant_concept_id
WHERE ca.ancestor_concept_id = 201826
AND condition_start_date >= '2026-01-01'
...
→ 可版本控制,並可在 ATLAS 之外用 CLI 執行。
3.4 Characterization
有了世代後 → 執行 Characterization 描述:
- 性別、年齡分層比例
- Top comorbid(index 前 365 天的前 100 種 condition)
- Top drug
- Top procedure
- 檢驗值
→ 輸出表格 + Forest plot。在比較 2 個世代(例如 Metformin vs SGLT2 為一線治療)時尤其強大。
4. ACHILLES
ACHILLES 是 R 套件,profile CDM 中所有欄位,輸出約 170 個 analysis ID:
- person 數、gender、race、出生年分布
- 依類型分的 visit count
- Top conditions、drugs、procedures、measurements
- 時間序列:每月計數
- Heel:離群值旗標(例如「偵測到 year_of_birth = 1850」)
library(Achilles)
achilles(
connectionDetails = connectionDetails,
cdmDatabaseSchema = "cdm",
resultsDatabaseSchema = "results",
vocabDatabaseSchema = "cdm",
numThreads = 4
)
執行後 → achilles_results、achilles_results_dist、achilles_heel_results 資料表。
ATLAS 的「Data Sources」分頁會視覺化呈現 ACHILLES 結果 — 這是向研究者介紹資料夥伴的看板。
5. Data Quality Dashboard (DQD)
3000+ 規則,依 Kahn 分為 3 類:
| 類別 | 說明 | 範例 |
|---|---|---|
| Conformance | 資料型別、格式、值域正確 | gender_concept_id ∈ {0, 8507, 8532} |
| Completeness | NULL 比例可接受 | < 5% person.year_of_birth NULL |
| Plausibility | 值在臨床上合理 | HbA1c 不超過 20% |
5.1 執行 DQD
library(DataQualityDashboard)
executeDqChecks(
connectionDetails = connectionDetails,
cdmDatabaseSchema = "cdm",
resultsDatabaseSchema = "results",
cdmSourceName = "BV ABC OMOP CDM",
outputFolder = "dqd_results",
cdmVersion = "5.4"
)
# 產生 viewer
viewDqDashboard("dqd_results/results.json")
輸出:
- 互動式 HTML dashboard
- 每項檢查的 JSON + pass/fail/threshold
5.2 解讀 DQD
每項檢查包含:
category:conformance / completeness / plausibilitysubcategory:例如「valueLow」、「valueHigh」level:TABLE / FIELD / CONCEPTseverity:error / warning / notificationpct_records_violating:違反比例threshold:可接受門檻pass/fail

5.3 處理模式
當 DQD fail:
- 閱讀 check description
- 找出根因(來源資料錯誤、ETL 錯誤,或門檻過嚴)
- 修正 ETL 或調整門檻(若理由合理)
- 重跑 DQD
- 將決策記錄至 ETL 規格
5.4 自訂檢查
DQD 支援新增自訂規則:
# custom_checks.csv
checkName: VN_BHYT_coverage
checkDescription: > 90% person 至少有 1 筆 PAYER_PLAN_PERIOD = BHYT
queryText: |
SELECT (1.0 - SUM(CASE WHEN p.person_id IS NOT NULL THEN 1 ELSE 0 END) / COUNT(*)) AS pct_violation
FROM person ps
LEFT JOIN payer_plan_period p ON ps.person_id = p.person_id
AND p.payer_concept_id = 2000010001 -- 越南 custom BHYT
threshold: 0.10
severity: warning
6. 將 DQD 整合 CI/CD
# .github/workflows/dqd.yml
name: OMOP DQ Weekly
on:
schedule:
- cron: '0 3 * * 1' # 週一凌晨 3 點
jobs:
dqd:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- run: Rscript scripts/run_dqd.R
- name: Upload result
uses: actions/upload-artifact@v4
with:
name: dqd-${{ github.run_id }}
path: dqd_results/
- name: Fail on critical errors
run: |
jq '.Overview | select(.numFailed > 0)' dqd_results/results.json && exit 1 || exit 0
7. 實際 production 堆疊
| 元件 | 建議規格 |
|---|---|
| Postgres CDM | 16 vCPU、64 GB RAM、2 TB SSD,依年份 partition |
| WebAPI | 4 vCPU、8 GB RAM、JVM heap 4GB |
| ATLAS Web | 2 vCPU、4 GB RAM(僅 static) |
| ACHILLES | 8 vCPU、16 GB RAM,1000 萬人資料集執行 4-12 小時 |
| DQD | 8 vCPU、16 GB RAM,依規則範圍 2-6 小時 |
| HADES R Studio | 16 vCPU、32 GB RAM,供 PLP 訓練 |
備份:CDM 每晚 snapshot,ACHILLES 結果每週備份。
8. ATLAS 安全性
ATLAS 預設無認證 → 絕對不能未保護地公開部署。設定方式:
- 透過 WebAPI 整合 LDAP / AD
- 用反向代理(NGINX)啟用 HTTPS
- 稽核所有世代產生
- 對敏感資料夥伴啟用列級安全性
9. 多租戶模式

WebAPI 支援多 source — 研究者透過下拉選單切換 source。每使用者/每 source 可設定權限。
10. 越南的網絡部署

聯邦模式:資料留在醫院,只有彙總結果上傳。
11. 常見陷阱
- ❌ 世代未使用
concept_ancestor→ 漏掉變異型疾病 - ❌ 世代未檢查 inclusion rule 重疊 → 重複計算
- ❌ 忽略 DQD warning → 投稿時被審稿者退稿
- ❌ ETL refresh 後未重跑 ACHILLES → ATLAS 顯示舊數
- ❌ 未認證的公開 ATLAS → 病人 metadata 外洩
- ❌ 忘記備份
webapi.cohort_definition→ 失去世代定義
結論
ATLAS + DQD + ACHILLES 是營運 OMOP 的三大支柱。Broadsea 讓你一鍵部署。從一開始就把 DQ 閘門整合進 CI/CD — 將來投稿時可省下大量時間。
