改造目标

改造点说明
简化请求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(严谨)
输出风格自然对话结构化审核结果

总结

上下文注入的核心步骤:

  1. 简化请求:currentMedications 改为可选
  2. 自动获取:从 medication_plan 表查询
  3. 注入提示词:把患者背景加入系统提示词
  4. 智能审核:AI结合患者情况给出精准建议

一个 elderlyId 字段,让AI从"等用户告诉"变成"自己去查"。

更多推荐