第18章 医疗健康MCP应用

36 阅读8分钟

第18章 医疗健康MCP应用

前言

健康关系生命。本章展示如何通过MCP将Claude集成到医疗健康系统中,实现临床决策支持、患者健康管理和医疗数据分析的智能化升级,同时严格遵循HIPAA等医疗隐私法规。


18.1 案例1:临床决策支持系统

18.1.1 应用场景

graph TB
    A["患者信息"] --> B["病历系统"]
    A --> C["检查报告"]
    A --> D["用药记录"]
    
    E["医学知识"] --> E1["临床指南"]
    E --> E2["医学文献"]
    E --> E3["最佳实践"]
    
    F["Claude临床助手"] --> F1["病情分析"]
    F --> F2["诊断建议"]
    F --> F3["用药检查"]
    F --> F4["治疗方案"]
    
    B --> F
    C --> F
    D --> F
    E1 --> F
    E2 --> F
    E3 --> F
    
    F --> G["医生决策支持"]

18.1.2 医疗数据模型

from typing import Dict, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
import hashlib

class MedicationWarningLevel(Enum):
    """药物警告等级"""
    NORMAL = "normal"
    WARNING = "warning"
    CRITICAL = "critical"
    CONTRAINDICATED = "contraindicated"


@dataclass
class Patient:
    """患者档案(已脱敏)"""
    patient_id: str  # 使用hash而不是真实ID
    age: int
    gender: str
    weight: float  # kg
    height: float  # cm
    allergies: List[str] = field(default_factory=list)
    comorbidities: List[str] = field(default_factory=list)
    current_medications: List[str] = field(default_factory=list)


@dataclass
class ClinicalRecord:
    """临床记录"""
    record_id: str
    patient_id: str
    visit_date: datetime
    chief_complaint: str
    vital_signs: Dict[str, float]
    physical_exam: str
    assessment: str
    plan: str
    icd_codes: List[str] = field(default_factory=list)


class ClinicalDecisionSupport:
    """临床决策支持系统"""
    
    def __init__(self):
        self.patients: Dict[str, Patient] = {}
        self.records: Dict[str, ClinicalRecord] = {}
        self.clinical_guidelines: Dict[str, Dict] = {}
        self.drug_interactions: Dict[str, List[str]] = {}
    
    async def analyze_patient_condition(self, patient_id: str,
                                       chief_complaint: str) -> Dict:
        """
        分析患者病情
        
        Args:
            patient_id: 患者ID
            chief_complaint: 主诉
            
        Returns:
            病情分析结果
        """
        patient = self.patients.get(patient_id)
        if not patient:
            return {"error": "Patient not found"}
        
        # 基于主诉和患者信息的初步分析
        keywords = chief_complaint.lower().split()
        differential_diagnoses = []
        
        # 简单的关键词匹配(实际应使用ML模型)
        condition_keywords = {
            "chest pain": ["心肌梗死", "心绞痛", "肺栓塞"],
            "shortness": ["哮喘", "肺炎", "心力衰竭"],
            "fever": ["感染", "流感", "细菌感染"],
            "headache": ["偏头痛", "紧张性头痛", "脑膜炎"],
            "abdominal": ["胆囊炎", "阑尾炎", "胃溃疡"]
        }
        
        for key, diagnoses in condition_keywords.items():
            if key in chief_complaint.lower():
                differential_diagnoses.extend(diagnoses)
        
        # 考虑患者既往史
        relevant_history = [c for c in patient.comorbidities 
                          if any(d.startswith(c[:3]) for d in differential_diagnoses)]
        
        return {
            "patient_id": patient_id,
            "chief_complaint": chief_complaint,
            "patient_age": patient.age,
            "patient_comorbidities": patient.comorbidities,
            "differential_diagnoses": list(set(differential_diagnoses))[:5],
            "relevant_history": relevant_history,
            "recommended_tests": self._recommend_tests(chief_complaint),
            "clinical_guidelines": self._get_relevant_guidelines(chief_complaint),
            "confidence": "medium"
        }
    
    def _recommend_tests(self, complaint: str) -> List[str]:
        """推荐检查"""
        tests_map = {
            "chest pain": ["ECG", "Troponin", "Chest X-ray", "CT angiography"],
            "shortness": ["Chest X-ray", "ABG", "D-dimer", "Echocardiogram"],
            "fever": ["CBC", "Blood culture", "Chest X-ray"],
            "headache": ["CT head", "Lumbar puncture", "MRI"],
            "abdominal": ["Abdominal ultrasound", "CT abdomen", "Lipase"]
        }
        
        for key, tests in tests_map.items():
            if key in complaint.lower():
                return tests
        return ["Labs", "Imaging"]
    
    def _get_relevant_guidelines(self, complaint: str) -> List[Dict]:
        """获取相关临床指南"""
        return [
            {
                "guideline": "AHA/ACC Chest Pain Guidelines",
                "url": "guideline_reference",
                "relevance": "high"
            },
            {
                "guideline": "ACCP VTE Guidelines",
                "url": "guideline_reference",
                "relevance": "medium"
            }
        ]
    
    async def check_medication_safety(self, patient_id: str,
                                     proposed_medication: str,
                                     dose: float) -> Dict:
        """
        检查药物安全性
        
        Args:
            patient_id: 患者ID
            proposed_medication: 提议的药物
            dose: 剂量
            
        Returns:
            药物安全检查结果
        """
        patient = self.patients.get(patient_id)
        if not patient:
            return {"error": "Patient not found"}
        
        warnings = []
        contraindications = []
        
        # 检查过敏
        if proposed_medication.lower() in [a.lower() for a in patient.allergies]:
            contraindications.append(f"患者对{proposed_medication}过敏")
        
        # 检查药物相互作用
        for current_med in patient.current_medications:
            if proposed_medication in self.drug_interactions.get(current_med, []):
                warnings.append(f"{proposed_medication}{current_med}存在相互作用")
        
        # 检查剂量(简化版)
        dose_limits = {
            "aspirin": {"min": 75, "max": 500},
            "metformin": {"min": 500, "max": 2000},
            "lisinopril": {"min": 10, "max": 80}
        }
        
        limits = dose_limits.get(proposed_medication.lower())
        if limits:
            if dose < limits["min"] or dose > limits["max"]:
                warnings.append(f"剂量{dose}mg可能超出推荐范围")
        
        # 检查肾功能和肝功能(简化版)
        if patient.age > 65:
            warnings.append("患者年龄>65岁,需考虑老年患者用药特点")
        
        # 确定警告等级
        if contraindications:
            level = MedicationWarningLevel.CONTRAINDICATED
        elif len(warnings) > 2:
            level = MedicationWarningLevel.CRITICAL
        elif warnings:
            level = MedicationWarningLevel.WARNING
        else:
            level = MedicationWarningLevel.NORMAL
        
        return {
            "patient_id": patient_id,
            "proposed_medication": proposed_medication,
            "proposed_dose": dose,
            "warning_level": level.value,
            "warnings": warnings,
            "contraindications": contraindications,
            "recommendation": "禁忌" if contraindications else "谨慎使用" if warnings else "安全"
        }
    
    async def generate_treatment_plan(self, patient_id: str,
                                     diagnosis: str) -> Dict:
        """
        生成治疗方案
        
        Args:
            patient_id: 患者ID
            diagnosis: 诊断
            
        Returns:
            治疗方案
        """
        patient = self.patients.get(patient_id)
        if not patient:
            return {"error": "Patient not found"}
        
        # 生成基于诊断的治疗方案
        treatment_options = {
            "高血压": {
                "first_line": ["Lisinopril 10mg", "Amlodipine 5mg"],
                "lifestyle": ["减钠摄入", "规律运动", "压力管理"],
                "monitoring": ["每周测血压", "3个月后复查"]
            },
            "糖尿病": {
                "first_line": ["Metformin 500mg", "GLP-1受体激动剂"],
                "lifestyle": ["控制饮食", "规律锻炼", "血糖监测"],
                "monitoring": ["每周测血糖", "3个月后测HbA1c"]
            }
        }
        
        plan = treatment_options.get(diagnosis, {
            "first_line": ["根据具体情况选择"],
            "lifestyle": ["健康生活方式改变"],
            "monitoring": ["定期随访"]
        })
        
        return {
            "patient_id": patient_id,
            "diagnosis": diagnosis,
            "treatment_plan": {
                "pharmacological": plan.get("first_line", []),
                "lifestyle": plan.get("lifestyle", []),
                "monitoring": plan.get("monitoring", []),
                "follow_up": "2周后门诊随访"
            },
            "contraindications": patient.allergies,
            "baseline_vitals": {"BP": "140/90", "HR": 75}
        }


class ClinicalMCPServer:
    """临床MCP服务器"""
    
    def __init__(self, cds: ClinicalDecisionSupport):
        self.cds = cds
    
    def get_tools(self) -> List[Dict]:
        """定义工具"""
        return [
            {
                "name": "analyze_condition",
                "description": "分析患者病情",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "patient_id": {"type": "string"},
                        "chief_complaint": {"type": "string"}
                    },
                    "required": ["patient_id", "chief_complaint"]
                }
            },
            {
                "name": "check_medication",
                "description": "检查药物安全性",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "patient_id": {"type": "string"},
                        "medication": {"type": "string"},
                        "dose": {"type": "number"}
                    },
                    "required": ["patient_id", "medication", "dose"]
                }
            },
            {
                "name": "treatment_plan",
                "description": "生成治疗方案",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "patient_id": {"type": "string"},
                        "diagnosis": {"type": "string"}
                    },
                    "required": ["patient_id", "diagnosis"]
                }
            }
        ]
    
    async def call_tool(self, tool_name: str, arguments: Dict) -> str:
        """调用工具"""
        import json
        
        try:
            if tool_name == "analyze_condition":
                result = await self.cds.analyze_patient_condition(
                    arguments["patient_id"],
                    arguments["chief_complaint"]
                )
            
            elif tool_name == "check_medication":
                result = await self.cds.check_medication_safety(
                    arguments["patient_id"],
                    arguments["medication"],
                    arguments["dose"]
                )
            
            elif tool_name == "treatment_plan":
                result = await self.cds.generate_treatment_plan(
                    arguments["patient_id"],
                    arguments["diagnosis"]
                )
            
            else:
                return json.dumps({"error": f"Unknown tool: {tool_name}"})
            
            return json.dumps(result, ensure_ascii=False, indent=2)
        
        except Exception as e:
            return json.dumps({"error": str(e)})

18.2 案例2:患者健康管理系统

18.2.1 个人健康数据管理

@dataclass
class HealthRecord:
    """健康记录"""
    record_id: str
    patient_id: str
    record_date: datetime
    metrics: Dict[str, float]  # BP, Weight, Blood Sugar等
    symptoms: List[str]
    medications_taken: List[str]


class PatientHealthManager:
    """患者健康管理"""
    
    def __init__(self):
        self.health_records: Dict[str, List[HealthRecord]] = {}
        self.health_goals: Dict[str, Dict] = {}
    
    async def track_vital_signs(self, patient_id: str,
                               vitals: Dict[str, float]) -> Dict:
        """
        追踪生命体征
        
        Args:
            patient_id: 患者ID
            vitals: 生命体征字典
            
        Returns:
            追踪结果
        """
        if patient_id not in self.health_records:
            self.health_records[patient_id] = []
        
        record = HealthRecord(
            record_id=f"HR_{len(self.health_records[patient_id])}",
            patient_id=patient_id,
            record_date=datetime.now(),
            metrics=vitals,
            symptoms=[],
            medications_taken=[]
        )
        
        self.health_records[patient_id].append(record)
        
        # 分析趋势
        alerts = self._check_vital_alerts(vitals)
        
        return {
            "patient_id": patient_id,
            "recorded_vitals": vitals,
            "timestamp": record.record_date.isoformat(),
            "alerts": alerts,
            "trend": self._analyze_vital_trends(patient_id)
        }
    
    def _check_vital_alerts(self, vitals: Dict[str, float]) -> List[str]:
        """检查生命体征告警"""
        alerts = []
        
        # 血压告警
        if "systolic_bp" in vitals:
            if vitals["systolic_bp"] > 160:
                alerts.append("收缩压过高,建议立即就医")
            elif vitals["systolic_bp"] > 140:
                alerts.append("收缩压升高,需要监测")
        
        # 血糖告警
        if "blood_glucose" in vitals:
            if vitals["blood_glucose"] > 300:
                alerts.append("血糖危险升高")
            elif vitals["blood_glucose"] < 70:
                alerts.append("血糖过低")
        
        # 心率告警
        if "heart_rate" in vitals:
            if vitals["heart_rate"] > 120:
                alerts.append("心率过快")
            elif vitals["heart_rate"] < 50:
                alerts.append("心率过缓")
        
        return alerts
    
    def _analyze_vital_trends(self, patient_id: str) -> Dict:
        """分析生命体征趋势"""
        records = self.health_records.get(patient_id, [])
        if len(records) < 2:
            return {"status": "insufficient_data"}
        
        # 获取最近两条记录
        recent = records[-1].metrics
        previous = records[-2].metrics
        
        trends = {}
        for key in recent:
            if key in previous:
                change = recent[key] - previous[key]
                trend = "increasing" if change > 0 else "decreasing"
                trends[key] = {
                    "trend": trend,
                    "change": f"{abs(change):.1f}"
                }
        
        return trends
    
    async def get_health_recommendations(self, patient_id: str) -> Dict:
        """
        获取健康建议
        
        Args:
            patient_id: 患者ID
            
        Returns:
            健康建议
        """
        records = self.health_records.get(patient_id, [])
        if not records:
            return {"error": "No health records found"}
        
        latest = records[-1]
        recommendations = []
        
        # 基于最新记录生成建议
        if latest.metrics.get("systolic_bp", 0) > 130:
            recommendations.append("需要控制盐摄入和加强运动")
        
        if latest.metrics.get("weight", 0) > 90:  # 示例体重
            recommendations.append("建议健康饮食和规律运动")
        
        if latest.metrics.get("blood_glucose", 0) > 125:
            recommendations.append("需要咨询营养师和内分泌科医生")
        
        return {
            "patient_id": patient_id,
            "latest_record": latest.record_date.isoformat(),
            "recommendations": recommendations,
            "next_checkup": "1周后"
        }


class HealthMCPServer:
    """健康MCP服务器"""
    
    def __init__(self, manager: PatientHealthManager):
        self.manager = manager
    
    def get_tools(self) -> List[Dict]:
        """定义工具"""
        return [
            {
                "name": "track_vitals",
                "description": "追踪生命体征",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "patient_id": {"type": "string"},
                        "vitals": {"type": "object"}
                    },
                    "required": ["patient_id", "vitals"]
                }
            },
            {
                "name": "health_recommendations",
                "description": "获取健康建议",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "patient_id": {"type": "string"}
                    },
                    "required": ["patient_id"]
                }
            }
        ]
    
    async def call_tool(self, tool_name: str, arguments: Dict) -> str:
        """调用工具"""
        import json
        
        try:
            if tool_name == "track_vitals":
                result = await self.manager.track_vital_signs(
                    arguments["patient_id"],
                    arguments["vitals"]
                )
            
            elif tool_name == "health_recommendations":
                result = await self.manager.get_health_recommendations(
                    arguments["patient_id"]
                )
            
            else:
                return json.dumps({"error": f"Unknown tool: {tool_name}"})
            
            return json.dumps(result, ensure_ascii=False, indent=2)
        
        except Exception as e:
            return json.dumps({"error": str(e)})

18.3 医疗隐私与合规

class HealthcarePrivacyManager:
    """医疗隐私管理"""
    
    def __init__(self):
        self.audit_logs: List[Dict] = []
        self.access_controls: Dict[str, List[str]] = {}
    
    def anonymize_patient_data(self, patient_data: Dict) -> Dict:
        """
        匿名化患者数据
        
        Args:
            patient_data: 患者数据
            
        Returns:
            匿名化后的数据
        """
        import hashlib
        
        # 创建伪ID
        pseudo_id = hashlib.sha256(
            patient_data.get("patient_id", "").encode()
        ).hexdigest()[:8]
        
        return {
            "pseudo_patient_id": pseudo_id,
            "age_range": f"{patient_data.get('age', 0) // 10 * 10}-{patient_data.get('age', 0) // 10 * 10 + 9}",
            "condition_type": patient_data.get("diagnosis", "").split()[0],
            "gender": patient_data.get("gender"),
            # 不包含:真实姓名、住址、电话、医保号等
        }
    
    def check_hipaa_compliance(self, data_access: Dict) -> Dict:
        """
        检查HIPAA合规性
        
        Args:
            data_access: 数据访问记录
            
        Returns:
            合规检查结果
        """
        # 检查最小必要原则
        accessed_fields = data_access.get("fields", [])
        allowed_fields = data_access.get("role") == "provider"
        
        # 记录审计日志
        self.audit_logs.append({
            "timestamp": datetime.now().isoformat(),
            "user": data_access.get("user_id"),
            "action": "access_patient_data",
            "patient": data_access.get("patient_id"),
            "status": "allowed" if allowed_fields else "denied"
        })
        
        return {
            "compliant": allowed_fields,
            "audit_logged": True,
            "fields_accessed": accessed_fields if allowed_fields else [],
            "reason_if_denied": "Insufficient authorization" if not allowed_fields else None
        }
    
    def get_audit_trail(self, patient_id: str, days: int = 30) -> List[Dict]:
        """
        获取审计日志
        
        Args:
            patient_id: 患者ID
            days: 天数
            
        Returns:
            审计日志
        """
        cutoff = datetime.now().timestamp() - (days * 86400)
        
        return [
            log for log in self.audit_logs
            if log.get("patient") == patient_id
        ]

18.4 医疗工作流示例

class ClinicialWorkflow:
    """临床工作流"""
    
    async def patient_visit_workflow(self, patient_id: str,
                                    chief_complaint: str) -> Dict:
        """
        患者就诊工作流
        
        Args:
            patient_id: 患者ID
            chief_complaint: 主诉
            
        Returns:
            就诊结果
        """
        workflow = {
            "patient_id": patient_id,
            "steps": [],
            "summary": None
        }
        
        # 第1步:病情分析
        workflow["steps"].append({"name": "Condition Analysis", "status": "running"})
        # 执行分析
        workflow["steps"][-1]["status"] = "completed"
        
        # 第2步:检查建议
        workflow["steps"].append({"name": "Test Recommendation", "status": "running"})
        workflow["steps"][-1]["status"] = "completed"
        
        # 第3步:药物检查
        workflow["steps"].append({"name": "Drug Safety Check", "status": "running"})
        workflow["steps"][-1]["status"] = "completed"
        
        # 第4步:治疗方案
        workflow["steps"].append({"name": "Treatment Plan", "status": "running"})
        workflow["steps"][-1]["status"] = "completed"
        
        # 第5步:随访安排
        workflow["steps"].append({"name": "Follow-up Scheduling", "status": "running"})
        workflow["steps"][-1]["status"] = "completed"
        
        workflow["summary"] = {
            "status": "completed",
            "patient_id": patient_id,
            "chief_complaint": chief_complaint,
            "next_appointment": "2周后"
        }
        
        return workflow

本章总结

关键点说明
病情分析基于主诉和病史的鉴别诊断
药物安全过敏、相互作用、剂量检查
治疗方案个性化治疗计划生成
健康追踪生命体征监测和趋势分析
健康建议个性化健康建议
隐私保护HIPAA合规、数据匿名化
审计日志完整的访问追踪

常见问题

Q1: 如何保证医疗数据安全? A: 加密存储、访问控制、审计日志、HIPAA合规、数据匿名化。

Q2: 如何处理患者隐私? A: 最小必要原则、伪ID、字段级访问控制、定期审计。

Q3: 如何实现临床决策支持? A: 循证医学、临床指南集成、ML模型辅助诊断。

Q4: 如何检查药物相互作用? A: 药物数据库、交叉检查、阈值告警、定期更新。

Q5: 如何优化患者随访? A: 自动提醒、健康指标监测、智能推荐、远程医疗集成。


下一章预告:第19章将讲述教育与培训MCP应用