山东大学软件学院项目实训-基于语言大模型的智能居家养老健康守护系统-个人博客(七)
·
一、本周工作目标
完成 AI 多角色对话系统的核心功能,包括 5 个 Agent 对话实现、用户安全隔离、家属辅诊身份修复。
二、AI 对话系统实现(5 个 Agent)
2.1 系统架构
采用"统一基座 + 差异化 Prompt"架构。所有 Agent 共享同一套会话管理(ChatSessionService)和大模型调用基础设施,通过不同的 System Prompt 定义角色能力边界。
调用链路:
用户消息 → Controller → resolveSession()
→ ElderlyContextService.getFullContext()(加载健康档案)
→ buildMessages()(构建消息数组)
→ AI API(/v1/chat/completions)
→ 保存会话 → 返回响应
2.2 Agent 矩阵
| Agent | 名字 | 接口前缀 | 核心能力 | 温度 |
|---|---|---|---|---|
| 情感陪伴 | 暖心 | /api/companion |
心理慰藉(companion)/ 陪诊助手(diagnosis) | 0.8 |
| 健康陪诊 | 康伴 | /api/health-companion |
全科健康问答、导诊 | 0.6 |
| 健康干预 | 养怡 | /api/health-intervention |
饮食/运动/作息个性化方案 | 0.5 |
| 用药安全审核 | — | /api/medication-safety |
药物配伍禁忌筛查 | 0.3 |
| 家属辅诊 | 家护 | /api/family-assist |
跨角色健康分析与照护建议 | 0.4 |
2.3 每个 Agent 提供 5 个接口
| 接口 | 方法 | 说明 |
|---|---|---|
/{prefix}/chat |
POST | 普通对话(等待完整回复) |
/{prefix}/chat/stream |
POST | 流式对话(SSE 逐字输出) |
/{prefix}/sessions |
GET | 当前用户的会话列表 |
/{prefix}/sessions/{sessionId} |
GET | 会话详情(含完整消息) |
/{prefix}/sessions/{sessionId} |
DELETE | 删除会话 |
2.4 请求/响应格式
请求体:
POST /api/companion/chat
Authorization: Bearer <token...ype: application/json
{
"elderlyId": 1,
"message": "我今天感觉有点头晕",
"mode": "companion",
"thinkingMode": "FAST"
}
普通响应:
{
"code": 200,
"data": {
"sessionId": "abc123...",
"reply": "您好呀,听到您说头晕,我心里有点惦记呢..."
}
}
流式响应(SSE):
event: sessionId
data: abc123...
event: message
data: 您好呀
event: message
data: ,听到您说头晕
event: done
data: [DONE]
2.5 个性化健康上下文
每次对话自动从数据库加载老人健康档案,注入 System Prompt:
- 基本信息(姓名、年龄、性别)
- 疾病列表(
disease表) - 当前用药计划(
medication_plan表) - 近期病历记录(
medical_record表,最近 5 条) - 最新体征数据(
elderly_health_data表)
AI 基于老人实际情况给出针对性建议,而非通用回答。
2.6 System Prompt 设计原则
- 明确身份:给 Agent 一个名字和职责范围
- 安全红线:急症关键词必须建议拨打 120
- 结构化输出:通过格式模板引导(如用药审核的【审核结果】【风险等级】)
- 隐私保护:指令 AI 不要主动暴露已知信息
三、用户隔离与安全加固
3.1 会话用户隔离
问题:15 个会话管理接口没有用户隔离,任意用户可查看/删除其他用户的对话。
修复:ChatSessionServiceImpl 注入 ElderlyAccessService,所有会话操作增加归属校验:
| 操作 | 隔离逻辑 |
|---|---|
| 列出会话 | 老人:elderlyId == 自己;家属:familyId == 自己 |
| 查看/删除 | 校验 session 归属,不匹配抛 403 |
| 创建会话 | assertCanAccessElderly(elderlyId) |
改动文件:ChatSessionService.java、ChatSessionServiceImpl.java、5 个 Controller
3.2 家属辅诊身份修复
问题:FamilyAssistController 的 familyId 从请求体获取,可被伪造。
修复:Controller 层用 JwtUserContext.requireFamilyId() 覆盖请求体中的值,非家属账号调用直接 403。
四、测试结果
| 测试项 | 结果 | 说明 |
|---|---|---|
| Agent 对话(5 个) | ✅ | 角色设定生效,回复符合预期 |
| 流式输出 | ✅ | SSE 逐字输出正常 |
| 用户隔离 | ✅ | 老人/家属只能看到自己的会话 |
| 家属辅诊身份 | ✅ | familyId 从 JWT 获取,不可伪造 |
五、前端对接指南
5.1 接口汇总
| 接口 | 方法 | 说明 |
|---|---|---|
/api/companion/chat |
POST | 情感陪伴 |
/api/companion/chat/stream |
POST | 情感陪伴流式 |
/api/health-companion/chat |
POST | 健康陪诊 |
/api/health-companion/chat/stream |
POST | 健康陪诊流式 |
/api/health-intervention/chat |
POST | 健康干预 |
/api/health-intervention/chat/stream |
POST | 健康干预流式 |
/api/medication-safety/check |
POST | 用药审核 |
/api/medication-safety/check/stream |
POST | 用药审核流式 |
/api/family-assist/chat |
POST | 家属辅诊 |
/api/family-assist/chat/stream |
POST | 家属辅诊流式 |
/{prefix}/sessions |
GET | 会话列表 |
/{prefix}/sessions/{id} |
GET/DELETE | 会话详情/删除 |
5.2 注意事项
- 所有接口需要 JWT 登录
- 会话隔离已生效,后端自动按用户过滤
- 家属辅诊的
familyId从 JWT 获取,前端不需要传 - 流式接口用
EventSource或fetch + ReadableStream接收
六、本周小结
完成了 AI 对话系统的核心功能:5 个 Agent 多轮对话、SSE 流式输出、用户安全隔离。通过统一的会话管理层 + 差异化的 System Prompt,用较少的代码量支撑了多个功能各异的 AI Agent。
更多推荐


所有评论(0)