临床试验入组判断同时涉及病历检索、方案条件匹配、药物安全风险和临床责任确认。传统流程往往需要人工在多个系统之间查找信息,速度受到限制;完全自动化又可能把不确定的模型判断直接变成医疗决策。
Amazon Bedrock AgentCore 提供了一种更适合临床场景的架构:让智能体负责整理证据、执行筛查和解释结论,让 AWS HealthLake 作为医疗数据来源,并通过 AgentCore Evaluations 持续检查准确性、完整性和安全边界。最终的入组决定仍由临床人员确认。
把筛查流程拆成可审计的步骤
一个实用的筛查智能体可以按以下链路工作:
- 接收试验方案、候选患者标识和筛查范围。
- 从 AWS HealthLake 检索结构化和非结构化医疗记录。
- 将入选标准、排除标准拆成独立的检查项。
- 为每个检查项寻找病历证据,并标记证据时间、来源和缺失信息。
- 评估潜在安全风险,例如既往疾病、过敏史、实验室指标或合并用药。
- 输出“符合”“不符合”或“需要人工确认”,同时给出理由。
- 把结果提交给临床人员,而不是直接执行入组操作。
这种拆分很重要。一个简单的“患者是否符合试验条件”答案不够支撑临床审查。审查者需要知道模型检查了什么、使用了哪条记录、哪些条件仍然没有证据,以及结论是否依赖模型推断。
推荐的组件边界
- AWS HealthLake:保存和检索经过标准化的临床数据,例如患者、诊断、用药、过敏、实验室结果和观察记录。
- Amazon Bedrock AgentCore:承载智能体的工具调用、会话上下文、权限边界和运行时行为。
- AgentCore Evaluations:使用固定测试集和评价指标检查智能体的输出质量,并持续发现回归问题。
- 临床审核界面:展示候选结论、证据、缺失字段和风险提示,并提供人工确认或驳回操作。
智能体不应拥有“入组患者”这类不可逆权限。它可以读取授权范围内的医疗资料、执行筛查和生成报告;写入研究系统、发送通知或改变患者状态的操作,应由独立服务和人工审批共同控制。
让模型输出证据,而不是只输出结论
入选和排除条件最好转换成结构化检查表。每个条件至少包含以下字段:
{
"criterion_id": "EX-03",
"criterion": "过去 6 个月内是否存在严重心血管事件",
"status": "needs_review",
"evidence": [
{
"resource_type": "Observation",
"resource_id": "example-resource-id",
"recorded_at": "2025-01-15",
"summary": "找到心电图记录,但病历未明确说明事件严重程度"
}
],
"missing_information": ["事件严重程度", "事件发生日期"],
"confidence": "low"
}
其中,needs_review 应该是正常结果,而不是异常结果。医疗记录经常存在时间冲突、缩写、缺失或描述不完整的情况。对于低置信度条件,智能体应主动停止自动判断,并把问题交给临床人员。
提示词也应该明确这种行为边界。例如,可以要求模型:
- 只能使用工具返回的患者数据,不得凭空补全病史;
- 每个通过或不通过的条件都必须引用证据;
- 找不到证据时输出
unknown或needs_review; - 不把统计相关性当作患者级别的医疗结论;
- 发现可能的安全风险时优先升级人工审核;
- 不执行诊断、处方或入组确认。
一个可改造的 Bedrock 筛查工作流
下面的 Python 示例展示了一个最小的“检索数据、调用模型、请求人工确认”流程。示例中的 get_patient_records 是 HealthLake 查询适配层的占位实现;生产环境应使用应用已有的 FHIR 搜索、身份认证、审计和最小权限策略进行替换。
运行前准备:配置 AWS 凭证和区域,确认调用方拥有 Bedrock Runtime 的调用权限,并把模型 ID 替换为组织批准使用的模型。不要把真实患者数据复制到本地测试文件或日志中。
import json
import os
import boto3
REGION = os.getenv("AWS_REGION", "us-east-1")
MODEL_ID = os.getenv("BEDROCK_MODEL_ID", "your-approved-model-id")
bedrock = boto3.client("bedrock-runtime", region_name=REGION)
def get_patient_records(patient_id: str) -> list[dict]:
"""Replace this adapter with an authorized HealthLake FHIR search."""
# Example only: production code should query HealthLake and redact logs.
return [
{
"resourceType": "Observation",
"id": "example-resource-id",
"recordedAt": "2025-01-15",
"text": "Cardiology event severity is not documented.",
}
]
def screen_patient(patient_id: str, trial_criteria: list[dict]) -> dict:
records = get_patient_records(patient_id)
request = {
"patient_id": patient_id,
"criteria": trial_criteria,
"records": records,
"required_output": {
"overall_status": "eligible|ineligible|needs_review",
"criteria_results": "one result per criterion",
"safety_flags": "risk, evidence, and urgency",
"human_review_questions": "specific unresolved questions",
},
}
prompt = (
"You are a clinical trial screening assistant. "
"Use only the supplied records. Do not infer missing facts. "
"Return JSON. Any uncertain or safety-sensitive condition must be "
"marked needs_review and include the missing evidence.\n\n"
+ json.dumps(request, ensure_ascii=False)
)
response = bedrock.converse(
modelId=MODEL_ID,
messages=[{"role": "user", "content": [{"text": prompt}]}],
inferenceConfig={"temperature": 0},
)
text = response["output"]["message"]["content"][0]["text"]
result = json.loads(text)
# The application must persist this as a pending review, not an enrollment.
result["patient_id"] = patient_id
result["review_state"] = "pending_clinician_review"
return result
if __name__ == "__main__":
criteria = [
{"id": "IN-01", "text": "Meets the trial's age requirement"},
{"id": "EX-03", "text": "No qualifying severe cardiovascular event in the exclusion window"},
]
print(json.dumps(screen_patient("example-patient-id", criteria), indent=2))
这个示例只负责生成待审核结果。生产系统还需要补充以下能力:
- 通过 IAM、短期凭证和患者级别授权限制数据访问;
- 对 FHIR 资源、模型请求和模型响应执行审计记录;
- 对患者标识、日志和评估数据执行脱敏;
- 设置超时、重试、模型不可用和工具调用失败的处理策略;
- 对高风险安全信号采用明确的升级路径;
- 把模型输出与原始记录绑定,避免证据链断裂。
用 AgentCore Evaluations 检查质量与边界
评估不能只看“最终答案是否正确”。临床筛查智能体至少应测试以下维度:
- 标准覆盖率:是否逐项检查了所有入选和排除条件;
- 证据准确性:引用的记录是否真的支持对应结论;
- 时间有效性:是否正确处理记录发生时间和方案时间窗口;
- 不确定性处理:信息缺失时是否升级人工审核,而不是猜测;
- 安全敏感性:潜在风险是否被识别并清楚呈现;
- 可解释性:临床人员能否快速理解结论依据;
- 权限与工具行为:智能体是否调用了超出授权范围的工具。
可以建立一组固定的脱敏案例,覆盖边界条件:完整符合、明确不符合、记录缺失、记录互相矛盾、时间窗口临界、存在高风险合并用药,以及恶意提示词试图让模型忽略安全规则的情况。每次更换模型、提示词、检索逻辑或工具权限后,都应重新运行这组评估。
评价结果应同时保存输入版本、方案版本、检索到的证据标识、模型版本和输出版本。这样才能区分“模型回答错误”和“检索层没有找到正确记录”这两类完全不同的问题。
上线前的工程检查清单
- 将智能体定位为筛查和证据整理工具,保留临床人员的最终决策权。
- 为每一个标准定义明确的
eligible、ineligible和needs_review状态。 - 对缺失、冲突和过期数据采用保守处理。
- 只暴露读取和分析所需的最小工具权限。
- 让所有结论都能回溯到 HealthLake 中的具体资源或文档。
- 使用 AgentCore Evaluations 建立可重复的回归测试集。
- 监控人工改判率、未发现风险率、证据引用错误率和工具失败率。
- 在真实临床流程中先以“建议模式”运行,确认审核人员能有效使用输出后,再逐步扩大范围。
这类系统的价值不在于让模型替代临床判断,而在于缩短资料整理时间、减少漏看条件的概率,并把不确定性清楚地交给合适的人处理。HealthLake 提供可检索的数据基础,AgentCore 负责受控的智能体执行,Evaluations 则帮助团队把质量要求变成持续可测量的工程流程。