下拉重新整理

在 Keycloak 和 HAPI FHIR 中間放一層 Rails(四):讓 AI Agent 只能走受控工具

526 字 2 分鐘閱讀 10 次閱讀

承上一篇。這篇是這系列我自己最在意的一塊,因為它直接關係到火線超人跟 AI 臨床工具會不會出包。

如果你要接 AI Agent 或 LINE Bot 去讀 FHIR 資料,最危險的做法就是讓模型自由產生查詢:

GET /Observation?...任意查詢...

只要模型被 prompt injection 帶偏,或自己組了個奇怪的參數,它就可能撈到不該撈的東西。所以我的做法是:不開放自由查詢,只開放一組受控工具(controlled tools)。

get_recent_labs
get_active_medications
get_latest_vital_signs
get_upcoming_appointments
get_encounter_summary
evaluate_diabetes_control

每個工具都有明確定義,參數範圍寫死。像這樣:

{
  "name": "get_recent_labs",
  "description": "Return laboratory results within an allowed period.",
  "parameters": {
    "type": "object",
    "properties": {
      "days": { "type": "integer", "minimum": 1, "maximum": 7 },
      "category": { "type": "string", "enum": ["laboratory"] }
    },
    "required": ["days"]
  }
}

參數要收斂,不能照單全收

就算工具定義寫了 maximum: 7,我在 Rails 這端還是會再收斂一次。模型送 {"days": 30} 過來,Rails 不照做:

allowed_days = [requested_days, policy.maximum_days].min

最後只會執行七天。工具定義是給模型看的提示,Rails 的收斂才是真正的閘門。這一層擋掉的東西很具體:AI 自由組合危險查詢、讀到其他病人、不受控的 _include=*、無上限的 _count$everything、任意 transaction、prompt injection 直接轉成 FHIR API、tool 參數越權、大量 PHI 外洩。

回傳給模型的,要是最小必要資料

還有一點常被忽略:別把完整的 Observation Resource 丟給模型。原始 FHIR 資源一堆 meta、identifier、performer、extension,既浪費 token 又擴大 PHI 暴露面。我讓 Rails 先轉成最小的資料再給模型:

{
  "test": "HbA1c",
  "value": 7.2,
  "unit": "%",
  "date": "2026-07-20",
  "interpretation": "high"
}

模型面對這種乾淨的結構,比直接吞一整包 FHIR Bundle 安全太多,也準太多。

這種 function tooling 特別適合火線超人、患者端 SMART App 跟 AI Agent 這類場景。它把「AI 能做什麼」限縮成一組你審查過的動作,而不是一個開放的查詢介面。下一篇我把 OPA 跟 Kafka 補進來,收整張架構圖。