医疗理赔处理最怕两件事:表单信息散落在 PDF、扫描件和附件里,人工录入又慢又容易出错。这个方案的核心变化是把“读单据、抽字段、校验、转成标准医疗数据”串成一条自动化流水线:Amazon Bedrock Data Automation 负责从理赔表单中提取结构化信息,Amazon Bedrock AgentCore 托管 AI Agent 来做校验和转换,最后把结果写入 AWS HealthLake 中的 FHIR 资源。
这不是简单的 OCR。理赔表单通常包含患者信息、服务日期、诊断代码、费用项目、服务提供方、保险计划等字段,很多字段之间还存在业务约束。Agentic pipeline 的价值在于:抽取之后还有一个可以执行规则、调用工具、补齐上下文并输出标准格式的智能处理层。
流水线里每个组件做什么
一个典型流程可以拆成四段:
- 文档进入对象存储:理赔表单、附件、扫描件上传到 Amazon S3。
- Bedrock Data Automation 抽取信息:从 claim form 中识别患者、服务、诊断、账单等结构化字段。
- AgentCore 托管的 Agent 做验证和转换:检查必填字段、日期范围、代码格式、金额一致性,并把结果映射为 FHIR 资源。
- 写入 AWS HealthLake:把验证通过的数据以 FHIR JSON 的形式导入或写入 HealthLake,便于后续检索、分析和互操作。
这里的关键是职责边界:Data Automation 专注“从文档里读出内容”,Agent 专注“理解这些内容是否合理,以及如何变成系统可用的数据”。这能避免把复杂业务规则塞进单纯的 OCR 或解析逻辑里。
为什么要转成 FHIR,而不是自定义 JSON
理赔数据如果只停留在自定义 JSON,短期看很灵活,长期会变成每个系统都要写一次适配器。FHIR 的意义在于把医疗数据放进一套行业通用的资源模型中。
在理赔场景里,常见映射可能包括:
- 患者基本信息可以映射到
Patient。 - 医疗服务提供方可以映射到
Practitioner或Organization。 - 理赔请求可以映射到
Claim。 - 诊断、服务项目、金额、保险信息可以进入
Claim的相关字段。
实际项目里不建议让模型“自由发挥”生成 FHIR。更稳妥的做法是让 Agent 只负责受控转换:输入结构、输出 schema、校验规则、失败原因都要明确。这样才能让自动化既快又可审计。
可以这样实践:用 Agent 校验并生成 FHIR Claim
下面是一个可改造的最小 Python 示例。它不依赖真实 AWS 调用,适合先在本地验证“抽取结果 → 校验 → FHIR Claim JSON”的处理逻辑。接入 Bedrock Data Automation 和 AgentCore 时,可以把 extracted_claim 替换成文档抽取结果,把 build_fhir_claim() 包装成 Agent 可调用工具。
运行前准备:
python -m venv .venv
source .venv/bin/activate
python claims_to_fhir.py
创建 claims_to_fhir.py:
import json
from datetime import date
REQUIRED_FIELDS = [
"claim_id",
"patient_id",
"patient_name",
"provider_id",
"service_date",
"diagnosis_code",
"procedure_code",
"amount_usd",
]
def validate_claim(claim: dict) -> list[str]:
errors = []
for field in REQUIRED_FIELDS:
if not claim.get(field):
errors.append(f"Missing required field: {field}")
if claim.get("amount_usd", 0) <= 0:
errors.append("amount_usd must be greater than 0")
if claim.get("service_date") > date.today().isoformat():
errors.append("service_date cannot be in the future")
if not str(claim.get("diagnosis_code", "")).startswith("ICD10:"):
errors.append("diagnosis_code must use ICD10:<code> format")
return errors
def build_fhir_claim(claim: dict) -> dict:
errors = validate_claim(claim)
if errors:
return {
"status": "validation_failed",
"claim_id": claim.get("claim_id"),
"errors": errors,
}
return {
"resourceType": "Claim",
"id": claim["claim_id"],
"status": "active",
"use": "claim",
"patient": {
"reference": f"Patient/{claim['patient_id']}",
"display": claim["patient_name"],
},
"provider": {
"reference": f"Organization/{claim['provider_id']}"
},
"created": date.today().isoformat(),
"diagnosis": [
{
"sequence": 1,
"diagnosisCodeableConcept": {
"coding": [
{
"system": "http://hl7.org/fhir/sid/icd-10-cm",
"code": claim["diagnosis_code"].replace("ICD10:", ""),
}
]
},
}
],
"item": [
{
"sequence": 1,
"productOrService": {
"coding": [
{
"system": "http://www.ama-assn.org/go/cpt",
"code": claim["procedure_code"],
}
]
},
"servicedDate": claim["service_date"],
"net": {
"value": claim["amount_usd"],
"currency": "USD",
},
}
],
}
extracted_claim = {
"claim_id": "claim-10001",
"patient_id": "patient-42",
"patient_name": "Jane Doe",
"provider_id": "provider-88",
"service_date": "2024-05-17",
"diagnosis_code": "ICD10:E11.9",
"procedure_code": "99213",
"amount_usd": 185.75,
}
print(json.dumps(build_fhir_claim(extracted_claim), indent=2))
这个示例刻意把校验和转换放在同一个小模块里,方便理解。在生产环境中,更推荐拆成三层:
- 抽取层:只输出结构化字段和置信度。
- 校验层:执行确定性规则,例如必填、格式、金额、日期、代码集。
- 转换层:生成符合 HealthLake 接收要求的 FHIR JSON。
接入 AWS 时的工作流骨架
下面这个 Step Functions 风格的 YAML 是一个可改造的编排骨架,用来表达端到端流程。具体 API 名称、权限策略和资源 ARN 需要按你的 AWS 账户、Region、Bedrock Data Automation 项目和 HealthLake 数据存储配置调整。
Comment: Claims processing pipeline with Bedrock and HealthLake
StartAt: ExtractClaimDocument
States:
ExtractClaimDocument:
Type: Task
Resource: arn:aws:states:::aws-sdk:bedrockdataautomation:startJob
Parameters:
InputS3Uri.$: $.document_s3_uri
OutputS3Uri.$: $.extraction_output_s3_uri
ProjectArn: arn:aws:bedrock:us-east-1:123456789012:data-automation-project/claims
Next: RunClaimsAgent
RunClaimsAgent:
Type: Task
Resource: arn:aws:states:::lambda:invoke
Parameters:
FunctionName: claims-agentcore-adapter
Payload:
extraction_output_s3_uri.$: $.extraction_output_s3_uri
Next: CheckValidation
CheckValidation:
Type: Choice
Choices:
- Variable: $.Payload.status
StringEquals: validation_failed
Next: SendToManualReview
Default: WriteToHealthLake
WriteToHealthLake:
Type: Task
Resource: arn:aws:states:::lambda:invoke
Parameters:
FunctionName: write-fhir-to-healthlake
Payload:
fhir_resource.$: $.Payload.fhir_resource
End: true
SendToManualReview:
Type: Task
Resource: arn:aws:states:::sns:publish
Parameters:
TopicArn: arn:aws:sns:us-east-1:123456789012:claims-review
Message.$: $.Payload.errors
End: true
这段 YAML 的重点不是让你直接部署,而是给出分层方式:抽取任务、Agent 校验转换、失败分流、成功写入。医疗和保险系统里,“不能自动处理”的路径和“自动成功”的路径一样重要,因为异常样本通常需要审计、追踪和人工复核。
生产落地时别跳过这些边界
医疗理赔涉及敏感数据,自动化越强,治理要求越高。建议上线前至少检查这些点:
- 最小权限:S3、Bedrock、Lambda、HealthLake、SNS 或 Step Functions 权限都应按资源和动作收窄。
- 字段级审计:保留原始文档位置、抽取字段、置信度、校验错误和最终 FHIR 资源版本。
- 人工复核通道:低置信度、金额异常、代码不匹配、缺失患者标识等情况必须可回退。
- 确定性校验优先:日期、金额、代码集、必填字段不要只交给模型判断。
- PHI 保护:日志、监控、调试样本和失败消息中避免泄露受保护健康信息。
这类架构的最佳切入点不是一上来追求“全自动理赔”,而是先选择格式稳定、规则明确、人工成本高的单据类型。让 Bedrock Data Automation 负责读文档,让 AgentCore 中的 Agent 负责受控推理和转换,再由 HealthLake 承接标准化数据。这样既能减少手工录入,又能保留医疗系统需要的准确性、可解释性和审计链路。