2026年软件学院创新项目实训|智能居家养老健康守护系统·第五周工作博客
2026年山东大学软件学院创新项目实训小组周汇报
一、项目概述
本项目为智能居家养老健康守护系统,基于语言大模型构建多Agent矩阵,为老人和家属提供健康咨询、个性化干预、用药提醒等服务。系统包含五个核心Agent:健康陪诊Agent、健康干预Agent、家属辅诊Agent、用药安全Agent和情感陪伴Agent,通过统一的上下文聚合层和会话管理机制实现“采集一次、多处复用”的架构目标。
二、本周工作进展
2.1 后端开发
2.1.1 用药提醒模块
完成了基于老人自定义用药时刻的定时提醒功能,主要工作包括:
数据访问层:
- 关联查询
medication_schedule_time与medication_plan表,过滤启用计划与有效日期 - 实现了基于
dose_time、interval_days、enabled、start_date/end_date、status等字段的联合查询逻辑 - 专供定时任务使用的查询方法避免了全表无差别扫描
定时任务实现:
- 每分钟扫描匹配
dose_time,批量查询待提醒列表并分页处理 - 时间窗口调度按分钟级执行,将
dose_time与服务器当前时刻对齐到分钟级命中规则 - 明确使用业务时区(Asia/Shanghai)确保时间计算的准确性
短信触达能力:
- 封装独立的用药提醒短信服务,与验证码通道解耦
- 使用通知类模板及独立配置,模板变量与阿里云控制台审核文案一致
- 拼装药品名、服药时间等模板变量,保证老人机无推送SDK时仍能收到提醒
幂等控制机制:
- 使用Redis SETNX实现
med:remind:{scheduleTimeId}:{yyyy-MM-dd}键占坑 - 发送前原子占坑,成功再调短信接口,避免任务重试或多实例下重复发短信
- 避免为幂等单独扩表,便于与组员分工和库表变更节奏对齐
配置项设计:
- 提供任务开关、模板编码、时区/扫描步长等配置项
- 在application.yml中落地骨架与说明,短信AK、模板编码等敏感信息统一走配置文件或环境变量
2.1.2 AI Agent模块
完成了三个核心Agent的设计与实现:
1. 健康陪诊Agent
功能定位:首页全科问答入口,提供24小时健康咨询,扮演"全科陪诊员"角色。
核心能力:
- 常见养生保健知识问答(如"吃什么对血管好")
- 身体不适的初步判断与就医引导(如"头晕可能是什么原因")
- 就诊前准备事项提醒与情绪安抚
- 疑似急症的紧急升级(建议拨打120)
Prompt工程设计:
- 角色命名:"康伴"这个名字的人格化设计让老年用户形成固定的交互预期
- 否定式安全边界:明确告知模型"不做什么"比列举"做什么"更有效,"绝不做明确诊断"指令显著降低模型幻觉风险
- 紧急升级机制:在Prompt中显式列举急症特征(胸痛、呼吸困难等),确保模型识别到关键词时立即切换为"建议就医"模式
- Temperature设置为0.6,在"创造性回答多样化问题"和"保持医学表述准确性"之间取得平衡
2. 健康干预Agent
功能定位:联动病历夹生成个性化饮食/运动/作息方案,打破传统健康建议"千篇一律"的困境。
核心能力:
- 深度读取老人的数字病历夹数据(疾病史、用药清单、体征指标)
- 基于真实病理特征进行LLM推理,而非给出通用建议
- 支持饮食营养、运动康复、作息指导三个细分方向
- 输出具体、可执行的量化建议(如每日钠盐控制在5g以内)
分模式Prompt架构:
- 采用"基础Prompt + 模式Prompt"叠加架构
- 健康干预支持diet/exercise/lifestyle三种模式动态切换
- 通过interventionType字段动态组装System Prompt,实现"一个Agent多种人格"的效果
- 每种子领域Prompt定义了结构化的输出格式模板,引导模型生成规范内容
3. 家属辅诊Agent
功能定位:基于绑定关系为家属解读老人健康数据,解决家属"关心但看不懂"的困境。
核心能力:
- 综合分析已绑定老人的健康档案,生成通俗易懂的健康状况总结
- 解读体征指标的变化趋势,识别需要关注的异常信号
- 提供家属可直接执行的照护建议(饮食搭配、复诊提醒、用药监督等)
- 帮助家属理解老人的疾病进展和治疗方案含义
安全模型设计:
- 必须通过绑定关系校验才能访问老人数据,这是系统安全设计的基石
- 绝对不允许未经绑定的家属查看任何老人的健康数据
- 即使通过API直接调用也必须被拦截
- 校验放在Service层而非Controller层,防止通过其他内部调用路径绕过校验
Prompt工程特点:
- 语言风格从"亲切温和"调整为"专业简洁",信息密度更高
- 侧重"可执行的照护建议",而非长篇的医学解释
- “表述准确但通俗,避免让家属过度焦虑”+"明确区分数据显示和建议就医确认"的指令
- Temperature设置为0.4,需要高准确性但比药理审核稍高
关键技术实现:
上下文聚合机制:
- ElderlyContextService从五张业务表(elderly、disease、medication_plan、medical_record、elderly_health_data)汇聚数据
- 将异构的结构化数据统一转换为LLM可理解的自然语言格式
- 为不同Agent提供不同粒度的上下文(全量/基础)
- 采用自然语言格式而非JSON,因为中文标签提供了清晰的语义分隔,LLM推理准确率更高
流式响应实现:
- 基于Java 11 HttpClient + SseEmitter实现逐字输出,降低老年用户等待焦虑
- 流式解析DeepSeek返回的SSE数据流,处理心跳行和错误响应
- 设置120秒超时并注册onTimeout回调确保连接干净关闭
权限校验机制:
- 家属辅诊在Service层前置绑定关系校验,防止跨用户数据泄露
- 流式接口的权限校验必须在建立SSE连接之前完成
- 校验失败时异常在Controller线程抛出,Spring的全局异常处理器可以正常捕获并返回JSON错误响应
多轮会话管理:
- 所有Agent共享一套ChatSessionService,通过agentType字段实现逻辑隔离
- 会话模型包含sessionId、agentType、mode、messages历史消息等
- 前端无需维护本地消息列表,所有状态由后端会话管理统一托管
2.2 前端开发
1. 用药提醒服务层对接
完成与后端MedicationReminderController和MedicationPlanController的接口适配:
medicationReminder.js:实现今日提醒、未确认提醒、历史记录、确认服药等功能medicationPlan.js:实现用药计划的增删改查
2. AI Agent服务层对接
完成5种Agent的统一服务层封装:
companion.js→ EmotionalCompanionController(情感陪伴)healthCompanion.js→ HealthCompanionController(健康陪诊)healthIntervention.js→ HealthInterventionController(健康干预)familyAssist.js→ FamilyAssistController(家属辅诊)medicationSafety.js→ MedicationSafetyController(用药安全)
3. 页面功能完善
用药提醒页面:
- 今日提醒列表展示
- 计划管理功能
- 确认服药操作
- Tab切换 between 不同视图
AI聊天页面:
- 5种Agent类型支持
- 流式/普通双模式切换
- 历史会话管理
- 会话ID的生命周期管理(首次请求生成UUID,后续请求恢复历史)
三、问题与处理
| 问题 | 原因 | 解决方案 |
|---|---|---|
| SSE流式响应中emitter.complete()重复调用 | AI生成代码在外层和内层各调用一次 | 仅在流结束时调用一次,去掉外层的emitter.complete()调用 |
| 绑定校验在异步线程中导致403无法被全局异常处理器捕获 | Spring MVC线程模型限制 | 将校验提到主线程执行,在executor.execute之前执行verifyBinding |
| 上下文注入后模型回复仍为通用建议 | buildMessages使用静态常量 | 改为动态拼接完整Prompt,调用buildSystemPrompt(context, interventionType)方法 |
| medication_plan关联查询N+1问题 | 每条记录单独查disease表 | 批量查询后内存关联,先查出所有相关disease构建Map后内存关联 |
| interventionType为null时NPE | switch直接调用.toLowerCase() | 前置null判断,在switch之前加null检查 |
| SSE流中DeepSeek返回的非标准行导致JSON解析异常 | 没有对objectMapper.readTree(data)做try-catch | 内层加try-catch跳过解析失败的行,并记录debug日志 |
| 会话并发写入导致消息顺序错乱 | 多线程同时操作同一个ChatSession的messages列表 | 在resolveSession和saveSession中对同一sessionId加基于ConcurrentHashMap的轻量锁 |
| currentMedications为空列表时输出不一致 | 判空逻辑只判了null没判空列表 | 补充isEmpty()判断 |
| 家属辅诊的"关键病理特征覆盖率"不足 | Prompt中缺少相关指令 | 在Prompt中加入"关键病理特征要完整覆盖,不遗漏重要信息"指令 |
四、下周计划
- 完成短信控制台模板与RAM/签名的端到端联调,验证高峰窗口下查询性能与短信到达率
- 与前端约定用药录入与展示字段,补充"今日用药"只读接口与错误码
- 优化AI聊天弱网环境下的降级策略
- 增加关键场景的自动化测试覆盖
- 继续配合组内病历OSS与写库联调,推进健康基线等并行任务
- 规划实现基于摘要压缩的历史消息裁剪策略,解决长对话的Token管理问题
五、总结
本周完成了用药提醒模块和AI Agent模块的后端实现与前端对接工作。通过统一的上下文聚合层和会话管理机制,五个Agent共享数据基座,实现了"采集一次、多处复用"的架构目标。前端服务层已全面适配后端新增接口,功能完整性得到显著提升。
在技术实现方面,我们取得了以下关键成果:
- Prompt工程成为核心竞争力:相同的模型,不同的Prompt可以产出天差地别的效果,通过精心设计的Prompt实现了不同Agent的差异化表现
- 分模式架构比多Agent拆分更经济:健康干预的diet/exercise/lifestyle三个方向共享基础设施,通过Prompt叠加实现差异化
- 医疗场景安全边界必须在Prompt和代码双层设定:不能仅靠模型"自觉",需要在代码层实现硬权限拦截
- 流式输出不是锦上添花而是刚需:对于老年用户,3-5秒的等待空白足以让他们以为系统"死机了"
- AI辅助编码的真正瓶颈在运行时:生成代码容易,但并发安全、性能优化、异常路径覆盖这些问题只有跑起来+人工审查才能发现
通过本周的工作,我们不仅完成了预定的功能开发,更在AI辅助开发实践中积累了宝贵经验,为后续的项目推进奠定了坚实基础。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)