山东大学软件学院项目实训-基于语言大模型的智能居家养老健康守护系统-个人博客(五)
·
改造目标
| 改造点 | 说明 |
|---|---|
| 简化请求 | currentMedications 改为可选 |
| 自动获取 | 从数据库查当前用药 |
| 注入背景 | 把患者信息加入提示词 |
第一步:修改请求DTO
修改 MedicationCheckRequest:
@Data
@Schema(description = "用药安全审核请求")
public class MedicationCheckRequest {
@Schema(description = "会话ID,为空则创建新会话")
private String sessionId;
@NotNull(message = "老人ID不能为空")
@Schema(description = "老人ID", example = "1")
private Long elderlyId; // 新增
@Schema(description = "当前用药,为空则自动从数据库查询",
example = "[\"降压药A\", \"活血药B\"]")
private List<String> currentMedications; // 改为可选
@NotBlank(message = "拟服用药物不能为空")
@Schema(description = "准备新增服用的药物", example = "阿司匹林")
private String newMedication;
}
改造前的请求:
{
"currentMedications": ["降压药A", "活血药B"],
"newMedication": "阿司匹林"
}
改造后的请求:
{
"elderlyId": 1,
"newMedication": "阿司匹林"
}
第二步:自动获取当前用药
在 MedicationSafetyServiceImpl 中添加自动查询逻辑:
@Override
public String checkMedicationSafety(MedicationCheckRequest request) {
// 1. 获取老人完整上下文
ElderlyContext context = elderlyContextService.getFullContext(request.getElderlyId());
// 2. 获取当前用药:优先用手动输入的,否则从数据库查
List<String> currentMedications = request.getCurrentMedications();
if (currentMedications == null || currentMedications.isEmpty()) {
if (context != null && context.getCurrentMedications() != null) {
// 从上下文中提取药品名称
currentMedications = context.getCurrentMedications().stream()
.map(ElderlyContext.MedicationInfo::getDrugName)
.collect(Collectors.toList());
} else {
currentMedications = List.of("无");
}
}
// 3. 构建用户消息
String currentDrugs = String.join("、", currentMedications);
String userMessage = String.format(
"患者(老年人)目前正在服用以下药物:【%s】,现准备加服【%s】。" +
"请判断是否存在药物配伍禁忌、药食冲突或其他用药安全风险。",
currentDrugs, request.getNewMedication()
);
// 4. 调用AI...
}
关键逻辑:
前端传了 currentMedications?
├─ 是 → 使用前端传的
└─ 否 → 从数据库自动获取
├─ 有数据 → 提取药品名称
└─ 无数据 → 返回 ["无"]
第三步:注入患者背景到提示词
修改 buildMessages 方法:
private List<Map<String, String>> buildMessages(ChatSession session, ElderlyContext context) {
List<Map<String, String>> messages = new ArrayList<>();
String systemPrompt = SYSTEM_PROMPT;
if (context != null) {
systemPrompt += "\n\n以下是当前患者的详细背景信息,"
+ "请结合这些信息进行用药安全审核:\n"
+ context.toFullContextString();
}
messages.add(Map.of("role", "system", "content", systemPrompt));
for (ChatMessage msg : session.getMessages()) {
messages.add(Map.of("role", msg.getRole(), "content", msg.getContent()));
}
return messages;
}
注入后的提示词示例:
你是一位经验丰富的临床药师 AI 助手,专注于老年人用药安全审核...
(原有提示词)
以下是当前患者的详细背景信息,请结合这些信息进行用药安全审核:
【基本信息】
- 姓名:张奶奶
- 性别:女
- 年龄:78岁
【疾病史】
- 高血压(确诊10年)
- 冠心病
- 2型糖尿病
【当前用药】
- 降压药A,剂量:10mg/次,用法:口服(用于治疗:高血压)
- 活血药B,用法:口服(用于治疗:冠心病)
- 降糖药C,剂量:500mg/次,用法:口服(用于治疗:2型糖尿病)
【最新健康数据】
- 血压:150/95 mmHg
- 血糖:7.2 mmol/L
第四步:修改 callDeepSeekApi 方法
private String callDeepSeekApi(ChatSession session, ElderlyContext context) {
String url = deepSeekConfig.getBaseUrl() + "/v1/chat/completions";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(deepSeekConfig.getApiKey());
// 传入context
Map<String, Object> body = Map.of(
"model", deepSeekConfig.getModel(),
"messages", buildMessages(session, context), // 传入context
"temperature", 0.3,
"max_tokens", 2000
);
// 调用API...
}
完整调用链
前端请求 {elderlyId: 1, newMedication: "阿司匹林"}
│
▼
┌─────────────────────────────────────────────────────────┐
│ checkMedicationSafety() │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. elderlyContextService.getFullContext(1) │
│ │ │
│ ▼ │
│ ElderlyContext { │
│ name: "张奶奶", │
│ age: 78, │
│ currentMedications: [ │
│ {drugName: "降压药A", ...}, │
│ {drugName: "活血药B", ...} │
│ ] │
│ } │
│ │
│ 2. 自动获取当前用药 │
│ │ │
│ ▼ │
│ ["降压药A", "活血药B"] │
│ │
│ 3. 构建用户消息 │
│ │ │
│ ▼ │
│ "患者目前服用:【降压药A、活血药B】,准备加服【阿司匹林】" │
│ │
│ 4. callDeepSeekApi(session, context) │
│ │ │
│ ▼ │
│ DeepSeek API │
│ │
└─────────────────────────────────────────────────────────┘
效果对比
请求:
{"elderlyId": 1, "newMedication": "阿司匹林"}
改造前的AI回复:
请告诉我您目前在吃什么药...
(卡住了,不知道当前用药)
改造后的AI回复:
【审核结果】:存在风险
【风险等级】:中危
【详细分析】:
1. 患者正在服用活血药B,与阿司匹林合用会增加出血风险
2. 患者78岁,高龄患者使用阿司匹林需谨慎
3. 患者血压150/95mmHg,控制不佳时使用阿司匹林风险更高
【建议措施】:
1. 不建议自行加服,请先咨询医生
2. 如需使用,建议先控制血压
3. 注意观察出血征兆
设计思考
1. 为什么保留手动输入?
// 优先级:手动输入 > 数据库查询
List<String> currentMedications = request.getCurrentMedications();
if (currentMedications == null || currentMedications.isEmpty()) {
// 从数据库查...
}
原因:
- 老人可能有院外用药(保健品、其他医院开的药)
- 数据库可能还没录入最新的用药变化
- 保留灵活性
2. 温度参数选择
"temperature", 0.3 // 用药审核用低温度
用药审核需要严谨、确定,所以用低温度(0.3),避免AI"创造性"地给出错误建议。
3. 与情感陪伴Agent的区别
| 对比项 | 情感陪伴Agent | 用药安全审核Agent |
|---|---|---|
| 上下文用途 | 个性化对话 | 自动获取用药 |
| 温度参数 | 0.8(灵活) | 0.3(严谨) |
| 输出风格 | 自然对话 | 结构化审核结果 |
总结
上下文注入的核心步骤:
- 简化请求:
currentMedications改为可选 - 自动获取:从
medication_plan表查询 - 注入提示词:把患者背景加入系统提示词
- 智能审核:AI结合患者情况给出精准建议
一个 elderlyId 字段,让AI从"等用户告诉"变成"自己去查"。
更多推荐

所有评论(0)