山东大学软件学院项目实训-基于语言大模型的智能居家养老健康守护系统-个人博客(四)
·
背景
用药安全审核的核心问题是:新药和正在吃的药会不会冲突?
原来的方案是让用户手动输入当前用药,但:
- 老人可能记不全
- 药名太专业可能说错
- 每次都要重复输入
数据库里明明有用药计划表,为什么不让AI自己查?
需要查哪些表
| 表名 | 查什么 | 为什么需要 |
|---|---|---|
elderly | 姓名、年龄 | 高龄患者用药需特别注意 |
disease | 疾病名称 | 了解治疗背景 |
medication_plan | 药品名称、剂量、用法 | 核心:当前用药 |
elderly_health_data | 血压、血糖 | 辅助判断用药风险 |
数据结构设计
复用 ElderlyContext,重点关注 MedicationInfo:
@Data
public class ElderlyContext {
private String name;
private Integer age;
private List<String> diseases;
private List<MedicationInfo> currentMedications; // 重点
private HealthData latestHealthData;
@Data
public static class MedicationInfo {
private String drugName; // 药品名称
private String dosage; // 剂量
private String usage; // 用法
private String diseaseName; // 用于治疗什么病
}
}
实现用药查询
查询当前用药
private List<MedicationInfo> getMedications(Long elderlyId) {
// 1. 查询用药计划表
List<MedicationPlan> plans = medicationPlanService.list(
new LambdaQueryWrapper<MedicationPlan>()
.eq(MedicationPlan::getElderlyId, elderlyId)
.eq(MedicationPlan::getStatus, 1) // 只查启用的
.orderByDesc(MedicationPlan::getCreatedAt)
);
// 2. 转换为MedicationInfo
List<MedicationInfo> result = new ArrayList<>();
for (MedicationPlan plan : plans) {
MedicationInfo info = new MedicationInfo();
info.setDrugName(plan.getDrugName());
info.setDosage(plan.getDosage());
info.setUsage(plan.getUsage());
// 3. 关联查询疾病名称
Disease disease = diseaseService.getById(plan.getDiseaseId());
if (disease != null) {
info.setDiseaseName(disease.getDiseaseName());
}
result.add(info);
}
return result;
}
查询结果示例
[
{
"drugName": "降压药A",
"dosage": "10mg/次",
"usage": "口服",
"diseaseName": "高血压"
},
{
"drugName": "活血药B",
"dosage": null,
"usage": "口服",
"diseaseName": "冠心病"
},
{
"drugName": "降糖药C",
"dosage": "500mg/次",
"usage": "口服",
"diseaseName": "2型糖尿病"
}
]
格式化输出
提供方法将用药信息格式化为字符串:
public String toMedicationInfoString() {
if (currentMedications == null || currentMedications.isEmpty()) {
return "\n【当前用药】\n- 无\n";
}
StringBuilder sb = new StringBuilder();
sb.append("\n【当前用药】\n");
for (MedicationInfo med : currentMedications) {
sb.append("- ").append(med.getDrugName());
if (med.getDosage() != null) {
sb.append(",剂量:").append(med.getDosage());
}
if (med.getUsage() != null) {
sb.append(",用法:").append(med.getUsage());
}
if (med.getDiseaseName() != null) {
sb.append("(用于治疗:").append(med.getDiseaseName()).append(")");
}
sb.append("\n");
}
return sb.toString();
}
输出示例:
【当前用药】
- 降压药A,剂量:10mg/次,用法:口服(用于治疗:高血压)
- 活血药B,用法:口服(用于治疗:冠心病)
- 降糖药C,剂量:500mg/次,用法:口服(用于治疗:2型糖尿病)
查询流程
getFullContext(elderlyId)
│
├─→ elderly表 ──→ 姓名、年龄
│
├─→ disease表 ──→ 疾病列表
│
├─→ medication_plan表 ──→ 用药计划列表
│ │
│ └─→ disease表 ──→ 关联疾病名称
│
└─→ elderly_health_data表 ──→ 健康数据
▼
ElderlyContext
│
▼
toMedicationInfoString()
│
▼
【当前用药】
- 降压药A,剂量:10mg/次...
优化点
1. 批量查询避免N+1
// ❌ 循环中逐个查询疾病
for (MedicationPlan plan : plans) {
Disease disease = diseaseService.getById(plan.getDiseaseId());
}
// ✅ 批量查询
List<Long> diseaseIds = plans.stream()
.map(MedicationPlan::getDiseaseId)
.distinct()
.collect(Collectors.toList());
Map<Long, Disease> diseaseMap = diseaseService.listByIds(diseaseIds)
.stream()
.collect(Collectors.toMap(Disease::getId, d -> d));
// 使用时直接从Map获取
Disease disease = diseaseMap.get(plan.getDiseaseId());
2. 处理空值
// 用药信息为空时的处理
if (currentMedications == null || currentMedications.isEmpty()) {
return List.of("无");
}
总结
这篇讲的是用药安全审核Agent的数据层工作:
- 从
medication_plan表查询当前用药 - 关联
disease表获取疾病名称 - 格式化为AI可理解的文本
更多推荐

所有评论(0)