
第六章 互操作设计:基于FHIR的标准化接口
6.1 互操作的重要性
医疗AI系统不是孤立存在的,必须与医院现有信息系统深度集成。互操作设计的目标是实现:
- 数据可交换:与EMR、LIS、PACS等系统无缝对接
- 功能可组合:作为更大医疗工作流的一部分
- 标准可遵循:符合行业标准,支持未来扩展
- 生态可融入:能够融入医院信息化生态
6.2 双层输出设计
6.2.1 业务回写层(当前可落地)
目标:实现与现有系统的直接对接
设计原则:
- 最小侵入性:尽量不修改现有系统
- 可追溯性:所有回写操作都有完整审计
- 幂等性:支持重复操作,避免数据不一致
实现方案:
python
class BusinessWriteBackLayer:
def __init__(self,
emr_adapter: EMRAdapter,
qc_adapter: QualityControlAdapter):
self.emr = emr_adapter
self.qc = qc_adapter
def write_back(self,
payload: CanonicalPayload,
write_targets: List[WriteTarget]) -> WriteBackResult:
results = []
for target in write_targets:
if target.system == "EMR":
result = self.write_to_emr(payload, target)
elif target.system == "QUALITY_CONTROL":
result = self.write_to_qc(payload, target)
elif target.system == "CODING_SYSTEM":
result = self.write_to_coding(payload, target)
else:
result = WriteResult(
success=False,
error=f"Unsupported system: {target.system}"
)
results.append(result)
# 检查所有写入是否成功
overall_success = all(r.success for r in results)
return WriteBackResult(
success=overall_success,
individual_results=results,
trace_id=payload.trace_id
)
def write_to_emr(self, payload: CanonicalPayload, target: WriteTarget) -> WriteResult:
"""写入电子病历系统"""
try:
# 构建EMR特定格式
emr_format = self.convert_to_emr_format(payload)
# 执行写入
if target.interface_type == "STORED_PROCEDURE":
result = self.emr.call_stored_procedure(
procedure_name=target.procedure_name,
parameters=emr_format
)
elif target.interface_type == "SOAP":
result = self.emr.call_soap_service(
endpoint=target.endpoint,
operation=target.operation,
parameters=emr_format
)
elif target.interface_type == "REST":
result = self.emr.call_rest_api(
url=target.url,
method=target.method,
data=emr_format
)
else:
raise ValueError(f"Unsupported interface: {target.interface_type}")
return WriteResult(
success=True,
external_id=result.document_id,
message="Write successful"
)
except Exception as e:
return WriteResult(
success=False,
error=str(e)
)
回写字段映射表:
| 智能体输出字段 | EMR表字段 | 数据类型 | 是否必填 | 备注 |
|---|---|---|---|---|
| doc.sections.text | 病历文书表.content | CLOB | 是 | 病历正文 |
| doc.sections.evidence | 病历文书表.evidence_json | JSON | 是 | 证据引用 |
| cdi.gaps | CDI建议表.suggestions | JSON | 否 | CDI缺口建议 |
| icd.diagnosis_candidates | 编码建议表.candidates | JSON | 否 | ICD编码建议 |
| trace_id | 所有表.trace_id | VARCHAR(64) | 是 | 追踪ID |
| versioning.model | 所有表.model_version | VARCHAR(32) | 是 | 模型版本 |
6.2.2 标准对齐层(长期演进)
目标:实现基于FHIR的标准化互操作
FHIR资源映射:
python
class FHIRMapper:
def to_fhir(self, payload: CanonicalPayload) -> Bundle:
"""将内部格式转换为FHIR Bundle"""
bundle = Bundle(
type="collection",
entry=[]
)
# 1. 创建Patient资源
patient = self.create_patient_resource(payload)
bundle.entry.append(BundleEntry(resource=patient))
# 2. 创建Encounter资源
encounter = self.create_encounter_resource(payload)
bundle.entry.append(BundleEntry(resource=encounter))
# 3. 创建DocumentReference资源(病历文书)
document_ref = self.create_document_reference(payload)
bundle.entry.append(BundleEntry(resource=document_ref))
# 4. 创建Condition资源(诊断)
for diagnosis in payload.get("diagnoses", []):
condition = self.create_condition_resource(diagnosis, payload)
bundle.entry.append(BundleEntry(resource=condition))
# 5. 创建Procedure资源(手术操作)
for procedure in payload.get("procedures", []):
proc = self.create_procedure_resource(procedure, payload)
bundle.entry.append(BundleEntry(resource=proc))
# 6. 创建Observation资源(检验检查)
for observation in payload.get("observations", []):
obs = self.create_observation_resource(observation, payload)
bundle.entry.append(BundleEntry(resource=obs))
return bundle
def create_document_reference(self, payload: CanonicalPayload) -> DocumentReference:
"""创建FHIR DocumentReference资源"""
return DocumentReference(
status="current",
docStatus="preliminary",
type=CodeableConcept(
coding=[Coding(
system="http://loinc.org",
code="11506-3", # Progress note
display="Progress note"
)]
),
subject=Reference(
reference=f"Patient/{payload.patient_id}"
),
context=Reference(
reference=f"Encounter/{payload.encounter_id}"
),
content=[
DocumentReferenceContent(
attachment=Attachment(
contentType="text/plain",
data=base64.b64encode(
json.dumps(payload.doc).encode()
).decode(),
title=f"AI-Generated Note for {payload.encounter_id}"
)
)
],
extension=[
Extension(
url="http://example.com/extension/ai-metadata",
extension=[
Extension(
url="modelVersion",
valueString=payload.versioning.model
),
Extension(
url="generationTimestamp",
valueInstant=datetime.now().isoformat()
)
]
)
]
)
FHIR实施路线图:
| 阶段 | FHIR资源 | 实施重点 | 预期收益 |
|---|---|---|---|
| 第一阶段 | DocumentReference | 病历文书索引与检索 | 文书级互操作 |
| 第二阶段 | Condition, Procedure, Observation | 关键临床数据标准化 | 数据交换与科研 |
| 第三阶段 | Composition, List | 结构化病历组装 | 完整病历交换 |
| 第四阶段 | CDS Hooks, SMART on FHIR | 临床决策支持集成 | 工作流集成 |
6.3 互操作技术实现
6.3.1 数据库直连模式
适用场景:院内网络,直接数据库访问
实现方案:
python
class DatabaseConnector:
def __init__(self,
config: DatabaseConfig,
audit_logger: AuditLogger):
self.config = config
self.audit_logger = audit_logger
def execute_read(self, query: str, params: tuple) -> List[dict]:
"""执行只读查询"""
# 记录审计日志
audit_id = self.audit_logger.log_query(
query_template=query,
parameters=params,
operation="READ",
timestamp=datetime.now()
)
try:
# 执行查询
with self.get_connection() as conn:
with conn.cursor() as cursor:
cursor.execute(query, params)
rows = cursor.fetchall()
# 转换为字典列表
columns = [col[0] for col in cursor.description]
result = [dict(zip(columns, row)) for row in rows]
# 记录成功
self.audit_logger.log_success(audit_id, len(result))
return result
except Exception as e:
# 记录失败
self.audit_logger.log_failure(audit_id, str(e))
raise
def call_stored_procedure(self,
sp_name: str,
params: dict) -> dict:
"""调用存储过程"""
# 构建调用语句
param_placeholders = ", ".join([f":{p}" for p in params.keys()])
call_stmt = f"BEGIN {sp_name}({param_placeholders}); END;"
# 记录审计日志
audit_id = self.audit_logger.log_procedure_call(
procedure_name=sp_name,
parameters=params,
operation="WRITE"
)
try:
with self.get_connection() as conn:
with conn.cursor() as cursor:
# 执行存储过程
cursor.execute(call_stmt, params)
conn.commit()
# 记录成功
self.audit_logger.log_success(audit_id)
return {"success": True}
except Exception as e:
# 记录失败
self.audit_logger.log_failure(audit_id, str(e))
raise
6.3.2 WebService接口模式
适用场景:跨系统、跨网络边界调用
SOAP实现:
python
class SoapClient:
def __init__(self,
wsdl_url: str,
security_config: SecurityConfig):
self.client = self._create_client(wsdl_url, security_config)
def _create_client(self, wsdl_url: str, security_config: SecurityConfig):
"""创建SOAP客户端"""
# 配置传输层
transport = Transport(
timeout=security_config.timeout,
verify=security_config.verify_ssl
)
# 配置WS-Security
if security_config.auth_type == "USERNAME_TOKEN":
wsse = UsernameToken(
security_config.username,
security_config.password
)
elif security_config.auth_type == "CERTIFICATE":
wsse = Signature(
security_config.certificate,
security_config.private_key
)
else:
raise ValueError(f"Unsupported auth type: {security_config.auth_type}")
# 创建客户端
client = Client(
wsdl=wsdl_url,
transport=transport,
wsse=wsse
)
return client
def call_service(self,
operation: str,
parameters: dict,
trace_id: str) -> dict:
"""调用SOAP服务"""
# 添加追踪头
headers = {
"Trace-ID": trace_id,
"Timestamp": datetime.now().isoformat()
}
try:
# 执行调用
response = self.client.service[operation](
**parameters,
_soapheaders=headers
)
return {
"success": True,
"data": response,
"trace_id": trace_id
}
except Exception as e:
return {
"success": False,
"error": str(e),
"trace_id": trace_id
}
REST实现:
python
class RestClient:
def __init__(self,
base_url: str,
auth_config: AuthConfig):
self.base_url = base_url.rstrip("/")
self.auth = self._create_auth_handler(auth_config)
def _create_auth_handler(self, config: AuthConfig):
"""创建认证处理器"""
if config.type == "OAUTH2":
return OAuth2Auth(
token_url=config.token_url,
client_id=config.client_id,
client_secret=config.client_secret,
scope=config.scope
)
elif config.type == "API_KEY":
return ApiKeyAuth(
key=config.api_key,
location=config.location # header, query, etc.
)
elif config.type == "BASIC":
return HTTPBasicAuth(
config.username,
config.password
)
else:
raise ValueError(f"Unsupported auth type: {config.type}")
def post(self,
endpoint: str,
data: dict,
trace_id: str) -> dict:
"""发送POST请求"""
url = f"{self.base_url}/{endpoint.lstrip('/')}"
# 添加追踪头
headers = {
"Trace-ID": trace_id,
"Content-Type": "application/json",
"X-Request-ID": str(uuid.uuid4())
}
try:
response = requests.post(
url=url,
json=data,
auth=self.auth,
headers=headers,
timeout=30,
verify=True # 验证SSL证书
)
response.raise_for_status()
return {
"success": True,
"status_code": response.status_code,
"data": response.json(),
"trace_id": trace_id
}
except requests.RequestException as e:
return {
"success": False,
"error": str(e),
"status_code": getattr(e.response, 'status_code', None),
"trace_id": trace_id
}
6.4 互操作最佳实践
6.4.1 接口设计原则
-
幂等性设计:
python# 使用唯一标识确保幂等性 def write_with_idempotency(self, data: dict, idempotency_key: str): # 检查是否已处理 if self.is_already_processed(idempotency_key): return self.get_previous_result(idempotency_key) # 处理并记录 result = self.process(data) self.record_processing(idempotency_key, result) return result -
版本管理:
python# 接口版本控制 class APIVersion: def __init__(self, version: str): self.version = version def is_compatible(self, other_version: str) -> bool: # 版本兼容性检查 major_self = int(self.version.split('.')[0]) major_other = int(other_version.split('.')[0]) return major_self == major_other -
错误处理标准化:
json{ "error": { "code": "VALIDATION_ERROR", "message": "请求数据验证失败", "details": [ { "field": "patient_id", "issue": "缺失必填字段" } ], "trace_id": "abc123", "timestamp": "2024-01-15T10:30:00Z" } }
6.4.2 性能优化策略
-
批量处理:
pythonclass BatchProcessor: def process_batch(self, items: List[dict], batch_size: int = 100): results = [] for i in range(0, len(items), batch_size): batch = items[i:i+batch_size] batch_result = self.process_single_batch(batch) results.extend(batch_result) # 避免过载 time.sleep(0.1) return results -
缓存策略:
pythonclass CachingConnector: def __init__(self, delegate: Connector, cache: Cache, ttl_seconds: int = 300): self.delegate = delegate self.cache = cache self.ttl = ttl_seconds def fetch_data(self, key: str, **kwargs): # 尝试从缓存获取 cached = self.cache.get(key) if cached is not None: return cached # 缓存未命中,从实际数据源获取 data = self.delegate.fetch_data(**kwargs) # 存入缓存 self.cache.set(key, data, ttl=self.ttl) return data -
连接池管理:
pythonclass ConnectionPool: def __init__(self, max_connections: int = 10, max_idle_time: int = 300): self.pool = Queue(maxsize=max_connections) self.max_idle_time = max_idle_time def get_connection(self): try: # 尝试从池中获取 conn = self.pool.get_nowait() # 检查连接是否仍然有效 if self.is_connection_valid(conn): return conn else: # 连接无效,创建新的 return self.create_new_connection() except Empty: # 池为空,创建新的 if self.pool.qsize() < self.max_connections: return self.create_new_connection() else: # 达到最大连接数,等待 return self.pool.get(timeout=10)
6.4.3 安全与合规
-
数据脱敏:
pythonclass DataMasker: def mask_sensitive_data(self, data: dict) -> dict: masked = data.copy() # 脱敏规则 rules = [ ("patient_name", self.mask_name), ("id_number", self.mask_id), ("phone_number", self.mask_phone), ("address", self.mask_address) ] for field, mask_func in rules: if field in masked: masked[field] = mask_func(masked[field]) return masked def mask_name(self, name: str) -> str: if len(name) <= 1: return "*" return name[0] + "*" * (len(name) - 1) -
访问控制:
pythonclass AccessController: def check_permission(self, user: User, resource: Resource, action: Action) -> bool: # 基于角色的访问控制 if not user.is_active: return False # 检查角色权限 required_role = self.get_required_role(resource, action) if required_role not in user.roles: return False # 检查数据权限 if not self.check_data_permission(user, resource): return False return True -
审计日志:
pythonclass AuditLogger: def log_access(self, user_id: str, resource_type: str, resource_id: str, action: str, success: bool, details: dict = None): log_entry = { "timestamp": datetime.now().isoformat(), "user_id": user_id, "resource_type": resource_type, "resource_id": resource_id, "action": action, "success": success, "ip_address": self.get_client_ip(), "user_agent": self.get_user_agent(), "details": details or {} } # 写入审计日志 self.write_log(log_entry) # 实时告警(如需要) if not success and self.is_suspicious_action(action, resource_type): self.trigger_alert(log_entry)
6.5 互操作实施建议
- 渐进式实施:从简单的数据读取开始,逐步实现复杂的双向同步
- 兼容性设计:新接口不影响现有系统的正常运行
- 性能监控:监控接口响应时间、错误率和吞吐量
- 容错处理:设计重试机制、降级策略和故障转移
- 文档完善:提供详细的接口文档和集成指南
- 测试充分:进行接口兼容性测试、性能测试和安全性测试
第七章 完整落地实施方案
7.1 实施路线图
7.1.1 Phase 1:单科室闭环试点(4-8周)
目标:在一个科室验证核心功能,建立基础流程
关键活动:
-
环境搭建:
bash# 1. K8s集群初始化 kubectl create namespace med-ai-pilot # 2. 部署基础组件 helm install postgresql bitnami/postgresql -n med-ai-pilot helm install redis bitnami/redis -n med-ai-pilot # 3. 部署模型服务 kubectl apply -f deploy/k8s/vllm-deployment.yaml -n med-ai-pilot # 4. 部署业务服务 kubectl apply -f deploy/k8s/api-gateway.yaml -n med-ai-pilot kubectl apply -f deploy/k8s/workflow-worker.yaml -n med-ai-pilot -
功能开发:
- 上下文构建Agent
- 病历生成Agent(基于模板)
- 事实一致性校验Agent
- 简单的人工审核界面
-
集成对接:
python# 试点科室EMR对接配置 pilot_config = { "department": "internal_medicine", "emr_connection": { "type": "oracle", "dsn": "10.0.100.10:1521/EMR", "readonly_user": "ai_reader", "write_user": "ai_writer" }, "templates": { "admission_note": "templates/internal_medicine/admission.yaml", "progress_note": "templates/internal_medicine/progress.yaml" }, "test_cases": "test_data/pilot_cases.json" } -
验收标准:
- 医生编辑距离下降30%以上
- 关键字段一致率≥99%
- 幻觉率≤0.5%
- 医生满意度评分≥4.0(5分制)
7.1.2 Phase 2:加入CDI/ICD功能(8-12周)
目标:扩展系统能力,支持临床文档改进和编码建议
关键活动:
-
CDI规则库建设:
python# CDI规则配置 cdi_rules = { "internal_medicine": [ { "id": "CDI-IM-001", "title": "慢性病急性加重证据", "condition": "慢性病诊断存在,但缺少急性加重证据", "severity": "high", "recommendation": "记录急性加重的具体表现和评估" }, # 更多规则... ], "surgery": [ # 外科特定规则 ] } -
ICD知识库构建:
sql-- ICD知识库表结构 CREATE TABLE icd_knowledge_base ( id SERIAL PRIMARY KEY, icd_code VARCHAR(20) NOT NULL, icd_name VARCHAR(500) NOT NULL, clinical_features JSONB, -- 典型临床表现 required_evidence JSONB, -- 必需证据 common_comorbidities JSONB, -- 常见合并症 exclusion_criteria JSONB, -- 排除标准 drg_impact VARCHAR(50), -- DRG分组影响 update_date DATE, UNIQUE(icd_code) ); -- 病例-ICD关联表 CREATE TABLE case_icd_mapping ( case_id VARCHAR(100) NOT NULL, icd_code VARCHAR(20) NOT NULL, is_primary BOOLEAN DEFAULT FALSE, confidence_score DECIMAL(5,4), supporting_evidence JSONB, gold_standard BOOLEAN DEFAULT FALSE, reviewer VARCHAR(100), review_date DATE, PRIMARY KEY(case_id, icd_code) ); -
功能开发:
- CDI缺口发现Agent
- ICD建议Agent
- 编码审核界面
- CDI建议反馈机制
-
验收标准:
- CDI命中率≥30%
- ICD编码Top-1准确率≥85%
- 编码员审核时间减少40%
- 编码准确性提升15%
7.1.3 Phase 3:全院平台化(3-6个月)
目标:构建全院统一的AI病历平台
关键活动:
-
平台架构升级:
yaml# 平台化架构配置 platform: multi_tenant: true department_templates: internal_medicine: "templates/im/" surgery: "templates/surgery/" pediatrics: "templates/pediatrics/" model_management: version_control: true a_b_testing: true canary_release: true monitoring: metrics: ["quality", "performance", "business"] alerts: pagerduty_integration: true wechat_notification: true -
服务治理增强:
- 引入服务网格(Istio)
- 实现多版本模型管理
- 建立统一的监控告警平台
- 实施细粒度的权限控制
-
双轨部署实现:
bash# 轨道A:弹性架构部署 helm install medical-ai ./charts/medical-ai \ -n med-ai-prod \ -f values/values-prod-a.yaml # 轨道B:合规架构部署 helm install medical-ai ./charts/medical-ai \ -n med-ai-onprem \ -f values/values-prod-b.yaml -
验收标准:
- 支持≥10个科室
- 系统可用性≥99.5%
- P95响应时间≤5秒
- 同时在线用户≥200人
7.2 技术实现细节
7.2.1 Kubernetes部署配置
yaml
# 完整的K8s部署配置示例
apiVersion: v1
kind: Namespace
metadata:
name: med-ai-prod
labels:
environment: production
compliance-level: hipaa
---
# PostgreSQL数据库(审计与状态存储)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql
namespace: med-ai-prod
spec:
serviceName: postgresql
replicas: 1
selector:
matchLabels:
app: postgresql
template:
metadata:
labels:
app: postgresql
spec:
containers:
- name: postgresql
image: postgres:15-alpine
env:
- name: POSTGRES_DB
value: medical_ai
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-credentials
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-credentials
key: password
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "4Gi"
cpu: "2000m"
readinessProbe:
exec:
command:
- pg_isready
- -h
- localhost
- -U
- postgres
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:
exec:
command:
- pg_isready
- -h
- localhost
- -U
- postgres
initialDelaySeconds: 60
periodSeconds: 10
volumes:
- name: data
persistentVolumeClaim:
claimName: postgresql-pvc
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Gi
---
# vLLM模型服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm
namespace: med-ai-prod
spec:
replicas: 2
selector:
matchLabels:
app: vllm
template:
metadata:
labels:
app: vllm
spec:
nodeSelector:
accelerator: nvidia-gpu
tolerations:
- key: "nvidia.com/gpu"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: vllm
image: vllm/vllm-openai:latest
args:
- --model
- /models/clinical-llm-v2
- --tensor-parallel-size
- "1"
- --max-model-len
- "8192"
- --gpu-memory-utilization
- "0.9"
- --port
- "8000"
- --served-model-name
- clinical-llm
env:
- name: CUDA_VISIBLE_DEVICES
value: "0"
ports:
- containerPort: 8000
resources:
limits:
nvidia.com/gpu: 1
memory: "16Gi"
cpu: "4000m"
requests:
nvidia.com/gpu: 1
memory: "16Gi"
cpu: "2000m"
volumeMounts:
- name: model-storage
mountPath: /models
readOnly: true
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 60
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
volumes:
- name: model-storage
persistentVolumeClaim:
claimName: model-storage-pvc
---
# API网关服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
namespace: med-ai-prod
spec:
replicas: 3
selector:
matchLabels:
app: api-gateway
template:
metadata:
labels:
app: api-gateway
spec:
containers:
- name: api-gateway
image: registry.example.com/medical-ai/api-gateway:v1.2.0
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: database-credentials
key: url
- name: REDIS_URL
value: "redis://redis:6379"
- name: VLLM_ENDPOINT
value: "http://vllm:8000"
- name: TEMPORAL_HOST
value: "temporal:7233"
ports:
- containerPort: 8080
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
7.2.2 安全配置
yaml
# 网络策略:默认拒绝所有
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: med-ai-prod
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 允许API网关接收外部流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-to-api
namespace: med-ai-prod
spec:
podSelector:
matchLabels:
app: api-gateway
ingress:
- from:
- ipBlock:
cidr: 10.0.0.0/8 # 院内网络
ports:
- protocol: TCP
port: 8080
---
# 允许服务间必要通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-internal-communication
namespace: med-ai-prod
spec:
podSelector:
matchLabels:
app.kubernetes.io/part-of: medical-ai
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/part-of: medical-ai
egress:
- to:
- podSelector:
matchLabels:
app.kubernetes.io/part-of: medical-ai
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8000
- protocol: TCP
port: 5432
- protocol: TCP
port: 6379
---
# 允许访问EMR系统
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-emr-access
namespace: med-ai-prod
spec:
podSelector:
matchLabels:
app: emr-connector
egress:
- to:
- ipBlock:
cidr: 10.0.100.0/24 # EMR系统网段
ports:
- protocol: TCP
port: 1521 # Oracle
- protocol: TCP
port: 443 # SOAP WebService
7.2.3 监控与告警配置
yaml
# Prometheus监控配置
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: medical-ai-monitor
namespace: med-ai-prod
spec:
selector:
matchLabels:
app.kubernetes.io/part-of: medical-ai
endpoints:
- port: metrics
interval: 30s
path: /metrics
- port: health
interval: 30s
path: /health
---
# 告警规则配置
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: medical-ai-alerts
namespace: med-ai-prod
spec:
groups:
- name: medical-ai
rules:
- alert: HighErrorRate
expr: |
rate(http_requests_total{status=~"5.."}[5m]) /
rate(http_requests_total[5m]) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "高错误率检测"
description: "服务错误率超过5% (当前值: {{ $value }})"
- alert: HighLatency
expr: |
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket[5m])
) > 6
for: 5m
labels:
severity: warning
annotations:
summary: "高延迟检测"
description: "P95延迟超过6秒 (当前值: {{ $value }}s)"
- alert: LowFactConsistency
expr: |
medical_ai_fact_consistency_rate < 0.98
for: 10m
labels:
severity: critical
annotations:
summary: "事实一致性下降"
description: "事实一致率低于98% (当前值: {{ $value }})"
- alert: HighHallucinationRate
expr: |
medical_ai_hallucination_rate > 0.005
for: 10m
labels:
severity: critical
annotations:
summary: "幻觉率过高"
description: "幻觉率超过0.5% (当前值: {{ $value }})"